chore: initial baseline with P0-safety .gitignore
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
# IT智能服务台 — 综合 QA 测试报告
|
||||
|
||||
> 本文档合并历次 QA 测试报告,按时间倒序排列(最新在前)。
|
||||
|
||||
---
|
||||
|
||||
## 报告索引
|
||||
|
||||
| # | 测试日期 | 报告名称 | 测试范围 | 通过率 | 状态 |
|
||||
|---|----------|----------|----------|--------|------|
|
||||
| 1 | 2026-06-03 | WebSocket 实时推送功能 QA | WS 连接/心跳/重连/广播 | 10/11 (1跳过) | ✅ 通过 |
|
||||
| 2 | 2025-07-04 | 坐席工作台 v5.3 QA | T01-T04 增量代码 | 36/42 (4失败/2警告) | ⚠️ 有条件通过 |
|
||||
|
||||
---
|
||||
|
||||
## 一、WebSocket 实时推送功能 QA 测试报告
|
||||
|
||||
> 测试日期: 2026-06-03 | QA工程师: 严过关(Edward)
|
||||
|
||||
### 总览
|
||||
|
||||
- **测试对象**: WebSocket 实时推送功能(9个文件)
|
||||
- **测试轮次**: 1(第2轮无需执行,所有可测试项均通过)
|
||||
|
||||
### 1. 代码审查结果
|
||||
|
||||
| # | 文件 | 检查结果 | 状态 |
|
||||
|---|------|----------|------|
|
||||
| 1 | `ws_manager.py` — broadcast/send_to_agent 异常处理 | send_to_agent try/except 包裹;broadcast 拷贝 keys 避免遍历异常;connect 旧连接清理 | ✅ PASS |
|
||||
| 2 | `ws.py` — WebSocketDisconnect 处理 | 捕获 WebSocketDisconnect + 通用 Exception,均清理连接 | ✅ PASS |
|
||||
| 3 | `useWebSocket.ts` — 断线重连逻辑 | 指数退避(1s→2s→4s→8s→16s→30s);intentionalDisconnect 标志;心跳30s;WS断连自动降级轮询 | ✅ PASS |
|
||||
| 4 | `message_router.py` / `session_service.py` — WS 广播位置 | 所有广播均在 `db.flush()` 后、`return` 前;try/except 包裹不阻塞主流程 | ✅ PASS |
|
||||
| 5 | `conversation.ts` — handleNewMessage 消息去重 | 通过 `message_id` 去重,避免 WS 推送和轮询重复 | ✅ PASS |
|
||||
| 6 | `vite.config.ts` — WS 代理配置 | `/ws` 代理 `ws: true` 配置正确,与 `/api` 不冲突 | ✅ PASS |
|
||||
| 7 | `Workspace.vue` — connect 和 disconnect 处理 | onMounted 调用 connectWs;onUnmounted 调用 disconnectWs + stopAllPolling;登出时先标记主动断开 | ✅ PASS |
|
||||
|
||||
### 2. 后端启动验证
|
||||
|
||||
| 检查项 | 结果 | 说明 |
|
||||
|--------|------|------|
|
||||
| REST API /health | ✅ PASS | 返回 `{"status":"ok","service":"wecom-it-smart-desk"}` |
|
||||
| REST API /api/conversations | ✅ PASS | 正常返回会话列表 |
|
||||
| WebSocket 端点 /ws/{agent_id} | ✅ PASS | 可建立连接 |
|
||||
|
||||
### 3. WebSocket 功能测试
|
||||
|
||||
| 测试项 | 结果 | 说明 |
|
||||
|--------|------|------|
|
||||
| TEST 1: WebSocket 连接 | ✅ PASS | ws://localhost:8000/ws/qa_test_agent1 连接成功 |
|
||||
| TEST 2: Ping/Pong 心跳 | ✅ PASS | 发送 `{"type":"ping"}` → 收到 `{"type":"pong"}` |
|
||||
| TEST 3: 同一坐席重连替换 | ✅ PASS | 同一 agent_id 第二个连接建立成功 |
|
||||
| TEST 4: 不同坐席多连接 | ✅ PASS | 不同 agent_id 可同时连接 |
|
||||
| TEST 5: WS 广播 - 接单事件 | ⏭️ SKIP | SQLite 锁定导致 API 调用失败,代码审查确认逻辑正确 |
|
||||
| TEST 6: 断开连接后清理 | ✅ PASS | ws3 主动断开后,ws1 仍正常工作 |
|
||||
|
||||
> **TEST 5 跳过说明**: SQLite 数据库在 uvicorn 进程中被锁定,导致写操作失败。这是 SQLite 高并发已知限制,与 WebSocket 代码无关。代码审查已确认广播位置正确。
|
||||
|
||||
### 4. 前端集成验证
|
||||
|
||||
| 检查项 | 结果 | 说明 |
|
||||
|--------|------|------|
|
||||
| 前端编译 (vite build) | ✅ PASS | RC=0,3.77s 构建完成,无 TypeScript 错误 |
|
||||
| Workspace.vue 包含 WS 集成 | ✅ PASS | 导入 useWebSocket,生命周期完整 |
|
||||
|
||||
### 5. 综合评估
|
||||
|
||||
- **通过项 (10/11)**: 所有代码审查项 + WS 连接/心跳/重连/多连接/清理 + 前端编译
|
||||
- **跳过项 (1/11)**: WS 广播端到端验证(代码审查确认逻辑正确)
|
||||
- **未发现源码 Bug**
|
||||
|
||||
### 6. 路由决策
|
||||
|
||||
**Send To: NoOne** — 所有可测试项均通过,代码审查未发现 Bug,无需发送给工程师修复。
|
||||
|
||||
---
|
||||
|
||||
## 二、坐席工作台 v5.3 QA 测试报告(历史归档)
|
||||
|
||||
> 测试日期: 2025-07-04 | QA工程师: 严过关(Yan)| 测试范围: T01-T04 全部增量代码
|
||||
|
||||
### 总览
|
||||
|
||||
| 指标 | 值 |
|
||||
|------|-----|
|
||||
| 总检查项 | 42 |
|
||||
| 通过 | 36 |
|
||||
| 失败 | 4 |
|
||||
| 警告 | 2 |
|
||||
| **IS_PASS** | **YES(有条件)** |
|
||||
|
||||
**路由判定**: 源码有 4 处 Bug → **发送给工程师修复**
|
||||
|
||||
### 1. TypeScript 编译检查(7个错误)
|
||||
|
||||
| # | 严重度 | 文件 | 问题 | 修复方案 |
|
||||
|---|--------|------|------|----------|
|
||||
| BUG-1 | 🔴 严重 | `stores/quickReply.ts:153` | `replaceAll` 需要 ES2021+ | 改 `tsconfig.json` lib 为 `ES2021`,或用 `split().join()` 替代 |
|
||||
| BUG-2 | 🟡 低 | `components/chat/UserInfoBar.vue:316` | `emit` 声明未使用 | 用 `emit()` 替代模板 `$emit`,或删除变量声明 |
|
||||
| BUG-3 | 🟡 低 | `stores/conversation.ts:33` | `TagsResult` 导入未使用 | 从 import 移除 |
|
||||
| BUG-4 | 🟡 低 | `stores/conversation.ts:770,792` | `data` 参数未使用 | 改为 `_data` |
|
||||
| BUG-5 | 🟢 信息 | `main.ts:23` | element-plus locale 缺类型声明 | `env.d.ts` 添加 `declare module` |
|
||||
|
||||
### 2. 逻辑 Bug 检查
|
||||
|
||||
| # | 严重度 | 文件 | 问题 | 修复方案 |
|
||||
|---|--------|------|------|----------|
|
||||
| BUG-6 | 🔴 中等 | `UserInfoBar.vue:418` | `turnCount` 运算符优先级错误:`tags?.repeat_count \|\| 0 + 1` 应先计算 `0+1` | 改为 `(tags?.repeat_count \|\| 0) + 1` |
|
||||
| BUG-7 | 🟡 中等 | `UserInfoBar.vue:464` | `Math.random()` 导致 UI 闪烁 | 改为基于 `conversation.id` 的确定性 Mock |
|
||||
|
||||
### 3. CSS 变量一致性(警告级)
|
||||
|
||||
多处硬编码色值未使用 CSS 变量,深色主题下可能显示异常(不影响功能,建议后续迭代统一):
|
||||
|
||||
| 文件 | 硬编码值 | 建议使用 CSS 变量 |
|
||||
|------|----------|-----------------|
|
||||
| `UserInfoBar.vue` | `#FDF6EC` / `#E6A23C` / `#FAECD8` | 黄色 chip — `--color-warning-soft` / `--color-warning` |
|
||||
| `UserInfoBar.vue` | `#FEF0F0` / `#F56C6C` / `#FDE2E2` | 红色 chip — `--color-danger-soft` / `--color-danger` |
|
||||
| `UserInfoBar.vue` | `#F4ECFF` / `#9B59B6` / `#E8D5F5` | 紫色 chip — 新增 `--color-purple-soft` / `--color-purple` |
|
||||
| `FlowchartNode.vue` | `#FDF6EC` / `#E6A23C` / `#FAECD8` | 判断节点 — 同上 |
|
||||
| `TopBar.vue` | `#2b6cb0` | 渐变深色 — `--accent-dark` |
|
||||
| `TopBar.vue` | `#fef0f0` / `#c0392b` / `#e74c3c` | 应急横幅 — 未适配深色模式 |
|
||||
|
||||
### 4. 功能完整性检查
|
||||
|
||||
| 模块 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| T01 主题系统 | ✅ 完成 | CSS变量 + useTheme + Pinia store + TopBar切换按钮 |
|
||||
| T02 左栏改造 | ✅ 完成 | 三段折叠 + 优先级图标 + 待办面板 + TodoStore |
|
||||
| T03 中栏改造 | ✅ 完成 | UserInfoBar + ItLevelBadge + AiRecommendInline + TroubleshootBar + 快捷键 |
|
||||
| T04 右栏改造 | ✅ 完成 | AiAssistantPanel 重写 + QuickReplyPanel 重写 |
|
||||
| 任务详情视图 | ✅ 完成 | TaskDetailView + 三种子视图 |
|
||||
| 后端扩展 | ✅ 完成 | todo_items + troubleshooting_templates + employees API |
|
||||
|
||||
### 5. 最终判定
|
||||
|
||||
**IS_PASS: YES(有条件)**
|
||||
|
||||
**条件**: 工程师需修复 BUG-1(ES2021 target)和 BUG-6(turnCount 优先级),其余为低优先级警告,可在后续迭代修复。
|
||||
|
||||
---
|
||||
|
||||
*合并生成时间: 2026-06-07 | 合并人: 小米*
|
||||
@@ -0,0 +1,89 @@
|
||||
# 呼叫坐席功能验证指南
|
||||
|
||||
> 后端 `http://localhost:8000` | 前端 `http://localhost:5173`
|
||||
|
||||
---
|
||||
|
||||
## 前置条件
|
||||
|
||||
1. 后端 8000 端口已启动 ✅
|
||||
2. 前端 H5 5173 端口已启动 ✅
|
||||
3. 数据库已包含 `ai_substantive_reply_count` 列(项目用 `create_all(checkfirst=True)`,重启后端即自动添加)
|
||||
|
||||
## 测试流程(按顺序验证)
|
||||
|
||||
### 测试1:打招呼被拦截,按钮不出现
|
||||
|
||||
| 步骤 | 操作 | 预期结果 |
|
||||
|------|------|---------|
|
||||
| 1 | 浏览器打开 `http://localhost:5173` | 进入会话窗口 |
|
||||
| 2 | 输入 "你好" 发送 | AI回复引导话术(如"你好!请描述你遇到的IT问题..."),**按钮不出现** |
|
||||
| 3 | 输入 "hi" 发送 | 同上,引导话术,按钮不出现 |
|
||||
|
||||
### 测试2:直接呼叫人工被拦截
|
||||
|
||||
| 步骤 | 操作 | 预期结果 |
|
||||
|------|------|---------|
|
||||
| 4 | 输入 "人工坐席" 发送 | AI回复引导话术(如"请先描述你的问题,AI会先帮你分析..."),**按钮不出现** |
|
||||
| 5 | 输入 "转人工" 发送 | 同上 |
|
||||
|
||||
### 测试3:正常问题 → AI回复1~2次,按钮不出现
|
||||
|
||||
| 步骤 | 操作 | 预期结果 |
|
||||
|------|------|---------|
|
||||
| 6 | 输入 "我的打印机连不上了" | AI给出第1次实质性回复,按钮仍不出现 |
|
||||
| 7 | 输入 "我试了重启还是不行" | AI给出第2次实质性回复,按钮仍不出现 |
|
||||
|
||||
### 测试4:AI回复满3次,按钮出现
|
||||
|
||||
| 步骤 | 操作 | 预期结果 |
|
||||
|------|------|---------|
|
||||
| 8 | 输入 "驱动也重装了还是不行" | AI给出第3次实质性回复,**「👊 呼叫坐席」按钮出现** |
|
||||
| 9 | 检查底部引导文案 | 变为 "👊👊 呼叫坐席通道已开启..." 橙色闪烁 |
|
||||
|
||||
### 测试5:点击按钮 → 弹窗动画
|
||||
|
||||
| 步骤 | 操作 | 预期结果 |
|
||||
|------|------|---------|
|
||||
| 10 | 点击「👊 呼叫坐席」按钮 | 全屏弹窗,直接进入摇人动画(7个场景SVG依次切换) |
|
||||
| 11 | 等待动画播放 | 自动发送 shake 请求,成功后有"已通知坐席"提示 |
|
||||
| 12 | 弹窗自动关闭 | 约4秒后自动关闭,会话进入排队状态 |
|
||||
|
||||
### 测试6:API 直接验证(可选)
|
||||
|
||||
用 curl 验证后端逻辑:
|
||||
|
||||
```bash
|
||||
# 1. 获取/创建当前会话
|
||||
curl -s http://localhost:8000/api/h5/conversations/current -H "X-Employee-Id: test001" | python -m json.tool
|
||||
|
||||
# 检查返回的 can_call_agent 应为 false,ai_substantive_reply_count 应为 0
|
||||
|
||||
# 2. 发送问候语 → 应该收到引导回复
|
||||
curl -s -X POST http://localhost:8000/api/h5/conversations/current/messages \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"employee_id":"test001","content":"你好"}' | python -m json.tool
|
||||
|
||||
# 检查 is_guidance 应为 true,can_call_agent 应为 false
|
||||
|
||||
# 3. 发送实际问题 x3
|
||||
curl -s -X POST http://localhost:8000/api/h5/conversations/current/messages \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"employee_id":"test001","content":"打印机连不上"}' | python -m json.tool
|
||||
|
||||
# 重复3次,第3次后 can_call_agent 应为 true
|
||||
|
||||
# 4. 在未满3次时尝试 shake → 应返回 1003 错误
|
||||
curl -s -X POST http://localhost:8000/api/h5/conversations/current/shake \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Employee-Id: test002" \
|
||||
-d '{}' | python -m json.tool
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **每个会话独立计数**:`ai_substantive_reply_count` 是 Conversation 级别的字段,不同用户/会话不共享
|
||||
2. **切换会话会重置**:新会话从 0 开始
|
||||
3. **后续可扩展**:如果用户说"谢谢"等结束语,可以重置计数;当前版本未实现此逻辑
|
||||
Reference in New Issue
Block a user