# 在线接诊（兽医）— 测试用例

> 依据：`在线接诊(兽医)功能需求.md`（v1.1）、`在线接诊(兽医)技术方案.md`（v1.1）  
> **兽医后台 Base Path**：`/diseaseTreatments/onlineConsult/vet`；**移动端**：`/app/onlineConsult`；鉴权与若依一致（Cookie / Token）。

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

- 兽医账号 **A** 已绑定兽医资源 **R1**（`biz_medical_resource.resource_type=1`、`account_assigned=1`、`sys_user_id=A`），角色 **100**；权限 `diseaseTreatment:vetOnlineConsult:list|query|send`。  
- 兽医账号 **B** 绑定 **R2**（另一兽医）。  
- 牧民账号 **U1**、**U2** 可用于移动端造数。  
- `biz_consult_session` / `biz_consult_message` 已执行 DDL；宜预置：

| 样本 | 说明 | 要点 |
| --- | --- | --- |
| **S0** | U1↔R1，`consult_type=1` | `last_message_time` 在 3 个月内；`vet_visible=1`；有多条文本/图片消息 |
| **S1** | U2↔R1 | 同上；用于筛选 |
| **S2** | U1↔R1 超窗 | `last_message_time` **早于** 3 个月自然日边界；默认列表不出现 |
| **SX** | U1↔**R2** | 账号 A **不可见/不可操作** |
| **SA** | A 本人 AI 会话 | `consult_type=2`，`receiver_provider_id=NULL` | 接诊列表**不可见** |
| **SH** | U1↔R1 已 hide | `vet_visible=0` | 列表不可见；消息/发送失败 |

**界面（UI）**：**Playwright** + **Chromium**（`channel: 'chrome'` 使用本机 **Google Chrome**）；菜单「牧业疫病诊疗服务 → 在线接诊（兽医）」；路由 `diseaseTreatment/onlineConsult/vet/index`。

---

