diff --git a/docs/01-产品文档/02-会话管理/PRD-REQ-会话-001-员工结束会话-v1.3.md b/docs/01-产品文档/02-会话管理/PRD-REQ-会话-001-员工结束会话-v1.3.archive.md similarity index 100% rename from docs/01-产品文档/02-会话管理/PRD-REQ-会话-001-员工结束会话-v1.3.md rename to docs/01-产品文档/02-会话管理/PRD-REQ-会话-001-员工结束会话-v1.3.archive.md diff --git a/docs/01-产品文档/02-会话管理/PRD-REQ-会话-001-员工结束会话-v1.4.md b/docs/01-产品文档/02-会话管理/PRD-REQ-会话-001-员工结束会话-v1.4.md new file mode 100644 index 0000000..ee8c0cd --- /dev/null +++ b/docs/01-产品文档/02-会话管理/PRD-REQ-会话-001-员工结束会话-v1.4.md @@ -0,0 +1,456 @@ +# 员工结束会话 PRD + +> **版本**: v1.4 +> **日期**: 2026-08-03 +> **REQ编号**: REQ-会话-001 +> **优先级**: P1 +> **阶段**: 近期 +> **状态**: 已拍板(v1.4 删除整合区状态条,整合区降为「操作按钮 + 进度胶囊 + 引导语」三元素) +> **基线版本**: v1.3(2026-07-31;v1.3.5 状态条删除决策于 v1.4 完整落地) + +--- + +## 一、需求概述 + +### 1.1 需求背景 + +**延续 v1.0/v1.1 背景**: +1. 用户无法主动结束会话,若要结束错误对话历史(如 AI 回答错误),只能开启新会话 +2. 人工咨询场景缺少员工主动结束的入口 +3. 满意度评价仅在 AI 判定问题已解决时触发,无法覆盖所有会话场景 +4. 按钮维度过载,5 种状态文案切换频繁 +5. 右栏信息冗余,移动端(<500px)不渲染右栏导致桌面端堆砌的功能"白做" + +**v1.2 新增背景**: +1. **顶部退出按钮的真实定位**:经产品澄清,标题栏红色退出按钮**仅服务于 AI 会话的兜底退出**,用于"用户主动告诉系统别再发未回复倒计时",**不应用于结束人工会话**。人工咨询启动后,顶部按钮应自动隐藏,由操作按钮的"结束咨询"接管。 +2. **「无会话」首次进入需要引导**:之前做成 hidden 是工程角度的偷懒,用户体验上应让按钮始终可见 + 引导语引导"先说问题",避免一打开就催人工。 +3. **「重新打开」按钮补全会话收尾体验**:会话已关闭后 24h 内,按钮变成"重新打开"而非 disabled,避免用户卡死无法继续。 +4. **end 态按钮回归**:v1.1 移除了"结束咨询"按钮态(统一改用顶部按钮),v1.2 恢复——因为顶部按钮的语义已收窄到 AI 场景,**人工场景的"挂断"动作必须保留在操作按钮上**。 + +### 1.2 需求目标 + +| 目标 | 说明 | 状态 | +|------|------|------| +| G1 | 员工可主动结束当前会话(AI 或人工) | 延续 v1.0 ✅ | +| G2 | 结束会话时强制收集满意度评价 | 延续 v1.0 ✅ | +| G3 | 操作按钮承载"会话进程"完整闭环(呼叫-排队-服务-结束-重开) | v1.2 增强 ✏️ | +| G4 | 服务可用性在标题栏显眼可见 | v1.1 沿用 ✅ | +| G5 | 排队进度靠近底部、不污染对话流 | v1.1 沿用 ✅ | +| G6 | 右栏聚焦核心:设备诊断 + 智能推荐 | v1.1 沿用 ✅ | +| G7 | 顶部退出按钮语义收窄到"AI 兜底退出",人工场景自动隐藏 | v1.2 新增 🆕 | +| G8 | 「无会话」/「<3 轮对话」用引导语代替禁用按钮 | v1.2 新增 🆕 | +| G9 | 「会话已关闭 24h 内」显示"重新打开"按钮 | v1.2 新增 🆕 | + +--- + +## 二、用户故事 + +| # | 角色 | 用户故事 | 优先级 | +|---|------|----------|--------| +| US-1 | 员工 | 作为员工,我希望在会话结束时能主动关闭会话,以便开始新会话获取正确回答 | P0 | +| US-2 | 员工 | 作为员工,我希望结束会话时能评价本次服务,以便反馈服务质量 | P0 | +| US-3 | 员工 | 作为员工,我希望一眼看到坐席是否在线,以便判断"AI 答不出时能否转人工" | P1 | +| US-4 | 员工 | 作为员工,我希望排队时能看到进度(前面几个人、还要多久),以便降低焦虑 | P1 | +| US-5 | 员工 | 作为员工,我希望 AI 对话中能用顶部按钮明确告诉系统"我走了",以免被打扰提醒 | P1 🆕 | +| US-6 | 员工 | 作为员工,我希望刚打开应用时知道"先说什么才能叫人",而不是看到灰按钮困惑 | P2 🆕 | +| US-7 | 员工 | 作为员工,我希望会话关闭后还能在 24h 内重新打开,避免反复开新会话丢失上下文 | P2 🆕 | + +> **v1.4 反转说明**:US-3("一眼看到坐席是否在线")在 v1.3 通过整合区状态条满足,但 v1.4 已删除状态条(不向员工暴露坐席在线/离线状态),故 US-3 在 v1.4 不再满足;相关诉求改以"引导语 + 操作按钮 disabled 态"间接体现(坐席离线时引导语提示"建议先用 AI 解答;如紧急可刷新重试")。 + +--- + +## 三、功能详情 + +### 3.1 设计哲学:维度分离 + 场景互斥 + +**v1.2 核心设计思想**:把 5 种操作按钮状态、引导语、顶部按钮可见性,按"会话场景"重新划分,确保每个 UI 元素的职责单一、场景不重叠。 + +**三维度划分**(v1.1 沿用 + v1.2 增强): + +| 维度 | 性质 | UI 形式 | v1.2 变化 | +|---|---|---|---| +| **A. 服务可用性** | 系统状态 | 标题栏徽章 🟢/⚫ | 沿用 | +| **B. 会话进程** | 用户动作 | 操作按钮 6 态 + 引导语 | **6 态 + 引导语** | +| **C. 排队进度** | 实时反馈 | 底部消息胶囊 | 沿用 | +| **D. 退出兜底**(v1.2 新增独立维度) | AI 场景专属 | 标题栏红色退出按钮 | **仅 AI 场景显示** | + +**为什么"退出兜底"独立成维度**: +- 顶部按钮的语义在 v1.1 模糊("既能退出 AI 又能结束人工") +- v1.2 收窄后,它变成"AI 会话兜底退出"的专用入口 +- 与操作按钮 end 态**场景互斥**——任何时候只有一个可用,从根本上避免"双入口混淆" + +### 3.2 操作按钮 6 态状态机(v1.2 核心变更) + +**位置**:输入栏控件区第一层(独占一行),与发送按钮上下相邻 + +**6 态定义**(移除 hidden / 恢复 end / 新增 reopen): + +| 状态值 | 触发条件 | 按钮文案 | 按钮图标 | 按钮样式 | 可点击 | +|--------|---------|---------|---------|---------|--------| +| **disabled**(v1.2 扩展场景) | 无会话 / AI <3 轮 / 坐席离线 / 会话过期 | 人工坐席 | 🔒 | 灰色禁用 | ❌ | +| **active** | AI ≥3 轮 / 无紧急词 | 人工坐席 | 🎧 | 绿色描边 | ✅ | +| **urgent** | 检测到紧急关键词 | 人工坐席 | 🚨 | 红色脉冲 | ✅ | +| **waiting** | 排队中 | 排队等待 | ⏳ | 橙色描边 | ✅(点击取消) | +| **end** 🆕(v1.2 恢复) | 坐席已接入(conv.status === 'serving') | 结束咨询 | 📴 | 红色填充 | ✅(点击弹满意度评价) | +| **reopen** 🆕(v1.2 新增) | 会话已关闭 + 24h 内 | 重新打开 | 🔄 | 蓝色填充 | ✅(调用 reopen API) | + +**v1.2 移除的态**: +- ❌ **hidden** — 不再使用,所有场景都有按钮呈现(避免用户找不到入口) + +**优先级顺序**(代码逻辑): +``` +end > reopen > waiting > active/urgent > disabled +``` + +### 3.3 引导语设计(v1.2 新增 G8) + +**位置**:操作按钮正下方的小字(参考现有 `input-bar__guide` 样式,InputBar.vue 行 128-130 已有此结构) + +**4 种场景引导语**: + +| 场景 | 引导语 | 设计意图 | +|---|---|---| +| **无会话**(刚打开应用) | 💡 先描述一下你遇到的问题,AI 助手会先帮你看看 | 一开始就让用户知道"先说问题" | +| **AI 对话 <3 轮** | 请继续描述您的问题或需求 | 鼓励继续描述,不显示进度数字(避免催促感) | +| **坐席离线** | ⚠️ 坐席当前离线,建议先用 AI 解答;如紧急可刷新重试 | 不完全堵死,给"刷新重试"出口 | +| **会话过期**(>24h) | ⏰ 上一会话已过期,开始新对话吧 | 引导开新会话 | + +**设计原则**: +1. **不显示 `{n}/3` 进度数字** — 避免催促感,让用户专注于描述问题 +2. **所有引导语都鼓励"先 AI"** — 不给坐席端制造流量压力 +3. **离线情况给出口** — 不直接禁用按钮的可达性,留"刷新重试" +4. **过期明确引导"开新对话"** — 避免用户困惑"为什么不能重开" + +**引导语和按钮态的对应关系**: + +| 按钮态 | 引导语 | +|---|---| +| disabled(无会话) | 先描述一下你遇到的问题... | +| disabled(AI <3 轮) | 请继续描述您的问题或需求 | +| disabled(坐席离线) | 坐席当前离线... | +| disabled(会话过期) | 上一会话已过期... | +| active | (无引导,或可选"AI 答不出再点人工") | +| urgent / waiting / end / reopen | (无引导,避免冗余) | + +### 3.4 服务可用性指示(v1.1 沿用 G4) + +**位置**:标题栏左上角,与"IT 智能服务"标题相邻 + +**当前实现**(ChatPanel.vue:21-28): +``` +[IT] 智能IT服务 · 🟢 坐席在线 +[IT] 智能IT服务 · ⚫ 坐席离线 +``` + +**v1.2 沿用**:永远显示,不随滚动消失。v1.3 将坐席状态从标题栏徽章迁移至整合区状态条;**v1.4 已删除整合区状态条**(不向员工暴露坐席在线/离线),本维度整体取消。 + +### 3.5 顶部退出按钮可见性规则(v1.2 核心新增 G7) + +**位置**:标题栏右侧红色退出按钮(`chat-panel__exit-btn`,SVG 退出图标) + +**v1.2 关键变更**:**仅 AI 会话场景显示** + +| 会话场景 | 顶部按钮可见 | 设计意图 | +|---|---|---| +| 无会话 | ❌ 隐藏 | 用户还没开始,没必要 | +| AI 对话中(disabled / active / urgent) | ✅ 显示 | 兜底退出,告诉系统"别发倒计时" | +| **人工咨询启动后**(waiting) | **❌ 隐藏** | 操作按钮 waiting 接管取消排队 | +| **人工服务中**(serving) | **❌ 隐藏** | 操作按钮 end 接管结束人工 | +| 会话已关闭 | ❌ 隐藏 | 顶部按钮只对"进行中"的会话有意义 | + +**为什么这么设计**: +- 顶部按钮的语义被收窄为「AI 会话兜底退出」 +- 人工场景的"结束"由操作按钮 end 态专管 +- 两个按钮**场景互斥**,任何时候只有一个可用,**从根源避免双入口混乱** +- 用户认知简单:"AI 时用顶部,人工时用底部" + +**文案强化建议**(技术方案配合): +- tooltip:「结束会话(不再发送提醒)」 +- 确认弹窗:「确定要结束这次咨询吗?将不再发送未回复提醒」 + +**store 新增字段**(技术方案配合): +- `store.showHeaderExitBtn: boolean` +- 由会话状态计算得出(见 3.5 表格) + +### 3.6 排队进度消息胶囊(v1.1 沿用 G5) + +**位置**:主对话流底部(输入框上方),锚定底部不随滚动消失 + +**4 种状态**(参照 conversation.ts:1800-1814 的"会话已关闭"消息样式): + +| 排队状态 | 胶囊文案 | 颜色 | +|---------|---------|------| +| 未排队 | (不显示胶囊) | — | +| 排队中 | `⏳ 排队中 · 前面 N 人 · 预计 MM:SS` | 橙色 | +| 已接入 | `🟢 已接入 · 客服小王` | 绿色,3 秒后淡出 | +| 会话已关闭 | `✅ 会话已关闭`(或隐藏) | 灰色 | + +**关键约束**: +- ❌ **不作为消息插入对话历史**(避免污染 AI 上下文) +- ✅ 仅在关键节点更新(进入排队 / 每跳 3 位 / 接听) + +### 3.7 右栏简化(v1.1 沿用 G6) + +**删除**(v1.1 已明确): +- 右栏底部整段 `right-panel__queue-section`(含标题栏、QueueWaiting 组件、答题挑战) +- api/queue、api/quiz、`store.queuePositionData`、`cancelQueue`、`handleQueuePositionUpdate` +- ChatPanel.vue 中 `handleCancelQueue` 流程(改为按钮 emit 到 store) + +**v1.2 保留**(桌面端右栏 2 大区块): +1. 顶部手风琴:设备信息 ↔ 自助诊断(互斥折叠) +2. 中部:智能推荐卡片 + +移动端(<500px)不渲染右栏,无变化。 + +### 3.8 结束会话流程(v1.2 修订 G7) + +**双入口,按场景分流**: + +#### 入口 A:操作按钮 end 态(仅坐席服务中) + +``` +点击操作按钮"📴 结束咨询" + ↓ +弹出确认框:"确定要结束人工咨询吗?" + ↓ 确认 +调用 employeeClose API → 会话状态 resolved + ↓ +弹出满意度评价(EvaluationDialog) + ↓ +提交评价 → 自动关闭窗口 +``` + +#### 入口 B:顶部红色退出按钮(仅 AI 会话) + +``` +点击顶部红色"退出会话"按钮 + ↓ +弹出确认框:"确定要结束这次咨询吗?将不再发送未回复提醒" + ↓ 确认 +调用 employeeClose API(标记 close_reason='ai_session_quit') + ↓ +弹出满意度评价(即使是 AI 服务也收集) + ↓ +提交评价 → 自动关闭窗口 +``` + +**两个入口的防抖/互斥保证**: +- 由 `store.showHeaderExitBtn` 和按钮态计算逻辑保证场景互斥 +- 同一按钮组件内 async handler 三件套(防抖 + 同步 store + try/finally 重置)——参见 ChatPanel.vue:403 handleExitWithEvaluation 的修复样本 + +--- + +## 四、非目标 + +| # | 明确不做 | +|---|----------| +| N1 | 不修改人工呼叫的后端逻辑(仅前端 UI 与状态管理调整) | +| N2 | 不区分 AI 会话与人工会话的结束流程(都是 close + evaluation) | +| N3 | 不支持跳过评价直接关闭(必须评价) | +| N4 | 不做 AI 意图识别"叫人工"功能(v1.3 路线图) | +| N5 | 不做答题挑战 / 插队机制(已永久移除) | +| N6 | 不做"在线/繁忙/离线"三态服务可用性(v1.3 路线图) | +| N7 | 不在引导语中显示 `{n}/3` 进度数字(v1.2 拍板不需要,避免催促感) | + +--- + +## 五、验收指标 + +| # | 指标 | 目标值 | 验收方式 | +|---|------|--------|---------| +| AC1 | 员工可主动结束会话(AI 或人工) | 100% | 双入口分别测试 | +| AC2 | 评价提交率 | =100% | 关闭会话前必须提交评价 | +| AC3 | 操作按钮状态切换正确 | 6 种状态正确切换 | 完整状态机测试 | +| AC4 | 服务可用性永远可见 | 标题栏徽章所有状态可见 | 滚动 + 弹窗场景 | +| AC5 | 排队进度胶囊准确显示 | 排队时显示位置/时间,接听后淡出 | WS 推送全链路 | +| AC6 | 右栏底部 queue section 完全移除 | 桌面端右栏只含 2 大区块 | 构建产物 + 视觉回归 | +| AC7 | 不污染对话流 | 排队进度不进入 store.messages | store 检查 + AI 推荐效果对比 | +| AC8 | 顶部按钮仅 AI 场景显示 🆕 | waiting / serving 时顶部按钮隐藏 | 状态切换测试 | +| AC9 | 引导语按场景正确显示 🆕 | 4 种场景对应正确引导语 | UI 截图比对 | +| AC10 | 重新打开按钮 24h 内可见 🆕 | 会话关闭 + 24h 内显示 🔄 按钮,>24h 不显示 | 时间边界测试 | +| AC11 | 双入口互斥 🆕 | 任何时候顶部按钮和 end 态不同时可用 | 状态机单元测试 | + +--- + +## 六、关联文档 + +| 文档 | 说明 | +|------|------| +| `前端组件-InputBar.vue` | 操作按钮 6 态实现 + 引导语渲染 | +| `前端组件-ChatPanel.vue` | 标题栏坐席状态徽章 + 顶部退出按钮(v1.2 新增 showHeaderExitBtn) | +| `前端组件-ResolveFeedback.vue` / `EvaluationDialog.vue` | 满意度评价组件 | +| `前端组件-RightPanel.vue` | 右栏(v1.1 已移除 queue section) | +| `前端组件-QueueWaiting.vue` | 右栏排队组件(v1.1 标记弃用) | +| `API-h5.py` | 关闭会话 API + reopen API | +| `stores/conversation.ts` | 新增 `showHeaderExitBtn` 字段 | +| `原型-REQ-会话-001-结束会话流程-v1.4.html` | v1.4 原型图(整合区删除状态条) | +| `../../02-技术文档/技术方案-REQ-会话-001-员工结束会话-v1.4.md` | v1.4 技术方案(同步更新) | + +--- + +## 七、里程碑 + +| 阶段 | 任务 | 预计时间 | +|------|------|---------| +| M1 | PRD v1.2 评审 | 0.5 天 | +| M2 | store 新增 `showHeaderExitBtn` 字段 + 状态计算逻辑 | 0.5 天 | +| M3 | InputBar 改造:hidden → disabled + 6 态扩展 + 4 种引导语 | 1 天 | +| M4 | ChatPanel 改造:顶部按钮 v-show 绑定 showHeaderExitBtn | 0.5 天 | +| M5 | 重新打开按钮 + 24h 边界逻辑 | 0.5 天 | +| M6 | 联调测试 + 视觉回归 | 1 天 | +| M7 | 上线 | 0.5 天 | +| **合计** | | **4.5 天** | + +--- + +## 八、风险与依赖 + +| 风险 | 影响 | 缓解措施 | +|------|------|---------| +| R1:end 态 + 顶部按钮双入口导致混乱 | 用户不知道该点哪个 | v1.2 设计为场景互斥,从根上避免 | +| R2:store.showHeaderExitBtn 计算错误 | 顶部按钮在错误场景显示 | 单元测试覆盖所有状态切换路径 | +| R3:24h 边界判断依赖客户端时钟 | 用户改时间可绕过 | 后端 reopen API 做权威校验,前端仅做 UI 提示 | +| R4:end 态按钮文案"结束咨询"被理解为"结束 AI 咨询" | 视觉歧义 | end 态仅在 serving 触发,文案下加微提示或 icon 强化"挂断"语义 | +| R5:引导语和按钮态不同步 | 用户看到引导语但按钮已可点击 | 引导语渲染条件与按钮态计算共享同一 computed | + +**依赖**: +- D1:WebSocket `queue_position_update` 事件已实现 +- D2:`store.agentOnline` 字段已存在 +- D3:EvaluationDialog 组件已实现 +- D4:reopen API 已在 `closing.ts:119` 实现 + +--- + +## 九、变更记录(v1.1 → v1.2 → v1.3 → v1.4) + +| 变更项 | v1.1 | v1.2 | v1.3(已拍板 ✅) | v1.4(已拍板 ✅) | 原因 | +|--------|------|------|--------|--------|------| +| 操作按钮状态数 | 5 态(含 hidden) | **6 态(移除 hidden,恢复 end,新增 reopen)** | 沿用 6 态(位置从 InputBar 移至整合区) | 沿用 6 态 | 隐藏按钮用户体验断裂;end 态回归解决人工场景主动结束需求;v1.3 整合区收纳 | +| 引导语 | 仅 active 态显示 | **4 种场景分阶段引导语**(在 InputBar 按钮下方) | **迁移到整合区按钮下方** | 沿用(整合区按钮下方) | v1.3 把 InputBar 工具栏瘦身,引导语随按钮一起进整合区 | +| 顶部按钮可见性 | 所有状态可显示 | **仅 AI 场景显示** | 沿用(仅 AI 场景显示) | 沿用 | 产品澄清:顶部按钮仅服务 AI 兜底退出,人工场景由操作按钮接管 | +| 「重新打开」按钮 | 无 | **新增(蓝色)** | 沿用(位置从 InputBar 移至整合区) | 沿用 | 会话关闭 24h 内可继续,避免用户卡死 | +| `{n}/3 进度提示` | 有 | **移除** | 沿用 | 沿用 | 用户拍板避免催促感 | +| 顶部按钮文案 | 无 tooltip | **加 tooltip + 确认弹窗** | 沿用 | 沿用 | 强化"不再发送提醒"语义 | +| 状态机互斥保证 | 无 | **showHeaderExitBtn 计算逻辑** | 沿用 | 沿用 | 顶部按钮和 end 态场景互斥 | +| `hidden` 态 | 存在 | **完全移除** | 沿用 | 沿用 | 按钮永远可见,避免用户找不到入口 | +| 结束会话入口 | 仅顶部按钮 | **顶部(AI)+ 操作按钮 end(人工)双入口** | 沿用(按钮位置迁移) | 沿用 | 两个入口场景互斥,不是冗余 | +| 🆕 **整合区(方案 A)** | 无 | 无 | **新增:状态条 + 操作按钮 + 进度胶囊整合** | **调整为三元素:操作按钮 + 进度胶囊 + 引导语(状态条移除)** | v1.3.5 决策不向员工暴露坐席在线/离线状态,整合区降为三元素 | +| 🆕 **标题栏坐席徽章** | 🟢/⚫ | 🟢/⚫ | **移至整合区顶部(标题栏瘦身)** | **v1.4 移除**(不再向员工展示坐席在线/离线) | 状态条删除后,坐席状态展示整体取消 | +| 🆕 **整合区背景色** | — | — | **`#fafafa`(浅灰,沿用 chat-mock)** | 沿用 | 与消息区视觉一致 | +| 🆕 **状态条策略** | — | — | **永久显示** | **✅ 删除(v1.3.5 决策,v1.4 完整落地)** | 产品决定不向员工暴露坐席在线/离线状态,减少焦虑来源而非增加 | +| 🆕 **状态条文案** | — | — | **🟢 在线 · 9:00-18:00 / 🟡 繁忙 · 预计 N 分钟 / ⚫ 客服暂休 · 9:00-18:00** | **随状态条一并删除** | 状态条删除后,文案与 `store.shiftHours` 计划同步取消 | +| 🆕 **移动端折叠** | — | — | **不折叠,默认展开** | 沿用 | 移动端与桌面端一致 | +| 🆕 **维度划分** | 3 维度 | 4 维度(新增"退出兜底"独立维度) | **5 维度(新增"整合区"统一收容)** | **4 维度(整合区降为三元素,取消状态条维度)** | 见 §十一 v1.4 整合区增量 | + +--- + +## 十、关联缺陷 + +| 缺陷编号 | 标题 | 状态 | 优先级 | +|----------|------|------|--------| +| [BUG-用户-003](../../03-测试文档/05-缺陷单/BUG-用户-H5结束会话失败-003.md) | H5员工端"结束会话失败,请稍后重试" | 已修复(2026-07-30) | P2-Medium | + +--- + +## 十一、v1.3 整合区增量(方案 A 已拍板 ✅) + +> **拍板日期**:2026-07-31 下午 +> **关联原型**:[原型-REQ-会话-001-结束会话流程-v1.3.html §⑨](../02-会话管理/原型-REQ-会话-001-结束会话流程-v1.3.html) +> **关联技术方案**:[技术方案-REQ-会话-001-员工结束会话-v1.3.md §v1.3 整合区实施要点](../../02-技术文档/技术方案-REQ-会话-001-员工结束会话-v1.3.md) + +### 11.1 设计理念 + +v1.2 把"结束会话"相关的 4 个维度(服务可用性 / 会话进程 / 排队进度 / 退出兜底)分散到页面的 4 个不同位置——标题栏坐席徽章、InputBar 操作按钮、消息流底部胶囊、顶部红色按钮。这种"分散式布局"导致: + +1. **用户的认知负担重**:要扫描整个对话区才能找到"现在能不能叫人、怎么叫人" +2. **组件之间的状态同步复杂**:6 态按钮 / 状态徽章 / 进度胶囊各自维护同一份会话状态的投影 +3. **InputBar 工具栏拥挤**:😊📎 输入框 🎧人工坐席 [发送] 一行塞 5 个元素 + +v1.3 方案 A 把这 4 个维度重新组织为**两段式**(v1.4 调整为:整合区移除状态条,降为三元素): +- **整合区**(永久容器,浅灰背景):操作按钮 + 进度胶囊 + 引导语 三件套纵向堆叠 +- **顶部退出**(沿用 v1.2):仅 AI 场景可见 + +### 11.2 整合区 3 元素纵向堆叠(v1.4 移除状态条) + +> **v1.4 变更**:v1.3 原「状态条 + 操作按钮 + 进度胶囊 + 引导语」四元素,v1.4 删除状态条,降为**三元素**。 + +| 元素 | 位置 | 性质 | UI 形式(沿用 v1.2 类) | +|------|------|------|------------------------| +| 操作按钮 | 整合区中部 | 核心 CTA | `.call-btn--disabled/active/urgent/waiting/end/reopen` 6 态 | +| 进度胶囊 | 整合区下部 | 按需显示 | `.queue-capsule` + `--connected` 4 态 | +| 引导语 | 按钮下方 | 4 种场景 | `.input-bar-mock__guide`(含 `--warn` 变体) | +| 整合区容器边界 | InputBar 上方 | 浅色容器 | inline 样式 `#fafafa`(沿用 chat-mock),不新增 CSS 类 | + +### 11.3 9 场景整合区 mockup(v1.4 移除状态条列) + +> 完整 mockup 见原型图 §⑨ 9.3;v1.4 起状态条已删除,下表不再含状态条列。 + +| # | 场景 | 按钮态 | 引导语 | 进度胶囊 | +|---|------|--------|--------|----------| +| 1 | 无会话 | 🔒 disabled | "先描述一下..." | (无) | +| 2 | AI < 3 轮 | 🔒 disabled | "请继续描述..." | (无) | +| 3 | AI ≥ 3 轮 | 🎧 active | (无) | (无) | +| 4 | 紧急关键词 | 🚨 urgent(脉冲) | (无) | (无) | +| 5 | 坐席离线 | 🔒 disabled | "坐席当前离线..." | (无) | +| 6 | 排队中 | ⏳ waiting("排队取消") | (无) | 🟠 排队中 | +| 7 | 已接入 | 📴 end("结束咨询") | (无) | 🟢 已接入(3 秒淡出) | +| 8 | 重新打开(24h 内) | 🔄 reopen | (无) | ✅ 会话已关闭 | +| 9 | 会话过期(>24h) | 🔒 disabled | "上一会话已过期..." | (无) | + +### 11.4 已拍板决策清单(v1.3 五项 + v1.4 反转一项) + +| # | 维度 | 拍板结果 | 状态 | +|---|------|----------|------| +| 1 | 状态条策略 | ❌ v1.3 拍板「永久显示」→ **v1.4 反转:删除**(v1.3.5 决策,v1.4 完整落地) | 已反转 | +| 2 | 状态条文案 | v1.3 拍板「在线 · 9:00-18:00」→ 随状态条一并删除 | 已移除 | +| 3 | 整合区背景色 | ✅ 浅灰 `#fafafa`(沿用 chat-mock) | 沿用 | +| 4 | 引导语位置 | ✅ 整合区按钮下方(方案 A 默认) | 沿用 | +| 5 | 移动端折叠 | ✅ 不折叠,默认展开 | 沿用 | + +> **v1.4 反转说明**:2026-07-31 v1.3 拍板「状态条永久显示」,但 v1.3.5 开发阶段产品口头决策**不向员工暴露坐席在线/离线状态**(减少焦虑来源、避免"离线即不可用"的误导),仅落地了引导语侧,整合区状态条模板残留至 v1.4 才彻底清理。v1.4 据此将整合区从「状态条 + 按钮 + 胶囊 + 引导语」四元素降为「按钮 + 胶囊 + 引导语」三元素,`IntegrationZone.vue` 状态条 DOM/CSS/`shiftHours` 引用全部移除(见 §11.6 与技术方案 §十)。 + +### 11.5 与 v1.2 位置对比表 + +| 位置 | v1.2 现状 | v1.3 方案 A | v1.4 方案(状态条移除) | 变化 | +|------|-----------|-------------|------------------------|------| +| 标题栏 | logo + 标题 + 坐席状态🟢⚫ + 主题 + 头像 + 退出 | logo + 标题 + 主题 + 头像 + 退出 | logo + 标题 + 主题 + 头像 + 退出 | -1 元素(坐席状态) | +| 整合区(永久) | 无 | 状态条 3 态文案 | 无(v1.4 移除) | +1 → -1 永久元素 | +| 整合区(按钮) | InputBar 工具栏内 | 整合区中部 | 整合区中部 | 位置迁移 | +| 整合区(按需胶囊) | 消息流底部独立 | 整合区下部(与按钮同容器) | 整合区下部(与按钮同容器) | 位置迁移 | +| InputBar 工具栏 | 😊📎[输入框][🎧人工坐席][发送] | 😊📎[输入框][发送] | 😊📎[输入框][发送] | -1 元素(按钮) | + +### 11.6 实施要点 + +> **v1.4 状态条清理**:`IntegrationZone.vue` 中状态条 DOM(`.integration-zone__status-bar`)、`statusBarText` computed、`buildStatusBarText` / `SHIFT_HOURS` 引用、`@/utils/shiftHours` 导入、`.integration-zone__status-bar` CSS 块已全部移除;`IntegrationZoneProps` 中 `agentOnline` / `shiftHours` 字段因下游 `QueueCapsule` 降级判定仍消费 `agentOnline` 而保留,`shiftHours` 为后端班次预留(当前无渲染)。回归单测见 `integrationZoneStatusBar.test.ts`(源码级守卫,8 用例)。 + +1. **整合区组件**:`IntegrationZone.vue` 容器组件,props 接口见技术方案 v1.4 §D。 +2. **文件清单**(详见技术方案 v1.4 §B): + - 新建:`IntegrationZone.vue` / `integrationZone.ts`(`shiftHours.ts` 一并移除,状态条相关工具常量随状态条删除) + - 修改:`InputBar.vue`(移除操作按钮)/ `ChatPanel.vue`(移除坐席徽章 + 集成 IntegrationZone)/ `QueueCapsule.vue`(集成到 IntegrationZone) +3. **不动 v1.2y 已 PASS 内容**:6 态按钮文案、坐席离线拦截、取消入口合并、淡出交互 全部保留不动(详见 11.7)。 + +### 11.7 关键约束 + +| # | 不动的 v1.2y 已 PASS 内容 | 文件 / 位置 | +|---|---------------------------|------------| +| 1 | 4 种引导语文案与按钮态对应关系 | `inputBarGuideText.ts` | +| 2 | 操作按钮 6 态状态机(含优先级 end > reopen > waiting > active/urgent > disabled) | `inputBarCallAgentState.ts` | +| 3 | "会话已关闭"消息文本(含带 emoji 兼容) | `conversation.ts:1911-1925 getResolveMessageText` | +| 4 | reopen API 调用与 24h 边界 | `closing.ts:119 reopenConversation` | + +**v1.3 增量 = 整合区结构 + 5 元素纵向堆叠**,不修改上述 4 处已 PASS 内容。 + +--- + +## 十二、拍板记录 + +| 日期 | 决策 | 决策人 | 影响范围 | +|------|------|--------|----------| +| 2026-07-31 下午 | 状态条永久显示 | 用户拍板 | §11.4 决策 1(v1.4 已反转) | +| 2026-07-31 下午 | 状态条文案"在线 · 9:00-18:00" | 用户拍板 | §11.4 决策 2(v1.4 已移除) | +| 2026-07-31 下午 | 整合区背景色 `#fafafa` 浅灰 | 用户拍板 | §11.4 决策 3 | +| 2026-07-31 下午 | 引导语放整合区按钮下方 | 用户拍板 | §11.4 决策 4 | +| 2026-07-31 下午 | 移动端不折叠,默认展开 | 用户拍板 | §11.4 决策 5 | +| **2026-08-03** | **反转:删除整合区状态条(v1.3.5 决策,v1.4 完整落地);整合区降为「操作按钮 + 进度胶囊 + 引导语」三元素** | 用户拍板 | §11.4 决策 1 / §11.2 / 技术方案 §十 / 原型图 §⑨ | + +> **后续同步动作**:PRD v1.4(本文档)+ 技术方案 v1.4 + 原型图 v1.4 三件套同步落地;状态条删除后,`store.shiftHours` 后端班次接入计划相应取消(无前端渲染目标)。 \ No newline at end of file diff --git a/docs/01-产品文档/02-会话管理/原型-REQ-会话-001-结束会话流程-v1.3.html b/docs/01-产品文档/02-会话管理/原型-REQ-会话-001-结束会话流程-v1.3.archive.html similarity index 100% rename from docs/01-产品文档/02-会话管理/原型-REQ-会话-001-结束会话流程-v1.3.html rename to docs/01-产品文档/02-会话管理/原型-REQ-会话-001-结束会话流程-v1.3.archive.html diff --git a/docs/01-产品文档/02-会话管理/原型-REQ-会话-001-结束会话流程-v1.4.html b/docs/01-产品文档/02-会话管理/原型-REQ-会话-001-结束会话流程-v1.4.html new file mode 100644 index 0000000..53dbf62 --- /dev/null +++ b/docs/01-产品文档/02-会话管理/原型-REQ-会话-001-结束会话流程-v1.4.html @@ -0,0 +1,1345 @@ + + + + + + 员工结束会话 - 原型图 v1.4 + + + +
+

