# 我的预约（机构）— 测试用例

> 依据：`我的预约(机构)功能需求.md`、`我的预约(机构)技术方案.md`  
> **接口 Base Path**：`/diseaseTreatment/myAppointment/org`；鉴权与若依一致（Cookie / Token）。  
> **本期范围**：登记制（列表 + 详情 + **完成接诊**）；**无**确认/拒绝/评价接口。

**通用前置（无特殊说明）**：机构账号 **B** 已通过「畜牧医疗资源管理」为机构 **O1**（`resource_type=3`、`account_assigned=1`、`sys_user_id=B`）分配账号并绑定角色 **102**；具备权限 `diseaseTreatment:orgMyAppointment:list|query|complete`（**无** confirm/reject）。`biz_service_appointment` 宜预置：

| 样本 | 归属 | 状态 | 要点 |
| --- | --- | --- | --- |
| **B0** | O1，`provider_type=2` | 已预约 `5` | 可操作完成接诊；`canComplete=true` |
| **B1** | O1 | 已取消 `3` | 仅查看 |
| **B2** | O1 | 已完成 `4` | 仅查看；**无**评价入口 |
| **BX** | O2（另一机构） | 已预约 `5` | 账号 B 不可见/不可查详情 |
| **V0** | 兽医 R1，`provider_type=1` | 待确认 `0` | 机构列表不可见 |
| **E1** | 专家，`provider_type=3` | 待确认 `0` | 机构列表不可见 |
| **BAD**（可选） | O1，`provider_type=2` | 待确认 `0` | 数据串单；用于异常防护用例 |

**界面（UI）测试**：**Playwright** + **Chromium**（`channel: 'chrome'` 使用本机 **Google Chrome**）；菜单示例「牧业疫病诊疗服务 → 我的预约（机构）」；组件路径 `diseaseTreatment/myAppointment/org/index`。

---