## 一、单元测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-ZXJZYS-UT-001 | 规则常量 | 问诊类型/消息类型 | 单元测试 | JUnit5 | §2.5、技术方案 §2.1 | 无 | 校验 `VET_ONLINE=1`、`AI=2`；`msgType` 1～4 合法 | 常量与方案一致 |
| ZCZX-ZXJZYS-UT-002 | 时间窗 | 3 个月边界计算 | 单元测试 | JUnit5 | §3.4#2、AC-02 | 固定「今日」2026-05-20 | `calcThreeMonthsAgo()` | 返回 `2026-02-20 00:00:00`（Asia/Shanghai 自然月） |
| ZCZX-ZXJZYS-UT-003 | 摘要 | 文本摘要截断 | 单元测试 | JUnit5 | §3.4#3 | 无 | 输入 60 字文本、`msg_type=1` | `last_message_preview` 最多 50 字 |
| ZCZX-ZXJZYS-UT-004 | 摘要 | 媒体固定文案 | 单元测试 | JUnit5 | §3.4#3、§6.1 | 无 | `msg_type` 2/3/4 | 分别为 `[图片]`、`[视频]`、`[语音]` |
| ZCZX-ZXJZYS-UT-005 | 参数校验 | 搜索条件为空 | 单元测试 | JUnit5 | §4.6 | 无 | `searchMode=true` 且 `askerName`、`contentKeyword` 均为空 | 失败；msg「请输入筛选条件」 |
| ZCZX-ZXJZYS-UT-006 | 参数校验 | 发送文本为空 | 单元测试 | JUnit5 | §6.3、§4.4 | 无 | `msgType=1`，`content` 空/空白 | 失败；「请输入消息内容」 |
| ZCZX-ZXJZYS-UT-007 | 参数校验 | 媒体 content 为空 | 单元测试 | JUnit5 | §6.3 | 无 | `msgType=2/3/4`，`content` 空 | 失败；「请上传文件」 |
| ZCZX-ZXJZYS-UT-008 | 参数校验 | 文件后缀白名单 | 单元测试 | JUnit5 | §3.4#7 | 无 | 图片 `.exe`；视频 `.avi`；合法 `.png`/`.mp4` | 非法失败「文件格式或大小不符合要求」；合法通过 |
| ZCZX-ZXJZYS-UT-009 | 范围解析 | 当前兽医 providerId | 单元测试 | JUnit5+Mockito | §2.4 | Mock 用户 A；库有 R1 | `resolveProviderId(A)` | 返回 R1.id |
| ZCZX-ZXJZYS-UT-010 | 范围解析 | 未绑定兽医 | 单元测试 | JUnit5+Mockito | §9 | 用户无资源绑定 | `resolveProviderId` | 空；列表/发送返回「未绑定兽医资源，无法接诊」 |
| ZCZX-ZXJZYS-UT-011 | Service | 默认列表 scope | 单元测试 | JUnit5+Mockito | §4.1、§6.1 | 有 S0、S2、SH、SX、SA | `list(searchMode=false)` 账号 A | 仅 S0、S1；无 S2/SX/SH/SA |
| ZCZX-ZXJZYS-UT-012 | Service | 搜索超窗 | 单元测试 | JUnit5+Mockito | §4.6、AC-03 | 有 S2 | `list(searchMode=true, contentKeyword=命中S2)` | 含 S2 |
| ZCZX-ZXJZYS-UT-013 | Service | 有筛选项未搜索 | 单元测试 | JUnit5+Mockito | §3.4#1 | 有 S2 | `askerName` 非空但 `searchMode=false` | 仍不含 S2（仅 3 个月窗） |
| ZCZX-ZXJZYS-UT-014 | Service | 消息首次加载 | 单元测试 | JUnit5+Mockito | §3.4#5 | S0 有 >50 条 | `listMessages(sessionId)` 无 `beforeId` | 返回最新 50 条；`send_time` 升序 |
| ZCZX-ZXJZYS-UT-015 | Service | 上拉更早消息 | 单元测试 | JUnit5+Mockito | §6.2 | S0 有 60 条 | `beforeId=最小id` | 再取 50 条；与首批无重叠 |
| ZCZX-ZXJZYS-UT-016 | Service | 兽医发送成功 | 单元测试 | JUnit5+Mockito | §6.3 | Mock S0 | `sendText(sessionId, "回复")` | 入库 `sender_role=2`；更新 `last_message_*`；触发推送 |
| ZCZX-ZXJZYS-UT-017 | Service | 越权-他兽医会话 | 单元测试 | JUnit5+Mockito | §2.4、AC-05 | 账号 A；目标 SX | `listMessages`/`send` | 失败；「无权查看该会话」 |
| ZCZX-ZXJZYS-UT-018 | Service | 已 hide 会话 | 单元测试 | JUnit5+Mockito | §4.1.1、AC-04 | Mock SH | `listMessages`/`send` | 失败；「会话不存在或已删除」 |
| ZCZX-ZXJZYS-UT-019 | Service | open 会话唯一 | 单元测试 | JUnit5+Mockito | §4.1 | 已有 U1+R1 会话 | 移动端 `open(vetResourceId=R1)` 两次 | 返回同一 `sessionId`；库仅 1 条 `consult_type=1` |
| ZCZX-ZXJZYS-UT-020 | Service | hide 仅问诊人 | 单元测试 | JUnit5+Mockito | §4.1.1 | S0 | 账号 A 调 `hide`；U1 调 `hide` | A 失败或无权；U1 成功 `vet_visible=0` |
| ZCZX-ZXJZYS-UT-021 | Mapper | 列表 SQL | 单元测试 | JUnit5 | 技术方案 §3.3 | 审阅 XML | 检查 `selectSessionList` | `consult_type=1`；`receiver_provider_id`；`vet_visible=1`；条件性 3 个月；`ORDER BY last_message_time DESC` |
| ZCZX-ZXJZYS-UT-022 | Mapper | 内容搜索 SQL | 单元测试 | JUnit5 | §3.3 | 审阅 XML | `searchMode=true` 分支 | 匹配 `preview`/`session_title`/消息文本子查询 |
| ZCZX-ZXJZYS-UT-023 | 推送 | NEW_MESSAGE 载荷 | 单元测试 | JUnit5 | §5.1、AC-01 | Mock 推送服务 | 发送后检查 payload | 含 §4.2 字段 + `lastMessagePreview` + `lastMessageTime` |
| ZCZX-ZXJZYS-UT-024 | 约束 | 不校验预约 | 单元测试 | JUnit5+Mockito | §3.4、§5.3 | U1 无预约单 | `open`+`send` | 成功；不访问 `biz_service_appointment` |
| ZCZX-ZXJZYS-UT-025 | 隔离 | AI 不进兽医列表 | 单元测试 | JUnit5+Mockito | §3.6、AC-07 | 有 SA | 账号 A `list` | 无 SA；SQL 无 `consult_type=2` |