🎯 员工结束会话功能 · 原型图 v1.4

+
+ v1.4 调整(2026-08-03)— 方案 A 整合区:操作按钮/进度胶囊/引导语三元素(状态条已删除,v1.3.5 决策) +
+ + +
+
设计哲学:4 维度分离(v1.2 新增"退出兜底"独立维度)
+
+ v1.1 三维度基础上,新增"退出兜底"作为独立维度——顶部按钮语义收窄到 AI 场景,与操作按钮 end 态场景互斥。 +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
维度性质UI 形式位置v1.2 变化
A. 服务可用性系统状态标题栏徽章 🟢/⚫顶部沿用
B. 会话进程用户动作操作按钮 6 态 + 引导语输入栏5 态 → 6 态 + 引导语
C. 排队进度实时反馈底部消息胶囊输入框上方沿用
D. 退出兜底 🆕AI 场景专属标题栏红色退出按钮顶部右侧仅 AI 场景显示
+ +
+ 💡 维度 D 与维度 B 的 end 态场景互斥,任何时候只有一个可用,从根本上避免"双入口混乱" +
+
+ + +
+
⭐ 操作按钮 · 6 态 + 4 种引导语(v1.2 核心变更)
+
+ v1.1 的 5 态调整:❌ 移除 hidden / ✅ 恢复 end / ✅ 新增 reopen
+ 新增 4 种场景引导语,按钮永远可见(仅状态变化),用户不会再"找不到入口"。 +
+ +
+ +
+
disabled · 无会话
+ +
💡 先描述一下你遇到的问题,AI 助手会先帮你看看
+
用户刚打开应用
+
+ +
+
disabled · AI <3 轮
+ +
请继续描述您的问题或需求
+
AI 对话早期
+
+ +
+
disabled · 坐席离线
+ +
⚠️ 坐席当前离线,建议先用 AI 解答
+
!store.agentOnline
+
+ + +
+
active · AI ≥3 轮
+ +
可呼叫
+
+ +
+
urgent · 紧急关键词
+ +
高优一键呼叫
+
+ +
+
waiting · 排队中
+ +
点击取消排队
+
+ + +
+
end 🆕 · 坐席服务中
+ +
v1.2 恢复 · 主动挂断人工
+
+ +
+
reopen 🆕 · 24h 内重开
+ +
v1.2 新增 · 蓝色填充
+
+ +
+
disabled · 会话过期
+ +
⏰ 上一会话已过期,开始新对话吧
+
>24h 不可重开
+
+
+ +
+ ⚠️ 优先级:end > reopen > waiting > active/urgent > disabled。hidden 已完全移除。 +
+
+ + +
+
⭐⭐ 顶部退出按钮 · 仅 AI 场景显示(v1.2 G7 关键变更)
+
+ 产品澄清:顶部按钮的语义被收窄为"AI 会话兜底退出"——告诉系统"我走了,别发倒计时"。
+ 人工咨询启动后(waiting / serving),顶部按钮自动隐藏,由操作按钮 end 态接管"结束人工"动作。 +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
会话场景顶部"退出会话"操作按钮说明
无会话❌ 隐藏🔒 disabled(引导"先说问题")用户还没开始
AI 对话中(任何状态)✅ 显示🎧 active / 🔒 disabled顶部 = AI 兜底退出
人工咨询启动后(waiting)❌ 隐藏⏳ waiting(取消排队)操作按钮接管
坐席服务中(serving)❌ 隐藏📴 end(结束咨询)操作按钮 end 态接管
会话已关闭(24h 内)❌ 隐藏🔄 reopen(重新打开)操作按钮 reopen 接管
会话已关闭(>24h)❌ 隐藏🔒 disabled(引导"开新会话")过期失效
+
+ + +
+
场景对比 mockup:AI 对话 vs 坐席服务中
+ +
+ +
+
AI 对话中(顶部按钮可见)
+ +
+
+
+ + 智能IT服务 +
+ + 在线 + +
+
+ ☀️🌙 +
S
+
+
+
+ +
+
+
VPN 连不上
+
请尝试重启...
+
重启了还是不行
+
+
+
+ 😊📎 +
请输入消息...
+ + +
+
+
+ +
+ ▲ 顶部红色按钮可用 · 用户可主动告诉系统"我走了" +
+
+ + +
+
坐席服务中(顶部按钮隐藏)
+ +
+
+
+ + 智能IT服务 +
+ + 在线 + +
+
+ ☀️🌙 +
S
+ +
+
+
+ +
+
+
VPN 连不上
+
请尝试重启...
+
客服小王已接入服务
+
您好,我是小王,我来帮您处理 VPN 问题
+
+
+
+ 😊📎 +
请输入消息...
+ + +
+
+
+ +
+ ▲ 顶部按钮已隐藏 · 操作按钮 end 态接管"结束人工" +
+
+
+ +
+ 💡 两个按钮场景互斥,从根源避免"两个都能结束,点哪个"的混乱 +
+
+ + +
+
🔄 「重新打开」按钮 mockup(v1.2 新增)
+
+ 会话已关闭 + 24h 内,按钮变 🔄 重新打开(蓝色)。不显示 24h 倒计时数字,避免紧迫感。 +
+ +
+
+ 💬 对话(已结束) +
+
+
好的,谢谢小王
+
不客气,随时找我
+
✅ 会话已关闭。24 小时内可重新打开。
+
+
+
+ 😊📎 +
会话已关闭
+ +
+
+
+ +
+ 💡 颜色选择:蓝色(--info: #1989fa),与"激活"绿色和"危险"红色明确区分,传达"中性恢复"语义 +
+
+ + +
+
⑥ 完整流程 · 双入口场景分流(v1.2 修订)
+
+ AI 会话走顶部退出路径,人工会话走操作按钮 end路径,两个入口场景互斥。 +
+ +
+ +
+
🅰️ AI 会话路径(顶部退出入口)
+
+ 🎧 AI 咨询 + + ⏏ 点击顶部退出 + + 确认弹窗 + + 😊 满意度评价 + + 🚪 关闭窗口 +
+
+ + +
+
🅱️ 人工会话路径(操作按钮 end 入口)
+
+ 🎧 呼叫人工 + + ⏳ 排队 + + 📴 服务中 end + + 📴 点击结束 + + 😊 满意度评价 + + 🚪 关闭窗口 +
+
+
+
+ + +
+
⑦ 右栏简化(v1.1 沿用 · G6)
+
+
+
v1.0 右栏(4 大区块)
+
+
▼ 设备信息
+ CPU / 内存 / 硬盘 +
+
+
▼ 自助诊断
+ 一键诊断 + 异常徽章 +
+
+
⚡ 智能推荐
+ 操作步骤 / 联系人 / 下载 +
+
+
⏳ 排队等待
+ 位置 / 预计时长 / 答题挑战 +
+
+
+
v1.2 右栏(2 大区块)✅
+
+
▼ 设备信息
+ CPU / 内存 / 硬盘 +
+
+
▼ 自助诊断
+ 一键诊断 + 异常徽章 +
+
+
⚡ 智能推荐
+ 操作步骤 / 联系人 / 下载 +
+
+
+
+ + +
+
⑧ v1.1 → v1.2 关键变更(已有) · v1.2 → v1.3 增量变更(待评审 ⏳)
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
变更项v1.2v1.3(待评审 ⏳)
操作按钮状态数6 态(移除 hidden / 恢复 end / 新增 reopen)沿用 6 态(不动)
引导语4 种场景分阶段引导语迁移至整合区按钮下方
顶部按钮可见性仅 AI 场景显示沿用(仅 AI 场景显示)
「重新打开」按钮新增(蓝色)沿用(位置从 InputBar 移至整合区)
{n}/3 进度提示移除(避免催促感)沿用(移除)
顶部按钮文案加 tooltip + 确认弹窗沿用
状态机互斥保证showHeaderExitBtn 计算逻辑沿用(整合区状态条 v1.4 已删除)
结束会话入口顶部(AI)+ 操作按钮 end(人工)双入口沿用(按钮位置从 InputBar 移至整合区)
维度划分4 维度(新增"退出兜底"独立维度)4 维度(整合区降为三元素,状态条 v1.4 已删除)
整合区结构 🆕4 维度分散(标题栏徽章 / 输入栏按钮 / 消息胶囊)4 维度整合区(按钮 + 进度胶囊 + 引导语)
标题栏坐席徽章 🆕显示 🟢/⚫移至整合区顶部(标题栏瘦身)
InputBar 操作按钮 🆕在工具栏内(与发送按钮并列)移至整合区(InputBar 工具栏更简洁)
引导语位置 🆕InputBar 按钮下方整合区按钮下方(v1.3 待评审)
+ +
+ 📌 对应 PRD:PRD-REQ-会话-001-员工结束会话-v1.4.md
+ 📌 对应技术方案:技术方案-REQ-会话-001-员工结束会话-v1.4.md +
+ +
✅ v1.3 方案 A 5 项细节已拍板(2026-07-31),见章节 9.6;⚠️ v1.4(2026-08-03)反转删除状态条
+
+ + +
+
⑨ 方案 A 整合区设计(v1.3 已拍板 ✅ · v1.4 删除状态条)
+
+ 把 v1.2 的 4 维度分离(服务可用性 / 会话进程 / 排队进度 / 退出兜底)重新组织为 "整合区 + 顶部退出" 两段式。
+ 整合区统一收容三元素:操作按钮(核心 CTA) + 进度消息胶囊(按需) + 引导语,标题栏瘦身(移除坐席徽章),InputBar 工具栏更简洁。
+ ✅ 5 项细节已拍板(2026-07-31),详见 9.6 节;⚠️ v1.4(2026-08-03)反转删除状态条,整合区降为三元素 +
+ + +
9.2 整合区结构示意(3 元素纵向堆叠,v1.4 移除状态条)
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
元素位置性质视觉表现(沿用 v1.2 类)
状态条(v1.4 已删除)v1.3 永久可见 → v1.4 删除不再渲染坐席在线/离线(v1.3.5 决策)
操作按钮整合区中部核心 CTA6 态样式(.call-btn--disabled/active/urgent/waiting/end/reopen
进度消息胶囊整合区下部按需显示.queue-capsule 4 态(含 --connected 变体)
引导语按钮下方4 种场景.input-bar-mock__guide(含 --warn 变体)
(整合区边界容器)InputBar 上方浅色背景容器用 inline 样式表达,不新增 CSS 类
背景色 ✅整合区整体浅色容器#fafafa(浅灰,沿用 chat-mock)
+ + +
9.3 9 场景 mockup(用 v1.2 现有 .header-mock / .chat-mock / .call-btn--* / .queue-capsule 表达,3 列网格共 3 行)
+ +
+ +
+
场景 1 · 无会话
+
+
+
+ 智能IT +
+
+
+
+
+
+ +
💡 先描述一下你遇到的问题
+
用户刚打开应用
+
+ + +
+
场景 2 · AI < 3 轮
+
+
+
+ 智能IT +
+
+
+
+
+
+ +
请继续描述您的问题或需求
+
AI 对话早期
+
+ + +
+
场景 3 · AI ≥ 3 轮
+
+
+
+ 智能IT +
+
+
+
+
+
+ +
可呼叫
+
+ + +
+
场景 4 · 紧急关键词
+
+
+
+ 智能IT +
+
+
+
+
+
+ +
高优一键呼叫
+
+ + +
+
场景 5 · 坐席离线
+
+
+
+ 智能IT +
+
+
+
+
+
+ +
⚠️ 坐席当前离线,建议先用 AI 解答
+
!store.agentOnline
+
+ + +
+
场景 6 · 排队中
+
+
+
+ 智能IT +
+
+
+
+
+
+ +
🟠 排队中 · 前面 2 人 · 预计 1 分钟
+
点击取消排队
+
+ + +
+
场景 7 · 已接入
+
+
+
+ 智能IT +
+
+
+
+
+
+ +
🟢 已接入 · 客服小王(3 秒淡出)
+
v1.2 恢复 · 主动挂断人工
+
+ + +
+
场景 8 · 重新打开(24h 内)
+
+
+
+ 智能IT +
+
+
+
+
+
+ +
v1.2 新增 · 蓝色填充
+
+ + +
+
场景 9 · 会话过期(>24h)
+
+
+
+ 智能IT +
+
+
+
+
+
+ +
⏰ 上一会话已过期,开始新对话吧
+
>24h 不可重开
+
+
+ +
+ 💡 每个 mockup 的整合区由"操作按钮 + 引导语/进度胶囊"纵向堆叠(v1.4 移除状态条),标题栏瘦身(无坐席徽章),退出按钮仅 AI 场景(场景 2-4)可见 +
+ + +
9.4 关键交互细节(R1-R5 · 沿用 v1.2 已 PASS 内容)
+ +
+ R1 · 状态条三态文案(v1.3 已拍板 ✅ → v1.4 已删除 ❌)
+ 🟢 在线 · 9:00-18:00 / 🟡 繁忙 · 预计 N 分钟 / ⚫ 客服暂休 · 9:00-18:00
+ v1.4 依 v1.3.5 决策删除状态条,不再向员工暴露坐席在线/离线;`store.shiftHours` 计划同步取消 +
+ +
+ R2 · 操作按钮 6 态保持
+ disabled / active / urgent / waiting / end / reopen 文案不变
+ waiting 态文案"排队取消"(v1.2y 已拍板),end 态"结束咨询",reopen 态"重新打开" +
+ +
+ R3 · 进度消息按需显示
+ 无排队时隐藏;queued 显示"🟠 排队中 · 前面 N 人"(整合区按钮下方);serving 显示"🟢 已接入 · 客服小王"(3 秒淡出);resolved 显示灰色"会话已关闭"
+ 位置从消息流底部 → 整合区(与按钮同一容器) +
+ +
+ R4 · 引导语迁移
+ 原 InputBar 4 种引导语(无会话 / AI<3 轮 / 坐席离线 / 会话过期)迁移到 整合区按钮下方,作为灰色小字
+ InputBar 工具栏更简洁(移除引导语容器) +
+ +
+ R5 · 不动 v1.2y 已 PASS 内容
+ 6 态按钮文案 / 坐席离线拦截(shakeAgent agentOnline=false)/ 取消入口合并(只通过按钮)/ 3 秒淡出(serving capsule)全部保持
+ 本次只做"位置迁移 + 容器整合",不动交互逻辑 +
+ + +
9.5 与 v1.2 对比
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
位置v1.2 现状v1.3 方案 A变化
标题栏logo + 标题 + 坐席状态🟢⚫ + 主题 + 头像 + 退出logo + 标题 + 主题 + 头像 + 退出-1 元素(坐席状态)
整合区(永久)v1.4 已移除(原状态条 3 态文案)-1 永久元素(v1.4 移除)
整合区(按钮)InputBar 工具栏内整合区中部位置迁移
整合区(按需胶囊)消息流底部独立整合区下部(与按钮同容器)位置迁移
InputBar 工具栏😊📎[输入框][🎧人工坐席][发送]😊📎[输入框][发送]-1 元素(按钮)
+ + +
9.6 6 项已拍板结论(2026-07-31 五项 + 2026-08-03 v1.4 反转一项)
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#维度拍板结果
1状态条策略❌ v1.3 永久显示 → v1.4 删除
2状态条文案❌ 随状态条一并删除
6状态条反转(v1.4)✅ 2026-08-03 反转:删除整合区状态条(v1.3.5 决策),整合区降为三元素
3整合区背景色✅ 浅灰 #fafafa
4引导语位置✅ 整合区按钮下方(方案 A 默认)
5移动端折叠✅ 不折叠,默认展开
+ +
+ 📌 拍板日期:2026-07-31 下午。后续 PRD/技术方案/任务说明书将同步更新。 +
+ +
+ ✅ 本章节为 v1.3 方案 A 已拍板方案(2026-07-31),v1.2 已 PASS 的 6 态按钮 / 引导语 / 坐席离线拦截 / 取消入口合并 / 淡出交互 全部保留不动,v1.4(2026-08-03)反转删除状态条 +
+
+
+ + \ No newline at end of file diff --git a/docs/02-技术文档/技术方案-REQ-会话-001-员工结束会话-v1.3.md b/docs/02-技术文档/技术方案-REQ-会话-001-员工结束会话-v1.3.archive.md similarity index 100% rename from docs/02-技术文档/技术方案-REQ-会话-001-员工结束会话-v1.3.md rename to docs/02-技术文档/技术方案-REQ-会话-001-员工结束会话-v1.3.archive.md diff --git a/docs/02-技术文档/技术方案-REQ-会话-001-员工结束会话-v1.4.md b/docs/02-技术文档/技术方案-REQ-会话-001-员工结束会话-v1.4.md new file mode 100644 index 0000000..795140d --- /dev/null +++ b/docs/02-技术文档/技术方案-REQ-会话-001-员工结束会话-v1.4.md @@ -0,0 +1,776 @@ +# 员工结束会话功能 - 技术方案 + +> **版本**: v1.3 +> **日期**: 2026-07-31 +> **关联PRD**: ../01-产品文档/02-会话管理/PRD-REQ-会话-001-员工结束会话-v1.3.md(§十一 v1.3 整合区增量) +> **关联原型**: ../01-产品文档/02-会话管理/原型-REQ-会话-001-结束会话流程-v1.3.html §⑨ +> **状态**: 已拍板(方案 A 5 项细节 2026-07-31 落地) + +--- + +## 一、概述 + +本文档描述 v1.2 调整的技术实现方案。**核心变更**: +1. 操作按钮从 5 态(hidden/disabled/active/urgent/waiting)扩展为 **6 态**(移除 hidden / 恢复 end / 新增 reopen) +2. 新增 **4 种引导语**渲染逻辑 +3. store 新增 `showHeaderExitBtn` 字段,**控制顶部退出按钮仅 AI 场景显示** +4. 双入口(顶部退出 + 操作按钮 end)**场景互斥**,从根源避免双入口混乱 +5. 24h 重新打开按钮实现 + +> 沿用 v1.1:排队进度底部消息胶囊、右栏移除 queue section、清理 api/queue 和 api/quiz。 + +--- + +## 二、技术架构 + +### 2.1 现有代码结构(v1.2 基准) + +``` +frontend-h5/src/components/chat/ +├── InputBar.vue # 输入栏(含操作按钮 6 态 + 引导语)— v1.2 改造 +├── ChatPanel.vue # 对话区(含顶部退出按钮 v-show)— v1.2 改造 +├── MessageBubble.vue # 消息气泡(含"会话已关闭"系统消息样式) +├── EvaluationDialog.vue # 满意度评价弹窗 +├── ResolveConfirmCard.vue # 坐席结单确认卡片 +└── ... 其他 + +frontend-h5/src/stores/ +└── conversation.ts # 新增 showHeaderExitBtn 字段 + reopenSession action + +frontend-h5/src/components/assistant/ +├── RightPanel.vue # 右栏(v1.1 已移除 queue section)— v1.2 沿用 +├── QueueWaiting.vue # 标记弃用,保留文件以备未来恢复 +└── ... +``` + +### 2.2 关键现有代码(InputBar.vue:194-243 v1.1 现状) + +```typescript +type CallAgentState = 'hidden' | 'disabled' | 'active' | 'urgent' | 'waiting' +``` + +**v1.2 改造**:扩展为 6 态,详细见 §3.1。 + +### 2.3 关键现有代码(ChatPanel.vue:59-65 顶部退出按钮) + +```vue + +``` + +**v1.2 改造**:增加 `v-show="store.showHeaderExitBtn"`,详见 §3.5。 + +--- + +## 三、方案设计 + +### 3.1 操作按钮 6 态状态机(v1.2 核心变更) + +**位置**:InputBar.vue 控件区第一层(行 78-88) + +**6 态定义**: + +| 状态值 | 触发条件 | 按钮文案 | 按钮图标 | 样式 | 可点击 | +|--------|---------|---------|---------|------|--------| +| `disabled` | 无会话 / AI<3 轮 / 坐席离线 / 会话过期 | 人工坐席 | 🔒 | 灰色禁用 | ❌ | +| `active` | AI≥3 轮 / 无紧急词 | 人工坐席 | 🎧 | 绿色描边 | ✅ | +| `urgent` | 检测到紧急关键词 | 人工坐席 | 🚨 | 红色脉冲 | ✅ | +| `waiting` | 排队中 | 排队等待 | ⏳ | 橙色描边 | ✅(取消排队)| +| `end` 🆕 | 坐席已接入(serving) | 结束咨询 | 📴 | 红色填充 | ✅(弹评价)| +| `reopen` 🆕 | 会话已关闭 + 24h 内 | 重新打开 | 🔄 | 蓝色填充 | ✅(reopen API)| + +**v1.2 移除**: +- ❌ `hidden` 态 — 完全移除,所有场景都有按钮呈现 + +**优先级顺序**(v1.2 修订): +``` +end > reopen > waiting > active/urgent > disabled +``` + +### 3.2 状态流转图 + +``` + ┌── (打开应用 / 重新进入) + ↓ + ┌──────────────────┐ + │ disabled │ ← 无会话 + │ "先说问题" │ + └────────┬─────────┘ + │ 用户输入 + AI ≥3 轮 + ↓ + ┌──────────────────┐ + │ active │ ── 检测到紧急词 ──→ urgent + │ "人工坐席" │ │ + └────────┬─────────┘ │ + │ 点击 / 紧急关键词 │ + ↓ ↓ + ┌──────────────────┐ ┌──────────────────┐ + │ waiting │ ←─────────────│ urgent │ + │ "排队等待" │ │ "人工坐席" │ + └────────┬─────────┘ └──────────────────┘ + │ 坐席接听 + ↓ + ┌──────────────────┐ + │ end 🆕 │ + │ "结束咨询" │ + └────────┬─────────┘ + │ 坐席挂断 / 用户点结束 + ↓ (close + 评价) + ┌──────────────────┐ + │ reopen 🆕 │ ← 会话已关闭 + 24h 内 + │ "重新打开" │ + └────────┬─────────┘ + │ 点击 reopen + ↓ + ┌──────────────────┐ + │ active │ (回到正常会话流程) + └──────────────────┘ +``` + +### 3.3 store 新增字段(v1.2 关键) + +**文件**:`stores/conversation.ts` + +```typescript +// 新增:顶部退出按钮是否可见(仅 AI 会话显示) +const showHeaderExitBtn = computed(() => { + const conv = currentConversation.value + if (!conv) return false // 无会话:隐藏 + if (conv.status === 'resolved') return false // 会话已关闭:隐藏 + + // 人工咨询启动后(waiting / serving):隐藏 + const isHumanActive = + conv.status === 'waiting' || + conv.status === 'serving' || + !!queuePositionData.value // 排队中 + if (isHumanActive) return false + + // AI 对话中:显示 + return true +}) + +// 新增:会话是否在 24h 重新打开窗口内 +const canReopen = computed(() => { + const conv = currentConversation.value + if (!conv || conv.status !== 'resolved') return false + if (!conv.resolved_at) return false + const elapsed = Date.now() - new Date(conv.resolved_at).getTime() + return elapsed < 24 * 60 * 60 * 1000 // 24h 内 +}) + +// 新增:重新打开会话 action(调用 closing.ts 已有的 reopenConversation) +async function reopenCurrentConversation(): Promise { + const conv = currentConversation.value + if (!conv || !canReopen.value) return + const result = await reopenConversation(conv.conversation_id) + // 更新 store,触发 UI 切回 active 态 + if (result) { + // ... 复用现有 openConversation 流程 + } +} +``` + +### 3.4 组件改动 + +#### 3.4.1 InputBar.vue + +**改动 1:状态类型扩展** + +```typescript +// v1.1 +type CallAgentState = 'hidden' | 'disabled' | 'active' | 'urgent' | 'waiting' + +// v1.2 +type CallAgentState = 'disabled' | 'active' | 'urgent' | 'waiting' | 'end' | 'reopen' +``` + +**改动 2:状态计算逻辑** + +```typescript +const callAgentState = computed(() => { + const conv = store.currentConversation + if (!conv) return 'disabled' // v1.2: 无会话 = disabled(不再 hidden) + + // 🆕 会话已关闭 + 24h 内 → reopen + if (conv.status === 'resolved' && store.canReopen) return 'reopen' + + // 🆕 坐席已接入 → end + if (conv.status === 'serving') return 'end' + + // 🆕 顶部按钮可见性也通过 store.showHeaderExitBtn 暴露给父组件 + + if (conv.status === 'waiting') return 'waiting' + + // 紧急关键词检测 + if (checkUrgentKeywords()) return 'urgent' + + // AI ≥3 轮 / canCallAgent + if (store.canCallAgent) return 'active' + + // 兜底:disabled(含 AI<3 轮、坐席离线、过期等场景) + return 'disabled' +}) +``` + +**改动 3:按钮文案 + 图标扩展** + +```typescript +const callAgentBtnText = computed(() => { + if (callAgentState.value === 'waiting') return '排队等待' + if (callAgentState.value === 'end') return '结束咨询' // 🆕 + if (callAgentState.value === 'reopen') return '重新打开' // 🆕 + return '人工坐席' +}) + +const callAgentBtnIcon = computed(() => { + if (callAgentState.value === 'waiting') return '⏳' + if (callAgentState.value === 'urgent') return '🚨' + if (callAgentState.value === 'active') return '🎧' + if (callAgentState.value === 'end') return '📴' // 🆕 + if (callAgentState.value === 'reopen') return '🔄' // 🆕 + return '🔒' +}) +``` + +**改动 4:按钮样式扩展** + +```typescript +const callAgentBtnClass = computed(() => ({ + 'call-agent-btn--disabled': callAgentState.value === 'disabled', + 'call-agent-btn--active': callAgentState.value === 'active', + 'call-agent-btn--urgent': callAgentState.value === 'urgent', + 'call-agent-btn--waiting': callAgentState.value === 'waiting', + 'call-agent-btn--end': callAgentState.value === 'end', // 🆕 + 'call-agent-btn--reopen': callAgentState.value === 'reopen', // 🆕 +})) +``` + +**改动 5:点击行为扩展(end / reopen 分支)** + +```typescript +function handleCallAgent(): void { + if (callAgentState.value === 'disabled') return + + // 🆕 end 态:触发结束会话流程(与顶部按钮共用 emit) + if (callAgentState.value === 'end') { + emit('end-conversation') + return + } + + // 🆕 reopen 态:调用 reopen API + if (callAgentState.value === 'reopen') { + store.reopenCurrentConversation() + return + } + + if (callAgentState.value === 'waiting') { + emit('cancel-queue') + return + } + + // active / urgent → 呼叫坐席 + emit('call-agent') +} +``` + +**改动 6:emit 扩展** + +```typescript +const emit = defineEmits<{ + (e: 'call-agent'): void + (e: 'cancel-queue'): void + (e: 'end-conversation'): void // 🆕(操作按钮 end 态专用,复用 handleExitWithEvaluation) +}>() +``` + +**改动 7:新增引导语渲染** + +```vue + + + +``` + +**改动 8:样式新增(end / reopen)** + +```scss +// 🆕 end 态:红色填充(最显眼的"危险/结束"语义) +.call-agent-btn--end { + border-color: var(--color-danger); + background: var(--color-danger); + color: #fff; + font-weight: 700; + + &:hover { + background: #dc2626; + } + + &:active { + transform: scale(0.96); + } +} + +// 🆕 reopen 态:蓝色填充(中性"恢复"语义) +.call-agent-btn--reopen { + border-color: var(--info, #1989fa); + background: var(--info-light, #ecf5ff); + color: var(--info, #1989fa); + + &:hover { + background: var(--info, #1989fa); + color: #fff; + } + + &:active { + transform: scale(0.96); + } +} +``` + +#### 3.4.2 ChatPanel.vue(顶部按钮可见性) + +**改动 1:顶部按钮 v-show 绑定** + +```vue + +