## 一、单元测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-WDYYJG-UT-001 | 参数校验 | 预约日期范围 | 单元测试 | JUnit5 | §6.1、§9 | 无 | `OrgAppointmentValidation`：`startDate` 晚于 `endDate`；相等；合法区间 | 前者失败，msg「结束日期不能早于开始日期」；后两者通过 |
| ZCZX-WDYYJG-UT-002 | 参数校验 | 状态筛选合法集 | 单元测试 | JUnit5 | §4.1、技术方案 §2.2 | 无 | `status` 为 `3/4/5`；`null`；`0/1/2` | 前三与 null 通过；`0/1/2` 失败，msg「状态筛选无效」 |
| ZCZX-WDYYJG-UT-003 | 状态展示 | 三态标签解析 | 单元测试 | JUnit5 | §4.1、§6.1 | 无 | `OrgAppointmentStatusResolver.resolveLabel(5/3/4)` | 已预约 / 已取消 / 已完成 |
| ZCZX-WDYYJG-UT-004 | 状态展示 | status=5 非「已确认」 | 单元测试 | JUnit5 | §3.1、技术方案 §5 | 无 | `resolveLabel(5)`；对比兽医 `resolveLabel(1)` | 机构为「已预约」；不得映射为「已确认」 |
| ZCZX-WDYYJG-UT-005 | 状态规则 | 可完成接诊 | 单元测试 | JUnit5 | §6.5、§7 | 无 | `canCompleteOrg(3/4/5)` | 仅 `status=5` 为 true |
| ZCZX-WDYYJG-UT-005a | 状态规则 | 机构无接单动作 | 单元测试 | JUnit5 | §5.2 | 无 | 审阅 Controller | 无 `confirm`/`reject` 路由 |
| ZCZX-WDYYJG-UT-016 | Service | 完成接诊成功 | 单元测试 | JUnit5+Mockito | §6.5 | Mock B0 | `complete(id)` | `status=4` |
| ZCZX-WDYYJG-UT-017 | Service | 已取消不可完成 | 单元测试 | JUnit5+Mockito | §6.5 | Mock B1 | `complete` | 失败；已取消或不允许 |
| ZCZX-WDYYJG-UT-018 | Mapper | 完成接诊 SQL | 单元测试 | JUnit5 | 技术方案 §3.2 | 审阅 XML | `updateCompleteOrgAppointment` | `provider_type=2`；`status=5`→`4` |
| ZCZX-WDYYJG-UT-006 | 范围解析 | 当前机构 providerId | 单元测试 | JUnit5+Mockito | §2.2、技术方案 §2.4 | Mock 用户 B；库有 O1（`resource_type=3`） | `OrgProviderResolver.resolveProviderId(B)` | 返回 O1.id |
| ZCZX-WDYYJG-UT-007 | 范围解析 | 未绑定机构 | 单元测试 | JUnit5+Mockito | §9 | 用户无 `resource_type=3` 绑定 | `resolveProviderId` | 返回 null 或 Optional.empty |
| ZCZX-WDYYJG-UT-008 | Service | 列表数据范围 | 单元测试 | JUnit5+Mockito | §6.1、§3.5 | Mock Mapper；有 B0、BX、V0 | `selectList` 账号 B | 查询含 `provider_type=2`、`provider_id=O1`；仅 B0/B1/B2；无 BX/V0 |
| ZCZX-WDYYJG-UT-009 | Service | 详情成功 | 单元测试 | JUnit5+Mockito | §6.2 | Mock B0 | `getById(B0.id)` | 返回全字段；含 `timeStart/timeEnd/serviceAddress/serviceRequirement` |
| ZCZX-WDYYJG-UT-010 | Service | 详情不含拒绝理由 | 单元测试 | JUnit5+Mockito | §6.2、§5.2 | Mock B0 | 检查 VO/Codec 或响应组装 | 不设置/不下发 `rejectReason` |
| ZCZX-WDYYJG-UT-011 | Service | 越权-他机构 | 单元测试 | JUnit5+Mockito | §2.2 | 账号 B；目标 BX（O2） | `getById(BX.id)` | 失败；msg「无权查看该预约记录」或「预约记录不存在」 |
| ZCZX-WDYYJG-UT-012 | Service | 未绑定无法查详情 | 单元测试 | JUnit5+Mockito | §9 | 无 O1 绑定 | `getById` | 失败；msg「未绑定机构资源，无法查询预约」 |
| ZCZX-WDYYJG-UT-013 | Service | 未绑定列表为空 | 单元测试 | JUnit5+Mockito | §9 | 无绑定 | `selectList` | 空列表（不抛错）或统一提示策略与实现一致 |
| ZCZX-WDYYJG-UT-014 | Service | 串单异常状态 | 单元测试 | JUnit5+Mockito | §4.3 | Mock BAD（`provider_type=2,status=0`） | `getById` 或列表过滤 | 不展示或报错/记日志（与技术方案 §5 一致） |
| ZCZX-WDYYJG-UT-015 | Mapper | 机构列表 SQL | 单元测试 | JUnit5 | §6.1、技术方案 §3.2 | 审阅 XML | `selectOrgAppointmentList` | `provider_type=2`；`provider_id=`；姓名 LIKE；日期区间；`status=`；`ORDER BY appoint_date DESC, create_time DESC, id DESC` |

---