---

## 二、接口测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-ZXJZYS-API-001 | 列表 | 默认分页排序 | 接口测试 | Postman | §6.1、AC-02 | 账号 A；S0、S1 | `GET /session/list` | `code=200`；仅 3 个月内；`last_message_time` 倒序；含 `askerAvatar` |
| ZCZX-ZXJZYS-API-002 | 列表 | 超窗默认不出现 | 接口测试 | Postman | AC-02 | 有 S2 | `GET /session/list`（`searchMode=false`） | 无 S2 |
| ZCZX-ZXJZYS-API-003 | 列表 | 搜索命中超窗 | 接口测试 | Postman | §4.6、AC-03 | 有 S2 | `searchMode=true`+`contentKeyword` 命中 | 含 S2 |
| ZCZX-ZXJZYS-API-004 | 列表 | 重置等价默认 | 接口测试 | Postman | §4.6 | 曾搜出 S2 | `searchMode=false`；筛选项空 | 无 S2 |
| ZCZX-ZXJZYS-API-005 | 列表 | 问诊人模糊 | 接口测试 | Postman | §6.1 | S0 问诊人含「扎西」 | `searchMode=true&askerName=扎` | 含 S0 |
| ZCZX-ZXJZYS-API-006 | 列表 | 仅填筛选项未搜索 | 接口测试 | Postman | §3.4#1 | 有 S2 | `askerName=扎` 且 **不传** `searchMode=true` | 仍无 S2 |
| ZCZX-ZXJZYS-API-007 | 列表 | 搜索条件全空 | 接口测试 | Postman | §4.6 | 已登录 | `searchMode=true` 无筛选项 | `code≠200`；「请输入筛选条件」 |
| ZCZX-ZXJZYS-API-008 | 列表 | 空列表提示数据 | 接口测试 | Postman | §6.1 | 账号 A 无会话 | `GET /session/list` | `rows=[]` |
| ZCZX-ZXJZYS-API-009 | 列表 | 数据隔离-他兽医 | 接口测试 | Postman | §2.4、AC-05 | 有 SX | 账号 A 列表 | 无 SX |
| ZCZX-ZXJZYS-API-010 | 列表 | 数据隔离-AI 会话 | 接口测试 | Postman | §3.6、AC-07 | 有 SA | 账号 A 列表 | 无 SA |
| ZCZX-ZXJZYS-API-011 | 列表 | 已 hide 不可见 | 接口测试 | Postman | AC-04 | 有 SH | 账号 A 列表 | 无 SH |
| ZCZX-ZXJZYS-API-012 | 列表 | 未绑定兽医 | 接口测试 | Postman | §9 | 无绑定账号 | `GET /session/list` | 空列表或「未绑定兽医资源，无法接诊」 |
| ZCZX-ZXJZYS-API-013 | 列表 | 禁止伪造 providerId | 接口测试 | Postman | §4.1 | 已登录 | 传 `receiverProviderId=伪造` | 仍以服务端 R1 为准 |
| ZCZX-ZXJZYS-API-014 | 消息 | 加载历史升序 | 接口测试 | Postman | §6.2、§3.4#5 | 有 S0 | `GET /session/{S0}/messages` | `rows`≤50；`send_time` 升序；含双方气泡字段 |
| ZCZX-ZXJZYS-API-015 | 消息 | 超窗会话全历史 | 接口测试 | Postman | §6.2 | S2 有 3 个月外消息 | `GET /session/{S2}/messages`（`searchMode` 搜出后） | 可返回全部历史，不受列表 3 个月限制 |
| ZCZX-ZXJZYS-API-016 | 消息 | 上拉 beforeId | 接口测试 | Postman | §3.4#5 | S0 >50 条 | 首次 GET；再 `beforeId=最小messageId` | 第二批更早；无重复 |
| ZCZX-ZXJZYS-API-017 | 消息 | 越权 sessionId | 接口测试 | Postman | AC-05 | 有 SX | 账号 A `GET /session/{SX}/messages` | 失败；「无权查看该会话」 |
| ZCZX-ZXJZYS-API-018 | 消息 | hide 后不可查 | 接口测试 | Postman | AC-04 | SH | `GET /session/{SH}/messages` | 失败；「会话不存在或已删除」 |
| ZCZX-ZXJZYS-API-019 | 发送 | 文本成功 | 接口测试 | Postman | §6.3、AC-01 | S0 | `POST /session/{id}/message` Body `msgType=1` | `code=200`；库有新消息；摘要更新 |
| ZCZX-ZXJZYS-API-020 | 发送 | 图片/视频/语音 | 接口测试 | Postman | §4.2、AC-06 | 先 `/common/upload` | `msgType=2/3/4`+url | 成功；preview 为 `[图片]` 等 |
| ZCZX-ZXJZYS-API-021 | 发送 | 文本为空 | 接口测试 | Postman | §6.3 | S0 | `msgType=1`，`content=""` | 失败；「请输入消息内容」 |
| ZCZX-ZXJZYS-API-022 | 发送 | 非法后缀 | 接口测试 | Postman | §3.4#7 | S0 | `msgType=2`，`content` 为非法 url | 失败；格式或大小不符合要求 |
| ZCZX-ZXJZYS-API-023 | 发送 | hide 后会话 | 接口测试 | Postman | AC-04 | SH | `POST .../message` | 失败；会话不存在或已删除 |
| ZCZX-ZXJZYS-API-024 | 发送 | 越权发送 | 接口测试 | Postman | AC-05 | SX | 账号 A POST | 失败；无权 |
| ZCZX-ZXJZYS-API-025 | 本期范围 | 无后台新建会话 | 接口测试 | Postman | §5.2 | 已登录 | `POST /session`（若暴露） | 404 或未实现 |
| ZCZX-ZXJZYS-API-026 | 鉴权 | 未登录 | 接口测试 | curl | 安全 | 无 Token | `GET /session/list` | 401 |
| ZCZX-ZXJZYS-API-027 | 权限 | 无 list | 接口测试 | Postman | §7 | 无 list 权限 | `GET /session/list` | 无权限 |
| ZCZX-ZXJZYS-API-028 | 权限 | 无 send | 接口测试 | Postman | §7 | 仅 list/query | `POST .../message` | 无权限 |
| ZCZX-ZXJZYS-API-029 | 移动端 | open 新建 | 接口测试 | Postman | §7.2、M1 | U1 首次问 R1 | `POST /app/.../open` Body `vetResourceId=R1` | 返回 `sessionId`；`consult_type=1` |
| ZCZX-ZXJZYS-API-030 | 移动端 | open 续聊唯一 | 接口测试 | Postman | §4.1 | U1 已有会话 | 再次 `open` | 同一 `sessionId` |
| ZCZX-ZXJZYS-API-031 | 移动端 | 牧民发消息 | 接口测试 | Postman | §7.2、AC-01 | S0；U1 Token | `POST /app/.../message` | 成功；兽医 `GET messages` 可见 |
| ZCZX-ZXJZYS-API-032 | 移动端 | hide 会话 | 接口测试 | Postman | AC-04 | S0 | U1 `POST .../hide` | `vet_visible=0`；兽医 API-011 |
| ZCZX-ZXJZYS-API-033 | 移动端 | hide 越权 | 接口测试 | Postman | §4.1.1 | S0 | U2 调 hide | 失败；无权 |
| ZCZX-ZXJZYS-API-034 | 端到端 | 接诊主流程 | 接口测试 | Postman | §7.1 | U1 open→发消息；A 登录 | A `list`→`messages`→`send`→U1 收 | 双向可见；列表摘要更新 |
| ZCZX-ZXJZYS-API-035 | 端到端 | 搜索重置流程 | 接口测试 | Postman | AC-03 | 有 S2 | 默认 list→search 出 S2→reset | 与 API-002～004 一致 |
| ZCZX-ZXJZYS-API-036 | 约束 | 无预约可问诊 | 接口测试 | Postman | §3.4 | U1 无 `biz_service_appointment` | open+send | 成功 |
| ZCZX-ZXJZYS-API-037 | 近实时 | 推送延迟 | 接口测试 | Postman+WS 客户端 | AC-01 | 双端在线 | U1 发文本；A 订阅 WS | A **≤1s** 收到 `NEW_MESSAGE` |
| ZCZX-ZXJZYS-API-038 | 响应 | 失败 msg 一致 | 接口测试 | Postman | §9 | 已登录 | 触发越权、空文本、hide | `msg` 与 §4.4/§9 一致 |

