# AI 诊断（兽医、机构）— 测试用例

> 依据：`AI诊断(兽医、机构)功能需求.md`（v1.1）、`AI诊断(兽医、机构)技术方案.md`（v1.6）  
> **后台 Base Path**：`/diseaseTreatments/onlineConsult/ai`；**移动端**：`/app/consult/ai`；鉴权与若依一致。

**通用前置（无特殊说明）**

- 兽医账号 **VA**（角色 **100**）、机构账号 **OA**（角色 **102**）；权限 `diseaseTreatment:aiOnlineConsult:list|query|send|add|remove`（**不要求**绑定 `biz_medical_resource`）。  
- 普通后台账号 **NB**（有 AI 权限、无医疗资源绑定）、另一用户 **VB**（有 AI 会话）。  
- 牧民 **U1** 已登录移动端。  
- `biz_consult_session` / `biz_consult_message` / `biz_diagnosis_user` 已执行 DDL（见 `sql/biz_diagnosis_user.sql`）；宜预置：

| 样本 | 说明 | 要点 |
| --- | --- | --- |
| **AS0** | VA 提问，`consult_type=2` | 3 个月内；`vet_visible=1`；`session_title` 有值；含提问+AI 消息 |
| **AS1** | VA 另一条 AI 会话 | 用于列表排序/筛选 |
| **AS2** | VA 超窗 AI 会话 | `last_message_time` 早于 3 个月；默认列表不出现 |
| **ASX** | **VB** 的 AI 会话 | VA/OA **不可见/不可操作** |
| **ASH** | VA 已 hide | `vet_visible=0` | 列表/消息/发送失败 |
| **AV0** | VA 的接诊会话 `type=1` | AI 列表**不可见**（隔离） |
| **AS-EMPTY** | VA 新建未提问 | `session_title=新会话`；`last_message_time=create_time` |

**界面（UI）**：**Playwright** + **Chromium**（`channel: 'chrome'`）；菜单「牧业疫病诊疗服务 → AI 诊断（兽医、机构）」；路由 `diseaseTreatment/onlineConsult/ai/index`。

---