## 二、接口测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-WDYYJG-API-001 | 列表 | 默认分页排序 | 接口测试 | Postman | §6.1 | 账号 B；O1 多条样本 | `GET /list` | `code=200`；`rows`≤20；`appointDate` 倒序 |
| ZCZX-WDYYJG-API-002 | 列表 | 预约人模糊 | 接口测试 | Postman | §6.1 | B0 预约人含关键字 | `appointeeName=关键字片段` | 含 B0；不含无关人 |
| ZCZX-WDYYJG-API-003 | 列表 | 预约日期区间 | 接口测试 | Postman | §6.1 | 样本日期已知 | `startDate`、`endDate` 含 B0 当天 | 含 B0；边界日包含 |
| ZCZX-WDYYJG-API-004 | 列表 | 状态-已预约 | 接口测试 | Postman | §6.1 | 有 B0 | `status=5` | 均为已预约；`statusLabel` 为「已预约」 |
| ZCZX-WDYYJG-API-005 | 列表 | 状态-已取消/已完成 | 接口测试 | Postman | §6.1 | 有 B1、B2 | `status=3`；`status=4` | 分别仅对应状态 |
| ZCZX-WDYYJG-API-006 | 列表 | 日期区间非法 | 接口测试 | Postman | §9 | 已登录 | `startDate` 晚于 `endDate` | `code≠200`；msg「结束日期不能早于开始日期」 |
| ZCZX-WDYYJG-API-007 | 列表 | 状态 0/1/2 非法 | 接口测试 | Postman | §4.3、技术方案 §2.2 | 已登录 | `status=0`、`1`、`2` 各一次 | 失败或 msg「状态筛选无效」 |
| ZCZX-WDYYJG-API-008 | 列表 | 数据隔离-他机构 | 接口测试 | Postman | §2.2 | 有 BX | 账号 B `GET /list` | 无 BX |
| ZCZX-WDYYJG-API-009 | 列表 | 数据隔离-兽医/专家 | 接口测试 | Postman | §3.5 | 有 V0、E1 | 账号 B `GET /list` | 无 V0、E1 |
| ZCZX-WDYYJG-API-010 | 列表 | 未绑定机构 | 接口测试 | Postman | §9 | 无 `resource_type=3` 绑定账号 | `GET /list` | 空列表；或 msg「未绑定机构资源，无法查询预约」 |
| ZCZX-WDYYJG-API-011 | 列表 | 禁止传 providerId | 接口测试 | Postman | 技术方案 §4.1 | 已登录 | `GET /list?providerId=伪造O2` | 仍以服务端 O1 为准；不可查 O2 数据 |
| ZCZX-WDYYJG-API-012 | 列表 | 列表字段精简 | 接口测试 | Postman | §6.1 | 有 B0 | 检查 `rows[0]` 字段 | 含 `appointeeName/appointDate/contactPhone/status/statusLabel`；可不返回或前端忽略 `serviceAddress` 等（以实现为准） |
| ZCZX-WDYYJG-API-013 | 详情 | 已预约全字段 | 接口测试 | Postman | §6.2 | 有 B0 | `GET /{B0.id}` | 含 `timeStart/timeEnd/serviceAddress/serviceRequirement`；`status=5`；`statusLabel=已预约` |
| ZCZX-WDYYJG-API-014 | 详情 | 三态均可查看 | 接口测试 | Postman | §7 | 有 B1、B2 | 分别 `GET /{id}` | `code=200`；状态与标签正确 |
| ZCZX-WDYYJG-API-015 | 详情 | 无拒绝理由字段 | 接口测试 | Postman | §6.2、§5.2 | 有 B0 | `GET /{id}` | 响应无 `rejectReason`；无 `confirmTime/rejectTime`（若实现统一 VO 则值为 null 且文档约定前端不展示） |
| ZCZX-WDYYJG-API-016 | 详情 | 越权-他机构 | 接口测试 | Postman | §2.2 | 有 BX | 账号 B `GET /{BX.id}` | 失败；msg「无权查看」或「不存在」 |
| ZCZX-WDYYJG-API-017 | 详情 | 不存在 id | 接口测试 | Postman | 技术方案 §4.3 | 已登录 | `GET /999999999` | 失败；msg「预约记录不存在或已删除」 |
| ZCZX-WDYYJG-API-018 | 详情 | 未绑定机构 | 接口测试 | Postman | §9 | 无绑定 | `GET /{任意id}` | 失败；msg「未绑定机构资源，无法查询预约」 |
| ZCZX-WDYYJG-API-019 | 本期范围 | 无确认接口 | 接口测试 | Postman | §5.2 | 有 B0 | `POST /confirm/{B0.id}` | 404 或 405；路由不存在 |
| ZCZX-WDYYJG-API-020 | 本期范围 | 无拒绝接口 | 接口测试 | Postman | §5.2 | 有 B0 | `POST /reject/{B0.id}` | 404 或 405 |
| ZCZX-WDYYJG-API-021 | 本期范围 | 无写方法 | 接口测试 | Postman | §5.2 | 已登录 | `PUT/DELETE /{id}` | 404 或 405 |
| ZCZX-WDYYJG-API-022 | 本期范围 | 无评价接口 | 接口测试 | Postman | §5.2、§3.4 | 有 B2 | `GET .../reviewList/{id}` | 404 或未实现 |
| ZCZX-WDYYJG-API-023 | 完成接诊 | 已预约成功 | 接口测试 | Postman | §6.5 | 有 B0 | `POST /complete/{B0.id}` | `code=200`；库 `status=4` |
| ZCZX-WDYYJG-API-023a | 完成接诊 | 已取消禁止 | 接口测试 | Postman | §6.5 | 有 B1 | `POST /complete/{B1.id}` | 失败 |
| ZCZX-WDYYJG-API-023b | 列表 | canComplete | 接口测试 | Postman | §6.1 | 有 B0 | `GET /list` | B0 行 `canComplete=true` |
| ZCZX-WDYYJG-API-031 | 权限 | 无 complete | 接口测试 | Postman | §7 | 无 complete | `POST /complete/{id}` | 无权限失败 |
| ZCZX-WDYYJG-API-032 | 端到端 | 登记+完成主流程 | 接口测试 | Postman | §8.1 | 有 B0 | `list`→`complete`→`list` | B0 变已完成 |
| ZCZX-WDYYJG-API-024 | 端到端 | 筛选组合 | 接口测试 | Postman | §6.1 | 多样本 | `appointeeName`+日期+`status=5` | 结果同时满足 |
| ZCZX-WDYYJG-API-025 | 鉴权 | 未登录 | 接口测试 | curl | 安全 | 无 Token | `GET /list` | 401 或未登录 |
| ZCZX-WDYYJG-API-026 | 权限 | 无 list 权限 | 接口测试 | Postman | §7 | 无 list 角色 | `GET /list` | 无权限失败 |
| ZCZX-WDYYJG-API-027 | 权限 | 无 query 权限 | 接口测试 | Postman | §7 | 仅 list | `GET /{id}` | 无权限失败 |
| ZCZX-WDYYJG-API-028 | 权限 | 无 confirm 误配 | 接口测试 | Postman | §7 | 机构角色仅 list/query | 尝试兽医路径 `POST .../vet/confirm/{V0.id}` | 与机构模块无关；机构路径无此接口（见 API-019） |
| ZCZX-WDYYJG-API-029 | 响应 | 失败 msg 可读 | 接口测试 | Postman | §9 | 已登录 | 触发日期非法、状态非法、越权 | `msg` 与 §9/技术方案 §4.3 一致 |
| ZCZX-WDYYJG-API-030 | 异常数据 | 串单记录 | 接口测试 | Postman | §4.3 | 有 BAD（可选） | `GET /list` 或 `GET /{BAD.id}` | 列表不含或详情报错；不展示待确认标签 |