---

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

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

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-ZXJZYS-UI-001 | 布局 | 左右分栏 | UI 测试 | Playwright+Chrome | §6、原型 | 账号 A；有 S0 | 进入「在线接诊（兽医）」 | 左「接诊会话」列表；右聊天区；标题区 |
| ZCZX-ZXJZYS-UI-002 | 列表 | 列表项字段 | UI 测试 | Playwright+Chrome | §6.1 | 有 S0 | 查看左侧项 | 头像/占位、问诊人姓名、摘要、日期「M月D日」 |
| ZCZX-ZXJZYS-UI-003 | 列表 | 默认仅 3 个月 | UI 测试 | Playwright+Chrome | AC-02 | 有 S0、S2 | 进入页不点搜索 | 见 S0；**不见** S2 |
| ZCZX-ZXJZYS-UI-004 | 列表 | 搜索超窗 | UI 测试 | Playwright+Chrome | AC-03 | 有 S2 | 填会话内容→点**搜索** | 出现 S2 |
| ZCZX-ZXJZYS-UI-005 | 列表 | 重置恢复默认 | UI 测试 | Playwright+Chrome | §6.1 | 已搜出 S2 | 点**重置** | 筛选项清空；S2 消失 |
| ZCZX-ZXJZYS-UI-006 | 列表 | 未点搜索仍 3 个月 | UI 测试 | Playwright+Chrome | §3.4#1 | 有 S2 | 仅输入问诊人→不点搜索 | 仍无 S2 |
| ZCZX-ZXJZYS-UI-007 | 列表 | 搜索无结果 | UI 测试 | Playwright+Chrome | §9 | 已登录 | 搜索不存在关键字 | 提示「未找到匹配的接诊会话」或空态 |
| ZCZX-ZXJZYS-UI-008 | 列表 | 空列表 | UI 测试 | Playwright+Chrome | §6.1 | 无会话 | 进入页 | 「暂无接诊会话」 |
| ZCZX-ZXJZYS-UI-009 | 聊天 | 未选会话空态 | UI 测试 | Playwright+Chrome | §6.2 | 有列表 | 不点左侧项 | 右侧「请选择接诊会话」 |
| ZCZX-ZXJZYS-UI-010 | 聊天 | 选中加载历史 | UI 测试 | Playwright+Chrome | §6.2 | 有 S0 | 点击 S0 | 顶部问诊人姓名；气泡左右分布；按日期分组 |
| ZCZX-ZXJZYS-UI-011 | 聊天 | 上拉更早 | UI 测试 | Playwright+Chrome | §6.2 | S0>50 条 | 滚至顶部触发加载 | 更早消息追加；顺序正确 |
| ZCZX-ZXJZYS-UI-012 | 发送 | 文本成功 | UI 测试 | Playwright+Chrome | §6.3 | 选中 S0 | 输入文本→发送 | 右侧立即出现气泡；左侧摘要更新 |
| ZCZX-ZXJZYS-UI-013 | 发送 | 文本为空 | UI 测试 | Playwright+Chrome | §6.3 | 选中 S0 | 空内容点发送 | 「请输入消息内容」；无假成功气泡 |
| ZCZX-ZXJZYS-UI-014 | 发送 | 图片文件上传 | UI 测试 | Playwright+Chrome | §4.2 | 选中 S0 | 选本地 jpg≤10MB→发送 | 聊天区缩略图；列表摘要「[图片]」 |
| ZCZX-ZXJZYS-UI-015 | 发送 | 视频/语音文件 | UI 测试 | Playwright+Chrome | §4.2、§5.3 | 选中 S0 | 选 mp4/mp3 合法文件发送 | 占位/播放控件；摘要「[视频]」「[语音]」 |
| ZCZX-ZXJZYS-UI-016 | 发送 | 非法/超大文件 | UI 测试 | Playwright+Chrome | §6.3 | 选中 S0 | 选超大或非法后缀 | 提示文件不合规；不插入成功气泡 |
| ZCZX-ZXJZYS-UI-017 | 近实时 | 收到牧民消息 | UI 集成 | Playwright+Chrome | AC-01、§4.3 | A 页打开 S0；U1 移动端发 | 观察 A 页 **≤1s** | 新气泡与列表摘要自动出现（WS，非仅 F5） |
| ZCZX-ZXJZYS-UI-018 | 本期范围 | 无新建会话按钮 | UI 测试 | Playwright+Chrome | §5.2 | 已登录 | 扫描工具栏/页头 | **无**「新建会话」 |
| ZCZX-ZXJZYS-UI-019 | 本期范围 | 无删除/结束会话 | UI 测试 | Playwright+Chrome | §5.2 | 选中 S0 | 扫描会话操作 | **无**删除/结束；牧民 hide 后项消失 |
| ZCZX-ZXJZYS-UI-020 | 本期范围 | 无 RTC/内嵌录播 | UI 测试 | Playwright+Chrome | §4.2 | 已登录 | 检查输入区图标 | 视频/语音为**选文件**；无通话/录音控件 |
| ZCZX-ZXJZYS-UI-021 | 权限 | 无 send 仅查看 | UI 测试 | Playwright+Chrome | §7 | 仅 list/query 角色 | 进入页选会话 | 无发送框或发送禁用 |
| ZCZX-ZXJZYS-UI-022 | 权限 | 未绑定账号 | UI 测试 | Playwright+Chrome | §9 | 无兽医绑定 | 进入菜单 | 无菜单或空列表+友好提示 |
| ZCZX-ZXJZYS-UI-023 | 隔离 | 菜单不含 AI 诊断混表 | UI 测试 | Playwright+Chrome | §6.4 | 有 SA 数据 | 本页列表 | 不出现 AI 问答标题/「AI 助手」会话 |
| ZCZX-ZXJZYS-UI-024 | 端到端 | 筛选聊天闭环 | UI 集成 | Playwright+Chrome | §7.1 | S0、S1 | 问诊人筛选→搜索→选会话→发回复 | 列表过滤正确；发送成功 |
| ZCZX-ZXJZYS-UI-025 | 端到端 | hide 后不可见 | UI 集成 | Playwright+Chrome | AC-04 | S0 | U1 移动端删除会话→A 刷新列表 | S0 从列表消失；无法再发 |

