2025-02-21 17:26:32 +08:00

1239 lines
41 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div style=" height: 100%;">
<div class="layout-center-wrap flex-column">
<!-- 上部数据 -->
<div class="layout-center-top-wrap flex-row justify-content-between">
<div class="top-wrap-title flex-row justify-content-between"></div>
<div class="top-wrap-btn-left flex-row justify-content-between">
<div class="flex-row justify-content-between align-items-center mr-16">
<el-button icon="el-icon-arrow-left" circle :disabled="(queue || index ===0) ? true : false" @click="getFrontCaseById"></el-button>
<div class="ml-16 mr-16 flex-row justify-content-between align-items-center">
<div class="mr-8 f16">{{ baseInfo.debtorEntityList.find(item => (item.role == 'DEBTOR' && item.type == '本人')).name }}</div>
<div class="mr-8">
<el-tag size="small" type="warning">{{ baseInfo.debtorEntityList.find(item => (item.role == 'DEBTOR' && item.type == '本人')).addr }}</el-tag>
</div>
<div class="mr-8 f16 color-FF7D00"><i class="el-icon-warning"></i></div>
<div class="f16 color-165DFF"><i class="el-icon-success"></i></div>
</div>
<el-button icon="el-icon-arrow-right" circle :disabled="(queue || index >= queueList.length - 1) ? true : false" @click="getNextCaseById"></el-button>
</div>
<el-popover
placement="top"
width="500"
v-model="singlesmsvisible"
title="发送短信"
trigger="click">
<singlesmsPopover :caseId="caseId" :sendPhone="sendPhones" :singlesmsvisible.sync="singlesmsvisible"/>
<el-button slot="reference" type="warning" icon="el-icon-message" circle></el-button>
</el-popover>
<div v-if="!queue" class="wrap-btn-left-dial-f2f3f5 f14 flex-row justify-content-between ml-16">
<el-button v-if="!calling" type="success" icon="el-icon-phone-outline" circle @click="startCall()"></el-button>
<div v-else class="flex-row justify-content-between align-items-center">
<div class="mr-8 color-fff wrap-btn-left-dial-f56c6c flex-row justify-content-between align-items-center" @click="hungUp(0)">
<i class="el-icon-phone-outline f20 mr-4"></i>
<span class="f12 ">挂断电话</span>
</div>
<div class="flex-row justify-content-between align-items-center ml-16 pr-24">
<div class="mr-8 f12 color-000">{{formattedTime || '00:00'}}</div>
<!-- <div class="mr-8 f20 cursor-p"><i class="el-icon-phone"></i></div> -->
<div class="mr-8 f20 cursor-p" v-if="!isMute" @click="muteMic()"><i class="el-icon-microphone"></i></div>
<div class="mr-8 f20 cursor-p" v-if="isMute" @click="unmuteMic()"><i class="el-icon-turn-off-microphone"></i></div>
<div class="mr-8 ai-logo-img"></div>
</div>
</div>
</div>
<div class="wrap-btn-left-dial pl-22 pr-24 f14 flex-row justify-content-between ml-16">
<div v-if="queue" class="flex-row justify-content-between align-items-center">
<div v-if="calling" class="mr-8 f16 color-F53F3F cursor-p" @click="pauseTimer()"><i class="el-icon-video-pause"></i></div>
<div v-else class="mr-8 f16 color-F53F3F cursor-p" @click="startCall()"><i class="el-icon-video-play"></i></div>
<div class="mr-8 cursor-p" v-if="calling" @click="pauseTimer()">已暂停自动拨打</div>
<div class="mr-8 cursor-p" v-else @click="startCall()">开始拨打</div>
<div class="mr-8 f12 color-000" v-if="calling">{{formattedTime || '00:00'}}</div>
<div class="mr-8 f20 cursor-p" v-if="calling" @click="hungUp(1)"><i class="el-icon-phone"></i></div>
<div class="mr-8 f20 cursor-p" v-if="calling && !isMute" @click="muteMic()"><i class="el-icon-microphone"></i></div>
<div class="mr-8 f20 cursor-p" v-if="calling && isMute" @click="unmuteMic()"><i class="el-icon-turn-off-microphone"></i></div>
<div class="mr-8 ai-logo-img" v-if="calling"></div>
</div>
<div class="flex-row justify-content-between align-items-center f14">
<el-popover
placement="bottom"
width="1000"
trigger="click">
<div>
<div class="f16 p-16 border-b-solid-lighter-1">{{queue ? '智能外呼案件列表' : '案件列表'}}</div>
<div class="p-16">
<el-scrollbar :style="'height:300px;'">
<el-table ref="queueTable" :data="queueList" style="width: 100%;" highlight-current-row>
<el-table-column type="index" label="序号" width="50"></el-table-column>
<el-table-column prop="contact" label="被申请人姓名" width="150"></el-table-column>
<el-table-column prop="caseNo" label="案件编号">
<template slot-scope="scope">
<span>{{scope.row.caseNo}}</span>
<span v-if="scope.$index === index && !queue" style="color:#4080FF;margin-left: 10px;">正在调解中...</span>
</template>
</el-table-column>
<el-table-column prop="phone" label="电话号码" width="150"></el-table-column>
<el-table-column prop="moneyAmount" label="逾期金额" width="150"></el-table-column>
<el-table-column label="操作" width="150" v-if="queue">
<template slot-scope="scope">
<div v-if="scope.$index === index" style="color:#4080FF">正在调解中...</div>
<div v-else-if="scope.row.status.code === 1" style="color:#BC6F60">未拨打<i class="el-icon-phone-outline el-icon--right"></i></div>
<div v-else style="color:#E5E6EB">已拨打</div>
</template>
</el-table-column>
</el-table>
</el-scrollbar>
</div>
</div>
<div slot="reference" class="flex-row justify-content-between align-items-center mr-24 cursor-p">
<div class="mr-8 f16"><i class="el-icon-s-operation"></i></div>
<div>{{queue ? '队列' : '列表'}} <span class="color-000">
{{queue ? callingInfoData.countInit : ''}}
</span></div>
</div>
</el-popover>
<div v-if="queue" class="flex-row justify-content-between align-items-center f14">
<div class="mr-24">已拨打 <span class="color-000">{{callingInfoData.countCall}}</span></div>
<div class="mr-24">已接通 <span class="color-000">{{callingInfoData.countOk}}</span></div>
<div>未接通 <span class="color-000">{{callingInfoData.countFail}}</span></div>
</div>
<div v-else class="flex-row justify-content-between align-items-center f14">
<div class="mr-24">今日已拨打 <span class="color-000">{{todayCountData.countCall}}</span></div>
<div class="mr-24">今日已接通 <span class="color-000">{{todayCountData.countOk}}</span></div>
<div>今日未接通 <span class="color-000">{{todayCountData.countFail}}</span></div>
</div>
</div>
</div>
</div>
<div class="flex-row justify-content-between">
<el-button icon="el-icon-setting" circle></el-button>
<el-button icon="el-icon-switch-button" circle @click="handleBack"></el-button>
</div>
</div>
<!-- 中间数据 -->
<LayoutContentNew ref="layoutContent" :caseId="caseId" :thisCaseInfo="thisCaseInfo" :updateUnm="updateUnm" @startOutboundCall="startOutboundCall" @updateCaseInfoById="getCaseInfoById" />
</div>
<div class="flex-row align-items-center pl-24 pr-24 btn-group-controls">
<div class="pt-16 pb-16 flex-row justify-content-between align-items-center btn-group-real-time">
<el-popover
placement="top"
width="400"
v-model="missedCallVisible"
:disabled="missedCallData.list.length <= 0"
title="未接来电"
trigger="click">
<missedCallPopover :missedCallData="missedCallData" :missedCallVisible.sync="missedCallVisible"/>
<span slot="reference" class="cursor-pointer position-r">
<i class="f24 el-icon-phone color-52ABF2"></i>
<div class="ell-warn-dot" v-if="missedCallData.list.length > 0">{{missedCallData.list.length}}</div>
</span>
</el-popover>
<el-popover
placement="top"
width="400"
v-model="videoReminderVisible"
:disabled="Object.keys(videoReminderData).length <= 0"
title="视频提醒"
trigger="click">
<videoReminderPopover :videoReminderData="videoReminderData" :videoReminderVisible.sync="videoReminderVisible"/>
<span slot="reference" class="cursor-pointer position-r">
<i class="f24 el-icon-video-camera color-52ABF2"></i>
<div class="ell-warn-dot" v-if="Object.keys(videoReminderData).length > 0">1</div>
</span>
</el-popover>
</div>
<div class="ml-24 mr-24 btn-group-interval"></div>
<div class="flex-row justify-content-between align-items-center btn-group-processing-event">
<div class="flex-row justify-content-between align-items-center cursor-pointer bottom-case-btn" @click="visiblePopover={caseId: caseId}">
<i class="f24 el-icon-video-camera color-4E5969"></i>
<div class="pl-4 f14">预约</div>
</div>
<div class="flex-row justify-content-between align-items-center cursor-pointer bottom-case-btn">
<i class="f24 el-icon-document color-4E5969"></i>
<div class="pl-4 f14">协议</div>
</div>
<el-popover
placement="top"
width="500"
v-model="singleofficevisible"
title="发起签字"
trigger="click">
<singleofficeWritPopover :caseId="caseId" :singleofficevisible.sync="singleofficevisible" @handleUpdate='getSetTimeWritCaseList'/>
<span slot="reference" class="flex-row justify-content-between align-items-center cursor-pointer bottom-case-btn">
<i class="f24 el-icon-document-remove color-4E5969"></i>
<a class="pl-4 f14">签字</a>
</span>
</el-popover>
<el-popover
placement="top"
width="500"
v-model="singlesealvisible"
title="发起签章"
trigger="click">
<singleofficeSealPopover :caseId="caseId" :singlesealvisible.sync="singlesealvisible"/>
<span slot="reference" class="flex-row justify-content-between align-items-center cursor-pointer bottom-case-btn">
<i class="f24 el-icon-s-check color-4E5969"></i>
<a class="pl-4 f14">签章</a>
</span>
</el-popover>
<el-popover
placement="top"
width="500"
v-model="singledeliveryvisible"
title="发起送达"
trigger="click">
<singleofficeDeliveryPopover :caseId="caseId" :singledeliveryvisible.sync="singledeliveryvisible"/>
<span slot="reference" class="flex-row justify-content-between align-items-center cursor-pointer bottom-case-btn">
<i class="f24 el-icon-s-claim color-4E5969"></i>
<a class="pl-4 f14">送达</a>
</span>
</el-popover>
<div class="flex-row justify-content-between align-items-center cursor-pointer bottom-case-btn">
<i class="f24 el-icon-wallet color-4E5969"></i>
<div class="pl-4 f14">类案</div>
</div>
<div class="flex-row justify-content-between align-items-center cursor-pointer bottom-case-btn" @click="handleChangeCaseStatus()">
<i class="f24 el-icon-document-checked color-4E5969"></i>
<div class="pl-4 f14">办结</div>
</div>
<div class="flex-row justify-content-between align-items-center cursor-pointer bottom-case-btn" @click="handleChangeMediation(4)">
<i class="f24 el-icon-document-delete color-4E5969"></i>
<div class="pl-4 f14">失败</div>
</div>
<div class="flex-row justify-content-between align-items-center cursor-pointer bottom-case-btn" @click="handleChangeMediation(5)">
<i class="f24 el-icon-bangzhu color-4E5969"></i>
<div class="pl-4 f14">成功</div>
</div>
<div class="flex-row justify-content-between align-items-center cursor-pointer bottom-case-btn">
<i class="f24 el-icon-user-solid color-4E5969"></i>
<div class="pl-4 f14">帮扶</div>
</div>
<el-popover
placement="top"
width="400"
v-model="singlejointlyvisible"
title="案件协办"
trigger="click">
<singleJointlyPopover :caseId="caseId" :assistMediatorId="baseInfo.assistMediatorId" :singlejointlyvisible.sync="singlejointlyvisible" @handleSubmit="getCaseInfoById()"/>
<span slot="reference" class="flex-row justify-content-between align-items-center cursor-pointer bottom-case-btn">
<i class="f24 el-icon-s-management color-4E5969"></i>
<a class="pl-4 f14">协办</a>
</span>
</el-popover>
</div>
</div>
<caseVideoReservationDialog v-if="visiblePopover" :visible-popover.sync="visiblePopover" />
<!-- 视频房间 -->
<VideoRoom v-if="VideoCallDialog" :eventDialog.sync="VideoCallDialog" />
</div>
</template>
<script>
import api from "@/services/caseManagement";
import {mapState} from 'vuex'
import voiceCall from "@/services/voiceCall";
export default {
components: {
caseVideoReservationDialog: () => import('./caseVideoReservationDialog'),//
singleofficeWritPopover: () => import('./singleofficeWritPopover.vue'),//发起签字
singleofficeSealPopover: () => import('./singleofficeSealPopover.vue'),//发起签章
singleofficeDeliveryPopover: () => import('./singleofficeDeliveryPopover.vue'),//发起送达
singleJointlyPopover: () => import('./singleJointlyPopover.vue'),//案件协办
singlesmsPopover: () => import('./singlesmsPopover.vue'),//发送短信
VideoRoom: () => import('./VideoRoom'),
LayoutContentNew: () => import('./LayoutContentNew'),//调解数据
missedCallPopover: () => import('./missedCallPopover'),//来电
videoReminderPopover: () => import('./videoReminderPopover'),//视频
},
data() {
return {
singlesmsvisible:false,
singlejointlyvisible:false,
visiblemediatRecord:false,
singledeliveryvisible:false,
singlesealvisible:false,
singleofficevisible:false,
eventDialog: {caseId: ''},
leftActive: 1,
rightActive: 1,
sendPhones:[],
mediationRecord: [],//调解记录
baseInfo: {debtorEntityList:[]},//基本信息
obligorInfo: [],//债务人信息
caseId: 0,//案件id或共债主案id
thisCaseInfo:{},//当前案件信息
// 联系人
contactAddObj: {},
contactAddFlag: false,
contactObj: {},
contactUpdate: false,
relationOptions: [{label: '本人', value: '本人'}, {label: '父母', value: '父母'}, {label: '配偶', value: '配偶'},
{label: '子女', value: '子女'}, {label: '其他', value: '其他'}, {label: '朋友', value: '朋友'}, {
label: '兄弟',
value: '兄弟'
},
{label: '同事', value: '同事'}, {label: '同学', value: '同学'}],
// 还款计划
repaymentObj: {
type: 'ALL'
},
RepaymentOptions: [{label: '一次性还款', value: 'ALL'}, {
label: '全部分期',
value: 'STAGES'
}, {label: '部分先还加分期', value: 'MIX'}, {label: '其他', value: 'OTHER'}],
rulesClientRepayment: {
type: [
{required: true, message: '请选择还款方式', trigger: 'change',},
],
totalAmount: [
{required: true, message: '请输入还款金额', trigger: 'change',},
{
pattern: /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0.\d{1,2}$/,
message: '请输入2位小数金额',
trigger: ['blur', 'change']
}
],
paybackDate: [
{required: true, message: '请选择还款截止日期', trigger: 'change',},
],
stagesDay: [
{required: true, message: '请选择每期还款日期', trigger: 'change',},
],
partAmount: [
{required: true, message: '请输入分期前偿还金额 ', trigger: 'change',},
{
pattern: /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0.\d{1,2}$/,
message: '请输入2位小数金额',
trigger: ['blur', 'change']
}
],
partDate: [
{required: true, message: '请选择分期前偿还日期', trigger: 'change',},
],
stagesNum: [
{required: true, message: '请输入分期期数', trigger: 'change',},
{pattern: /^[1-9]\d*$/, message: '只能输入正整数', trigger: ['blur', 'change']}
],
},
communicationRecord: [],
visiblePopover: null,
VideoCallDialog: null,
mediaterecordpm:{
caseId:'',
linkedWay:''
},
materialTypeOptions: this.$util.getMediationprogress(),
queue: false,
queueList: [],
phoneNumber: '13982024318',
sessionId: '',
index: 0, //当前通话的索引
calling: false, // 是否在通话
isMute: false, //是否静音
isPause: false, //是否暂停
updateUnm:1,
callingInfoData: {
countInit: 0,
countOk: 0,
countFail: 0,
countCall: 0,
},
todayCountData: {
countInit: 0,
countOk: 0,
countFail: 0,
countCall: 0,
},
startTime: 0,
elapsedTime: 0,
timerInterval: null,
isRunning: false,
contactId: '',
// 未接来电
missedCallVisible: false,
missedCallData: {
list: []
},
// 视频提醒
videoReminderVisible: false,
videoReminderData: {},
videoCallInterval: null,
};
},
computed: {
// 左侧
leftContentHeight() {
let oh = document.documentElement.clientHeight;
return oh - 100
},
// 获取右侧滚动高度
rightContentHeight() {
let oh = document.documentElement.clientHeight;
return oh - 57
},
// 获取抽屉drawer的内容高度
OfficecontentHeight() {
let oh = document.documentElement.clientHeight;
return oh - 185
},
CommunicationcontentHeight() {
let oh = document.documentElement.clientHeight;
return oh - 57 - 48 - 38 -308
},
MediationrecordHeight() {
let oh = document.documentElement.clientHeight;
return oh - 57 - 128
},
formattedTime() {
const totalSeconds = Math.floor(this.elapsedTime / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
},
...mapState({
videoReminder: state => state.videoReminder
}),
},
watch: {
videoReminder: {
deep: true,
handler: function (val) {
if (val){
console.log(val, '---视频提前5分钟提醒')
this.videoReminderData = JSON.parse(val)
}
}
},
'$route.query': {
handler(newQuery) {
console.log(newQuery, '---newQuery')
if (newQuery && newQuery.caseId != null && newQuery.caseId != undefined && this.caseId !== newQuery.caseId){
this.caseId = this.$route.query.caseId || null
this.getCaseInfoById();//获取详情
this.missedCallList();//未接来电
}
},
immediate: true,
deep: true
}
},
async created() {
// if(this.$route.query.caseId != null && this.$route.query.caseId != undefined) {
// this.caseId = this.$route.query.caseId || null
// this.queue = this.$route.query.queue || null
// await this.getCaseInfoById();//获取详情
// }
this.queue = this.$route.query.queue || null
await this.callingTodayCount() //今日通话次数
if (this.queue) {
await this.callingQueue() //呼叫队列
await this.callingInfo() //呼叫统计
} else {
await this.callingCaseList() //案件列表
}
this.videoCallInterval = setInterval(() => {
console.log('进入videoCall---------setInterval')
this.videoCall()
}, 30000);
const that = this
window.tccc.on('sessionEnded', (options) => {
console.log('监听挂断事件', options)
that.calling = false
that.resetTimer()
that.nextCall()
})
},
beforeDestroy() {
if(this.timerInterval) { //如果定时器还在运行 或者直接关闭,不用判断
clearInterval(this.timerInterval); //关闭
}
if (this.videoCallInterval) {
clearInterval(this.videoCallInterval)
}
},
methods: {
getSetTimeWritCaseList(){
this.updateUnm ++;
},
debtorEntityCardNo(datalist, len) {
let datacardno = ''
let dataphone = ''
datalist.forEach((item, index) => {
if (index == 0) {
datacardno = item.cardNo
dataphone = item.phone
} else {
datacardno += ',' + item.cardNo
dataphone += ',' + item.phone
}
})
return {cardNo: datacardno.substring(0, len), phone: dataphone.substring(0, len)};
},
// 视频快开提醒
videoCall() {
api.videoCall({}).then(res => {
console.log('视频提前提醒:',res)
if (!res.code) {
this.videoReminderData = res ? JSON.parse(res) : {}
}
})
},
// 获取详情
async getCaseInfoById() {
// this.$loading(true)
this.sendPhones = []
await api.getCaseInfoById(this.caseId).then(res => {
if (!res.code) {
this.baseInfo = res
this.phoneNumber = res.debtorEntityList.find(item => item.role == 'DEBTOR' && item.type == '本人').phone
this.contactId = res.debtorEntityList.find(item => item.role == 'DEBTOR' && item.type == '本人').id
if(this.baseInfo.debtorEntityList !=undefined)
{
this.baseInfo.debtorEntityList.forEach(item =>{
if(item.role == 'DEBTOR' && item.type == '本人'){
this.sendPhones.push(item.phone)
}
})
}
this.thisCaseInfo = res
if(res.jointDebt == 1){
// 有共债 mainCaseId
this.caseId = res.mainCaseId.toString()
} else {
this.caseId = res.id.toString()
}
}
this.$loading().close();
this.eventDialog.caseId = this.caseId
// this.getmediate_record()
}).catch(err => {
this.$loading().close();
})
},
// 获取上一件案件
getFrontCaseById() {
if (!this.$clickThrottle(1000)) {
return
}//防止重复点击
if(this.queue || this.index === 0) return
this.index--
this.caseId = String(this.queueList[this.index].caseId)
this.$loading({
lock: true,
text: '加载中...',
target: 'body'
});
this.getCaseInfoById()
// api.getFrontCaseById({id: this.caseId}).then(res => {
// if (!res.code) {
// // let caseChangeData = res
// this.detailData(res)
// }
// })
},
// 获取下一件案件
getNextCaseById() {
if (!this.$clickThrottle(1000)) {
return
}//防止重复点击
if(this.queue || this.index >= this.queueList.length - 1) return
this.index++
this.caseId = String(this.queueList[this.index].caseId)
console.log('下一个案件id: ' + this.caseId, this.index, this.queueList)
this.$loading({
lock: true,
text: '加载中...',
target: 'body'
});
this.getCaseInfoById()
// api.getNextCaseById({id: this.caseId}).then(res => {
// if (!res.code) {
// this.detailData(res)
// }
// })
},
handleBack() {
// this.$route.query.sourcePage == 'mediationManagement'
this.$router.push('/mediation-management')
},
// 获取调解记录
getmediate_record() {
this.mediaterecordpm.caseId = this.caseId
api.mediate_record_list(this.mediaterecordpm).then(res => {
if (!res.code) {
this.communicationRecord = res
}
})
},
// 调解成功或者失败
handleChangeMediation(resultStatus){
let data={
id:this.caseId,
mediateStatus:resultStatus
}
let resultmsg = '成功'
if(resultStatus == 4){resultmsg = '失败'}
this.$confirm("请确定是否将案件标记为"+resultmsg+"?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
if(!this.$clickThrottle()) { return }//防止重复点击
api.updateResultStatus(data).then(res => {
this.$message({message: '案件标记成功', type: "success",customClass:'messageZindex'})
this.$refs.layoutContent.getCaseInfoById();
})
}).catch(() => {});
},
// 办结
async handleChangeCaseStatus(){
let data={
id:this.caseId,
caseStatus:2
}
this.$confirm("请确定是否将案件办结?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
if(!this.$clickThrottle()) { return }//防止重复点击
api.updateResultStatus(data).then(res => {
this.$message({message: '案件办结成功', type: "success",customClass:'messageZindex'})
})
}).catch(() => {});
},
async callingInfo() {
try {
let res = await api.callingInfo({})
this.callingInfoData = res
} catch (err) {}
},
async callingTodayCount() {
try {
let res = await api.callingTodayCount({})
this.todayCountData = res
} catch (err) {}
},
// 获取案件列表
callingCaseList() {
api.callingCaseList({}).then(res => {
this.queueList = res.queue || []
})
},
// 当前自动呼叫队列
callingQueue() {
api.callingQueue({}).then(res => {
this.queueList = res.queue || []
this.caseId = String(res.queue[0].caseId) || ''
this.getCaseInfoById()
})
},
startCall () {
if (!this.$clickThrottle()) {
return
}
console.log('queueList==================',this.queueList)
if (this.queue) {
for (let i=0; i < this.queueList.length; i++) {
if (this.queueList[i].status.code === 1) {
this.index = i
this.startOutboundCall({phone:this.queueList[i].phone,contactId:this.queueList[i].contactId})
return
}
}
} else {
let phone = this.baseInfo.debtorEntityList.find(item => (item.role == 'DEBTOR' && item.type == '本人')).phone
let contactId = this.baseInfo.debtorEntityList.find(item => (item.role == 'DEBTOR' && item.type == '本人')).id
this.startOutboundCall({phone:phone,contactId:contactId})
}
},
// 电话呼出
async startOutboundCall(params) {
// this.phoneNumber = this.queue ? this.queueList[this.index].phone : this.baseInfo.phone
if (this.calling) return
this.phoneNumber = params.phone
this.contactId= params.contactId
console.log('进入呼叫电话:', params)
try {
let res = await window.tccc.Call.startOutboundCall({phoneNumber: this.phoneNumber})
this.sessionId = res.data.sessionId
console.log('呼叫成功', res.data)
this.calling = true
if (res.status === 'success') {
this.callingSuccess()
this.startTimer()
}
} catch (err) {
this.$message.error('呼叫失败' + err.message)
console.log('呼叫失败',err.message)
this.calling = false
this.callingFail()
// 呼叫失败
} finally {}
},
// 呼叫成功
async callingSuccess () {
try {
let res = await api.callingSuccess({caseId: this.caseId,contactId: this.contactId})
console.log('呼叫成功请求接口==callingSuccess', res)
// this.getmediate_record()
this.$refs.layoutContent.getmediate_record();
this.$refs.layoutContent.openRecordDialog(res);
} catch (err) { }
},
// 呼叫失败
async callingFail () {
try {
let res = await api.callingFail({caseId: this.caseId,contactId: this.contactId})
} catch (err) { }
},
// 挂断会话
async hungUp(type) {
if (!this.$clickThrottle()) {
return
}
try {
let res = await window.tccc.Call.hungUp({sessionId: this.sessionId})
this.calling = false
this.resetTimer()
this.nextCall()
} catch (err) {
// 挂断失败
} finally {}
},
// 自动拨打下一个会话
nextCall() {
if (!this.queue) return
if (this.isPause) {
this.isPause = false
this.calling = false
return
}
const that = this
that.index ++
setTimeout(() => {
if (that.index <= that.queueList.length - 1) {
that.caseId = String(that.queueList[that.index].caseId) || ''
that.getCaseInfoById()
console.log(that.queueList[that.index],'that.queueList[that.index]')
that.startOutboundCall({phone:that.queueList[that.index].phone,contactId:that.queueList[that.index].contactId})
}
}, 5000)
},
// 删除会话
async deleteCall() {
try {
let data = await window.tccc.Call.deleteCall({sessionId: this.sessionId})
} catch (err) {
// 删除失败
} finally {
}
},
// 静音会话
async muteMic() {
if (!this.$clickThrottle()) {
return
}
try {
let data = await window.tccc.Call.muteMic({sessionId: this.sessionId})
this.isMute = true
this.$message.success('已静音')
} catch (err) {
// 静音失败
this.$message.error('静音失败')
}
},
// 取消静音
async unmuteMic() {
if (!this.$clickThrottle()) {
return
}
try {
let data = await window.tccc.Call.unmuteMic({sessionId: this.sessionId})
this.isMute = false
this.$message.success('已取消静音')
} catch (err) {
// 取消静音失败
this.$message.error('取消静音失败')
}
},
startTimer() {
if (!this.isRunning) {
this.startTime = Date.now() - this.elapsedTime;
this.timerInterval = setInterval(() => {
this.elapsedTime = Date.now() - this.startTime;
}, 1000);
this.isRunning = true;
}
},
pauseTimer() {
if (this.isRunning) {
this.isPause=true
clearInterval(this.timerInterval);
this.isRunning = false;
}
},
resetTimer() {
clearInterval(this.timerInterval);
this.elapsedTime = 0;
this.isRunning = false;
},
// 未接来电
missedCallList() {
voiceCall.notAnswerList({}).then(res => {
this.missedCallData.list = res;
// this.missedCallData.list = [
// {
// contact: '唐 138',
// createAt: 1737441082000,
// phone: '13882832314'
// }
// ]
})
},
}
};
</script>
<style lang="scss" scoped>
.ai-logo-img{
width: 29px;
height: 29px;
background: url('~@/assets/image/ai-logo.png') no-repeat;
background-size: 100%,100%;
}
.bg-F2F3F5{
background-color: #F2F3F5;
}
.btn-group-controls{
width: 864px;
height: 56px;
border-radius: 16px;
background-color: #fff;
position: fixed;
bottom: 20px;
left: calc(50% - 432px);
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
.btn-group-real-time{
width: 64px;
.ell-warn-dot{
background-color: #f56c6c;
border-radius: 11px;
color: #fff;
display: inline-block;
font-size: 12px;
line-height: 17px;
height: 18px;
padding: 0 6px;
text-align: center;
border: 1px solid #fff;
position: absolute;
top: 0;
right: 10px;
transform: translateY(-50%) translateX(100%);
}
}
.btn-group-interval{
width: 1px;
height: 40px;
background-color: #C9CDD4;
}
.btn-group-processing-event{
width: calc(100% - 64px - 1px - 48px);
.bottom-case-btn:hover{
color: #BC6F60;
i{color: #BC6F60;}
}
}
}
.layout-center-wrap {
height: 100%;
font-size: 14px;
.layout-center-top-wrap {
padding: 8px 16px;
border-bottom: solid 1px #E5E6EB;
.top-wrap-title{
width: 223px;
height: 32px;
background: url('~@/assets/image/logo-tjs.png');
background-size: 100%,100%;
margin-top: 4px;
}
.top-wrap-btn-left{
//width: 55%;
min-width: 1034px;
.wrap-btn-left-dial{
background-color: #FFF2F0;
border-radius: 20px;
}
.wrap-btn-left-dial-f2f3f5 {
background-color: #F2F3F5;
border-radius: 20px;
}
.wrap-btn-left-dial-f56c6c {
background-color: #F56C6C;
border-radius: 20px;
height: 100%;
padding: 0px 10px;
}
}
}
.layout-center-center-wrap {
height: 100%;
.background-color-F5F5F5 {
background-color: #F5F5F5;
}
.border-E5E6EB {
border: solid 1px #E5E6EB;
}
.width120px {
width: 140px;
}
.width180px {
width: 220px;
}
.width200px {
width: calc(50% - 320px);
}
.layout-center-left-wrap {
background: url('~@/assets/image/mediate/m-left-bg.png') no-repeat;
background-size: 100% 100%;
width: 540px;
height: 100%;
border-right: 1px solid var(--fill-3, #E5E6EB);
.layout-center-left1-wrap {
width: 80px;
height: 100%;
text-align: center;
.left-rbobot {
width: 100%;
height: 80px;
text-align: center;
margin: 30px 0 0 0;
img {
width: 64px;
}
}
.separation {
width: 50px;
margin: 15px 0 0 15px;
border-bottom: solid 1px #dedfe4;
}
.left-img-info {
margin-top: 15px;
width: 100%;
font-size: 12px;
cursor: pointer;
img {
width: 48px;
margin-left: 15px;
}
a {
margin-top: 5px;
}
}
.left-img-info.active {
background: url('~@/assets/image/mediate/m-triangle.png') no-repeat;
background-size: 15px 30px;
background-position: 68px 10px;
}
.left-img-info:hover {
background: url('~@/assets/image/mediate/m-triangle.png') no-repeat;
background-size: 15px 30px;
background-position: 68px 10px;
}
}
.layout-center-left2-wrap {
width: 460px;
height: 100%;
background-color: #fff;
// border-radius: 25px 0px 0px 25px;
padding: 20px 30px;
.case-debt-info{
.descriptions-t{
.descriptions-t-title{
//margin-bottom: 5px;
}
.descriptions-t-item-l{
padding: 12px 10px;
text-align: right;
width: 40%;
}
.descriptions-t-item-r{
padding: 12px 10px;
text-align: left;
width: 60%;
}
.bgColor-F7F8FA{
background-color: #F7F8FA;
}
}
.case-debt-info-call{
padding: 12px 42px;
}
}
.case-contact-person{
.contact-person-type{
background-color: #F2F3F5;
padding:5px 15px;
border-radius: 8px;
margin: 0 5px;
cursor: pointer;
}
}
.case-detail-des {
border: solid 1px #E5E6EB;
padding: 10px 15px;
border-radius: 8px;
font-size: 14px;
span {
margin: 3px 0;
padding: 3px 10px;
// a:first-child{width: 120px;display: inline-block;text-align: right;}
}
span:nth-child(even) {
background-color: #F7F8FA;
}
.case-img {
width: 50px;
height: 50px;
text-align: center;
line-height: 50px;
img {
max-width: 50px;
max-height: 50px;
}
}
}
.case-materials-person {
.case-detail-des {
i {
margin-right: 4px;
}
}
}
.case-office-person {
.case-detail-des {
.case-img {
width: 55px;
height: 55px;
text-align: center;
line-height: 55px;
img {
max-width: 55px;
max-height: 55px;
}
}
i {
margin-right: 4px;
}
}
}
}
}
.layout-center-right-wrap {
background: #F2F3FA;
// background: url('~@/assets/image/mediate/m-right-bg.png') no-repeat;
background-size: 100% 100%;
width: calc(100% - 540px);
height: 100%;
.right-wrap-left{
width: 367px;
height: 100%;
}
.right-wrap-right{
width: calc(100% - 367px - 40px);
.timeline-layout{
.timeline-layout-w{
width: calc(50% - 8px);
.icon-bg{
width: 20px;
height: 20px;
// border-radius: 4px;
// color: #FFFFFF;
.callphone-icon{
background: url('~@/assets/image/mediate/callphone.png') no-repeat;
display: inline-block;
width: 20px;
height: 20px;
background-size: 100% 100%;
}
.callbackphone-icon{
background: url('~@/assets/image/mediate/callbackphone.png') no-repeat;
display: inline-block;
width: 20px;
height: 20px;
background-size: 100% 100%;
}
.nocallphone-icon{
background: url('~@/assets/image/mediate/nocallbackphone.png') no-repeat;
display: inline-block;
width: 20px;
height: 20px;
background-size: 100% 100%;
}
.callvideo-icon{
background: url('~@/assets/image/mediate/callvideo.png') no-repeat;
display: inline-block;
width: 20px;
height: 20px;
background-size: 100% 100%;
}
.callwechat-icon{
background: url('~@/assets/image/mediate/WeChat.png') no-repeat;
display: inline-block;
width: 20px;
height: 20px;
background-size: 100% 100%;
}
}
// .icon-phone{
// background-color: #52ABF2;
// }
.icon-video{
background-color: #FF7D00;
}
.timeline-layout-w-records{
background-color: #F5F5F5;
border-radius: 4px;
padding: 8px 12px 12px 12px;
}
}
.timeline-layout-ai{
padding: 6px 16px;
border-radius: 4px;
background: linear-gradient(270deg, #F1F4FE 0%, #FFF2F8 100%);
}
}
}
.right-wrap-side{
width: 40px;
height: 100%;
background-color: #F7F8FA;
}
//.case-communication-record {
// .btn-communication {
// padding: 5px 15px;
// border-radius: 8px;
// cursor: pointer;
// }
//
// .case-communication-cont {
// // background: ;
// padding: 20px;
// border-radius: 8px;
// margin-top: 15px;
// }
//}
//.case-office-record, .case-materials-record {
//
// span a {
// color: #C66A5B;
// margin-right: 13px;
// cursor: pointer;
// }
//
// span a:last-child {
// margin-right: 0;
// }
//}
}
}
}
.cursor-p {
cursor: pointer;
}
</style>