---

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

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

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-WDYYJG-UI-001 | 列表 | 页面与精简列 | UI 测试 | Playwright+Chrome | §6.1 | 账号 B 登录；有样本 | 进入「我的预约（机构）」 | 列含预约人、预约日期、联系电话、状态、操作；**无**时段、地址、需求、拒绝理由列 |
| ZCZX-WDYYJG-UI-002 | 列表 | 状态标签三态 | UI 测试 | Playwright+Chrome | §6.1 | 有 B0/B1/B2 | 查看各行状态 | 分别展示已预约/已取消/已完成；颜色可区分 |
| ZCZX-WDYYJG-UI-003 | 列表 | 预约人筛选 | UI 测试 | Playwright+Chrome | §6.1 | 有 B0 | 填预约人→搜索 | 含匹配行 |
| ZCZX-WDYYJG-UI-004 | 列表 | 日期与状态筛选 | UI 测试 | Playwright+Chrome | §6.1 | 有 B1 | 选日期区间+状态「已取消」→搜索 | 仅已取消行 |
| ZCZX-WDYYJG-UI-005 | 列表 | 状态下拉仅三项 | UI 测试 | Playwright+Chrome | §4.1 | 已登录 | 打开状态下拉 | 仅已预约、已取消、已完成；**无**待确认/已确认/已拒绝 |
| ZCZX-WDYYJG-UI-006 | 列表 | 日期非法提示 | UI 测试 | Playwright+Chrome | §9 | 已登录 | 结束日期早于开始→搜索 | 提示「结束日期不能早于开始日期」 |
| ZCZX-WDYYJG-UI-007 | 列表 | 重置 | UI 测试 | Playwright+Chrome | §6.1 | 已筛选 | 搜索→点「重置」 | 条件清空；列表恢复 |
| ZCZX-WDYYJG-UI-008 | 列表 | 默认分页 | UI 测试 | Playwright+Chrome | §6.1 | >20 条 O1 数据 | 进入列表 | 每页 20 条；可翻页 |
| ZCZX-WDYYJG-UI-009 | 操作列 | 已预约可完成 | UI 测试 | Playwright+Chrome | §7 | 有 B0 | 查看操作列 | 有查看、完成接诊 |
| ZCZX-WDYYJG-UI-009a | 操作列 | 已取消/已完成仅查看 | UI 测试 | Playwright+Chrome | §7 | B1/B2 | 查看操作列 | 仅有「查看」；**无**确认/拒绝/评价 |
| ZCZX-WDYYJG-UI-010 | 详情 | 只读弹窗全字段 | UI 测试 | Playwright+Chrome | §6.2 | 有 B0 | 点击查看 | 含预约人、日期、时段（`HH:mm~HH:mm`）、电话、地址、需求、状态；字段不可编辑 |
| ZCZX-WDYYJG-UI-011 | 详情 | 无拒绝理由区 | UI 测试 | Playwright+Chrome | §6.2、§5.2 | 有 B0/B1/B2 | 分别打开详情 | 无「拒绝理由」表单项 |
| ZCZX-WDYYJG-UI-012 | 详情 | 已完成无评价 | UI 测试 | Playwright+Chrome | §3.4、§5.2 | 有 B2 | 打开 B2 详情 | 无星级、综合评价、「查看评价」按钮 |
| ZCZX-WDYYJG-UI-013 | 详情 | 关闭不变态 | UI 测试 | Playwright+Chrome | §6.2 | 有 B0 | 打开详情→点「确定」或「关闭」 | 弹窗关闭；列表状态仍为已预约；无成功提交类提示 |
| ZCZX-WDYYJG-UI-014 | 详情 | 三态均可进入 | UI 测试 | Playwright+Chrome | §7 | 有 B0/B1/B2 | 各点查看 | 均可打开详情且字段完整（时段等仅在详情） |
| ZCZX-WDYYJG-UI-015 | 范围 | 未绑定账号 | UI 测试 | Playwright+Chrome | §9 | 无机构绑定账号 | 进入菜单或列表 | 无菜单或列表空/友好提示；页面不崩溃 |
| ZCZX-WDYYJG-UI-016 | 权限 | 无 complete 角色 | UI 测试 | Playwright+Chrome | §7 | 仅 list/query | 有 B0 | 无完成接诊；无确认/拒绝 |
| ZCZX-WDYYJG-UI-017 | 对比 | 与兽医页差异 | UI 测试 | Playwright+Chrome | §3.3 | 可选 | 对比列表列与操作 | 机构列更少；无确认/拒绝；有完成接诊（已预约） |
| ZCZX-WDYYJG-UI-019 | 完成接诊 | 成功提示 | UI 测试 | Playwright+Chrome | §6.5 | 有 B0 | 完成接诊→确定 | 成功；状态变已完成 |
| ZCZX-WDYYJG-UI-020 | 权限 | 无 complete 按钮 | UI 测试 | Playwright+Chrome | §7 | 无 complete | 已预约行 | 无完成接诊 |
| ZCZX-WDYYJG-UI-018 | 端到端 | 登记+完成流程 | UI 集成 | Playwright+Chrome | §8.1 | 权限齐备 | 筛选已预约→完成接诊→查已完成 | 状态与按钮符合 §7 矩阵 |

