123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- <script setup>
- import { useRoute } from 'vue-router';
- import { ElMessage } from 'element-plus';
- import { workbenchApi } from '@/api/voice/workbench';
- import useVoiceStore from "@/store/modules/voice";
- import AudioPlayer from '@/components/AudioPlayer';
- import CustomRowItem from '@/components/CustomRowItem';
- import VoiceToText from '@/components/VoiceToText';
- import { watch, watchEffect } from 'vue';
- const emit = defineEmits(['onEnd'])
- const props = defineProps({
- noInit: {
- type: Boolean,
- default: false
- },
- data: {
- type: Object,
- default: () => ({})
- }
- })
- const voiceStore = useVoiceStore();
- const route = useRoute();
- const audioPlayerRef = ref(null);
- const remark = ref('');
- const callDetails = ref({});
- const dialogVisible = ref(false);
- const categoryTypeEnum = {
- 0: '人工客服',
- 1: '机器人',
- 2: '机器人转人工'
- }
- const typeEnum = {
- 0: '白名单',
- 1: 'AI客服',
- 2: '传统服务'
- }
- watch(() => props.data, () => {
- // console.log("中间层", props.data);
- // // times: audioPlayerRef.value.durationTime
- // callDetails.value = {...props.data };
- })
- watchEffect(() => {
- // times: audioPlayerRef.value.durationTime
- callDetails.value = {...props.data };
- })
- const durationTime = computed(() => {
- const durationTime = audioPlayerRef.value?.durationTime;
- return durationTime ? durationTime: '00:00';
- })
- // 编辑
- const handleEdit = () => {
- dialogVisible.value = true;
- remark.value = callDetails.value.remark;
- }
- // 弹窗 - 确定
- const onDialogConfirm = () => {
- const { id } = callDetails.value;
- workbenchApi.putCallRecord({ id, remark: remark.value }).then(() => {
- dialogVisible.value = false;
- callDetails.value.remark = remark.value;
- ElMessage({
- message: '备注更改成功',
- type: 'success',
- })
- })
- }
- // 弹窗 - 取消
- const onDialogCancel = () => {
- dialogVisible.value = false;
- remark.value = callDetails.value.remark;
- }
- // 拨打电话
- const onConfirm = () => {
- voiceStore.onMakingCall(callDetails.value.phone);
- }
- // 语音转换文字
- const onVoiceParsed = ({ parsedVoiceContent, id }) => {
- emit('onEnd', { parsedVoiceContent, id });
- }
- // onMounted(async () => {
- // if (props.noInit) return;
- // const { id } = route.query;
- // const { data } = await workbenchApi.getCallRecordDetails(id);
- // callDetails.value = data;
- // });
- </script>
- <template>
- <div class="details-inner">
- <el-descriptions title="">
- <el-descriptions-item label="呼入分类" label-class-name="custom-label" class-name="custom-colums"
- v-if="callDetails.category != 1">
- <span class="text-[#FF3636]">{{ typeEnum[callDetails.type] }}</span>
- </el-descriptions-item>
- <el-descriptions-item label="客服" label-class-name="custom-label" class-name="custom-colums">
- {{ callDetails.userName }}
- </el-descriptions-item>
- <el-descriptions-item label="服务类型" label-class-name="custom-label" class-name="custom-colums">
- {{ categoryTypeEnum[callDetails.serviceCategory] }}
- </el-descriptions-item>
- <el-descriptions-item label="通话发起时间" label-class-name="custom-label" class-name="custom-colums">
- {{ callDetails.timeBegin }}
- </el-descriptions-item>
- <el-descriptions-item label="通话结束时间" label-class-name="custom-label" class-name="custom-colums">
- {{ callDetails.timeEnd }}
- </el-descriptions-item>
- <el-descriptions-item label="通话时长" label-class-name="custom-label" class-name="custom-colums">
- <!-- {{ callDetails.times }} -->
- {{ durationTime }}
- </el-descriptions-item>
- <el-descriptions-item label="通话类型" label-class-name="custom-label" class-name="custom-colums">
- {{ callDetails.category == 0 ? '呼入' : '呼出' }}
- </el-descriptions-item>
- <el-descriptions-item label="通话状态" label-class-name="custom-label" class-name="custom-colums">
- {{ callDetails.status == 0 ? '未接听' : '已接通' }}
- </el-descriptions-item>
- <el-descriptions-item label="业务类型" label-class-name="custom-label" class-name="custom-colums"
- v-if="callDetails.category != 1">{{ callDetails.bussinessType }}</el-descriptions-item>
- <el-descriptions-item label="电话号码" label-class-name="custom-label" class-name="custom-colums">
- <div class="inline-block">
- <div class="flex items-center space-x-[4px]">
- <span>{{ callDetails.phone }}</span>
- <el-popconfirm width="250" icon-color="#626AEF" title="请确认,是否呼叫该电话号码?" @confirm="onConfirm">
- <template #reference>
- <img src="@/assets/images/workbench/icon-call-square.svg" alt="" class="cursor-pointer" v-if="voiceStore.isAuthPane">
- </template>
- <template #actions="{ confirm, cancel }">
- <el-button size="small" @click="cancel">否</el-button>
- <el-button type="primary" size="small" @click="confirm">是</el-button>
- </template>
- </el-popconfirm>
- </div>
- </div>
- </el-descriptions-item>
- </el-descriptions>
- <custom-row-item label="备注">
- <div class="space-x-[14px] flex items-center">
- <span class="custom-colums">{{ callDetails.remark ? callDetails.remark : '暂无' }}</span>
- <span class="text-[#165DFF] text-[14px] cursor-pointer" @click="handleEdit">编辑</span>
- </div>
- </custom-row-item>
- <custom-row-item label="通话录音" v-if="callDetails.url">
- <VoiceToText @on-parsed="onVoiceParsed" :content="callDetails.parsedVoiceContent" :id="callDetails.id">
- <AudioPlayer :audioUrl="callDetails.url" ref="audioPlayerRef"></AudioPlayer>
- </VoiceToText>
- </custom-row-item>
- <el-dialog v-model="dialogVisible" title="编辑备注" width="530" modal-class="custom-workbench-dialog" align-center>
- <template #header>
- <div class="dialog-header">
- <h4>编辑备注</h4>
- </div>
- </template>
- <div class="dialog-body">
- <el-input type="textarea" :autosize="{ minRows: 6, maxRows: 6 }" resize="none" v-model="remark"></el-input>
- </div>
- <template #footer>
- <div class="dialog-footer space-x-[14px]">
- <div class="custom-btn custom-btn_primary" @click="onDialogConfirm">确定</div>
- <div class="custom-btn custom-btn_default" @click="onDialogCancel">取消</div>
- </div>
- </template>
- </el-dialog>
- </div>
- </template>
- <style lang="scss" scoped>
- .details-inner {
- :deep(.custom-label) {
- display: inline-block;
- width: 84px;
- color: #86909C;
- box-sizing: border-box;
- font-size: 14px;
- font-weight: normal;
- line-height: 23px;
- text-align: left;
- }
- :deep(.custom-colums) {
- font-size: 14px;
- color: #1D2129;
- }
- .record-box {
- width: 100%;
- padding: 16px;
- border-radius: 8px;
- background: linear-gradient(90deg, #F6F5F8 0%, #FFF 100%);
- .record-play-control {
- display: flex;
- align-items: center;
- padding: 0;
- font-size: 14px;
- }
- .record-play-content {
- padding-top: 12px;
- color: #4E5969;
- font-family: "PingFang SC";
- font-size: 13px;
- line-height: 20px;
- }
- }
- }
- .dialog-footer {
- display: flex;
- justify-content: center;
- }
- :deep(.el-textarea__inner) {
- background: #f2f4f7;
- }
- </style>
|