feat(calls): 语音通话列表列布局全面对齐云客(头像/多行标签/结束时间/时长格式)

- 客户信息/员工微信列:加头像+微信号用脱敏alias+客户加备注名
- 通话信息:改多行标签式(状态/微信语音/来源),去「xx:」前缀
- 员工信息:改纯文本(云客不可点)
- 通话录音:接通时显示时长+播放
- 通话时长列:显示endTime+MM'SS"格式

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
浅念
2026-08-24 14:43:03 +08:00
parent a9a30d49e7
commit d945a1e4ce
+56 -19
View File
@@ -254,6 +254,20 @@ const staffDrawerSections = computed(() => {
})
/** 把通话类型(voice_call/wa_voice_call)映射到聊天渠道(wechat/whatsapp)。电话返回 null。 */
function callSourceText(row: PhoneCall): string {
const v = cell(row, 'callFrom') ?? cell(row, 'dataFrom')
if (v === 1 || v === '1') return '手机'
return '--'
}
function callDurationText(row: PhoneCall): string {
const sec = row.call_duration ?? 0
if (!sec) return '--'
const m = Math.floor(sec / 60)
const s = sec % 60
return `${String(m).padStart(2, '0')}'${String(s).padStart(2, '0')}"'
}
function chatChannel(ch: CallChannel): 'wechat' | 'whatsapp' | null {
return ch === 'voice_call' ? 'wechat' : ch === 'wa_voice_call' ? 'whatsapp' : null
}
@@ -398,52 +412,67 @@ onMounted(() => {
@row-click="openDrawer"
>
<template v-if="callType === 'voice_call'">
<el-table-column label="通话信息" min-width="150">
<el-table-column label="通话信息" min-width="140">
<template #default="{ row }">
<div>通话状态:{{ callStatusLabel(row.call_status, row.channel) }}</div>
<div class="yk-cell__sub">类型:{{ callTypeLabel(row.channel) }}</div>
<div class="yk-cell__sub">来源:{{ cell(row, 'from') || '--' }}</div>
<div>{{ callStatusLabel(row.call_status, row.channel) }}</div>
<div class="yk-cell__sub">微信语音</div>
<div class="yk-cell__sub">{{ callSourceText(row) }}</div>
</template>
</el-table-column>
<!-- 客户信息(好友 scope) / 群信息(群 scope) — 云客微信好友/微信群两 tab 各自的列 -->
<el-table-column :label="voiceScope === 'group' ? '群信息' : '客户信息'" min-width="150">
<el-table-column :label="voiceScope === 'group' ? '群信息' : '客户信息'" min-width="180">
<template #default="{ row }">
<template v-if="voiceScope === 'group'">
<div>{{ cell(row, 'roomName') || cell(row, 'talker') || '--' }}</div>
<div class="yk-cell__sub">{{ cell(row, 'roomId') || '--' }}</div>
</template>
<template v-else>
<el-button v-if="cell(row, 'talkerNickName')" link type="primary" size="small" @click.stop="viewCallCustomer(row)">{{ cell(row, 'talkerNickName') }}</el-button>
<span v-else>--</span>
<div class="yk-cell__sub">{{ row.call_number || cell(row, 'talker') || '--' }}</div>
<div class="yk-call-person">
<el-avatar v-if="cell(row, 'talkerHeadImg')" :size="32" :src="String(cell(row, 'talkerHeadImg'))" shape="square" />
<div class="yk-call-person__meta">
<el-button v-if="cell(row, 'talkerNickName')" link type="primary" size="small" @click.stop="viewCallCustomer(row)">{{ cell(row, 'talkerNickName') }}</el-button>
<span v-else>--</span>
<div class="yk-cell__sub">{{ cell(row, 'talkerAlias') || cell(row, 'talker') || '--' }}</div>
<div v-if="cell(row, 'friendRemark')" class="yk-cell__sub">备注名 {{ cell(row, 'friendRemark') }}</div>
</div>
</div>
</template>
</template>
</el-table-column>
<el-table-column label="员工微信" min-width="150">
<el-table-column label="员工微信" min-width="180">
<template #default="{ row }">
<el-button v-if="cell(row, 'userWeChatNickName')" link type="primary" size="small" @click.stop="viewCallStaff(row)">{{ cell(row, 'userWeChatNickName') }}</el-button>
<span v-else>--</span>
<div class="yk-cell__sub">{{ cell(row, 'userWeChatAlias') || cell(row, 'weChatId') || '--' }}</div>
<div class="yk-call-person">
<el-avatar v-if="cell(row, 'userWeChatHeadImg')" :size="32" :src="String(cell(row, 'userWeChatHeadImg'))" shape="square" />
<div class="yk-call-person__meta">
<el-button v-if="cell(row, 'userWeChatNickName')" link type="primary" size="small" @click.stop="viewCallStaff(row)">{{ cell(row, 'userWeChatNickName') }}</el-button>
<span v-else>--</span>
<div class="yk-cell__sub">{{ cell(row, 'userWeChatAlias') || cell(row, 'weChatId') || '--' }}</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="员工信息" min-width="130">
<template #default="{ row }">
<el-button v-if="row.user_id_name" link type="primary" size="small" @click.stop="goToStaffDetail(row)">{{ row.user_id_name }}</el-button>
<span v-else>--</span>
<div>{{ row.user_id_name || cell(row, 'userName') || '--' }}</div>
<div class="yk-cell__sub">{{ cell(row, 'userPhone') || '--' }}</div>
</template>
</el-table-column>
<el-table-column label="通话录音" width="140" align="center">
<el-table-column label="通话录音" width="150" align="center">
<template #default="{ row }">
<el-button v-if="row.record_media_hash || row.record_file || cell(row, 'recordFile')" size="small" type="primary" link @click.stop="playRecord(row)">播放</el-button>
<template v-if="row.record_media_hash || row.record_file || cell(row, 'recordFile')">
<div class="yk-cell__sub">{{ callDurationText(row) }}</div>
<el-button size="small" type="primary" link @click.stop="playRecord(row)">播放</el-button>
</template>
<span v-else style="color:#c0c4cc">--</span>
<div style="margin-top:2px">
<el-button size="small" type="primary" link @click.stop="openVoiceClip(row)">查看长语音</el-button>
</div>
</template>
</el-table-column>
<el-table-column label="通话时长" width="100" align="right">
<template #default="{ row }">{{ formatCallDuration(row.call_duration) }}</template>
<el-table-column label="通话时长" min-width="170">
<template #default="{ row }">
<div>{{ cell(row, 'endTime') || '--' }}</div>
<div class="yk-cell__sub">{{ callDurationText(row) }}</div>
</template>
</el-table-column>
</template>
<template v-if="callType === 'wa_voice_call'">
@@ -769,4 +798,12 @@ onMounted(() => {
.yk-drawer__empty {
color: #c0c4cc;
}
.yk-call-person {
display: flex;
align-items: center;
gap: 8px;
}
.yk-call-person__meta {
min-width: 0;
}
</style>