---

## 四、覆盖对照

| 类别 | 单元 UT | 接口 API | 界面 UI |
| --- | --- | --- | --- |
| 正常主流程 | UT-011～016、019 | API-001、014～016、019～020、029～034 | UI-001～002、010～012、014～015、024 |
| 3 个月窗/搜索重置 | UT-002、012～013 | API-002～007、035 | UI-003～006 |
| 近实时 ≤1s | UT-023 | API-037 | UI-017 |
| 发送校验/媒体 | UT-003～008、006～007 | API-020～022 | UI-013～016 |
| hide/可见性 | UT-018、020 | API-011、018、032～033 | UI-019、025 |
| 越权/隔离 | UT-017、025 | API-009～010、017、024、010 | UI-023 |
| AI/预约约束 | UT-024～025 | API-010、036、025 | UI-018～020、023 |
| 权限/鉴权 | UT-010 | API-026～028 | UI-021～022 |
| 本期不做 | — | API-025 | UI-018～020 |

---

## 五、功能需求与技术方案追溯

| 需求/方案章节 | 要点 | 主要用例 |
| --- | --- | --- |
| §4.1 时间窗与搜索 | 默认 3 月；搜索超窗；重置 | UT-011～013；API-002～007、035；UI-003～006 |
| §4.1.1 hide | 牧民删除兽医不可见 | UT-018、020；API-011、018、032；UI-019、025 |
| §4.2 消息类型 | 文本/图/视/音文件 | UT-003～008；API-020；UI-014～016 |
| §4.3 近实时 | ≤1 秒 | UT-023；API-037；UI-017 |
| §5.3 产品确认五项 | 见技术方案 §3.4 | UT-002～013；API-001～007、037；UI-003～017 |
| §6.1 列表 | 筛选、字段、空态 | API-001～008；UI-001～008 |
| §6.2 详情 | 全历史、气泡、未选 | API-014～016；UI-009～011 |
| §6.3 发送 | 校验、失败不假成功 | UT-006～007；API-019～023；UI-012～016 |
| §6.4 与 AI 互斥 | 分列表 | UT-025；API-010；UI-023 |
| §3.4 不绑定预约 | 无预约可聊 | UT-024；API-036 |
| 技术方案 AC-01～07 | 验收 | API-037；各节对应用例编号 |

