docs(plan): CallList ④ 微信语音 单元格可点 实现计划
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
# 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.vue` voice_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`:
|
||||
```typescript
|
||||
import { useRouter } from 'vue-router'
|
||||
```
|
||||
`const router = useRouter()`(放 script 顶部状态区,如 `const drawerOpen = ref(false)` 之前)。
|
||||
|
||||
加 helper + handlers(放 `openDrawer` 附近):
|
||||
```typescript
|
||||
/** 通话类型 → 聊天渠道(voice_call→wechat, wa_voice_call→whatsapp, phone_call→无)。 */
|
||||
function chatChannel(ch: CallChannel): 'wechat' | 'whatsapp' | null {
|
||||
return ch === 'voice_call' ? 'wechat' : ch === 'wa_voice_call' ? 'whatsapp' : null
|
||||
}
|
||||
|
||||
/** 客户昵称 → 该员工×客户 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) } })
|
||||
}
|
||||
```
|
||||
> `CallChannel` 已在 import(`import type { CallChannel, PhoneCall }`)。`chatChannel` 本 task 只用于 voice_call,但保留 WA 映射供后续。
|
||||
|
||||
- [ ] **Step 2: voice_call 模板 3 处单元格包 link button**
|
||||
|
||||
`<template v-if="callType === 'voice_call'">` 内:
|
||||
|
||||
**客户信息** 列(约 line 170):
|
||||
```vue
|
||||
<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):
|
||||
```vue
|
||||
<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):
|
||||
```vue
|
||||
<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**
|
||||
|
||||
```bash
|
||||
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**
|
||||
|
||||
```bash
|
||||
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 -b` exit 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'`)。
|
||||
Reference in New Issue
Block a user