|
@@ -1,393 +0,0 @@
|
|
|
-<script setup>
|
|
|
-import { ElMessage } from 'element-plus';
|
|
|
-import { workbenchApi } from '@/api/voice/workbench';
|
|
|
-import useVoiceStore from "@/store/modules/voice";
|
|
|
-
|
|
|
-import RecordCardItem from './components/RecordCardItem';
|
|
|
-import CustomRowItem from './components/CustomRowItem.vue';
|
|
|
-import AudioPlayer from '@/components/AudioPlayer';
|
|
|
-import CallView from '@/components/CallView';
|
|
|
-
|
|
|
-const queryParams = ref({
|
|
|
- pageNum: 1,
|
|
|
- pageSize: 10,
|
|
|
- category: 0,
|
|
|
- phone: ''
|
|
|
-});
|
|
|
-
|
|
|
-const voiceStore = useVoiceStore();
|
|
|
-
|
|
|
-const remark = ref('');
|
|
|
-const tabCallRecordList = ref([]);
|
|
|
-const tabCurrentActive = ref(null);
|
|
|
-const callDetails = ref({});
|
|
|
-
|
|
|
-const isExpand = ref(false);
|
|
|
-const dialogVisible = ref(false);
|
|
|
-
|
|
|
-const total = ref(0);
|
|
|
-const loading = ref(false);
|
|
|
-
|
|
|
-const tabEnum = ['通话呼入', '通话呼出'];
|
|
|
-const categoryTypeEnum = {
|
|
|
- 0: '人工客服',
|
|
|
- 1: '机器人',
|
|
|
- 2: '机器人转人工'
|
|
|
-}
|
|
|
-
|
|
|
-const typeEnum = {
|
|
|
- 0: '白名单',
|
|
|
- 1: 'AI客服',
|
|
|
- 2: '传统服务'
|
|
|
-}
|
|
|
-
|
|
|
-const disabled = computed(() => loading.value || total.value == tabCallRecordList.value.length);
|
|
|
-
|
|
|
-// 切换tabs
|
|
|
-const handleChangeTab = (index) => {
|
|
|
- queryParams.value.pageNum = 1;
|
|
|
- queryParams.value.category = index;
|
|
|
- tabCallRecordList.value = [];
|
|
|
- initTabsData();
|
|
|
-}
|
|
|
-
|
|
|
-// 选中通话记录
|
|
|
-const hanldeTabItem = (i) => {
|
|
|
- tabCurrentActive.value = i;
|
|
|
- callDetails.value = tabCallRecordList.value[i];
|
|
|
-}
|
|
|
-
|
|
|
-// 编辑
|
|
|
-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 onSearch = () => {
|
|
|
- queryParams.value.pageNum = 1;
|
|
|
- tabCallRecordList.value = [];
|
|
|
- initTabsData();
|
|
|
-}
|
|
|
-
|
|
|
-// 拨打电话
|
|
|
-const onConfirm = () => {
|
|
|
- voiceStore.onMakingCall("15810954324");
|
|
|
-}
|
|
|
-
|
|
|
-const initTabsData = async () => {
|
|
|
- loading.value = true;
|
|
|
- const { rows, total: t } = await workbenchApi.getCallRecordList(queryParams.value);
|
|
|
-
|
|
|
- tabCallRecordList.value = [...tabCallRecordList.value, ...rows];
|
|
|
- total.value = t;
|
|
|
- loading.value = false;
|
|
|
-}
|
|
|
-
|
|
|
-onMounted(async () => {
|
|
|
- initTabsData();
|
|
|
-});
|
|
|
-
|
|
|
-const loadMoreData = () => {
|
|
|
- queryParams.value.pageNum += 1;
|
|
|
- initTabsData();
|
|
|
-}
|
|
|
-</script>
|
|
|
-
|
|
|
-<template>
|
|
|
- <div class="workbench-viewport space-x-[16px]">
|
|
|
- <div class="record-section">
|
|
|
- <ul class="tabs-nav space-x-[48px]">
|
|
|
- <li v-for="item, index in tabEnum" :class="['tabs-nav-item', { active: queryParams.category === index }]"
|
|
|
- :key="item" @click="handleChangeTab(index)">{{ item }}</li>
|
|
|
- </ul>
|
|
|
- <div class="tabs-content">
|
|
|
- <div class="search-inp-wrapper">
|
|
|
- <div class="search-inp">
|
|
|
- <input type="text" class="inp" placeholder="请输入电话号码" v-model="queryParams.phone">
|
|
|
- <div class="btn" @click="onSearch">搜索</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="search-result-wrapper">
|
|
|
- <el-scrollbar height="100%">
|
|
|
- <div
|
|
|
- class="search-result-inner space-y-[8px]"
|
|
|
- v-infinite-scroll="loadMoreData"
|
|
|
- :infinite-scroll-disabled="disabled"
|
|
|
- v-show="tabCallRecordList.length"
|
|
|
- >
|
|
|
- <RecordCardItem
|
|
|
- v-for="item, index in tabCallRecordList"
|
|
|
- :data="item"
|
|
|
- :index="index"
|
|
|
- :active="tabCurrentActive === index"
|
|
|
- :key="item.id"
|
|
|
- @on-click="hanldeTabItem(index)"
|
|
|
- ></RecordCardItem>
|
|
|
- <div class="flex justify-center text-[#999] text-[12px]">
|
|
|
- <p class="pb-[6px]" v-if="loading">Loading...</p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="flex items-center justify-center pt-[100px]" v-show="!tabCallRecordList.length">
|
|
|
- <span class="text-[#999] text-[14px]">暂无数据</span>
|
|
|
- </div>
|
|
|
- </el-scrollbar>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="details-section">
|
|
|
- <div class="empty-wrapper" v-show="!callDetails.id">
|
|
|
- <img src="@/assets/images/workbench/img-empty.png" alt="">
|
|
|
- <p class="empty-text">
|
|
|
- <span>Hi, 下午好~</span>
|
|
|
- <span>欢迎登录智能语音客服</span>
|
|
|
- </p>
|
|
|
- </div>
|
|
|
- <div class="details-wrapper" v-show="callDetails.id">
|
|
|
- <h4 class="title">通话详情</h4>
|
|
|
- <el-scrollbar class="details-scrollbar">
|
|
|
- <CallView></CallView>
|
|
|
- </el-scrollbar>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <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>
|
|
|
-$primaryColor: #165DFF;
|
|
|
-
|
|
|
-.workbench-viewport {
|
|
|
- display: flex;
|
|
|
- height: 100%;
|
|
|
- background: #eceff6;
|
|
|
-
|
|
|
- .record-section {
|
|
|
- flex-shrink: 0;
|
|
|
- width: 292px;
|
|
|
- height: 100%;
|
|
|
- border-radius: 8px;
|
|
|
- background: linear-gradient(180deg, #FFF 0%, #FFF 100%);
|
|
|
-
|
|
|
- .tabs-nav {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- height: 46px;
|
|
|
- padding-top: 15px;
|
|
|
- border-bottom: 1px solid #E5E6EB;
|
|
|
- font-size: 14px;
|
|
|
- line-height: 20px;
|
|
|
- color: #4E5969;
|
|
|
-
|
|
|
- .tabs-nav-item {
|
|
|
- position: relative;
|
|
|
- cursor: pointer;
|
|
|
-
|
|
|
- &.active {
|
|
|
- color: $primaryColor;
|
|
|
- font-weight: bold;
|
|
|
-
|
|
|
- &::after {
|
|
|
- position: absolute;
|
|
|
- left: 0;
|
|
|
- bottom: -6px;
|
|
|
- content: ' ';
|
|
|
- display: block;
|
|
|
- width: 100%;
|
|
|
- height: 2px;
|
|
|
- background: $primaryColor;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- .tabs-content {
|
|
|
- height: calc(100% - 46px);
|
|
|
-
|
|
|
- .search-inp-wrapper {
|
|
|
- padding: 12px 22px;
|
|
|
-
|
|
|
- .search-inp {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- height: 34px;
|
|
|
- padding: 2px;
|
|
|
- border-radius: 8px;
|
|
|
- background: #F2F4F7;
|
|
|
-
|
|
|
- .inp {
|
|
|
- width: 100%;
|
|
|
- padding: 0 10px;
|
|
|
- background: transparent;
|
|
|
- outline: none;
|
|
|
- font-size: 13px;
|
|
|
- color: #1D2129;
|
|
|
- }
|
|
|
-
|
|
|
- .btn {
|
|
|
- flex-shrink: 0;
|
|
|
- width: 52px;
|
|
|
- height: 30px;
|
|
|
- border-radius: 8px;
|
|
|
- background: #165DFF;
|
|
|
- color: #FFF;
|
|
|
- font-size: 13px;
|
|
|
- line-height: 30px;
|
|
|
- text-align: center;
|
|
|
- cursor: pointer;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .search-result-wrapper {
|
|
|
- height: calc(100% - 58px);
|
|
|
-
|
|
|
- .search-result-inner {
|
|
|
- padding: 0 22px;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .details-section {
|
|
|
- width: 100%;
|
|
|
- min-width: 700px;
|
|
|
- height: 100%;
|
|
|
- border-radius: 8px;
|
|
|
- overflow: hidden;
|
|
|
- padding: 20px;
|
|
|
- background: #fff;
|
|
|
-
|
|
|
- .details-scrollbar {
|
|
|
- height: calc(100% - 50px);
|
|
|
- }
|
|
|
-
|
|
|
- .empty-wrapper {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- flex-flow: column;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
-
|
|
|
- .empty-text {
|
|
|
- span {
|
|
|
- display: block;
|
|
|
- text-align: center;
|
|
|
- font-weight: bold;
|
|
|
- font-size: 24px;
|
|
|
- line-height: 32px;
|
|
|
-
|
|
|
- &:nth-child(1) {
|
|
|
- color: #165DFF;
|
|
|
- }
|
|
|
-
|
|
|
- &:nth-child(2) {
|
|
|
- color: #1D2129;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .details-wrapper {
|
|
|
- height: 100%;
|
|
|
-
|
|
|
- .title {
|
|
|
- margin-bottom: 24px;
|
|
|
- color: #1D2129;
|
|
|
- font-size: 18px;
|
|
|
- font-weight: bold;
|
|
|
- line-height: 26px;
|
|
|
- }
|
|
|
-
|
|
|
- .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>
|