## 一、单元测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-AIZD-UT-001 | 规则常量 | AI 问诊类型 | 单元测试 | JUnit5 | §2.6、技术方案 §2.1 | 无 | 校验 `CONSULT_TYPE_AI=2`、`SENDER_ROLE_AI=3` | 与方案一致 |
| ZCZX-AIZD-UT-005 | 参数校验 | 搜索关键字为空 | 单元测试 | JUnit5 | §5.4#3、§4.4 | 无 | `searchMode=true` 且 `contentKeyword` 空 | 失败；「请输入筛选条件」 |
| ZCZX-AIZD-UT-006 | 参数校验 | 发送校验复用 | 单元测试 | JUnit5 | §6.3 | 无 | 空文本/空媒体/非法后缀 | 同在线接诊校验文案 |
| ZCZX-AIZD-UT-007 | 会话创建 | receiver 全 NULL | 单元测试 | JUnit5+Mockito | §3.1 | 无 | 审阅 `insertAiSession` 入参 | `consult_type=2`；`receiver_*` 均为 NULL |
| ZCZX-AIZD-UT-008 | 会话创建 | 新会话时间 | 单元测试 | JUnit5+Mockito | §3.5#1、AI-09 | 创建空会话 | `createSession` | `session_title=新会话`；`last_message_time` 非空 |
| ZCZX-AIZD-UT-009 | Service | 默认列表 scope | 单元测试 | JUnit5+Mockito | §6.1 | 有 AS0、AS2、ASH、ASX | VA `selectAiSessionList` | 仅 AS0、AS1；`consult_type=2`；`asker_user_id=VA` |
| ZCZX-AIZD-UT-010 | Service | 搜索超窗 | 单元测试 | JUnit5+Mockito | §5.3#1、AI-03 | 有 AS2 | `list(true, keyword命中)` | 含 AS2 |
| ZCZX-AIZD-UT-011 | Service | 未搜索仍 3 个月 | 单元测试 | JUnit5+Mockito | §5.3#2 | 有 AS2 | 填 keyword 但 `searchMode=false` | 不含 AS2 |
| ZCZX-AIZD-UT-012 | Service | 首问更新标题 | 单元测试 | JUnit5+Mockito | §5.3#8 | AS-EMPTY | 首条文本提问成功 | `session_title` 更新为摘要≤50 字 |
| ZCZX-AIZD-UT-013 | Service | 提问+AI 回复 | 单元测试 | JUnit5+Mockito | §5、§4.3 | Mock Gateway 返回文本 | `sendMessage` | 提问 `role=1`；AI `role=3`；摘要更新；推送 2 次 |
| ZCZX-AIZD-UT-014 | Gateway | 视频固定文案 | 单元测试 | JUnit5 | §3.5#3、AI-07 | 无 | `reply(msgType=3)` | 返回「已收到视频，请补充文字描述症状。」 |
| ZCZX-AIZD-UT-015 | Gateway | 语音固定文案 | 单元测试 | JUnit5 | §3.5#3 | 无 | `reply(msgType=4)` | 返回「已收到语音，请补充文字描述。」 |
| ZCZX-AIZD-UT-016 | Gateway | 图片失败软回复 | 单元测试 | JUnit5+Mockito | §3.5#4、AI-11 | Mock 识图失败 | `sendMessage` 图片 | 仍插入 AI 消息；内容为图片识别暂不可用… |
| ZCZX-AIZD-UT-017 | Gateway | 单轮上下文 | 单元测试 | JUnit5+Mockito | §3.5#6 | 会话有多条历史 | 第二次 `sendMessage` | Gateway 入参**仅**当前提问，不含历史 |
| ZCZX-AIZD-UT-018 | Service | 处理中拒发 | 单元测试 | JUnit5+Mockito | §3.5#7、AI-10 | 第一次未释放锁 | 连续两次 `sendMessage` | 第二次失败；「AI 正在回复中，请稍候」 |
| ZCZX-AIZD-UT-019 | Service | 越权会话 | 单元测试 | JUnit5+Mockito | §3.6 | VA 访问 ASX | `messages`/`send` | 「无权查看该会话」 |
| ZCZX-AIZD-UT-020 | Service | hide 后会话 | 单元测试 | JUnit5+Mockito | §4.1.1、AI-04 | ASH | `messages`/`send` | 「会话不存在或已删除」 |
| ZCZX-AIZD-UT-021 | Service | 快捷模板 | 单元测试 | JUnit5 | §6 M1、AI-08 | 无 | `resolvePromptTemplate(2)` | 返回疾病诊疗预填模板非空 |
| ZCZX-AIZD-UT-022 | Mapper | AI 列表 SQL | 单元测试 | JUnit5 | §3.3 | 审阅 XML | `selectAiSessionList` | `consult_type=2`；`asker_user_id`；`vet_visible=1`；`COALESCE` 时间窗 |
| ZCZX-AIZD-UT-023 | 隔离 | 不进接诊列表 | 单元测试 | JUnit5+Mockito | AI-05 | 有 AV0 | 兽医接诊 `list` | 无 AS0 |
| ZCZX-AIZD-UT-024 | 隔离 | 接诊不进 AI 列表 | 单元测试 | JUnit5+Mockito | AI-05 | 有 AV0 | VA `ai list` | 无 AV0 |
| ZCZX-AIZD-UT-025 | 约束 | 不校验预约 | 单元测试 | JUnit5+Mockito | §3.4 | 无预约单 | `create`+`send` | 成功；不查 `biz_service_appointment` |
| ZCZX-AIZD-UT-026 | 诊断用户 | 新建会话插入 | 单元测试 | JUnit5+Mockito | §3.0 | `biz_diagnosis_user` 无 VA | `createAiSession` | `INSERT` 一行；`user_id=VA`；`first_use_time`、`last_use_time` 非空且相等 |
| ZCZX-AIZD-UT-027 | 诊断用户 | 已存在不重复插 | 单元测试 | JUnit5+Mockito | §3.0 | VA 已在用户表 | `createAiSession` | 不调用 `insertBizDiagnosisUser` |
| ZCZX-AIZD-UT-028 | 诊断用户 | 发消息更新末次 | 单元测试 | JUnit5+Mockito | §3.0 | 有 AS0 | `sendAiMessage` | `updateLastUseTime(VA, last_message_time)` 至少 1 次 |

