Co-Authored-By: Claude <noreply@anthropic.com>
6.5 KiB
CallList 列内可点(④,微信语音)Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development or superpowers:executing-plans. Steps use checkbox (
- [ ]).
Goal: CallList「微信语音」tab 的 客户信息/员工微信/员工信息 三类单元格可点,对齐云客(复用 Phase B 客户→1:1 chat + step 5 员工→账号级聊天窗 + drawer)。
Architecture: 纯前端,仅 CallList.vue。加 useRouter + chatChannel 映射 + viewCallCustomer/viewCallStaff 两个 handler + voice_call 模板 3 处单元格包 <el-button link>。WA语音/电话 tab 不动。
Tech Stack: Vue3+TS+Element Plus;门禁 vue-tsc -b。无后端、无路由、无新组件。
Spec: docs/superpowers/specs/2026-08-08-yunke-calllist-cell-click-design.md(已过审 + 已收窄至 voice_call)。
关键事实(plan 核实,codebase)
CallList.vuevoice_call 模板块(<template v-if="callType === 'voice_call'">)现有 6 列:通话信息 / 客户信息 / 员工微信 / 员工信息 / 通话录音 / 通话时长。- 客户信息 单元格:
<div>{{ cell(row, 'talkerNickName') || '--' }}</div>+ 子行call_number || cell(row,'talker')。 - 员工微信 单元格:
<div>{{ cell(row, 'userWeChatNickName') || '--' }}</div>+ 子行cell(row,'userWeChatAlias') || cell(row,'weChatId')。 - 员工信息 单元格:
<div>{{ row.user_id_name || '--' }}</div>+ 子行cell(row,'userPhone')。
- 客户信息 单元格:
cell(row, camelKey)已存在(包装readField)。openDrawer(row)已存在。PhoneCall(api/types.ts):channel(通话类型 voice_call/wa_voice_call/phone_call)、user_id/user_id_name、call_number、raw_json。- 路由
/chat/:channel/:ownerId/:talkerId?(name'chat',talkerId 可选)—— account 级/chat/wechat/{owner}与 1:1/chat/wechat/{owner}/{talker}都可用(step 5/Phase B 已建)。 CALL_FIELD_LABELS(callFields.ts)含weChatId、talker——可经cell()读。- 云客真机(2026-08-08):客户→
detail/message/{owner}/{talker}、员工→wechat-window/1/{owner}、员工姓名→详情页。
文件清单
- 改
yunkes/src/views/CallList.vue(仅 voice_call 模板 3 处 + script 加 router/handlers)。仅此一文件。
Task 1: CallList 微信语音 单元格可点
Files: Modify yunkes/src/views/CallList.vue(仅此一文件)。
- Step 1: script 加 router + handlers
import { computed, onMounted, ref } from 'vue' 行附近加 useRouter:
import { useRouter } from 'vue-router'
const router = useRouter()(放 script 顶部状态区,如 const drawerOpen = ref(false) 之前)。
加 handlers(放 openDrawer 附近):
/** 客户昵称 → 该员工×客户 1:1 聊天(复用 Phase B 导航)。 */
function viewCallCustomer(row: PhoneCall): void {
const owner = cell(row, 'weChatId')
const talker = cell(row, 'talker')
if (!owner || !talker) return
router.push({
name: 'chat',
params: { channel: 'wechat', ownerId: String(owner), talkerId: String(talker) },
})
}
/** 员工微信昵称 → 账号级聊天窗(复用 step 5 导航)。 */
function viewCallStaff(row: PhoneCall): void {
const owner = cell(row, 'weChatId')
if (!owner) return
router.push({ name: 'chat', params: { channel: 'wechat', ownerId: String(owner) } })
}
本 plan 仅微信语音(voice_call→
'wechat'硬编码)。WA 映射chatChannel()(voice_call→wechat, wa_voice_call→whatsapp)留待 WA tab 实现时再加(避免noUnusedLocals死代码)。PhoneCall已在 import。
- Step 2: voice_call 模板 3 处单元格包 link button
<template v-if="callType === 'voice_call'"> 内:
客户信息 列(约 line 170):
<el-button v-if="cell(row, 'talkerNickName')" link type="primary" size="small" class="yk-cell__main" @click.stop="viewCallCustomer(row)">{{ cell(row, 'talkerNickName') }}</el-button>
<span v-else class="yk-cell__main">--</span>
(替换原 <div>{{ cell(row, 'talkerNickName') || '--' }}</div>;子行 call_number || talker 不变。)
员工微信 列(约 line 177):
<el-button v-if="cell(row, 'userWeChatNickName')" link type="primary" size="small" class="yk-cell__main" @click.stop="viewCallStaff(row)">{{ cell(row, 'userWeChatNickName') }}</el-button>
<span v-else class="yk-cell__main">--</span>
(替换原 <div>{{ cell(row, 'userWeChatNickName') || '--' }}</div>;子行不变。)
员工信息 列(约 line 183):
<el-button v-if="row.user_id_name" link type="primary" size="small" class="yk-cell__main" @click.stop="openDrawer(row)">{{ row.user_id_name }}</el-button>
<span v-else class="yk-cell__main">--</span>
(替换原 <div>{{ row.user_id_name || '--' }}</div>;子行 userPhone 不变。)
@click.stop阻止冒泡到 row-click(避免同时开 drawer)。class="yk-cell__main"让按钮文字继承主文本样式(13px);可在<style scoped>加.yk-cell__main { font-size: 13px; }(若需要;el-button link 默认字号可能略偏)。
- Step 3: vue-tsc
cd /d/refactor/yunke/yunkes && npx vue-tsc -b
Expected: exit 0。
- Step 4: 浏览器实测
启动后端(smoke.db)+前端。/calls → 微信语音 tab:
-
点客户昵称 →
/chat/wechat/{owner}/{talker}(侧栏+该会话+消息)。 -
点员工微信昵称 →
/chat/wechat/{owner}(账号级聊天窗+空态或会话列表)。 -
点员工姓名 → drawer。
-
行点击空白处 → drawer(row-click 不受影响)。
-
缺字段格显
--(不可点);WA语音/电话 tab 不变。 -
Step 5: Commit
git add yunkes/src/views/CallList.vue
git commit -m "feat(calls): CallList 微信语音 客户/员工/姓名 单元格可点(复用聊天导航,对齐云客)"
End with blank line + Co-Authored-By: Claude <noreply@anthropic.com>。
验收(spec §6)
vue-tsc -bexit 0。- 浏览器(本地 smoke.db,无云客):微信语音 三单元格可点且跳转正确;缺字段
--不可点;WA语音/电话 不变;row-click→drawer 不变;network 仅 localhost。
风险
weChatId/talker缺失:守卫已加(if (!owner || !talker) return),该格显--不可点。- WA语音/电话:本 plan 不动;WA 待云客真机核实其 WA 语音列表后另做(小补丁,复用同 handler +
chatChannel('wa_voice_call')→'whatsapp')。