facc04aa65
本提交为 .git 对象库损坏后的重建提交,内容等价于原先三个本地提交 (5e2fd4c2 / 57a53c98 / 5d7e1873)的累积结果,未做任何额外改动。 一、docs 结构整改(整改 #14) 根因:重构时新结构为 untracked 文件,执行 git stash(未带 -u)未纳入, 随后 git reset 拉回 HEAD 旧 tracked 树,导致旧树复活、新旧两棵目录 树并存于 docs/,共 791 文件、双分类体系冲突。 修复动作: - b2 同名异主题文件改名迁移保全 9 个 - C 类 39 个孤立文件按主题正确归类 - A/B1 类 222 个重复文件删除(新结构已有内容副本) - 9 个旧独有空目录删除 - 270 处内部引用按 verified 映射改写 - 整改记录 #14 登记于 04-运维文档/部署运维 结果:docs 791 → 569 文件,顶层仅规范 8 类 + 治理文件,单树恢复。 残留:约 20 处指向从未存在文件的陈旧死链,归入独立文档卫生任务。 二、compose 双目录对齐(消除踩坑 A) - docker-compose.yml:nginx 前端挂载全部由根目录 frontend-*/dist 改为 src/frontend-*/dist(h5 / agent / admin / terminal) - docker-compose.dev.yml:dev 服务 build context 与卷同步改 src/ - 效果:本地 docker compose up 不再把根目录 stale dist 挂回, 与线上一致,分叉隐患消除(已 docker compose config 校验通过) 防复发铁律: - 重构须提交;仓库修复须 git stash -u 或先 commit - 新结构须 git add 并提交,避免再次 untracked 复活 - H5 改动只动 src/frontend-h5/,禁改根目录遗留 frontend-*/
14 KiB
14 KiB
员工结束会话 PRD
版本: v1.1 日期: 2026-07-30 REQ编号: REQ-会话-001 优先级: P1 阶段: 近期 状态: 待评审(v1.1 调整稿) 基线版本: v1.0(2026-07-24)
一、需求概述
1.1 需求背景
v1.0 背景(延续):
- 用户无法主动结束会话,若要结束错误对话历史(如 AI 回答错误),只能开启新会话
- 人工咨询场景缺少员工主动结束的入口
- 满意度评价仅在 AI 判定问题已解决时触发,无法覆盖所有会话场景
v1.1 新增背景:
- AI 能力演进:短期 AI 咨询无法取代人工(高频刚需:VPN、密码、紧急断网等),但长期 AI 咨询将逐步取代人工常规工作内容。设计需兼顾"现在好用"和"未来演进"。
- 按钮维度过载:v1.0 把"服务可用性"(坐席离线/繁忙)和"会话进程"(呼叫/排队/结束)合并到同一按钮,导致 5 种状态文案切换,老人找错功能。
- 右栏信息冗余:右栏底部"排队等待标签" + "答题挑战"占视觉位且非核心路径,桌面端右栏过度堆砌,移动端(<500px)又根本不渲染右栏。
- 2026-07-27 实现变更:InputBar 已实际采用 5 态合并按钮(hidden/disabled/active/urgent/waiting),并移除"结束咨询"按钮态,统一由头像右边红色按钮触发满意度评价。PRD 需与实现对齐。
1.2 需求目标
| 目标 | 说明 | 状态 |
|---|---|---|
| G1 | 员工可主动结束当前会话 | 延续 v1.0 ✅ |
| G2 | 结束会话时强制收集满意度评价 | 延续 v1.0 ✅ |
| G3 | 操作按钮承载"会话进程"(呼叫-排队) | v1.1 调整 ✏️ |
| G4 | 服务可用性(坐席是否在线)在显眼位置可见 | v1.1 新增 🆕 |
| G5 | 排队进度反馈靠近底部、不污染对话流 | v1.1 新增 🆕 |
| G6 | 右栏聚焦核心:设备诊断 + 智能推荐 | v1.1 新增 🆕 |
二、用户故事
| # | 角色 | 用户故事 | 优先级 |
|---|---|---|---|
| US-1 | 员工 | 作为员工,我希望在会话结束时能主动关闭会话,以便开始新会话获取正确回答 | P0 |
| US-2 | 员工 | 作为员工,我希望结束会话时能评价本次服务,以便反馈服务质量 | P0 |
| US-3 | 员工 | 作为员工,我希望一眼看到坐席是否在线,以便判断"AI 答不出时能否转人工" | P1 🆕 |
| US-4 | 员工 | 作为员工,我希望排队时能看到进度(前面几个人、还要多久),以便降低焦虑 | P1 🆕 |
三、功能详情
3.1 设计哲学:维度分离
核心思想:把 5 个状态按性质拆成两个独立维度,每个维度用最合适的 UI 形式呈现。
| 维度 | 性质 | UI 形式 | 位置 |
|---|---|---|---|
| A. 服务可用性 | 系统状态(坐席/排班决定) | 标题栏徽章 | 顶部,永远可见 |
| B. 会话进程 | 用户动作(员工点击决定) | 操作按钮 5 态切换 | 输入栏上方 |
| C. 排队进度 | 实时反馈(WS 推送) | 底部消息胶囊 | 输入框上方,锚定底部 |
为什么这样拆:
- 服务可用性是"系统告诉员工能不能叫到人" → 不该占用操作按钮位
- 会话进程是"员工告诉系统想干什么" → 操作按钮正确
- 排队进度是"系统实时反馈" → 既不能丢(员工焦虑),又不能污染对话流(影响 AI 上下文)
3.2 操作按钮状态机(v1.1 与实现对齐)
位置:输入栏控件区第一层(独占一行),与发送按钮上下相邻
5 态定义(与 InputBar.vue:194-243 实现完全一致):
| 状态 | 触发条件 | 按钮文案 | 按钮图标 | 样式 | 可点击 |
|---|---|---|---|---|---|
| hidden | 无会话 / 会话已关闭 | (不显示) | — | — | — |
| disabled | 坐席离线(!store.agentOnline) | 人工坐席 | 🔒 | 灰色禁用 | ❌ |
| waiting | 排队中(conv.status === 'waiting') | 排队等待 | ⏳ | 橙色描边 | ✅(点击取消) |
| active | AI 回复 ≥ 3 次 / 无紧急词 | 人工坐席 | 🎧 | 绿色描边 | ✅ |
| urgent | 检测到紧急关键词 | 人工坐席 | 🚨 | 红色脉冲 | ✅ |
2026-07-27 变更说明:
- 移除 v1.0 PRD 中的"结束咨询"按钮态
- 服务中(坐席已接入)不再通过按钮触发结束,统一由头像右边红色按钮(
chat-panel__exit-btn)触发 - 这样按钮语义更聚焦:只承担"呼叫"和"取消排队"两个动作
优先级顺序(代码行 214):
hidden > waiting > active/urgent > disabled
3.3 服务可用性指示(v1.1 新增 / G4)
位置:标题栏左上角,与"IT 智能服务"标题相邻
当前实现(ChatPanel.vue:21-28):
[IT] 智能IT服务 · 🟢 坐席在线
[IT] 智能IT服务 · ⚫ 坐席离线
v1.1 增强要求:
- 永远显示,不随页面滚动消失
- 颜色区分:在线 = 绿色圆点(
chat-panel__status--online),离线 = 灰色圆点(chat-panel__status--offline) - 后续 v1.2 可扩展为"在线 / 繁忙 / 离线"三态(增加预计等待时长)
3.4 排队进度消息胶囊(v1.1 新增 / G5)
核心思想:参考"会话已关闭"系统消息(conversation.ts:1800-1814 的 getResolveMessageText)的视觉样式,但视觉锚定到对话区底部(输入框上方),不随对话流向上滚动消失。
位置:
┌──────────────────────────────┐
│ (主对话流消息列表) │ ← 正常消息流
│ │
│ │
│ │
├──────────────────────────────┤
│ ⏳ 排队中 · 前面 3 人 · 1:32 │ ← 排队进度胶囊(sticky bottom)
├──────────────────────────────┤
│ 😊 📎 [输入框] 🎤 [发送] │ ← 输入栏
└──────────────────────────────┘
状态映射:
| 排队状态 | 胶囊文案 | 颜色 |
|---|---|---|
| 未排队 | (不显示胶囊) | — |
| 排队中 | ⏳ 排队中 · 前面 N 人 · 预计 MM:SS |
橙色 |
| 已接入 | 🟢 已接入 · 客服小王 |
绿色,3 秒后淡出 |
更新机制:
- 仅在关键节点触发胶囊内容更新,不每次位置变化都重渲染
- 关键节点:进入排队、每跳 3 位(如 5 → 2 → 1)、接听
- 普通位置变化由胶囊内的数字自动平滑过渡(CSS transition)
与对话流的关系:
- ❌ 不作为消息插入对话历史(避免污染 AI 上下文与推荐系统)
- ✅ 作为独立 UI 元素渲染,DOM 位置在
chat-panel__messages与InputBar之间 - ✅ 类似 "会话已关闭"消息的视觉样式,但位置上移到对话流底部区域
3.5 右栏简化(v1.1 新增 / G6)
删除:
- 右栏底部整段
right-panel__queue-section(含标题栏、QueueWaiting 组件、答题挑战) - 连带的
__divider分隔线 - WebSocket 中
queue_position_update事件回调(改由底部胶囊消费) api/queue+api/quiz两个 API 模块useConversationStore中queuePositionData/cancelQueue/handleQueuePositionUpdateChatPanel.vue中handleCancelQueue流程(改为按钮直接 emit 到 store)
保留(桌面端右栏最终结构):
┌─ 右栏 ─────────────────────┐
│ ▼ 设备信息(默认折叠) │ 保留
│ ▼ 自助诊断(异常徽章) │ 保留
├─────────────────────────────┤
│ ⚡ 智能推荐卡片 │ 保留
├─────────────────────────────┤
│ │
│ (空,剩余滚动空间) │
│ │
└─────────────────────────────┘
移动端:<500px 默认不渲染右栏,无变化。
3.6 结束会话流程(延续 v1.0,对齐 2026-07-27 变更)
触发方式:点击标题栏右侧红色退出按钮(chat-panel__exit-btn,SVG 退出图标)
流程:
点击"结束会话"红色按钮
↓
弹出确认对话框:"退出后会话记录会清空,当前咨询进度将丢失"
↓ 确认
调用后端 employeeClose API → 会话状态变为 resolved
↓
前端同步 store 状态为 resolved(防止 WS 延迟)
↓
弹出满意度评价组件(EvaluationDialog)
↓
用户提交评价(必填)
↓
评价提交成功 → 关闭窗口 / 跳转登录页
技术要点:
- 必须同步更新前端 store(防 BUG-用户-003 重现,参见 ChatPanel.vue:438-444 的修复)
- axios 拦截器先弹
res.message,ChatPanel catch 兜底再显示一次(双重错误信息) - 三层降级关闭窗口:WeixinJSBridge → window.close() → 跳转 /h5/login
四、非目标
| # | 明确不做 |
|---|---|
| N1 | 不修改人工呼叫的后端逻辑(仅前端 UI 与状态管理调整) |
| N2 | 不区分 AI 会话与人工会话的结束流程 |
| N3 | 不支持跳过评价直接关闭(必须评价) |
| N4 | 不做 AI 意图识别"叫人工"功能(v1.2 路线图,本期不实现) |
| N5 | 不做答题挑战 / 插队机制(v1.1 移除,保留代码可未来恢复) |
| N6 | 不做"在线/繁忙/离线"三态服务可用性(v1.2 路线图,本期仅在线/离线二态) |
五、验收指标
| # | 指标 | 目标值 | 验收方式 |
|---|---|---|---|
| AC1 | 员工可主动结束会话 | 100% | 点击"结束会话"红色按钮可触发关闭流程 |
| AC2 | 评价提交率 | =100% | 关闭会话前必须提交评价 |
| AC3 | 操作按钮状态切换正确 | 5 种状态正确切换 | 人工呼叫全流程测试 |
| AC4 | 服务可用性永远可见 | 标题栏徽章在所有页面状态可见 | 滚动 + 弹窗场景测试 |
| AC5 | 排队进度胶囊准确显示 | 排队时显示位置/时间,接听后淡出 | WS 推送全链路测试 |
| AC6 | 右栏底部 queue section 完全移除 | 桌面端右栏只含 2 大区块 | 构建产物 + 视觉回归 |
| AC7 | 不污染对话流 | 排队进度不进入 store.messages | store 检查 + AI 推荐效果对比 |
六、关联文档
| 文档 | 说明 |
|---|---|
前端组件-InputBar.vue |
操作按钮 5 态实现(hidden/disabled/active/urgent/waiting) |
前端组件-ChatPanel.vue |
标题栏坐席状态徽章 + 结束会话流程 |
前端组件-ResolveFeedback.vue / EvaluationDialog.vue |
满意度评价组件 |
前端组件-RightPanel.vue |
右栏(v1.1 移除 queue section) |
前端组件-QueueWaiting.vue |
右栏排队组件(v1.1 标记弃用,保留文件) |
API-h5.py |
关闭会话 API |
PRD-REQ-集成-002-邀请功能 |
会话管理系列功能 |
原型-REQ-会话-001-结束会话流程-v1.1.html |
v1.1 原型图(重绘) |
七、里程碑
| 阶段 | 任务 | 预计时间 |
|---|---|---|
| M1 | PRD v1.1 评审 | 0.5 天 |
| M2 | 移除右栏 queue section | 0.5 天 |
| M3 | 实现底部进度消息胶囊 | 1 天 |
| M4 | 操作按钮文案与样式微调 | 0.5 天 |
| M5 | 联调测试 + 回归 | 1 天 |
| M6 | 上线 | 0.5 天 |
| 合计 | 4 天 |
八、风险与依赖
| 风险 | 影响 | 缓解措施 |
|---|---|---|
| R1:底部胶囊位置冲突 | 可能与排查步骤(TroubleshootFlow)、参与者缩略头像条(ParticipantStrip)重叠 | 胶囊仅在排队中显示,其他 UI 元素按现有优先级层叠 |
| R2:标题栏徽章挤占空间 | 移动端窄屏下"坐席在线"可能被截断 | 响应式:<360px 改为图标 only |
| R3:API 清理影响其他模块 | api/queue 和 api/quiz 可能被其他文件引用 | 搜索全项目引用,确认无人调用后再删 |
| R4:胶囊与"会话已关闭"消息同时出现 | 排队中会话关闭时,胶囊和系统消息并存 | 关闭会话时立即清除胶囊,避免视觉冲突 |
| R5:WS 推送频率影响胶囊渲染 | 每次位置变化都推 → 胶囊频繁重渲染 | 已在 3.4 节加限制,仅关键节点更新内容 |
依赖:
- D1:WebSocket
queue_position_update事件已实现(useH5WebSocket.ts:460) - D2:
store.agentOnline字段已存在(用于服务可用性指示) - D3:EvaluationDialog 组件已实现
九、变更记录(v1.0 → v1.1)
| 变更项 | v1.0 | v1.1 | 原因 |
|---|---|---|---|
| 按钮状态数 | 3 态(人工咨询/排队等待/结束咨询) | 5 态(hidden/disabled/active/urgent/waiting) | 与 InputBar.vue 实际实现对齐 + 2026-07-27 移除"结束咨询"按钮态 |
| 服务可用性 UI | 未单独呈现 | 标题栏徽章(在线/离线) | v1.1 G4 新增要求 |
| 排队进度位置 | 右栏底部 QueueWaiting 卡片 | 底部消息胶囊(输入框上方) | v1.1 G5:移动端不可见右栏、桌面端右栏过度堆砌 |
| 答题挑战 | 右栏内嵌(含插队机制) | 完全移除 | v1.1 N5:非核心路径、游戏化双刃剑 |
| 结束会话入口 | 操作按钮"结束咨询"态 | 头像右边红色按钮 | 2026-07-27 已变更,对齐实现 |
| 右栏结构 | 4 大区块(设备/诊断/推荐/排队) | 2 大区块(设备+诊断 / 推荐) | v1.1 G6:聚焦核心 |
| API 清理 | 保留 queue + quiz API | 移除 api/queue + api/quiz | 配套代码清理 |
十、关联缺陷
| 缺陷编号 | 标题 | 状态 | 优先级 |
|---|---|---|---|
| BUG-用户-003 | H5员工端"结束会话失败,请稍后重试" | 已修复(2026-07-30) | P2-Medium |