---

## 二、接口测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-AIZD-API-001 | 列表 | 默认分页 | 接口测试 | Postman | §6.1、AI-03 | VA；AS0、AS1 | `GET /session/list` | `code=200`；仅 3 个月内；含 `sessionTitle` |
| ZCZX-AIZD-API-002 | 列表 | 超窗默认不出现 | 接口测试 | Postman | AI-03 | 有 AS2 | `searchMode=false` | 无 AS2 |
| ZCZX-AIZD-API-003 | 列表 | 搜索超窗 | 接口测试 | Postman | §5.3#2 | 有 AS2 | `searchMode=true&contentKeyword=命中` | 含 AS2 |
| ZCZX-AIZD-API-004 | 列表 | 重置 | 接口测试 | Postman | §6.1 | 曾搜出 AS2 | `searchMode=false` 清空条件 | 无 AS2 |
| ZCZX-AIZD-API-005 | 列表 | 仅填关键字未搜索 | 接口测试 | Postman | §5.3#2 | 有 AS2 | 传 keyword 无 `searchMode=true` | 仍无 AS2 |
| ZCZX-AIZD-API-006 | 列表 | 搜索关键字空 | 接口测试 | Postman | §4.4 | 已登录 | `searchMode=true` 无 keyword | 「请输入筛选条件」 |
| ZCZX-AIZD-API-007 | 列表 | 含 disclaimer | 接口测试 | Postman | §3.5#8 | VA 已登录 | `GET /session/list` | 响应含 `disclaimer` 非空 |
| ZCZX-AIZD-API-008 | 列表 | 机构账号 | 接口测试 | Postman | §3.5、AI-06 | OA 已登录有权限 | `GET /session/list` | `code=200` |
| ZCZX-AIZD-API-009 | 列表 | 无医疗资源绑定 | 接口测试 | Postman | §5.4#7 | NB 有 AI 权限、未绑定资源 | `GET /session/list` | `code=200`；按 NB 本人会话返回（可为空） |
| ZCZX-AIZD-API-010 | 列表 | 越权隔离 | 接口测试 | Postman | AI-05 | 有 ASX | VA 列表 | 无 ASX |
| ZCZX-AIZD-API-011 | 列表 | 已 hide | 接口测试 | Postman | AI-04 | ASH | VA 列表 | 无 ASH |
| ZCZX-AIZD-API-012 | 新建 | 空会话 | 接口测试 | Postman | §4.2、AI-01、AI-09 | VA | `POST /session` | 返回 `sessionId`、`disclaimer`；再 `list` 含「新会话」 |
| ZCZX-AIZD-API-013 | 消息 | 历史升序 | 接口测试 | Postman | §6.2 | AS0 | `GET /session/{id}/messages` | ≤50 条；`senderRole` 1/3；升序 |
| ZCZX-AIZD-API-014 | 消息 | 越权 | 接口测试 | Postman | §3.6 | ASX | VA `GET messages` | 无权 |
| ZCZX-AIZD-API-015 | 消息 | hide 后 | 接口测试 | Postman | AI-04 | ASH | `GET messages` | 会话不存在或已删除 |
| ZCZX-AIZD-API-016 | 提问 | 文本+AI 回复 | 接口测试 | Postman | §4.4、AI-02 | AS0 或新建 | `POST .../message` `msgType=1` | `data` 含 `userMessage`、`aiMessage`；`aiMessage.senderRole=3` |
| ZCZX-AIZD-API-017 | 提问 | 首问更新标题 | 接口测试 | Postman | §5.3#8 | AS-EMPTY | 发首条文本 | `list` 中标题非「新会话」 |
| ZCZX-AIZD-API-018 | 提问 | 图片 | 接口测试 | Postman | §5.4#8 | 先 upload | `msgType=2`+url | 成功；有 AI 回复 |
| ZCZX-AIZD-API-019 | 提问 | 视频固定回复 | 接口测试 | Postman | AI-07、§3.5#3 | AS0 | `msgType=3`+mp4 url | AI `content` 含「已收到视频」 |
| ZCZX-AIZD-API-020 | 提问 | 语音固定回复 | 接口测试 | Postman | AI-07 | AS0 | `msgType=4`+mp3 url | AI `content` 含「已收到语音」 |
| ZCZX-AIZD-API-021 | 提问 | 文本为空 | 接口测试 | Postman | §6.3 | AS0 | `content=""` | 「请输入消息内容」 |
| ZCZX-AIZD-API-022 | 提问 | 处理中拒发 | 接口测试 | Postman | AI-10、§4.4 | 首条未返回前 | 连续两次 `POST message` | 第二次「AI 正在回复中，请稍候」 |
| ZCZX-AIZD-API-023 | 提问 | Gateway 硬失败 | 接口测试 | Postman | §5 步骤13 | Mock/断网 AI | `POST message` | 无 AI 消息入库；「AI 回复失败/超时」 |
| ZCZX-AIZD-API-024 | 鉴权 | 未登录 | 接口测试 | curl | 安全 | 无 Token | `GET /session/list` | 401 |
| ZCZX-AIZD-API-025 | 权限 | 无 add | 接口测试 | Postman | §7 | 无 add 权限 | `POST /session` | 无权限 |
| ZCZX-AIZD-API-026 | 权限 | 无 send | 接口测试 | Postman | §7 | 仅 list/query | `POST .../message` | 无权限 |
| ZCZX-AIZD-API-027 | 隔离 | 接诊列表无 AI | 接口测试 | Postman | AI-05 | 有 AS0、AV0 | VA 调 `.../vet/session/list` | 无 AS0 |
| ZCZX-AIZD-API-028 | 移动端 | 新建+模板 | 接口测试 | Postman | M1、AI-08 | U1 | `POST /app/.../session` Body `category=2` | `sessionId`、`promptTemplate` 含疾病诊疗 |
| ZCZX-AIZD-API-029 | 移动端 | 牧民提问 | 接口测试 | Postman | M4 | U1 会话 | `POST /app/.../message` | 成功；`sender_role=1`+AI |
| ZCZX-AIZD-API-030 | 移动端 | 隐藏会话 | 接口测试 | Postman | M5、AI-04 | U1 会话 | `POST /app/consult/ai/session/{id}/hide` | `vet_visible=0`；管理端列表不可见 |
| ZCZX-AIZD-API-031 | 移动端 | 隐藏越权 | 接口测试 | Postman | §4.1.1 | U1 会话 | U2 `hide` | 失败 |
| ZCZX-AIZD-API-032 | 移动端 | 列表搜索 | 接口测试 | Postman | §3.5#5 | U1 有超窗会话 | `GET /app/.../list?searchMode=true` | 可命中超窗 |
| ZCZX-AIZD-API-033 | 新建 | 不要求医疗资源 | 接口测试 | Postman | §5.4#7 | NB 或 U1 无绑定 | `POST /session` 或 `/app/.../session` | 成功（不校验 `biz_medical_resource`） |
| ZCZX-AIZD-API-034 | 端到端 | 后台主流程 | 接口测试 | Postman | §7.1 | VA | `POST session`→`message`→`list` | 新会话、问答、摘要更新 |
| ZCZX-AIZD-API-035 | 端到端 | 搜索重置 | 接口测试 | Postman | AI-03 | 有 AS2 | list→search→reset | 与 API-002～004 一致 |
| ZCZX-AIZD-API-036 | 近实时 | AI 推送 | 接口测试 | Postman+WS | §5.1、AI-02 | 订阅 `/topic/consult/ai/{VA}` | `POST message` | AI 消息 **≤1s** 收到 `NEW_MESSAGE` |
| ZCZX-AIZD-API-037 | 响应 | 失败文案 | 接口测试 | Postman | §9 | 已登录 | 触发越权、空搜索、处理中 | `msg` 与 §4.4 一致 |
| ZCZX-AIZD-API-038 | 管理端 | 隐藏会话 | 接口测试 | Postman | §4.5、AI-04 | VA；AS0 | `POST /diseaseTreatment/onlineConsult/ai/session/{id}/hide` | `code=200`；列表无该会话 |
| ZCZX-AIZD-API-039 | 管理端 | 隐藏越权 | 接口测试 | Postman | §4.1.1 | ASX 属 VB | VA `POST .../hide` | 「会话不存在或已删除」 |
| ZCZX-AIZD-API-040 | 权限 | 无 remove | 接口测试 | Postman | §4.5 | 仅 list/query/add | `POST .../hide` | 无权限 |
| ZCZX-AIZD-API-041 | 落库 | realSessionId | 接口测试 | Postman | §4.3、§5 | VA；AS0 | `POST .../message` Body 含 `aiReplyContent` + `realSessionId` | `code=200`；`data.realSessionId` 与库 `real_session_id` 一致 |
| ZCZX-AIZD-API-042 | 落库 | aiCategory | 接口测试 | Postman | §3.2、§4.3 | VA；AS0 | `POST .../message` Body `aiCategory=2` + `aiReplyContent` | `userMessage.aiCategory=2`；`aiMessage.aiCategory` 为空 |
| ZCZX-AIZD-API-043 | 校验 | aiCategory 无效 | 接口测试 | Postman | §4.4 | VA；AS0 | `aiCategory=99`（纯数字超范围） | 失败；「AI提问分类无效」 |
| ZCZX-AIZD-API-044 | 诊断用户 | 新建写入用户表 | 接口测试 | Postman/SQL | §3.0 | VA；`biz_diagnosis_user` 无 VA | `POST /session` 后查库 | 新增 1 行；`first_use_time`、`last_use_time`≈会话 `create_time` |
| ZCZX-AIZD-API-045 | 诊断用户 | 提问更新末次 | 接口测试 | Postman/SQL | §3.0 | VA；AS0；记下提问前 `last_use_time` | `POST .../message` 成功后查库 | `biz_diagnosis_user.last_use_time` 与 `biz_consult_session.last_message_time` 一致（或晚于提问前） |

