Files
wecom_it_smart_desk/docs/07-项目管理/任务说明书/任务说明书-REQ-用户-001-群聊入口接线.md
T

296 lines
15 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.
# 任务说明书 - 员工端 H5 群聊入口接线
> **REQ 编号**: REQ-用户-001-群聊入口接线
> **版本**: v1.0
> **日期**: 2026-08-08
> **作者**: 高见远(架构师)
> **状态**: ✅ 已完成(代码已落地,未部署)
> **子系统**: 05-用户端H5
> **模块**: 群聊
> **关联文档**:
> - **PRD**`docs/01-产品文档/05-用户端H5/PRD-REQ-用户-001-群聊双模式-v1.0.md`
> - **本次技术方案**`docs/02-技术文档/技术方案-REQ-用户-001-群聊入口接线-v1.0.md`
> - **既有技术方案**`docs/02-技术文档/技术架构/技术方案-REQ-用户-001-群聊双模式-v1.0.md`
> - **既有架构设计**`docs/02-技术文档/01-架构设计/群聊参与者展开缩略双模式-架构设计.md`
---
## 📋 一、基本信息
| 项目 | 内容 |
|------|------|
| **任务名称** | 员工端 H5 工具栏「群聊」按钮入口接线 |
| **任务ID** | REQ-用户-001-群聊入口接线 |
| **优先级** | 🟠P1(功能可见性缺陷:能力已具备但入口断路,导致用户误判功能未开发) |
| **类型** | 功能开发(入口接线)+ 文档完善(关联回写) |
| **状态** | 已完成(代码 + 文档已落地,**未部署**) |
| **负责人** | 前端工程师(实现)/ 高见远(方案与验收) |
| **创建日期** | 2026-08-08 |
| **计划完成日期** | 2026-08-08 |
| **预估工期** | 0.5 天(含测试同步与文档回写) |
| **风险等级** | 低(仅 1 个前端业务文件,0 后端 / 0 store / 0 新组件) |
| **回滚预案** | 单函数体回退即可;无数据与接口副作用 |
---
## 📥 二、输入项来源
### 2.1 产品需求
| 来源文档 | 相关章节 | 说明 |
|----------|----------|------|
| `docs/01-产品文档/05-用户端H5/PRD-REQ-用户-001-群聊双模式-v1.0.md` | §3 FE-H5-01 / FE-H5-02 | 缩略头像条 + 底部弹出展开面板的需求定义 |
### 2.2 技术方案
| 来源文档 | 相关章节 | 说明 |
|----------|----------|------|
| `docs/02-技术文档/技术方案-REQ-用户-001-群聊入口接线-v1.0.md` | §三 实现细节 / §五 验收标准 | 本次接线的实现契约与验收口径 |
| `docs/02-技术文档/技术架构/技术方案-REQ-用户-001-群聊双模式-v1.0.md` | 全文 | 群聊双模式既有实现(本次仅复用,不改动) |
| `docs/02-技术文档/01-架构设计/群聊参与者展开缩略双模式-架构设计.md` | Part A §1 | `useParticipantDisplay` 数据规范化层与双模式组件架构 |
### 2.3 原型设计
| 来源文档 | 页面 | 说明 |
|----------|------|------|
| `docs/01-产品文档/05-用户端H5/原型-REQ-用户-001-群聊双模式-v1.0.html` | H5 缩略 / 展开 | 参与者面板交互基准 |
| `docs/01-产品文档/02-会话管理/原型-REQ-会话-001-工具栏统一设计v2.0-员工端服务蓝扁平版.html` | 工具栏 | **5 按钮基线(当前生产版本 v2.0)**,本次严禁改动其 DOM 结构;v1.9 已归档为 `.archive` 仅供回溯 |
### 2.4 需了解的现有代码(历史现状)
| 模块/文件 | 说明 | 需了解的内容 |
|-----------|------|-------------|
| `src/frontend-h5/src/components/chat/InputBar.vue` | 工具栏 + 输入区 | L345-360 群聊按钮模板;改造前 L872-874 占位 toastL903 「不向 ChatPanel emit」约定 |
| `src/frontend-h5/src/stores/conversation.ts` | 会话 store | L135 / L191 / L194 状态,L1296 `toggleParticipantPanel()` |
| `src/frontend-h5/src/components/chat/ChatPanel.vue` | 聊天页容器 | L69 缩略条渲染条件;L133-142 底部弹层 |
| `src/frontend-h5/src/components/chat/ParticipantList.vue` | 展开面板 | L115 已挂载 `InviteParticipantSheet`;发起人 `canInvite` 恒真 |
| `src/frontend-h5/src/components/chat/ParticipantStrip.vue` | 缩略头像条 | L91 已挂载 `InviteParticipantSheet`(第二处) |
### 2.5 上游依赖
- 无 Alembic 迁移需求
- 无后端 API 变更
- 无新增 npm 依赖
- 坐席端 `src/frontend-agent/**` 零改动
---
## 🎯 三、范围
### 3.1 在范围内
- ✅ 仅**员工端 H5**`src/frontend-h5/**`
-`InputBar.vue``handleGroupChat()` 接线(占位 toast → 真实能力)
- ✅ 两个测试文件断言同步(契约常量化 + 弃用串清零)
- ✅ PRD ↔ 技术方案 ↔ 任务说明书 三件套关联回写
### 3.2 明确不做
-**0 后端改动**(接口 / 模型 / 推送均不动)
-**不部署**(仅留工作区改动,部署另行安排)
-**坐席端不动**(已有「邀请」入口,用户已拍板)
- ❌ 不在 InputBar 挂第三个 `InviteParticipantSheet`
- ❌ 不改 `ChatPanel.vue` L69 渲染条件
- ❌ 不做需求编号收敛及其他文档治理
---
## 📤 四、输出成果要求(交付物)
### 4.1 代码交付物
| # | 文件 | 类型 | 改动说明 | 状态 |
|---|------|------|---------|------|
| 1 | `src/frontend-h5/src/components/chat/InputBar.vue` | 代码 | 新增 2 个文案常量 + 重写 `handleGroupChat()` 三分支 | ✅ 已落地 |
| 2 | `src/frontend-h5/src/components/chat/InputBar.test.ts` | 测试 | 三分支契约用例 + 弃用串断言 | ✅ 已落地 |
| 3 | `src/frontend-h5/src/components/chat/__tests__/InputBar.vitest.test.ts` | 测试 | 按钮属性正则 + 接线目标断言 | ✅ 已落地 |
### 4.2 文档交付物
| # | 文档 | 类型 | 状态 |
|---|------|------|------|
| 1 | `docs/02-技术文档/技术方案-REQ-用户-001-群聊入口接线-v1.0.md` | 文档 | ✅ 已建 |
| 2 | `docs/07-项目管理/任务说明书/任务说明书-REQ-用户-001-群聊入口接线.md`(本文档) | 文档 | ✅ 当前 |
| 3 | `docs/01-产品文档/05-用户端H5/PRD-REQ-用户-001-群聊双模式-v1.0.md` | 文档 | ✅ 已回写(新增 `关联文档`,状态 → 已实现) |
### 4.3 代码要求
- 遵循项目代码规范;ESLint 零新增告警
- 文案**必须常量化**`GROUP_CHAT_NO_CONVERSATION_TIP` / `GROUP_CHAT_EMPTY_TIP`),测试侧复刻同名常量,禁止两侧各写裸字符串
- 严禁改动 `InputBar.vue` L345-360 模板(v1.9 工具栏基线)
- 严禁通过删除/跳过测试来消红
### 4.4 部署交付物
- **本次不部署**。工作区改动保留,交由后续统一发布窗口处理。
---
## 📁 五、涉及文件清单(含行号)
### 5.1 需修改
| 文件 | 行号 | 改动 |
|------|------|------|
| `src/frontend-h5/src/components/chat/InputBar.vue` | **L872-874**(改造前占位) | `showToast('群聊功能开发中')` 整段替换 |
| 同上 | **L867-899**(改造后现状) | L868 `GROUP_CHAT_NO_CONVERSATION_TIP`、L871 `GROUP_CHAT_EMPTY_TIP`、L886-899 `handleGroupChat()` |
| `src/frontend-h5/src/components/chat/InputBar.test.ts` | L177 / L180 / L186-187 / L797 / L848 / L861 | 契约常量、弃用串常量、三分支 describe、清零断言 |
| `src/frontend-h5/src/components/chat/__tests__/InputBar.vitest.test.ts` | L625 / L847 / L867 / L871 | 按钮属性正则、接线目标、两处弃用串断言 |
### 5.2 只读引用(严禁修改)
| 文件 | 行号 | 内容 |
|------|------|------|
| `src/frontend-h5/src/components/chat/InputBar.vue` | L345-360 | 群聊按钮模板(L348 `title="群聊"`、L349 `aria-label="群聊"`、L350 `@click="handleGroupChat"` |
| `src/frontend-h5/src/stores/conversation.ts` | L135 | `currentConversation` |
| 同上 | L191 | `participants` |
| 同上 | L194 | `participantPanelVisible` |
| 同上 | L1296 | `toggleParticipantPanel()` |
| 同上 | L2185 / L2214 | 状态与 action 导出 |
| 同上 | L1367 | 会话清理时面板状态复位 |
| `src/frontend-h5/src/components/chat/ChatPanel.vue` | L69 | `<ParticipantStrip v-if="store.participants.length > 0" />` |
| 同上 | L133-142 | 底部弹层 `van-popup`L141 `<ParticipantList />` |
| `src/frontend-h5/src/components/chat/ParticipantList.vue` | L115 | `InviteParticipantSheet` 挂载点一 |
| `src/frontend-h5/src/components/chat/ParticipantStrip.vue` | L91 | `InviteParticipantSheet` 挂载点二 |
> `InviteParticipantSheet.vue` 由面板内部挂载,`handleGroupChat` **不直接调用**,避免出现第三次挂载。
### 5.3 坐席端(本次零改动,仅登记已实现事实)
| 文件 | 行号 | 内容 |
|------|------|------|
| `src/frontend-agent/src/components/chat/ChatArea.vue` | L38 / L50 | `<ParticipantBar>` + `@invite` |
| 同上 | L214 / L221-222 | `<InviteDialog>` / `<InviteParticipantDialog>` |
| 同上 | L277-279 | 三处组件 import |
| `src/frontend-agent/src/components/conversation/ParticipantBar.vue` | L78 | `<ParticipantExpandedPanel>` |
---
## 📊 六、工作项拆分
| # | 子任务 | 涉及文件 | 负责人 | 预估工时 | 状态 |
|---|--------|---------|--------|---------|------|
| 1 | **接线 `handleGroupChat`** —— 占位 toast 替换为三分支实现,文案常量化 | `InputBar.vue` L867-899 | 前端 | 1h | ✅ 已完成 |
| 2 | **同步两测试** —— 复刻契约常量,新增三分支用例,弃用串 `'群聊功能开发中'` / `'startGroupChat'` 断言 0 命中 | `InputBar.test.ts``__tests__/InputBar.vitest.test.ts` | 前端 | 1.5h | ✅ 已完成 |
| 3 | **文档关联回写** —— 新建技术方案与本说明书;PRD 头部补 `关联文档`、状态改 `已实现` | 3 份文档 | 架构 | 1h | ✅ 已完成 |
### 子任务验收要点
- **子任务 1**:分支 1 提前 return 不得调用 toggle;分支 3 的 toast 仅在「收起 → 展开」方向触发
- **子任务 2**:不得以删除或 skip 测试的方式消红(R1 为预期内的红)
- **子任务 3**:PRD 与技术方案的 `关联文档` 必须双向一致
---
## 🔧 七、验证方式
### 7.1 单元测试
| 用例 | 断言 | 位置 |
|------|------|------|
| 无会话点击 | toast = `'请先发起会话'`**未**调用 `toggleParticipantPanel` | `InputBar.test.ts` L797 起 |
| 有会话 + 有参与者 | `toggleParticipantPanel()` 恰好 1 次,无 toast | 同上 |
| 有会话 + 零参与者(展开方向) | `toggleParticipantPanel()` 1 次 + toast = `GROUP_CHAT_EMPTY_TIP` | 同上 |
| 收起方向不重复提示 | 零参与者收起面板时无 toast | 同上 |
| 弃用串清零 | `'群聊功能开发中'` / `'startGroupChat'``InputBar.vue` 中 0 命中 | `InputBar.test.ts` L848 / L861`InputBar.vitest.test.ts` L867 / L871 |
| 按钮属性不变 | `title="群聊"` + `aria-label="群聊"` + `@click="handleGroupChat"` | `InputBar.vitest.test.ts` L625 |
### 7.2 功能验证(手工)
| # | 步骤 | 预期结果 |
|---|------|---------|
| M1 | 未发起会话 → 点群聊 | toast「请先发起会话」,无面板 |
| M2 | 有会话(0 被邀请人)→ 点群聊 | 面板弹出(显示坐席 + 我),并 toast 邀请引导 |
| M3 | M2 中点「+ 邀请参与者」→ 选人确认 | 复用既有 `InviteParticipantSheet`,提交成功 |
| M4 | M3 成功后观察聊天页 | WS 推送到达,`ParticipantStrip` 自动出现(无需刷新) |
| M5 | 反复点群聊 | 面板开合正常,收起时不重复弹提示,无状态卡死 |
| M6 | 对照工具栏基线 | 5 按钮顺序 emoji / 文件 / 坐席 / 语音 / 群聊 不变,拱形轨道无形变 |
| M7 | 被邀请人身份进入会话 → 点群聊 | 面板显示「退出会话」,二次确认可用 |
### 7.3 安全验证
| 验证项 | 验证方法 | 预期结果 |
|--------|----------|---------|
| 权限控制 | 非发起人 / 非参与者身份点击群聊 | 沿用 `ParticipantList` 既有 `canInvite` 判定,无越权邀请入口 |
| 输入验证 | 本次无新增用户输入 | N/A(纯状态切换,无网络请求) |
### 7.4 性能验证
| 验证项 | 验证方法 | 预期结果 |
|--------|----------|---------|
| 响应时间 | 点击到面板弹出 | 纯本地状态切换,无网络往返,肉眼无延迟 |
| 并发能力 | N/A | 本次不涉及后端 |
### 7.5 回归范围
- `pnpm test` 全量通过(重点 `InputBar` 相关 2 文件)
- 手工回归工具栏其余 4 键(emoji / 文件 / 坐席 / 语音)
- 坐席端零改动,不参与本次回归
---
## ✅ 八、完成标准
### 验收条件
- [x] `handleGroupChat` 三分支行为与技术方案 §3.3 契约一致
- [x] 文案常量化,测试侧复刻同名常量
- [x] `'群聊功能开发中'` / `'startGroupChat'``InputBar.vue` 中 0 命中
- [x] 未在 InputBar 新增 `InviteParticipantSheet` 挂载
- [x] 工具栏 5 按钮基线未被破坏(L345-360 模板未改)
- [x] 后端 / store / 坐席端 零改动
- [x] 文档已更新(技术方案 + 任务说明书 + PRD 回写)
- [ ] 所有测试通过(CI/CD 绿灯)—— 待工程侧执行 `pnpm test` 确认
- [ ] 代码合入主干分支 —— **本次不提交、不部署**,工作区改动待发布窗口
### 产出确认
- [x] 单元测试新增/修复完成
- [x] 文档更新已完成(三件套关联双向一致)
- [ ] Code Review
- [ ] 部署验证(本次明确不部署)
---
## 📞 九、依赖与阻塞
### 前置依赖
| 依赖任务 | 依赖说明 | 状态 |
|----------|----------|------|
| REQ-用户-001 群聊双模式 | 缩略条 / 展开面板 / 邀请 / 退出能力,本次直接复用 | ✅ 已完成 |
| REQ-会话-001 工具栏统一设计 v1.9 | 提供群聊按钮的 DOM 位(第 5 键) | ✅ 已完成 |
| store `toggleParticipantPanel()` | 面板显隐 action,已存在并导出 | ✅ 已完成 |
### 阻塞因素
| 阻塞项 | 影响范围 | 解决方案 |
|--------|----------|---------|
| 无 | — | 本任务无阻塞项 |
### 遗留登记(不在本轮范围)
| 项 | 说明 | 处置 |
|----|------|------|
| 同需求双 PRD | `02-会话管理/群聊参与者展开缩略双模式-PRD.md``05-用户端H5/PRD-REQ-用户-001-群聊双模式-v1.0.md` 描述同一需求(两文件均存在,非死链) | 归入需求编号收敛,本轮按用户要求不处理 |
| 坐席端按钮命名 | 坐席端入口叫「邀请」,需求语义是「群聊」,术语不对齐 | 将来若统一,采用「邀请」改名方案,保持 5 键基线 |
---
## 📈 十、变更记录
| 日期 | 变更内容 | 变更人 | 说明 |
|------|----------|--------|------|
| 2026-08-08 | 创建任务 | 高见远 | 初始版本;记录员工端 H5 群聊入口接线与三件套关联回写 |
---
## 📎 十一、附件
- PRD`docs/01-产品文档/05-用户端H5/PRD-REQ-用户-001-群聊双模式-v1.0.md`
- 本次技术方案:`docs/02-技术文档/技术方案-REQ-用户-001-群聊入口接线-v1.0.md`
- 既有技术方案:`docs/02-技术文档/技术架构/技术方案-REQ-用户-001-群聊双模式-v1.0.md`
- 既有架构设计:`docs/02-技术文档/01-架构设计/群聊参与者展开缩略双模式-架构设计.md`
- 原型(用户端):`docs/01-产品文档/05-用户端H5/原型-REQ-用户-001-群聊双模式-v1.0.html`
- 工具栏基线交付清单:`docs/01-产品文档/02-会话管理/交付-REQ-会话-001-工具栏统一设计v1.9-开发交付清单.md`