---

## 四、覆盖对照

| 类别 | 单元 UT | 接口 API | 界面 UI |
| --- | --- | --- | --- |
| 正常流程（列表/详情/三态） | UT-003、008、009 | API-001～005、012～015、023～024 | UI-001～004、008～010、014、018 |
| 异常/校验 | UT-001～002 | API-006～007、017、029 | UI-005～006 |
| 完成接诊（唯一写操作） | UT-005、016～018 | API-023～023b、031～032 | UI-009、019～020 |
| 无确认/拒绝 | UT-005a | API-019～020 | UI-009a |
| 状态机（三态） | UT-003～004 | API-004～005、014 | UI-002、005、014 |
| 数据范围/三端隔离 | UT-006～008、011 | API-008～011、016 | UI-015、017 |
| 列表精简/详情完整 | UT-010 | API-012～013 | UI-001、010 |
| 无拒绝/无评价 | UT-010 | API-015、022 | UI-011～012 |
| 串单/非法状态 | UT-002、014 | API-007、030 | UI-005 |
| 权限/鉴权 | UT-012、013 | API-025～028 | UI-016 |
| 与兽医差异（不做接单） | UT-005 | API-019～021、028 | UI-009、017 |

---

## 五、功能需求追溯

| 需求章节 | 要点 | 主要用例 |
| --- | --- | --- |
| §6.1 列表 | 范围、筛选、分页、精简列 | API-001～012；UI-001～008 |
| §6.2 详情 | 只读、时段/地址/需求、无拒绝理由 | API-013～015；UI-010～011、013～014 |
| §4.1 三态 | 已预约/已取消/已完成 | UT-002～004；API-004～005；UI-002、005 |
| §4.3 不应出现待确认等 | 串单防护 | UT-014；API-007、030 |
| §5.2 不做 | 确认/拒绝/评价 | API-019～022；UI-009a、012 |
| §6.5 完成接诊 | 已预约→已完成 | UT-016～018；API-023～032；UI-009、019 |
| §7 权限矩阵 | 查看+完成接诊 | API-026～027、031；UI-009、016、020 |
| §2.2、§3.5 数据隔离 | 仅本机构；与兽医/专家隔离 | UT-008、011；API-008～009、016；UI-015、017 |
| §8.1 主流程 | 查阅+完成 | API-032；UI-018、019 |
| §9 提示 | 文案一致 | API-006、029；UI-005～006 |