---

## 三、界面测试用例（UI）

**测试工具**：**Playwright** + **Chromium**（`channel: 'chrome'` 使用本机 **Google Chrome**）。

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-AIZD-UI-001 | 布局 | 左右分栏 | UI 测试 | Playwright+Chrome | §6、原型 | VA 登录 | 进入「AI 诊断（兽医、机构）」 | 左「历史会话」；右「AI 助手」 |
| ZCZX-AIZD-UI-002 | 列表 | 列表字段 | UI 测试 | Playwright+Chrome | §6.1 | 有 AS0 | 查看左侧项 | 问答标题、摘要、M月D日 |
| ZCZX-AIZD-UI-003 | 列表 | 默认 3 个月 | UI 测试 | Playwright+Chrome | AI-03 | AS0、AS2 | 进入不搜索 | 见 AS0；**不见** AS2 |
| ZCZX-AIZD-UI-004 | 列表 | 搜索超窗 | UI 测试 | Playwright+Chrome | AI-03 | 有 AS2 | 填会话内容→**搜索** | 出现 AS2 |
| ZCZX-AIZD-UI-005 | 列表 | 重置 | UI 测试 | Playwright+Chrome | §6.1 | 已搜出 AS2 | 点**重置** | 条件清空；AS2 消失 |
| ZCZX-AIZD-UI-006 | 列表 | 未点搜索 | UI 测试 | Playwright+Chrome | §5.3#2 | 有 AS2 | 仅输入关键字不点搜索 | 仍无 AS2 |
| ZCZX-AIZD-UI-007 | 列表 | 搜索无结果 | UI 测试 | Playwright+Chrome | §9 | 已登录 | 搜索不存在内容 | 「未找到匹配的 AI 诊断会话」或空态 |
| ZCZX-AIZD-UI-008 | 新建 | 新增会话 | UI 测试 | Playwright+Chrome | §6.1、AI-01 | VA 登录 | 点**新增会话** | 右侧空态/引导；左侧出现「新会话」 |
| ZCZX-AIZD-UI-009 | 新建 | 免责声明 | UI 测试 | Playwright+Chrome | §5.4#6、§3.5#8 | 首次进入或新建后 | 观察页面 | 展示免责声明文案 |
| ZCZX-AIZD-UI-010 | 聊天 | 未选会话 | UI 测试 | Playwright+Chrome | §6.2 | 有列表 | 不点左侧 | 「请选择历史会话或新增会话」 |
| ZCZX-AIZD-UI-011 | 聊天 | 加载历史 | UI 测试 | Playwright+Chrome | §6.2 | 有 AS0 | 点击 AS0 | 标题「AI 助手」；左提问右 AI 气泡 |
| ZCZX-AIZD-UI-012 | 提问 | 文本与等待态 | UI 测试 | Playwright+Chrome | §4.3、§6.3 | 选中会话 | 输入问题→发送 | 提问立即出现；「AI 正在思考…」；随后 AI 回复 |
| ZCZX-AIZD-UI-013 | 提问 | 文本为空 | UI 测试 | Playwright+Chrome | §6.3 | 选中会话 | 空内容发送 | 「请输入消息内容」 |
| ZCZX-AIZD-UI-014 | 提问 | 图片上传 | UI 测试 | Playwright+Chrome | §6.3 | 选中会话 | 选 jpg 上传发送 | 图片气泡；AI 有回复或引导文案 |
| ZCZX-AIZD-UI-015 | 提问 | 视频/语音文件 | UI 测试 | Playwright+Chrome | §4.2 | 选中会话 | 发 mp4/mp3 | AI 回复为补文字引导（§3.5#3） |
| ZCZX-AIZD-UI-016 | 提问 | 处理中拒发 | UI 测试 | Playwright+Chrome | AI-10 | 已点发送 | AI 未返回前再次点发送 | 「AI 正在回复中，请稍候」 |
| ZCZX-AIZD-UI-017 | 本期范围 | 不改前端 | UI 测试 | Playwright+Chrome | §4.1.1 | 已登录 | 扫描页面 | **无**隐藏按钮；接口 **API-038** 可 Postman 验证 |
| ZCZX-AIZD-UI-018 | 本期范围 | 无接诊混用 | UI 测试 | Playwright+Chrome | §6.4、AI-05 | 有接诊数据 | 本页列表 | 无问诊人姓名式接诊项 |
| ZCZX-AIZD-UI-019 | 权限 | 机构账号 | UI 测试 | Playwright+Chrome | §3.5 | OA 登录 | 进入同菜单 | 可新建、提问 |
| ZCZX-AIZD-UI-020 | 权限 | 无资源绑定可用 | UI 测试 | Playwright+Chrome | §5.4#7 | NB 有菜单与 AI 权限 | 进入 AI 诊断→新增会话 | 可正常使用；无「未绑定医疗资源」阻断 |
| ZCZX-AIZD-UI-021 | 权限 | 无 send | UI 测试 | Playwright+Chrome | §7 | 仅 list/query | 选中会话 | 无发送区或发送禁用 |
| ZCZX-AIZD-UI-022 | 端到端 | 新建问答闭环 | UI 集成 | Playwright+Chrome | §7.1 | VA 权限齐 | 新增会话→提问→看 AI 回复→列表摘要更新 | 全流程成功 |
| ZCZX-AIZD-UI-023 | 端到端 | hide 同步 | UI 集成 | Playwright+Chrome | AI-04 | U1 移动端 hide | VA 刷新列表 | 该会话消失 |

