236 lines
10 KiB
Markdown
236 lines
10 KiB
Markdown
|
|
# 员工端结束会话 — 固定按钮退出
|
|||
|
|
|
|||
|
|
> **版本**: v1.1
|
|||
|
|
> **日期**: 2026-07-26
|
|||
|
|
> **REQ编号**: REQ-用户-005
|
|||
|
|
> **状态**: [已实现]
|
|||
|
|
> **作者**: Simon
|
|||
|
|
> **关联文档**:
|
|||
|
|
> - 技术方案: `02-技术文档/技术方案-REQ-用户-005-头像菜单退出-v1.1.md`
|
|||
|
|
> - 任务说明书: `07-项目管理/任务说明书/任务说明书-REQ-用户-005-头像菜单退出.md`
|
|||
|
|
> - 测试用例: `03-测试文档/03-功能测试用例/TC-用户-005-头像菜单退出.md`
|
|||
|
|
> - 相关 PRD: `01-产品文档/02-会话管理/PRD-REQ-会话-001-员工结束会话-v1.3.md`(InputBar 结束咨询按钮)
|
|||
|
|
> - 参考原型: `01-产品文档/05-用户端H5/原型-REQ-用户-005-头像菜单退出-v1.1.html`
|
|||
|
|
> - 前端组件: `frontend-h5/src/components/chat/ChatPanel.vue`(头像区域)
|
|||
|
|
> - 后端 API: `backend/app/api/auth.py`(logout)、`backend/app/api/h5.py`(close conversation)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、问题陈述
|
|||
|
|
|
|||
|
|
**现状**:员工端 H5 标题栏右侧展示员工头像和姓名,但**缺少直接可见的退出入口**。员工若要退出,需要点击头像展开下拉菜单(交互隐蔽,发现性差)。前端 `employeeStore.logout()` 方法和后端 `POST /api/auth/logout` 接口均已实现。
|
|||
|
|
|
|||
|
|
**痛点**:
|
|||
|
|
- 下拉菜单入口隐蔽,员工难以发现退出功能
|
|||
|
|
- 结束会话的唯一入口是 InputBar 的"结束咨询"按钮(仅人工服务态可见),AI 自助模式无快捷结束入口
|
|||
|
|
- 企微 WebView 内用户期望简单直接的操作方式,多步菜单增加操作成本
|
|||
|
|
|
|||
|
|
**不解决的成本**:用户找不到退出入口,多人共用设备场景存在信息泄露风险;AI 对话结束后缺少自然的"离开"操作点。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 二、目标
|
|||
|
|
|
|||
|
|
| # | 目标 | 衡量标准 |
|
|||
|
|
|---|------|---------|
|
|||
|
|
| G1 | 头像右侧提供固定的「结束会话」按钮 | 按钮始终可见,无需展开菜单 |
|
|||
|
|
| G2 | 提供"结束会话"一键操作 | 用户点击后完成:关闭会话 → 登出 → 跳转登录页(或关闭窗口) |
|
|||
|
|
| G3 | 操作前有确认步骤,防止误触 | 弹出确认对话框,用户确认后才执行 |
|
|||
|
|
| G4 | 复用已有后端 API,不新增接口 | 复用 `POST /h5/conversations/current/close` + `POST /api/auth/logout` |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、非目标(Non-Goals)
|
|||
|
|
|
|||
|
|
| # | 明确不做 | 原因 |
|
|||
|
|
|---|----------|------|
|
|||
|
|
| N1 | 不提供下拉菜单/二级操作入口 | 固定按钮更直观,一步到位 |
|
|||
|
|
| N2 | 不提供"切换账号"功能 | 企微 WebView 内账号由企微自身管理,不支持多账号 |
|
|||
|
|
| N3 | 不修改人工呼叫/结束咨询的现有流程 | 本需求仅新增固定按钮入口,与 InputBar 按钮并存不冲突 |
|
|||
|
|
| N4 | 不在按钮旁展示会话历史/设置等二级功能 | v1 范围仅限结束+退出操作,后续版本可扩展 |
|
|||
|
|
| N5 | 不强制要求物理关闭窗口 | 企微 WebView 不支持 `window.close()`,降级方案为跳转登录页 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 四、用户故事
|
|||
|
|
|
|||
|
|
| # | 角色 | 用户故事 | 优先级 |
|
|||
|
|
|---|------|----------|--------|
|
|||
|
|
| US-1 | 员工 | 作为员工,我希望头像右侧有醒目的「结束会话」按钮,一键结束当前会话并退出登录 | P0 |
|
|||
|
|
| US-2 | 员工 | 作为员工,我希望退出前有确认提示并被告知"会话记录会清空",以免误触导致数据丢失 | P0 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 五、需求详情
|
|||
|
|
|
|||
|
|
### 5.1 交互流程
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
员工看到头像右侧「结束会话」按钮
|
|||
|
|
↓
|
|||
|
|
点击「结束会话」按钮
|
|||
|
|
↓
|
|||
|
|
弹出确认对话框
|
|||
|
|
├── 标题:结束会话
|
|||
|
|
├── 内容:退出后会话记录会清空,当前咨询进度将丢失,确定要结束会话吗?
|
|||
|
|
├── [取消] → 关闭对话框,回到聊天页
|
|||
|
|
└── [确定退出] → 执行退出流程
|
|||
|
|
↓
|
|||
|
|
1. 判断是否有活跃会话
|
|||
|
|
├── 有 → 调用 POST /h5/conversations/current/close
|
|||
|
|
└── 无 → 跳过
|
|||
|
|
↓
|
|||
|
|
2. 调用 POST /api/auth/logout
|
|||
|
|
↓
|
|||
|
|
3. 清除前端状态(token、employeeInfo、localStorage)
|
|||
|
|
↓
|
|||
|
|
4. 尝试关闭窗口
|
|||
|
|
├── 成功 → 窗口关闭
|
|||
|
|
└── 失败(WebView 限制)→ 跳转至 /h5/login
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 UI 规格
|
|||
|
|
|
|||
|
|
#### 5.2.1 标题栏右侧改造
|
|||
|
|
|
|||
|
|
| 属性 | 当前 | 改造后 |
|
|||
|
|
|------|------|--------|
|
|||
|
|
| 头像+姓名 | 纯展示 | 纯展示(去掉下拉箭头和点击事件) |
|
|||
|
|
| "结束会话"按钮 | 无 | 头像右侧固定的红色边框按钮 |
|
|||
|
|
| 按钮位置 | — | 头像右边,与主题切换开关相邻 |
|
|||
|
|
| 按钮样式 | — | 红色边框圆角按钮,hover 填充红色白字 |
|
|||
|
|
|
|||
|
|
#### 5.2.2 固定按钮
|
|||
|
|
|
|||
|
|
| 属性 | 规格 |
|
|||
|
|
|------|------|
|
|||
|
|
| 文案 | 「结束会话」 |
|
|||
|
|
| 颜色 | 红色(`#ee0a24`),与危险操作一致 |
|
|||
|
|
| 样式 | 透明背景 + 红色边框,圆角 14px,字号 12px |
|
|||
|
|
| hover 态 | 填充红色背景 + 白色文字 |
|
|||
|
|
| 位置 | 头像右侧,header-actions 内 |
|
|||
|
|
|
|||
|
|
#### 5.2.3 确认对话框
|
|||
|
|
|
|||
|
|
| 属性 | 规格 |
|
|||
|
|
|------|------|
|
|||
|
|
| 组件 | Vant `Dialog`(`van-dialog`) |
|
|||
|
|
| 标题 | 结束会话 |
|
|||
|
|
| 消息 | 退出后会话记录会清空,当前咨询进度将丢失,确定要结束会话吗? |
|
|||
|
|
| 确认按钮 | 「确定退出」(红色/警告色,退出风险) |
|
|||
|
|
| 取消按钮 | 「取消」(灰色/默认色) |
|
|||
|
|
|
|||
|
|
### 5.3 状态处理
|
|||
|
|
|
|||
|
|
| 场景 | 行为 |
|
|||
|
|
|------|------|
|
|||
|
|
| 无活跃会话 | 跳过关闭会话步骤,直接登出 |
|
|||
|
|
| 有活跃会话(AI 模式) | 调用 close API,等待响应后再登出 |
|
|||
|
|
| 有活跃会话(人工服务中) | 调用 close API,等待响应后再登出 |
|
|||
|
|
| close API 调用失败 | Toast 提示"会话关闭失败",仍然继续登出流程(不阻塞) |
|
|||
|
|
| logout API 调用失败 | Toast 提示"退出失败,请稍后重试",不跳转 |
|
|||
|
|
| 窗口关闭失败(WebView 限制) | 静默降级,`window.location.href = '/h5/login'` 或使用 `WeixinJSBridge` |
|
|||
|
|
|
|||
|
|
### 5.4 技术对接
|
|||
|
|
|
|||
|
|
#### 已有 API(直接复用,无需后端改动)
|
|||
|
|
|
|||
|
|
| API | 方法 | 用途 | 文件 |
|
|||
|
|
|-----|------|------|------|
|
|||
|
|
| `/api/h5/conversations/current/close` | POST | 关闭当前会话 | `backend/app/api/h5.py:1965` |
|
|||
|
|
| `/api/auth/logout` | POST | 退出登录(Token 入黑名单 + 清 Redis) | `backend/app/api/auth.py:305` |
|
|||
|
|
|
|||
|
|
#### 前端改动范围
|
|||
|
|
|
|||
|
|
| 文件 | 改动内容 |
|
|||
|
|
|------|---------|
|
|||
|
|
| `frontend-h5/src/components/chat/ChatPanel.vue` | 移除下拉菜单,头像区域简化;新增「结束会话」固定按钮 + 确认对话框文案更新 |
|
|||
|
|
| `frontend-h5/src/stores/employee.ts` | 无需改动(`logout()` 已实现) |
|
|||
|
|
| `frontend-h5/src/api/auth.ts` | 无需改动(`logout()` 已实现) |
|
|||
|
|
| `frontend-h5/src/api/closing.ts` | 无需改动(`employeeClose()` 已实现) |
|
|||
|
|
|
|||
|
|
#### 企微 WebView 关闭窗口方案
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 方案优先级
|
|||
|
|
// 1. WeixinJSBridge(企微环境首选)
|
|||
|
|
if (typeof WeixinJSBridge !== 'undefined') {
|
|||
|
|
WeixinJSBridge.call('closeWindow')
|
|||
|
|
}
|
|||
|
|
// 2. 标准 window.close()
|
|||
|
|
else {
|
|||
|
|
window.close()
|
|||
|
|
}
|
|||
|
|
// 3. 兜底:跳转登录页
|
|||
|
|
setTimeout(() => {
|
|||
|
|
if (!document.hidden) {
|
|||
|
|
window.location.href = '/h5/login'
|
|||
|
|
}
|
|||
|
|
}, 500)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 六、验收标准
|
|||
|
|
|
|||
|
|
### 6.1 功能验收
|
|||
|
|
|
|||
|
|
| # | 验收项 | 验收方式 |
|
|||
|
|
|---|--------|---------|
|
|||
|
|
| AC1 | 头像右侧显示「结束会话」固定按钮 | 手动测试:页面加载后按钮可见 |
|
|||
|
|
| AC2 | 点击「结束会话」弹出确认框 | 手动测试:点击按钮 → 确认框出现 |
|
|||
|
|
| AC3 | 确认框标题和内容正确 | 手动测试:核对文案含"退出后会话记录会清空" |
|
|||
|
|
| AC4 | 点击「取消」关闭确认框,回到聊天页 | 手动测试:取消 → 对话框消失,会话不受影响 |
|
|||
|
|
| AC5 | 点击「确定退出」执行退出流程 | 手动测试:确认 → loading → 跳转登录页 |
|
|||
|
|
| AC6 | 退出后 Token 失效,无法访问聊天页 | 手动测试:退出后访问 `/h5/` → 重定向到 `/h5/login` |
|
|||
|
|
| AC7 | 按钮 hover 态有视觉反馈 | 手动测试:鼠标悬停 → 按钮填充红色背景+白字 |
|
|||
|
|
| AC8 | 退出后 WebSocket 连接断开 | 手动测试:退出后无 WS 心跳或重连 |
|
|||
|
|
|
|||
|
|
### 6.2 边界验收
|
|||
|
|
|
|||
|
|
| # | 验收项 | 验收方式 |
|
|||
|
|
|---|--------|---------|
|
|||
|
|
| AC10 | 无活跃会话时退出,不报错 | 新登录用户直接退出 → 正常跳转登录页 |
|
|||
|
|
| AC11 | close API 失败时不阻塞退出 | 模拟网络错误 → Toast 提示但仍跳转 |
|
|||
|
|
| AC12 | logout API 失败时留在当前页 | 模拟网络错误 → Toast 提示,不跳转 |
|
|||
|
|
| AC13 | 企微 WebView 内点击退出,窗口关闭或跳转 | 企微环境真实测试 |
|
|||
|
|
| AC14 | 退出后 WebSocket 连接断开 | 手动测试:退出后无 WS 心跳或重连 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、成功指标
|
|||
|
|
|
|||
|
|
| 指标 | 类型 | 目标值 | 测量方式 |
|
|||
|
|
|------|------|--------|---------|
|
|||
|
|
| 「结束会话」按钮点击率 | 先行 | 上线首周 > 10% 活跃用户 | 前端埋点:按钮点击事件 |
|
|||
|
|
| 误触取消率 | 健康 | < 30%(接受一定比例的"看看"行为)| 确认框中"取消"/"确定"比例 |
|
|||
|
|
| 退出异常率 | 健康 | < 2%(logout API 失败或窗口关闭失败)| 前端日志上报 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 八、风险与依赖
|
|||
|
|
|
|||
|
|
| 风险 | 概率 | 影响 | 缓解措施 |
|
|||
|
|
|------|------|------|---------|
|
|||
|
|
| R1:企微 WebView `closeWindow` 不可用 | 中 | 窗口无法关闭,需降级到跳转登录页 | 已设计三层降级方案(见 5.4) |
|
|||
|
|
| R2:与 InputBar「结束咨询」并存,用户困惑 | 低 | 用户不知道该用哪个 | 两者功能一致——结束会话+登出 vs 仅结束会话不登出,文案区分 |
|
|||
|
|
| R3:固定按钮误触(比下拉菜单更容易点到)| 中 | 用户意外点击 | 确认对话框拦截,误触取消率可能上升 |
|
|||
|
|
|
|||
|
|
**依赖**:
|
|||
|
|
- D1:`POST /h5/conversations/current/close` API 可用(已实现)
|
|||
|
|
- D2:`POST /api/auth/logout` API 可用(已实现)
|
|||
|
|
- D3:Vant `ActionSheet` 和 `Dialog` 组件已在项目中可用(已引入)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 九、变更记录
|
|||
|
|
|
|||
|
|
| 日期 | 版本 | 变更内容 | 变更人 | 变更原因 |
|
|||
|
|
|------|------|----------|--------|----------|
|
|||
|
|
| 2026-07-26 | v1.0 | 初始版本(头像下拉菜单方案) | Simon | 新增需求 |
|
|||
|
|
| 2026-07-26 | v1.1 | 交互调整:下拉菜单 → 头像右侧固定「结束会话」按钮;对话框消息改为含"会话记录会清空"提示 | Simon | 用户反馈:下拉菜单隐蔽,固定按钮更直观 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
*文档结束*
|