---

## 六、Playwright 实施提示

- 安装：`npm i -D @playwright/test`；`npx playwright install chrome`。  
- 配置：`use: { channel: 'chrome', locale: 'zh-CN', baseURL: 'http://localhost:80' }`；`storageState` 复用机构账号 B 登录态。  
- 路由：`page.goto('/diseaseTreatment/myAppointment/org')`（以菜单 `component` 为准）。  
- 定位示例：`page.getByPlaceholder('请输入预约人')`；`page.getByRole('button', { name: '搜索' })`；`page.getByRole('button', { name: '查看' })`；`page.getByRole('button', { name: '完成接诊' })`；断言 `page.getByRole('button', { name: '确认接诊' })` **count=0**。  
- 数据准备：「畜牧医疗资源管理」为 O1（`resource_type=3`）分配账号 B；向 `biz_service_appointment` 插入 `provider_type=2`、`provider_id=O1.id`、`status∈{5,3,4}` 样本；另备 O2/V0/E1 用于隔离用例。

---

## 七、修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初版：单元 15、接口 30、UI 18；覆盖登记制三态只读、列表精简/详情完整、三端隔离、无确认拒绝评价、Playwright+Chrome |
| 1.1 | 增补完成接诊；修正 Base Path；权限含 `complete`；取消「只读」表述 |