---

## 四、覆盖对照

| 类别 | 单元 UT | 接口 API | 界面 UI |
| --- | --- | --- | --- |
| 正常主流程 | UT-008～013、021 | API-012～018、034 | UI-008、011～012、022 |
| 列表/搜索/重置 | UT-009～011 | API-001～006、035 | UI-003～006 |
| 新建会话/空会话 | UT-008、012 | API-012、017 | UI-008、009 |
| AI 回复/网关 | UT-013～017 | API-016～020、023、036 | UI-012、014～015 |
| 处理中/超时 | UT-018 | API-022、023 | UI-016 |
| 隐藏 hide | UT-020 | API-030～031、038～040 | UI-017、023 |
| 越权/隔离 | UT-019、023～024 | API-010、014、027 | UI-018 |
| 机构/兽医/无绑定 | — | API-008～009 | UI-019～020 |
| 移动端/牧民 | UT-021 | API-028～033 | — |
| 快捷入口 | UT-021 | API-028 | （移动端 UI 可另补） |
| 免责声明 | — | API-007 | UI-009 |
| 预约解耦 | UT-025 | — | — |

---

## 五、功能需求追溯

| 需求章节 | 要点 | 主要用例 |
| --- | --- | --- |
| §5.3 产品确认 | 八项已确认 | API-001～012；UI-003～009 |
| §5.4 补充约定 | 十二条 | UT-014～018；API-019～022；§3.5 |
| §6.1 列表 | 搜索、新增、3 个月 | API-001～012；UI-001～008 |
| §6.2 对话 | 全历史、AI 助手标题 | API-013；UI-010～011 |
| §6.3 发送 | 多媒体、等待、失败 | API-016～023；UI-012～016 |
| §6.4 与接诊互斥 | 隔离 | UT-023～024；API-027；UI-018 |
| §7 流程 | 后台/移动/时序 | API-034～036；UI-022 |
| 技术方案 AI-01～11 | 验收 | API/UI 对应编号 |

