Files
yunke/docs/superpowers/specs/2026-08-08-yunke-calllist-cell-click-design.md
T

91 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CallList 列内可点(④)设计
> 日期:2026-08-08|分支:`feat/yunke-data-mirror`|路线图 ④
> 前置:Phase B(stat modal 客户微信→`/chat/{ch}/{owner}/{talker}`)+ step 5(badge/员工→账号级 `/chat/{ch}/{owner}` 聊天窗 + ChatSidebar)。
> 数据/交互:全本地(运行时不碰云客)。云客「微信语音通话列表」**2026-08-08 Playwright 真机核实**(`/cms/wechat/voice-call-list`)。
## 1. 目标与范围
**目标**:CallList 的「微信语音」「WA 语音」两 tab 里,**客户信息 / 员工微信 / 员工信息** 三类单元格可点,行为对齐云客——复用 Phase B + step 5 已建的导航。
**在本 plan**:
- **微信语音(voice_call)/ WA 语音(wa_voice_call)** tab,每行使三类单元格可点:
- **客户信息**(微信/WA 昵称)→ `/chat/{chatChannel}/{owner_account_id}/{talker_id}`(该客户 1:1 聊天;复用 Phase B)。
- **员工微信**(昵称)→ `/chat/{chatChannel}/{owner_account_id}`(账号级聊天窗;复用 step 5)。
- **员工信息**(姓名)→ `openDrawer(row)`(通话全字段详情;云客姓名→员工详情页,我们降级 drawer,同 StaffList)。
**不在本 plan**:
- **电话(phone_call)tab**:号码型,无 wechat/WA chat 映射;云客电话列表是另一套 CRM。**维持不可点**(row-click→drawer 保留),待电话数据映射明确后再议。
- 客户/员工的云客独立详情页(`userDetailNew` 等):维持降级(drawer / 聊天窗),与 StaffList 一致。
- 录音播放、行点击→drawer:现状不变。
## 2. 云客真机核实(2026-08-08,微信语音通话列表)
逐单元格 DOM 核实(首行):
- **客户信息**:`<a href="/cms/wechat/detail/message/{ownerWxid}/{customerWxid}/1?start={callTime}&scrollToBottom=0">微信昵称</a>` → 该客户 1:1 聊天(带 callTime 定位)。
- **员工微信**:`<a href="/cms/wechat/salewechat/message/wechat-window/1/{ownerWxid}/1">昵称</a>` → 账号级聊天窗。
- **员工信息**:`<div class="link">姓名</div>` → 员工详情页。
- 通话信息 / 通话录音 / 通话时长:不可点(录音是播放按钮)。
**结论**:3 类可点单元格,目标 = 客户聊天 / 账号聊天窗 / 员工详情——全部我们已有对应物。
## 3. 前端(仅 `yunkes/src/views/CallList.vue`)
- **call-type → chat-channel 映射**:call 的 `channel` 是通话类型(`voice_call`/`wa_voice_call`/`phone_call`),chat 路由用 `wechat`/`whatsapp`。加 helper:
```ts
function chatChannel(ch: CallChannel): 'wechat' | 'whatsapp' | null {
return ch === 'voice_call' ? 'wechat' : ch === 'wa_voice_call' ? 'whatsapp' : null
}
```
- **读 owner/talker**(经 `readField`,CallList 已用):
- 语音:`owner = readField(row,'weChatId')`,`talker = readField(row,'talker')`(fallback `row.call_number`)。
- WA:owner/talker 用 WA 字段(plan 核实具体键名,如 `uid`/`talker` 或 `waId`)。
- **3 个 onClick handler**:
```ts
function viewCallCustomer(row: PhoneCall) {
const ch = chatChannel(row.channel); const owner = cell(row,'weChatId') /* WA 另定 */; const talker = cell(row,'talker')
if (!ch || !owner || !talker) return
router.push({ name: 'chat', params: { channel: ch, ownerId: String(owner), talkerId: String(talker) } })
}
function viewCallStaff(row: PhoneCall) {
const ch = chatChannel(row.channel); const owner = cell(row,'weChatId') /* WA 另定 */
if (!ch || !owner) return
router.push({ name: 'chat', params: { channel: ch, ownerId: String(owner) } })
}
// 员工信息姓名 → openDrawer(row)(已有)
```
> 不带 `start/end` query:聊天窗默认近 2 周(step 5),近期通话在其内可见;简化。
- **模板**:把对应单元格的昵称/姓名文本包成 `<el-button link type="primary" size="small" @click.stop="...">`(与 StaffList 数字单元格一致风格);缺失字段则显 `--`(不可点)。三处:
- 微信语音/wa语音 `客户信息` 列的昵称行 → `viewCallCustomer`。
- 微信语音/wa语音 `员工微信` 列的昵称行 → `viewCallStaff`。
- 微信语音/wa语音 `员工信息` 列的姓名行 → `openDrawer`。
- **电话 tab 模板不动**。
- `import { useRouter } from 'vue-router'` + `const router = useRouter()`。
## 4. 关键决策(已与用户确认 2026-08-08)
1. **范围 = 微信语音 + WA语音**;电话不动(无 chat 映射)。
2. **复用 Phase B(客户→1:1 chat)+ step 5(员工→账号级聊天窗)+ drawer(员工详情降级)**——不新增导航逻辑/路由/组件。
3. **不带日期窗 query**:聊天窗默认近 2 周覆盖近期通话;简化。
4. **call-type→chat-channel 映射**(voice_call→wechat, wa_voice_call→whatsapp)。
5. **WA owner/talker 字段** plan 核实 raw_json 键名(语音已确认 weChatId/talker)。
## 5. 文件清单
- 改 `yunkes/src/views/CallList.vue`(加 `useRouter`、`chatChannel`、3 个 onClick、模板 6 处单元格包 link button)。**仅此一文件**;无后端、无路由、无新组件。
## 6. 验收
- `vue-tsc -b` exit 0。
- **浏览器实测**(本地 smoke.db,无云客):
- 微信语音 tab:点客户昵称 → `/chat/wechat/{owner}/{talker}`(侧栏+该会话);点员工微信昵称 → `/chat/wechat/{owner}`(账号级聊天窗+空态);点员工姓名 → drawer。
- WA语音 tab:同上,channel=whatsapp(若 smoke.db 有 WA 语音数据)。
- 电话 tab:单元格不可点,row-click→drawer 不变。
- 缺字段格显 `--` 不可点;network 仅 localhost。
## 7. 风险
- **WA 字段键名**:WA 语音 raw_json 的 owner uid / talker 键名 plan 核实(语音 weChatId/talker 已确认);缺失→该格不可点。
- **smoke.db WA 语音数据**:可能稀疏(Plan 4a 实跑 WA 593 条进库,应可测;若无则以语音为主验)。
- **owner/talker 类型**:raw_json 值可能非 string,onClick 里 `String(...)` 强制 + 守卫。