baodan/docs/开发任务清单.md

600 lines
29 KiB
Markdown
Raw Permalink 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.

# 开发任务清单
> 完成一项勾一项。格式:`- [ ]` → `- [x]`
>
> 引用文档简称:
> - **[需求]** = `docs/保险智能客服系统_需求文档.md`(章节号如 §1.1.1
> - **[API]** = `docs/保险智能客服系统_API接口文档.md`(接口号如 A1.1.1
> - **[规范]** = `docs/保险智能客服系统_编码规范.md`(章节号如 §二)
> - **[测试]** = `docs/保险智能客服系统_测试用例.md`(用例号如 M1-01、API-01
> - **[前端]** = `docs/前端开发计划.md`(章节号如 §6.1
> - **[curl]** = `docs/API_curl示例.md`(调试示例)
---
## Phase 0项目脚手架0.5 天)✅ 已完成
- [x] **0.1** 后端目录结构 — **[规范] §五 / §十一 11.2**
- [x] 创建 `api/insurance/__init__.py`
- [x] 创建 `api/insurance/config.py`JWT_SECRET、企微配置等常量
- [x] 创建 `api/insurance/utils/__init__.py`
- [x] 创建 `api/insurance/utils/response.py``success()` / `error()`)— **[API] §一 1.1**
- [x] 创建 `api/insurance/utils/auth.py`JWT 签发/校验)— **[需求] §5.2**
- [x] 创建 `api/insurance/utils/db.py`(复用 BaoDan DB**[规范] §十一 11.3**
- [x] 创建 `api/insurance/wecom/` 目录routes.py / wecom_bot.py / wecom_oauth.py / wecom_api.py
- [x] 创建 `api/insurance/recommend/` 目录routes.py / workflow_helper.py
- [x] 创建 `api/insurance/permissions/` 目录routes.py / middleware.py
- [x] 创建 `api/insurance/stats/` 目录routes.py
- [x] 创建 `api/insurance/db/` 目录models.py
- [x] **0.2** 注册路由到 BaoDan — **[部署指南] §三**
- [x] 找到 Flask app 初始化位置
- [x] 添加 try/except 包裹的 Blueprint 注册代码
- [x] 验证:`curl http://localhost:5001/api/auth/password-login` 返回保险模块响应 — 2026-06-08 已验证
- [x] **0.3** BaoDan iframe 配置 — **[部署指南] §四 + [需求] §9.6**
- [x] 在 docker-compose.baodan.yml 中配置 `NEXT_PUBLIC_ALLOW_EMBED=true`
- [x] **0.4** 数据库建表 — **[需求] §六 6.2**
- [x] init.sql 已更新(含 password_hash 字段)
- [x] Docker 容器内自动执行建表 + 迁移 — 2026-06-08 已验证81 张表)
- [x] **0.5** 后端工具函数 + 错误码体系
- [x] `utils/response.py` — 统一响应 — **[API] §一 1.1**
- [x] `utils/auth.py` — JWT 工具 — **[API] §一 1.4**
- [x] `utils/db.py` — 复用 BaoDan DB
- [x] **完整错误码实现****[需求] §28 + §18**
- [x] 1001 参数错误(含具体字段提示)— **[需求] §18.2**
- [x] 1002 未授权 — **[需求] §18.2**
- [x] 1003 Token 已过期(与 1002 区分)— **[需求] §18.2**
- [x] 1004 权限不足 — **[需求] §18.2**
- [x] 1005 资源不存在 — response.py ErrorCode 已定义
- [x] 2001-2004 BaoDan 相关错误 — response.py ErrorCode 已定义
- [x] 3001 企微 API 调用失败 — **[需求] §18.4**
- [x] 3002-3005 企微错误 — response.py ErrorCode 已定义
- [x] 4001-4003 文件错误 — response.py ErrorCode 已定义
- [x] 5001-5002 数据库/Redis 错误 — error_handler.py 全局处理
- [x] 9999 服务器内部错误 — error_handler.py 全局处理
- [x] **错误展示规范**:前端 ElMessage.error 统一处理 — **[需求] §18.8**
- [x] **0.6** 前端项目验证 — **[前端] §二**
- [x] `npm install` + `vite build` 成功318 模块0 错误)
- [x] `vite.config.ts` 代理配置正确 — **[前端] §2.1**
---
## Phase 1认证系统1 天)✅ 已完成
- [x] **1.1** 密码登录接口 — `POST /api/auth/password-login`**[API] A1.1.2 + [需求] §13.1 + [curl] §一**
- [x] `wecom_user_mapping` 表加 `password_hash` 字段init.sql + models.py
- [x] 参数校验3-64 / 8-128**[需求] §13.1 A1.1.2**
- [x] bcrypt 校验 — **[需求] §5.3**
- [x] 签发 JWT — **[需求] §5.3 Token 有效期 2 小时**
- [x] 记录操作日志 — **[需求] §4.3.1**
- [x] 错误码:用户名不存在/密码错误 → 1002 — **[需求] §28**
- [ ] 验证curl 登录拿到 token — **[curl] A1.1.2**(需 BaoDan + PostgreSQL 运行)
- [x] **1.2** 刷新 Token — `POST /api/auth/refresh-token`**[API] A1.1.3 + [curl] §一**
- [x] 校验旧 Token未过期、未在黑名单
- [x] 签发新 Token + 旧 Token 加入 Redis 黑名单
- [x] 区分错误码Token 过期 → 1003不是 1002**[需求] §18.2**
- [ ] 验证 — **[curl] A1.1.3**(需 Redis 运行)
- [x] **1.3** 退出登录 — `POST /api/auth/logout`**[API] A1.1.4 + [curl] §一**
- [x] Token 加入 Redis 黑名单 + 记录日志
- [ ] 验证 — **[curl] A1.1.4**(需 Redis 运行)
- [x] **1.4** 企微 OAuth 登录 — `POST /api/auth/wework-login`**[API] A1.1.1 + [需求] §12.4**
- [x] code 换 access_token → 获取用户信息 → 查/建映射 → 签 JWT
- [x] 企微用户不在系统 → 自动创建映射
- [x] 企微 API 失败 → 3001
- [x] **1.5** 企微 OAuth 流程 — `GET /api/wecom/oauth` + `GET /api/wecom/oauth/callback`**[API] §二 2.4/2.5**
- [x] **1.6** 前端登录页 — `LoginPage.vue`**[前端] §6.1 + [需求] §17.1**
- [x] 企微登录按钮 — **[前端] §6.1 loginWithWechat**
- [x] 分隔线 + 账密登录表单 — **[前端] §6.1**
- [x] 表单校验 — **[前端] §6.1 rules**
- [x] 提交 → 存 token → 跳 /chat
- [x] 移动端适配 — **[需求] §5.4**
- [ ] **页面状态****[需求] §17.1 状态表**(部分实现):
- [x] 初始状态 → 登录方式选择界面
- [ ] 企微授权中 → 全屏 loading需 Phase 4
- [ ] 授权回调中 → 全屏 loading需 Phase 4
- [ ] 登录失败 → 顶部红色提示条
- [x] 已登录 → 自动跳转 /chat
- [x] **按钮行为****[需求] §17.1 按钮行为**
- [x] 企微登录按钮:点击后 loading + 禁止重复点击
- [x] 登录按钮:验证通过后可点击,点击后 loading + "登录中..."
- [x] Enter 键在密码框触发登录
- [x] **1.7** 前端路由守卫 + Token 管理 — **[前端] §5.1 + §4.2 + §4.1**
- [x] `router.beforeEach`**[前端] §5.1**
- [x] `useAuth.ts`**[前端] §4.2**
- [x] `api.ts` 拦截器:自动加 Authorization 头 — **[前端] §4.1**
- [x] 401 → refresh → 重试 / 跳登录页
- [x] `code !== 0` → ElMessage.error
- [x] URL 回调处理 → 从参数提取 token — **[前端] §4.2 restoreFromUrl**
---
## Phase 2对话页面1 天)
- [x] **2.1** 发送消息接口 — `POST /api/chat/message`SSE**[API] A2.1.1 + [需求] §9.2**
- [x] JWT 鉴权 + 参数校验 — **[需求] §13.2**
- [x] 调 BaoDan Chat APIstreaming, 超时 120s**[需求] §9.2**
- [x] SSE 返回delta → source → done — **[API] A2.1.1 SSE 事件类型**
- [x] 错误处理:超时/BaoDan 错误/空回答 — **[需求] §10.1 + §28**
- [ ] 险种/保司枚举校验 — **[API] A2.1.1**(待 BaoDan App 创建后补)
- [ ] 根据险种映射 BaoDan App ID — **[需求] §1.3**(待 BaoDan App 创建后补)
- [ ] **日志脱敏**:问答记录只存前 50 字符 — **[需求] §24 §16.2**(待验证)
- [x] **2.2** 会话列表 — `GET /api/chat/sessions`**[API] A2.1.2**
- [x] 封装 BaoDan API + 分页
- [x] **2.3** 创建会话 — `POST /api/chat/sessions`**[API] A2.1.3**
- [x] **2.4** 删除会话 — `DELETE /api/chat/sessions/{id}`**[API] A2.1.4**
- [x] **2.5** 消息记录 — `GET /api/chat/sessions/{id}/messages`**[API] A2.1.5**
- [x] **2.6** 提交反馈 — `POST /api/chat/messages/{id}/feedback`**[API] A2.1.6**
- [x] rating 校验helpful / not_helpful — **[API] A2.1.6 字段约束**
- [x] 封装 BaoDan feedback API
- [x] **2.7** 纠错反馈入口 — 复用 feedback 接口rating=not_helpful + comment
- [x] 后端接口已实现
- [ ] 前端弹窗组件(待补)
- [x] **2.8** 前端对话页 — `ChatPage.vue`**[前端] §6.2**
- [x] 布局:筛选器 + iframe + 增强栏 — **[前端] §6.2**
- [x] ChatEmbediframe 加载 BaoDan WebApp — **[前端] §7.1**
- [x] iframe src 根据险种动态切换 — **[前端] §6.2 appMapping**
- [ ] **页面状态**(部分实现):
- [x] 正常 → iframe + 增强栏
- [ ] 加载中 → 骨架屏
- [ ] 空状态 → 快捷提问
- [ ] 错误 → 顶部红色提示条
- [x] **2.9** 筛选器 — `ChatFilters.vue`**[前端] §7.2**
- [x] 险种下拉 + 保司下拉 + clearable
- [x] **2.10** 复制按钮 — `ChatCopyButton.vue`**[前端] §7.3**
- [x] **2.11** 推荐问题 — `ChatSuggestions.vue`**[前端] §7.4**
- [x] **2.12** 导航布局 — `App.vue`**[前端] §5.2**
- [x] 用户端菜单:智能问答/产品推荐/历史方案
- [x] 管理端菜单(条件显示)+ 顶部栏
- [x] 暗色侧边栏 #001529
---
## Phase 2.5BaoDan Workflow 配置0.5 天)
> 在 BaoDan 后台可视化编辑器中拖拽编排 6 个节点。配置完后才能做 Phase 3 的后端调用。
- [ ] **W.1** 创建 Workflow 应用 — **[需求] §15.7**
- [ ] 名称:`产品推荐方案生成`
- [ ] 类型:工作流
- [ ] **W.2** 节点1参数校验Code Node**[需求] §19.2**
- [ ] 输入变量age/gender/occupation/annual_income/monthly_budget/insurance_types/coverage_amount/coverage_period全部 string
- [ ] 输出变量validated_params(object) / error_msg(string) / is_valid(bool)
- [ ] 代码逻辑:年龄 1-150、性别 male/female、职业非空、预算>0、保额>=10000、险种枚举校验
- [ ] 错误处理is_valid=False 时跳转节点5
- [ ] **W.3** 节点2检索策略生成Code Node**[需求] §19.3**
- [ ] 输入validated_params
- [ ] 输出search_queries每项含险种+query
- [ ] 代码逻辑:为每个险种生成检索词 `"{险种} 产品条款 保额 费率 {age}岁"`
- [ ] **W.4** 节点3知识库检索Knowledge Retrieval Node**[需求] §19.4**
- [ ] 关联所有险种知识库
- [ ] 检索模式:混合检索(向量+全文)
- [ ] Top-K = 5Score 阈值 = 0.6
- [ ] **W.5** 节点4LLM 方案生成LLM Node**[需求] §19.5**
- [ ] 模型deepseek-chatTemperature=0.7Top P=0.9Max Tokens=8192
- [ ] **完整 Prompt**(按 [需求] §19.5 原文配置):
- [ ] 客户信息变量age/gender/occupation/annual_income/monthly_budget/insurance_types/coverage_amount/coverage_period
- [ ] 检索结果变量retrieved_docs
- [ ] 输出要求:三套方案(基础/均衡/全面),表格格式,含推荐理由
- [ ] 重要规则保费来自检索不编造、总保费不超过月预算x12、免责声明
- [ ] **W.6** 节点5异常处理Code Node**[需求] §19.6**
- [ ] 输入is_valid / error_msg / recommendation
- [ ] 输出final_output / is_success
- [ ] 校验失败 → 返回 error_msg生成为空 → 返回"未能生成推荐方案"
- [ ] **W.7** 节点6格式化输出Code Node**[需求] §19.7**
- [ ] 去除多余空行 + 首尾空白
- [ ] **W.8** 条件分支逻辑 — **[需求] §19.8**
- [ ] is_valid=True → 节点2→3→4→5→6→结束
- [ ] is_valid=False → 节点5→6→结束
- [ ] **W.9** 节点失败行为 — **[需求] §19.9**
- [ ] 每个节点失败时 BaoDan 自动重试 1 次失败则跳转节点5
- [ ] **W.10** 测试验证 — **[需求] §19.10**
- [ ] 测试用例1标准场景35岁/男/工程师/30万收入/月预算2000/重疾+医疗)→ 三套方案,基础方案年保费<=24000
- [ ] 测试用例2低预算25岁/女/教师/月预算500/意外险)→ 基础方案年保费<=6000
- [ ] 测试用例3异常参数age=-1/gender=unknown→ 返回参数校验失败
---
## Phase 3产品推荐2 天)
### 后端
- [ ] **3.1** 数据库扩展 — **[需求] §6.2 表2**
- [ ] `recommendation_records` 表加 `share_token`、`share_expire_at`
- [ ] 创建 `share_tokens`
- [ ] **3.2** 生成方案 — `POST /api/recommend/generate`**[API] A3.1.1 + [需求] §13.3 + §14 + [curl] §三**
> 参数校验严格按 [需求] §13.3 A3.1.1 + §14。健康状况枚举以 API 文档为准4项
- [ ] 参数校验:
- [ ] customer.age1-150 整数 — **[需求] §13.3**
- [ ] customer.gendermale/female — **[需求] §13.3**
- [ ] customer.health_status**健康/有既往病史/慢性病/重大疾病史**4项以 API 文档为准)— **[API] A3.1.1**
- [ ] customer.occupation1-64 字符 — **[需求] §13.3**
- [ ] customer.monthly_budget>=1 — **[需求] §13.3**
- [ ] insurance_types1-10 项枚举 — **[需求] §13.3**
- [ ] coverage_amount>=10000 — **[需求] §13.3**
- [ ] coverage_period枚举校验 — **[需求] §13.3**
- [ ] INSERT recommendation_recordsstatus=pending**[需求] §23 状态机**
- [ ] 调 BaoDan Workflow APIblocking, 超时 120s**[需求] §9.3**
- [ ] 解析 Markdown → 3 套方案 JSON — **[需求] §2.2.2**
- [ ] UPDATE recordsdone/failed**[需求] §23 状态转换规则**
- [ ] 错误码Workflow 失败 → 2003超时 → 2004 — **[需求] §28**
- [ ] 记录操作日志 — **[需求] §4.2.2**
- [ ] 验证 — **[curl] A3.1.1**
- [ ] **3.3** 查询状态 — `GET /api/recommend/generate/{task_id}`**[API] A3.1.2 + [curl] §三**
- [ ] 返回 processing / done含 proposal/ failed含 error_message**[需求] §23**
- [ ] **3.4** 导出方案 — `POST /api/recommend/{id}/export`**[API] A3.1.3 + [curl] §三**
- [ ] format 校验pdf/pptx/docx — **[API] A3.1.3**
- [ ] Word 导出python-docx**[需求] §2.4.2**
- [ ] PDF 导出reportlab/weasyprint**[需求] §2.4.1**
- [ ] PPT 导出python-pptx**[需求] §2.4.1**
- [ ] 含免责声明 — **[需求] §24 §16.3 + §19.5**
- [ ] **3.5** 分享链接 — `POST /api/recommend/{id}/share`**[API] A3.1.4 + [curl] §三**
- [ ] expire_hours 校验 1-720 — **[API] A3.1.4**
### 前端
- [ ] **3.6** 推荐表单 — `RecommendForm.vue`**[前端] §7.5 + [需求] §2.1 + §14**
> 校验规则严格按 [需求] §14。验证触发时机按 §14.5。
- [ ] 基础信息:姓名/年龄/性别/健康状况4项枚举/职业 — **[需求] §2.1.1 + §6.2**
- [ ] 收入预算:年收入(万)/ 月预算(元)— **[需求] §6.2**
- [ ] 险种 checkbox6种**[需求] §2.1.2**
- [ ] 保额 slider1万-1000万步进 10000/ 保障期限 select — **[需求] §2.1.3 + §14.2**
- [ ] **已有保单**(折叠面板,动态添加)— **[需求] §2.1.5 + §14.3**
- [ ] 每条包含:产品名称(**必填**)、保司(**必填**)、保额(可选)、生效日期(可选)
- [ ] 上限 20 条
- [ ] "添加保单"按钮 + 每行"删除"按钮
- [ ] [生成方案] 按钮loading 状态)
- [ ] 表单校验(按 [需求] §14.1 + §14.2
- [ ] 年龄:必填,整数 1-150 — **[需求] §14.1**
- [ ] 性别:必选 — **[需求] §14.1**
- [ ] 健康状况:默认"健康" — **[需求] §14.1**
- [ ] 职业:必填 — **[需求] §14.1**
- [ ] 月预算:必填,>0上限 100 万 — **[需求] §14.1**
- [ ] 险种:至少选 1 项 — **[需求] §14.2**
- [ ] 保额:>=1 万,步进 10000 — **[需求] §14.2**
- [ ] 保障期限:必选 — **[需求] §14.2**
- [ ] **验证触发时机****[需求] §14.5**
- [ ] blur 事件:触发首次验证
- [ ] input 事件:已触发首次验证后实时验证
- [ ] 点击按钮:全量验证
- [ ] 错误提示:红色 #F56C6C12px字段下方
- [ ] 输入框边框变红
- [ ] 提交按钮所有必填项通过前 disabled
- [ ] useDraft 草稿保存 — **[需求] §2.1.6**
- [ ] **防重复提交**:第一次点击后按钮立即 disabled — **[需求] §14.4**
- [ ] **网络断开提示**"网络异常,请检查网络连接" — **[需求] §14.4 + §18.7**
- [ ] **数据安全**:客户个人信息不在前端日志中打印 — **[需求] §24 §16.1**
- [ ] **3.7** 推荐主页面 — `RecommendPage.vue`**[前端] §6.3 + [需求] §17.3**
> 状态机按 [需求] §17.3。
- [ ] RecommendForm 嵌入
- [ ] 提交 → POST /api/recommend/generate → 拿 task_id
- [ ] 轮询逻辑2s 间隔):
- [ ] processing → "正在生成方案,请稍候..." — **[需求] §17.3 状态表**
- [ ] done → 显示方案
- [ ] failed → 错误提示 + "重新生成"按钮 — **[需求] §10.2**
- [ ] 超时120s→ "方案生成超时,请重试" — **[需求] §10.2**
- [ ] **页面状态****[需求] §17.3**
- [ ] 初始状态 → 空白表单
- [ ] 表单验证失败 → 未通过字段标红 + 行内错误
- [ ] 提交中 → 按钮 loading + "方案生成中..."
- [ ] 生成中(轮询)→ "正在生成方案,请稍候..."
- [ ] 网络错误 → 弹窗 "网络异常,请检查网络连接"
- [ ] **3.8** 推荐结果组件 — `RecommendResult.vue`**[需求] §17.4**
> **上下排列**展示三套方案(不是 Tab 也不是 Collapse
- [ ] 三套方案上下排列:基础方案 → 均衡方案 → 全面方案 — **[需求] §17.4 操作流程**
- [ ] 每套方案:方案名称 + 总年保费 + 产品表格 + 推荐理由 + 方案总结
- [ ] Markdown 渲染 — **[需求] §1.2.1**
- [ ] 操作栏:[浏览器打印] [重新生成] [导出 PDF] [分享] — **[需求] §2.4**
- [ ] 免责声明 — **[需求] §24 §16.3 + §19.5**
- [ ] "重新生成"按钮:重置表单为上次提交值 — **[需求] §17.3 按钮行为**
- [ ] **3.9** 历史方案列表 — `RecommendHistory.vue`**[需求] §2.5 + §17.5**
- [ ] 分页表格 + 筛选 + 操作 — **[需求] §2.5.1-2.5.4**
- [ ] **页面状态****[需求] §17.5**
- [ ] 加载中 → 表格骨架屏
- [ ] 空状态 → "暂无推荐方案" + "去生成"按钮
- [ ] 筛选为空 → "暂无匹配数据"
- [ ] 删除确认 → 弹窗
- [ ] **3.10** 方案详情页 — `RecommendDetail.vue`**[需求] §2.5.3**
- [ ] 完整方案内容 + 客户信息 + 导出按钮组 + 分享按钮
---
## Phase 4企微集成1.5 天)
- [x] **4.1** 企微 API 封装 — `wecom/service.py`**[需求] §8**
- [x] `get_access_token()` — 获取企微 access_token
- [x] `_send_text(user_id, content)` — 发送文本消息
- [x] `send_long_message`>2048字节分段 — **[需求] §8.5 + WB-05**
- [ ] Token 缓存 Redis + 提前刷新 — **[需求] §8.5**(待优化)
- [ ] **4.2** XML 加解密 — **[需求] §8.2 + §8.3**
- [ ] AES-CBC 解密 — **[需求] §8.3**TODO: 需企微 SDK
- [x] SHA1 签名验证 — **[需求] §8.2**
- [ ] 解析 XML 提取字段(简化版已实现)
- [x] **4.3** URL 验证 — `GET /api/wecom/callback`**[API] §二 2.2**
- [x] **4.4** 消息接收 — `POST /api/wecom/callback`**[API] §二 2.3**
- [x] **5 秒内返回 "success"****[需求] §8.5 + WB-02**
- [x] 异步处理threading.Thread
- [x] text → 调 BaoDan → 回复
- [x] 非 text → "暂不支持" — **[需求] §8.6 + WB-03**
- [x] 群聊:去掉"@机器人"前缀 — **[需求] §8.3**
- [x] 调 BaoDan Chat APIblocking, 超时 60s**[需求] §12.3**
- [ ] 日志脱敏 — **[需求] §24 §16.2**(待补)
- [x] **4.5** 非文本消息 — **[需求] §8.6**
- [x] 非 text → "暂不支持该消息类型"
- [x] **4.6** 长消息分段 — **[需求] §8.5 + WB-05**
- [x] >2048字节 → 按固定长度分段发送
- [x] **4.7** 企微 OAuth 登录 — `GET /api/wecom/oauth` + `GET /api/wecom/oauth/callback`
- [x] 重定向到企微授权页
- [x] 回调 → code 换用户信息 → JWT → 重定向前端
- [x] **4.8** 前端环境变量 — docker-compose.baodan.yml 已添加 WECOM_CORP_ID/SECRET/TOKEN/AES_KEY
---
## Phase 5用户权限管理1 天)
### 后端
- [x] **5.1** 用户列表 — `GET /api/admin/users`**[API] A5.1.1 + [需求] §13.5**
- [x] 参数page/page_size/role/department — **[需求] §13.5**
- [ ] **数据权限**(按角色过滤)— **[需求] §5.2.3 + §21.2**(待补)
- [x] **5.2** 新增用户 — `POST /api/admin/users`**[API] A5.1.1**
- [x] 参数校验 + 插入 + bcrypt 密码
- [x] **5.3** 编辑用户 — `PUT /api/admin/users/{id}`**[API] A5.1.1**
- [x] 更新 username/role/department/status
- [x] **5.4** 停用用户 — `DELETE /api/admin/users/{id}`**[API] A5.1.1**
- [x] status → disabled
- [ ] **5.5** 批量导入 — `POST /api/admin/users/batch-import`**[API] A5.1.2**TODO 占位)
- [x] **5.6** 角色列表 — `GET /api/admin/roles`**[API] A5.1.3**
- [x] 5 个内置角色(超级管理员/管理员/销售主管/销售人员/客户)
- [x] **5.7** 角色 CRUD — **[API] A5.1.3**(后端占位实现)
- [x] **5.8** 权限校验中间件 — `middleware.py`**[需求] §5.2.2**
- [x] `jwt_required` / `admin_required` / `super_admin_required` 装饰器
- [x] 无权限 → 1004
- [ ] **5.9** 数据权限过滤 — **[需求] §5.2.3 + §21.2**(待补)
### 前端
- [x] **5.10** 用户管理页 — `UsersPage.vue`**[需求] §5.1 + §7.1**
- [x] 表格 + 筛选 + 新增/编辑弹窗 + 停用确认
- [x] **5.11** 角色权限页 — `PermissionsPage.vue`**[前端] §6.5 + [需求] §5.2**
- [x] 角色列表 + 权限配置 + 保存
---
## Phase 6数据统计1 天)
### 后端
- [x] **6.1** 使用概览 — `GET /api/stats/overview`**[API] A8.1.1**(占位数据)
- [x] **6.2** 趋势数据 — `GET /api/stats/trend`**[API] A8.1.2**(占位数据)
- [x] **6.3** 知识库健康度 — `GET /api/stats/kb-health`**[API] A8.1.3**(占位数据)
- [x] **6.3.1** Token 消耗 — `GET /api/stats/token-cost`**[API] A8.1.4**(占位数据)
### 前端
- [x] **6.4** 统计仪表盘 — `StatsPage.vue`**[需求] §7.1-7.3**
- [x] 3 个 Tab趋势 / 知识库健康度 / 成本监控
- [x] 筛选器 + 数据表格
---
## Phase 7知识库增强1 天)
### 后端
- [x] **7.1** 数据库追加表 — `kb_datasources` / `kb_sync_logs`(通过 SQL 查询,未建独立模型)
- [x] **7.2** 上传文档 — `POST /api/kb/documents/upload`**[API] A4.1.1**
- [x] 调用 BaoDan Dataset API 上传
- [x] 返回上传结果
- [x] **7.3** 文档列表 — `GET /api/kb/documents`**[API] A4.1.2**
- [x] **7.4** 更新元数据 — `PATCH /api/kb/documents/{id}`**[API] A4.1.5**
- [x] **7.5** 文档状态 — `GET /api/kb/documents/{id}/status`**[API] A4.1.3**
- [x] **7.6** 删除文档 — `DELETE /api/kb/documents/{id}`**[API] A4.1.6**
- [x] **7.7** 重试文档 — `POST /api/kb/documents/{id}/retry`**[API] A4.1.4**
- [x] **7.8** 数据源 CRUD — **[API] A4.2.1-A4.2.4**
- [x] 列表 / 新建 / 手动同步 / 同步日志
- [ ] **7.8** 编号自动生成 — **[需求] §3.1.3**(待补)
- [x] **7.9** 数据源 CRUD — **[API] A4.2.1-A4.2.4**
- [x] 列表 / 新建 / 手动同步 / 同步日志
- [x] 同步失败告警 → 企微 webhook — **[需求] §3.3.5**
- [ ] API Key AES 加密 — **[需求] §6.1.2**(待补)
### 前端
- [x] **7.10** 知识库管理页 — `KBManagePage.vue`**[需求] §3.1 + §3.2**
- [x] 文档列表 + 筛选 + 上传 + 删除 + 状态查看
- [x] **7.11** 数据源配置页 — `DataSourcePage.vue`**[需求] §3.3**
- [x] 数据源列表 + 新建 + 同步 + 日志查看
---
## Phase 8导出增强 + 收尾0.5 天)
- [x] **8.1** PDF 导出 — **[需求] §2.4.1**
- [x] HTML 模板渲染 + 免责声明
- [x] weasyprint 生成 PDF不可用时回退 HTML
- [x] **8.2** Word 导出 — **[需求] §2.4.2**
- [x] python-docx 生成 Word 文档
- [x] 含客户信息表格 + 方案表格 + 免责声明
- [ ] **8.3** PPT 导出 — **[需求] §2.4.1**(暂不实现)
- [x] **8.4** 系统操作日志 — **[需求] §4.3**
- [x] operation_log 模型已定义
- [x] 登录/登出/操作日志查询接口已实现
- [x] audit.py 工具函数:登录/登出/创建用户/停用用户/方案生成 自动写入
- [x] **8.5** 通知告警 — **[需求] §6.4**
- [x] notify.py 企微 Webhook 通知服务
- [x] 数据源同步失败通知
- [x] Token 超限通知
- [x] 方案生成完成通知
- [x] **8.6** 数据安全检查 — **[需求] §24**
- [x] 密码修改接口change-password
- [x] 密码强度校验8-128位 + 字母数字组合
- [x] JWT Token 黑名单机制
- [x] 操作审计日志
- [x] **8.7** 前端导出按钮 — RecommendResult/Detail/History 添加 Word/PDF 下载
- [ ] 日志脱敏:问答记录只存前 50 字符 — **[需求] §24 §16.2**
- [ ] 前端脱敏API Key 显示为 `sk-xxxx****xxxx`**[需求] §24 §16.2**
- [ ] 客户个人信息不在日志中明文记录 — **[需求] §24 §16.1**
- [ ] 生产环境不返回详细错误堆栈 — **[需求] §28 §19.3**
---
## 交叉验证清单
> 每项标注了对应的测试用例编号。
- [ ] **X.1** 认证 — **[测试] §2.4 + §2.8**
- [ ] 账密登录 → JWT → 能调接口 — **[测试] M5-01 + API-01**
- [ ] 企微 OAuth 完整流程 — **[测试] M5-01**
- [ ] Token 过期 → 自动刷新 — **[测试] M5-03 + API-04**
- [ ] 退出 → 旧 Token 失效 — **[测试] A-04 + API-05**
- [ ] 停用用户 → Token 全部失效 — **[测试] A-01**
- [ ] **X.2** 对话 — **[测试] §2.1 + §2.9**
- [ ] iframe 正常加载 — **[测试] M1-01**
- [ ] 险种筛选切换知识库 — **[测试] M1-10**
- [ ] 提问 → 回答 → 来源引用 — **[测试] M1-01 + M1-07**
- [ ] 点赞/点踩 — **[测试] M1-13**
- [ ] 复制按钮 — **[需求] §1.2.5**
- [ ] 纠错反馈弹窗 — **[需求] §1.4.2**
- [ ] 空状态/加载状态/错误状态 — **[需求] §17.2**
- [ ] **X.3** 产品推荐 — **[测试] §2.2 + §2.9**
- [ ] 表单校验全部生效 — **[测试] M2-02 至 M2-06**
- [ ] 防重复提交(按钮 disabled**[需求] §14.4**
- [ ] 提交 → loading → 出结果 — **[测试] M2-07 + M2-08**
- [ ] 三套方案**上下排列**展示 — **[需求] §17.4**
- [ ] 已有保单 4 字段 + 20 条上限 — **[需求] §14.3**
- [ ] 导出 PDF/Word/PPT — **[测试] API-16**
- [ ] 分享链接 — **[测试] API-18**
- [ ] 历史方案分页 — **[需求] §2.5.1**
- [ ] 草稿保存/恢复 — **[需求] §2.1.6**
- [ ] 免责声明 — **[需求] §24 §16.3**
- [ ] 所有页面状态(加载/空/正常/错误)— **[需求] §17.3-17.5**
- [ ] **X.4** 企微 — **[测试] §2.3 + §7.3**
- [ ] 私聊 → AI 回复 — **[测试] M4-01**
- [ ] 群聊 @机器人 → 回复到群里 — **[测试] M4-05**
- [ ] 发图片 → "暂不支持" — **[测试] M4-08**
- [ ] 长消息分段 — **[需求] §8.5**
- [ ] **X.5** 权限 — **[测试] §2.8 + [需求] §21.1**
- [ ] 销售:仅 /chat + /recommend — **[测试] A-05**
- [ ] 销售数据隔离 — **[需求] §5.2.3**
- [ ] 主管:本组数据 — **[需求] §21.2**
- [ ] 管理员:本部门数据 — **[需求] §21.2**
- [ ] super_admin全部数据 + 全部页面
- [ ] 401 → 跳登录页 — **[测试] A-01**
- [ ] 403 → 显示无权限 — **[测试] A-05**
- [ ] **X.6** 统计 — **[测试] §2.7**
- [ ] 仪表盘数据正确 — **[测试] M7-01**
- [ ] 图表正常渲染 — **[测试] M7-02**
- [ ] **X.7** 知识库增强 — **[测试] §2.5 + §7.1**
- [ ] 上传 → 自动编号 — **[需求] §3.1.3**
- [ ] 修改标签 → 成功 — **[需求] §3.1.4**
- [ ] 数据源同步 — **[需求] §3.3.2**
- [ ] 文档处理状态机正确 — **[需求] §23**
- [ ] **X.8** 错误码覆盖
- [ ] 1001-1005 认证错误全部可触发 — **[需求] §28 + §18.2**
- [ ] 2001-2004 BaoDan 错误全部可触发 — **[需求] §18.3**
- [ ] 3001-3005 企微错误全部可触发 — **[需求] §18.4**
- [ ] 4001-4003 文件错误全部可触发 — **[需求] §18.5**
- [ ] 错误展示位置正确Toast/行内/弹窗)— **[需求] §18.8**
- [ ] **X.9** 非功能 — **[需求] §5 + §24**
- [ ] HTTPS — **[需求] §5.3 传输加密**
- [ ] API Key AES 加密 — **[需求] §5.3 + §6.1.2**
- [ ] XSS 防护 — **[需求] §5.3**
- [ ] SQL 注入防护 — **[需求] §5.3**
- [ ] 企微 5 秒内响应 — **[需求] §8.5**
- [ ] 页面首屏 < 3 **[需求] §5.1**
- [ ] 日志脱敏 **[需求] §24 §16.2**
- [ ] 客户信息不入日志明文 **[需求] §24 §16.1**
- [ ] **X.10** 验收标准 **[需求] §32**
- [ ] 智能问答准确率 >= 85%30 个测试问题)— **[需求] §32**
- [ ] 产品推荐质量10 组数据方案合理 — **[需求] §32**
- [ ] 知识库覆盖9GB 文档全部入库 — **[需求] §32**
- [ ] 响应时间 < 15 **[需求] §32**
- [ ] 并发 5 人无明显延迟 **[需求] §32**
- [ ] 日志可查询导出 **[需求] §32**