---

## 六、Playwright 实施提示

- 安装：`npm i -D @playwright/test`；`npx playwright install chrome`。  
- 配置：`use: { channel: 'chrome', locale: 'zh-CN', baseURL: 'http://localhost:80' }`；`storageState` 复用兽医账号 A。  
- 路由：`page.goto('/diseaseTreatment/onlineConsult/vet')`（与菜单 `component` 一致）。  
- 定位示例：`page.getByPlaceholder('请输入问诊人')`；`page.getByPlaceholder('请输入会话内容')`；`page.getByRole('button', { name: '搜索' })`；`page.getByRole('button', { name: '重置' })`；`page.locator('.session-list .session-item').first().click()`；`page.getByRole('button', { name: '发送' })`；`page.locator('input[type=file]').setInputFiles('fixtures/sample.jpg')`。  
- 近实时（UI-017）：`page.waitForEvent` 监听 WS 帧，或 `expect(locator).toBeVisible({ timeout: 1000 })`。  
- 数据准备：移动端 `POST /app/onlineConsult/session/open` + `message` 造 S0；SQL 直接插 S2（`last_message_time` 超窗）、SH（`vet_visible=0`）、SA（`consult_type=2`）。

---

## 七、修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初版：单元 25、接口 38、UI 25；覆盖列表/消息/发送、3 个月与搜索、hide、近实时、AI 隔离、预约解耦、移动端 M1/M2/M4；Playwright+Chrome |