---

## 六、Playwright 实施提示

- 安装：`npm i -D @playwright/test`；`npx playwright install chrome`。  
- 配置：`use: { channel: 'chrome', locale: 'zh-CN', baseURL: 'http://localhost:80' }`；`storageState` 复用兽医 VA、机构 OA。  
- 路由：`page.goto('/diseaseTreatment/onlineConsult/ai')`。  
- 定位示例：`page.getByPlaceholder('请输入会话内容')`；`page.getByRole('button', { name: '搜索' })`；`page.getByRole('button', { name: '重置' })`；`page.getByRole('button', { name: '新增会话' })`；`page.getByRole('button', { name: '发送' })`；右侧标题 `page.getByText('AI 助手')`。  
- AI 等待：发送后对 `text=AI 正在思考` 断言可见，再 `expect(aiBubble).toBeVisible({ timeout: 65000 })`（覆盖 60s AI 超时）。  
- 造数：`POST /diseaseTreatment/onlineConsult/ai/session`；`POST .../message`；隐藏：`POST .../session/{id}/hide`（管理端或移动端）。

---

## 七、修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初版：单元 25、接口 37、UI 23；覆盖列表/新建/提问/AI 回复/搜索/hide/隔离/机构/移动/网关/免责声明；Playwright+Chrome |
| 1.1 | 补充 `biz_diagnosis_user`：UT-026～028、API-044～045；前置 DDL 含 `sql/biz_diagnosis_user.sql` |
