# 大屏 — 疫病风险统计 — 测试用例

> 依据：`大屏疫病风险功能需求.md`（v1.1）、`大屏疫病风险技术方案.md`  
> **接口 Base Path**：`/bigScreen/epidemicRisk`（含 `context-path`、网关前缀须补齐）。鉴权：若依 Cookie / `Authorization` Token；权限 `bigScreen:epidemicRisk:query`。

**通用前置（无特殊说明）**：已执行 `sql/biz_lab_detection.sql`、`sql/biz_epidemic_report.sql`、`sql/biz_quarantine_station.sql`、`sql/biz_risk_factor_weight.sql`；测试账号具备大屏查询权限。

**口径摘要**

| 域 | 规则 |
| --- | --- |
| 实验室检测 | `test_date` 落在统计年 **Y**；按月 12 刻度，缺月 **0** |
| 疫情（饼图/列表/类型/途径） | `report_date` 在 **Y** 年内 |
| 防控中地区 | `report_date` 在 **Y** 且 `release_date IS NULL`；`affected_location_track` **去重** |
| 已解除地区 / 解除时效 | `release_date` 在 **Y** 年内；时效 = **AVG**(解除日−上报日) 按 `epidemic_type` |
| 检疫点 | `del_flag=0`；正常=1；停用=2+3；**不按 Y** |
| 风险因子 | `biz_risk_factor_weight.id=1` 只读 |
| 气象 | **前端**公开接口；本模块接口不含气象 |

**UI 测试**：**Playwright** + **Chromium**，`playwright.config` 中 `use: { channel: 'chrome' }` 调用本机 **Google Chrome**。

---

## 测试数据样本

| 代号 | 说明 |
| --- | --- |
| **LAB-Y** | 统计年 **Y** 检测记录；如 `LAB-2026` 仅 `2026-03`、`2026-08` 各 1 条（检测量/阳性可不同） |
| **LAB-EMPTY** | 某年无任何检测 |
| **LAB-SRC** | 2026 四类 `sample_source` 各至少 1 条，检测量已知便于算占比 |
| **RPT-Y** | `report_date` 在 **Y** 的上报；含高/中/低危、四类型、四途径 |
| **RPT-EMPTY** | 某年按上报日无疫情 |
| **RPT-REL-Y** | `release_date` 在 **Y**；如类型 1 两条时效 10 天、20 天 → 平均 **15** 天 |
| **RPT-REL-OUT** | `report_date` 在 **Y** 外、`release_date` 在 **Y** 内（验证解除日口径） |
| **RPT-ACTIVE** | `report_date` 在 **Y**、`release_date` NULL |
| **AREA-DUP** | 两条防控中记录 `affected_location_track` 文案完全相同 |
| **AREA-DIFF** | 两条防控中涉疫点位文案不同 |
| **QN-MIX** | 检疫站：正常 2、停业 1、注销 1（`del_flag=0`） |
| **RF-OK** | `id=1` 五项权重已配置且合计为 1 |
| **RF-EMPTY** | 无 `id=1` 配置行 |

---

## 一、单元测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| DP-DYFX-UT-001 | 参数校验 | statYear 合法 | 单元测试 | JUnit5 | 年份解析 | 无 | 传入 `2026`、`2000` | 解析为整数通过 |
| DP-DYFX-UT-002 | 参数校验 | statYear 非法 | 单元测试 | JUnit5 | 异常入参 | 无 | 空、`26`、`abcd`、`1899` | 抛 `ServiceException` 或等价失败 |
| DP-DYFX-UT-003 | 检测聚合 | 按月缺月补 0 | 单元测试 | JUnit5 | §2.2、DYFX-03 | Mock `LAB-2026` 仅 3、8 月 | `buildLabMonthly(2026, rows)` | `monthly.length=12`；非 3/8 月 `testQuantity=0`、`positiveCount=0` |
| DP-DYFX-UT-004 | 检测聚合 | 年度检出率 | 单元测试 | JUnit5 | §2.7、DYFX-05 | 检测量 100、阳性 12 | `calcPositiveRate` | `positiveRate=0.12` |
| DP-DYFX-UT-005 | 检测聚合 | 检测量 0 检出率 | 单元测试 | JUnit5 | §2.7 | 有记录但 `testQuantity` 合计 0 | `calcPositiveRate` | `positiveRate=0` 或 `null`（与实现约定一致） |
| DP-DYFX-UT-006 | 样本来源 | 四类占比 | 单元测试 | JUnit5 | §5.2、DYFX-04 | `LAB-SRC` 四类量 10/20/30/40 | `buildSampleSourceStats` | 四项 `ratio` 为 0.1/0.2/0.3/0.4；`sum(ratio)≈1` |
| DP-DYFX-UT-007 | 样本来源 | 无检测空态标记 | 单元测试 | JUnit5 | §7.1 | `LAB-EMPTY` | `loadDashboard(2026)` | `hasLabData=false`；`labDetection=null` 或空态约定字段 |
| DP-DYFX-UT-008 | 风险等级 | 三类固定桶 | 单元测试 | JUnit5 | §5.4 | 高危 2、中危 1、低危 0 | `buildRiskLevelStats` | 3 项；`ratio` 和为 1（有数据时） |
| DP-DYFX-UT-009 | 疫情空态 | 无上报 | 单元测试 | JUnit5 | §7.1 | `RPT-EMPTY` | `buildRiskLevelStats` | `hasEpidemicData=false`；各 `count=0` 或整块空态 |
| DP-DYFX-UT-010 | 地区去重 | 防控中 | 单元测试 | JUnit5 | §2.5、DYFX-08 | `AREA-DUP` 2 条 + `AREA-DIFF` 1 条，均未解除 | `countActiveAreas` | `activeControlAreaCount=2` |
| DP-DYFX-UT-011 | 地区去重 | 已解除 | 单元测试 | JUnit5 | §2.5 | 同点位 2 条已解除且解除日在 Y | `countReleasedAreas` | `releasedAreaCount=1` |
| DP-DYFX-UT-012 | 解除时效 | 按类型算术平均 | 单元测试 | JUnit5 | §2.7、DYFX-10 | 类型 1：10 天、20 天；类型 2：无记录 | `buildRelieveDuration` | 类型 1 `avgRelieveDays=15`；类型 2 `null` |
| DP-DYFX-UT-013 | 解除时效 | 上报日不在 Y 仍计入 | 单元测试 | JUnit5 | §2.4 | `RPT-REL-OUT` 解除日在 2026 | `selectRelievedByReleaseYear(2026)` | 纳入平均；**不**纳入按上报日饼图 |
| DP-DYFX-UT-014 | 检疫点 | 状态计数 | 单元测试 | JUnit5 | §2.6、DYFX-07 | `QN-MIX` | `buildEpidemicSituation` | 可用=2；停用=2（停业+注销） |
| DP-DYFX-UT-015 | 检疫点 | 切年不变 | 单元测试 | JUnit5 | §5.5 | 固定 `QN-MIX` | `loadDashboard(2025)` 与 `2026` | 两响应 `availableQuarantinePointCount` 相同 |
| DP-DYFX-UT-016 | 风险因子 | 五项组装 | 单元测试 | JUnit5 | §5.10 | `RF-OK` | `buildRiskFactorWeights` | 5 项名称与权重与库一致；`hasRiskFactorConfig=true` |
| DP-DYFX-UT-017 | 风险因子 | 未配置 | 单元测试 | JUnit5 | §7.1 | `RF-EMPTY` | `buildRiskFactorWeights` | `hasRiskFactorConfig=false` |
| DP-DYFX-UT-018 | 可选年份 | 并集含当前年 | 单元测试 | JUnit5 | §2.1 | Mock 检测年 `[2025]`、上报年 `[]`；当前年 2026 | `buildAvailableYears` | 含 `2026`；降序 |
| DP-DYFX-UT-019 | 列表排序 | 上报日倒序 | 单元测试 | JUnit5 | §5.6 | 同日报两条 `create_time` 不同 | `sortReports` | 创建晚者在前 |
| DP-DYFX-UT-020 | 约束 | 只读无写 | 单元测试 | JUnit5 | §3.2 | 检查 ScreenService/Controller | 无 insert/update/delete/relieve | 仅查询组装 |
| DP-DYFX-UT-021 | 约束 | 无详情接口 | 单元测试 | JUnit5 | §5.6 | 检查 Controller 映射 | 无 `GET .../reports/{id}` | 仅 dashboard、reports |
| DP-DYFX-UT-022 | 缓存 | forceRefresh | 单元测试 | JUnit5 | 技术§2.3 | 启用缓存未过期 | `loadDashboard(2026,true)` | 跳过缓存重新聚合 |

---

## 二、接口测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| DP-DYFX-API-001 | 看板 | 满数据正常 | 接口测试 | Postman/curl | DYFX-01、正常流程 | 已登录；2026 检测+疫情+检疫+权重齐全 | `GET .../dashboard?statYear=2026` | `code` 成功；`hasLabData=true`；`hasEpidemicData=true`；`labDetection.monthly.length=12`；各 stats 有值 |
| DP-DYFX-API-002 | 看板 | 缺月补零 | 接口测试 | Postman | DYFX-03 | `LAB-2026` 仅 3、8 月 | `statYear=2026` | 缺月 `testQuantity=0`；`monthly` 共 12 条 |
| DP-DYFX-API-003 | 看板 | 年度检出率 | 接口测试 | Postman | DYFX-05 | 2026 检测量 100、阳性 12 | `GET dashboard` | `positiveRate=0.12`（或前端换算 12%） |
| DP-DYFX-API-004 | 看板 | 样本来源占比 | 接口测试 | Postman | DYFX-04 | `LAB-SRC` | `GET dashboard` | `sampleSourceStats.length=4`；`sum(ratio)≈1` |
| DP-DYFX-API-005 | 看板 | 风险等级占比 | 接口测试 | Postman | DYFX-06 | `RPT-Y` 已知条数 | `GET dashboard` | `riskLevelStats.length=3`；`sum(count)=` 当年上报总数；`sum(ratio)≈1` |
| DP-DYFX-API-006 | 看板 | 疫病类型/途径 | 接口测试 | Postman | §5.7、§5.9 | `RPT-Y` 四类型四途径 | `GET dashboard` | `epidemicTypeStats`、`transmissionRouteStats` 各 4 项；占比之和≈1 |
| DP-DYFX-API-007 | 看板 | 检疫点计数 | 接口测试 | Postman | DYFX-07 | `QN-MIX` | `GET dashboard` | `availableQuarantinePointCount=2`；`disabledQuarantinePointCount=2` |
| DP-DYFX-API-008 | 看板 | 防控/解除地区 | 接口测试 | Postman | DYFX-08 | `AREA-DUP`+`AREA-DIFF`+`RPT-REL-Y` | `GET dashboard` | `activeControlAreaCount`、`releasedAreaCount` 与手工去重一致 |
| DP-DYFX-API-009 | 看板 | 解除时效平均 | 接口测试 | Postman | DYFX-10 | 类型 1 两条 10、20 天 | `GET dashboard` | `relieveDurationByType` 中类型 1 `avgRelieveDays=15` |
| DP-DYFX-API-010 | 看板 | 解除日口径 | 接口测试 | Postman | §2.4 | `RPT-REL-OUT` | `GET dashboard` 2026 | 计入 `relieveDuration`/`releasedAreaCount`；**不**计入 `riskLevelStats` 分母（若上报日不在 2026） |
| DP-DYFX-API-011 | 看板 | 全年无检测 | 接口测试 | Postman | §7.1 | `LAB-EMPTY` 2026 | `GET dashboard` | `hasLabData=false`；`labDetection` 为 null 或空态约定 |
| DP-DYFX-API-012 | 看板 | 全年无疫情 | 接口测试 | Postman | §7.1 | `RPT-EMPTY` 2026 | `GET dashboard` | `hasEpidemicData=false`；饼图 stats 空态或 count 全 0 |
| DP-DYFX-API-013 | 看板 | 无已解除记录 | 接口测试 | Postman | §7.1 | 2026 有上报无解除 | `GET dashboard` | `relieveDurationByType` 各项 `avgRelieveDays=null` 或 `hasRelievedData=false` |
| DP-DYFX-API-014 | 看板 | 风险因子 | 接口测试 | Postman | DYFX-11 | `RF-OK` | `GET dashboard` | `riskFactorWeights` 五项与后台一致 |
| DP-DYFX-API-015 | 看板 | 未配置权重 | 接口测试 | Postman | §5.10 | `RF-EMPTY` | `GET dashboard` | `hasRiskFactorConfig=false` |
| DP-DYFX-API-016 | 看板 | 缺 statYear | 接口测试 | Postman | 异常 | 已登录 | 不传 `statYear` | 失败或默认当前年（与实现一致，文档须统一） |
| DP-DYFX-API-017 | 看板 | 非法 statYear | 接口测试 | Postman | 异常 | 已登录 | `statYear=abc` | 失败；`msg` 提示参数错误 |
| DP-DYFX-API-018 | 看板 | statYear 回显 | 接口测试 | Postman | 一致性 | 已登录 | `statYear=2025` | `data.statYear=2025` |
| DP-DYFX-API-019 | 看板 | availableYears | 接口测试 | Postman | §2.1 | 检测 2025、上报 2026 | `GET dashboard` | `availableYears` 含 2025、2026、当前年；降序 |
| DP-DYFX-API-020 | 看板 | 切年不串 | 接口测试 | Postman | DYFX-02 | 2025、2026 数据不同 | 分别 `statYear=2025/2026` | 各年 `monthly`/stats 互不混入 |
| DP-DYFX-API-021 | 看板 | 切年检疫点不变 | 接口测试 | Postman | §5.5 | `QN-MIX` | `statYear=2025` 与 `2026` | 检疫点两数字段相同 |
| DP-DYFX-API-022 | 看板 | forceRefresh | 接口测试 | Postman | 技术§2.3 | 已启用缓存 | `?statYear=2026&forceRefresh=true` | 成功；与库最新一致 |
| DP-DYFX-API-023 | 列表 | 分页首页 | 接口测试 | Postman | DYFX-09 | 2026 ≥9 条上报 | `GET .../reports?statYear=2026&pageNum=1&pageSize=8` | `rows.length≤8`；`total` 正确 |
| DP-DYFX-API-024 | 列表 | 第二页 | 接口测试 | Postman | 分页 | 同上 | `pageNum=2` | 与第一页 `id` 不重复；`reportDate` 倒序 |
| DP-DYFX-API-025 | 列表 | 行内字段 | 接口测试 | Postman | §5.6 | 含已解除、未解除各 1 条 | `GET reports` | 含 `reportDate`、途径/类型/名称/等级、轨迹、`relieveStatus`、`releaseDate` |
| DP-DYFX-API-026 | 列表 | 仅上报日在 Y | 接口测试 | Postman | §2.4 | 上报 2025、解除 2026 各 1 条 | `statYear=2026` reports | `total` 不含仅上报 2025 的记录 |
| DP-DYFX-API-027 | 列表 | 全年无上报 | 接口测试 | Postman | §7.1 | `RPT-EMPTY` | `GET reports` | `rows=[]`；`total=0` |
| DP-DYFX-API-028 | 列表 | 缺 statYear | 接口测试 | Postman | 异常 | 已登录 | 不传 `statYear` | 失败 |
| DP-DYFX-API-029 | 一致性 | 列表 total=饼图分母 | 接口测试 | Postman | §6 | 2026 `RPT-Y` 共 N 条 | `GET dashboard`+`reports` | `riskLevelStats` 各 `count` 之和 = `reports.total` |
| DP-DYFX-API-030 | 范围 | 无详情接口 | 接口测试 | Postman | §5.6 | 已登录 | `GET .../epidemicRisk/reports/1` | 404/405 |
| DP-DYFX-API-031 | 范围 | 无维护接口 | 接口测试 | Postman | §3.2 | 已登录 | `POST/PUT/DELETE .../epidemicRisk/**` | 404/405 或无权限 |
| DP-DYFX-API-032 | 联动 | 补录检测后 | 接口测试 | Postman | DYFX-12 | 2026 原 `LAB-EMPTY` | 后台新增检测→`GET dashboard` | `hasLabData=true`；样本来源/趋势更新 |
| DP-DYFX-API-033 | 联动 | 上报/解除后 | 接口测试 | Postman | DYFX-12 | 2026 原无防控中 | 后台新增上报→解除→`GET dashboard` | 地区数、时效、列表同步变化 |
| DP-DYFX-API-034 | 鉴权 | 未登录 | 接口测试 | curl | 安全 | 无 Token | `GET dashboard` | 401 或统一未登录 |
| DP-DYFX-API-035 | 权限 | 无大屏权限 | 接口测试 | Postman | 越权 | 无 `bigScreen:epidemicRisk:query` | `GET dashboard`、`GET reports` | 403 或无权限 |
| DP-DYFX-API-036 | 权限 | 有大屏无疫情写 | 接口测试 | Postman | 只读 | 仅有 query | `GET` 成功；`POST /diseaseDetection/epidemicReport` 依后台权限 | 大屏可读；台账写权限独立 |

---

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

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| DP-DYFX-UI-001 | 页面 | 默认当前年加载 | UI 测试 | Playwright+Chrome | DYFX-01 | 已登录有权限；有当前年数据 | 打开「大屏疫病风险」路由 | 年份为当前自然年；请求 `dashboard`+`reports`；各区块同年 |
| DP-DYFX-UI-002 | 筛选 | 切换年份整页刷新 | UI 测试 | Playwright+Chrome | DYFX-02 | 含 2025、2026 数据 | 年份 2025→2026 | 检测/疫情图表、卡片、列表同步更新；无旧年残留 |
| DP-DYFX-UI-003 | 筛选 | 加载中防残留 | UI 测试 | Playwright+Chrome | §7.3 | 已登录 | 切年（可 `route.fulfill` 延迟） | Loading/遮罩；完成后仅新年数据 |
| DP-DYFX-UI-004 | 气象 | 与业务解耦 | UI 测试 | Playwright+Chrome | DYFX-13、§5.1 | 已登录 | 进入页面；Mock 气象接口失败 | 气象区失败提示；检测/疫情区块仍展示（若 dashboard 成功） |
| DP-DYFX-UI-005 | 空态 | 全年无检测 | UI 测试 | Playwright+Chrome | §7.1 | 选 `LAB-EMPTY` 年 | 进入或切换该年 | 样本来源、实验室检测空态；**不**用全 0 冒充有业务 |
| DP-DYFX-UI-006 | 空态 | 全年无疫情 | UI 测试 | Playwright+Chrome | §7.1 | `RPT-EMPTY` 年 | 切换该年 | 风险等级/类型/途径/列表空态；**无**单级 100% 假象 |
| DP-DYFX-UI-007 | 空态 | 无已解除 | UI 测试 | Playwright+Chrome | §7.1 | 有上报无解除 | 查看解除时效图 | 空态文案；防控中区块仍可有数 |
| DP-DYFX-UI-008 | 检测 | 年度三指标 | UI 测试 | Playwright+Chrome | §5.3 | 2026 有检测 | 查看实验室检测区 | 检测量、阳性数、检出率 **%** 与 API 一致 |
| DP-DYFX-UI-009 | 图表 | 按月趋势 12 月 | UI 测试 | Playwright+Chrome | DYFX-03 | `LAB-2026` 缺月 | 查看折线/面积图+悬停 | 12 刻度；缺月为 0；Tooltip 含月份+两份数 |
| DP-DYFX-UI-010 | 图表 | 样本来源 | UI 测试 | Playwright+Chrome | DYFX-04 | `LAB-SRC` | 查看样本来源图 | 四类图例；占比之和 100%（有检测时） |
| DP-DYFX-UI-011 | 图表 | 风险等级饼图 | UI 测试 | Playwright+Chrome | DYFX-06 | `RPT-Y` | 查看疫病风险饼图 | 高/中/低危图例；占比之和 100% |
| DP-DYFX-UI-012 | 卡片 | 检疫点与地区 | UI 测试 | Playwright+Chrome | DYFX-07、DYFX-08 | `QN-MIX`+地区样本 | 查看疫病态势卡片 | 文案区分「检疫点」与「地区」；数字与 API 一致 |
| DP-DYFX-UI-013 | 卡片 | 切年检疫点不变 | UI 测试 | Playwright+Chrome | §5.5 | 固定检疫站数据 | 2025→2026 | 可用/停用检疫点数不变；地区数随年变 |
| DP-DYFX-UI-014 | 图表 | 疫病类型分布 | UI 测试 | Playwright+Chrome | §5.7 | 四类型均有 | 查看类型图 | 四类名称与 API 一致 |
| DP-DYFX-UI-015 | 图表 | 传播途径 | UI 测试 | Playwright+Chrome | §5.9 | 四途径均有 | 查看途径图 | 数量与占比与 API 一致 |
| DP-DYFX-UI-016 | 图表 | 解除时效平均 | UI 测试 | Playwright+Chrome | DYFX-10 | 类型 1 平均 15 天 | 查看柱状/条形图 | 纵轴为「天」；类型 1 柱高约 15（与 API 一致） |
| DP-DYFX-UI-017 | 风险因子 | 五项只读 | UI 测试 | Playwright+Chrome | DYFX-11 | `RF-OK` | 查看风险因子区 | 五项名称+权重；无保存/编辑按钮 |
| DP-DYFX-UI-018 | 风险因子 | 未配置空态 | UI 测试 | Playwright+Chrome | §5.10 | `RF-EMPTY` | 打开大屏 | 提示前往风险因子设置配置 |
| DP-DYFX-UI-019 | 列表 | 行内字段 | UI 测试 | Playwright+Chrome | §5.6 | 含解除/未解除 | 查看疫情列表 | 日期、途径、类型、名称、等级、轨迹、状态、解除日可见 |
| DP-DYFX-UI-020 | 列表 | 无详情跳转 | UI 测试 | Playwright+Chrome | §5.6 | 列表有数据 | 点击行/名称（若有） | **不**跳转后台详情路由 |
| DP-DYFX-UI-021 | 列表 | 分页翻页 | UI 测试 | Playwright+Chrome | DYFX-09 | ≥9 条；pageSize=8 | 点下一页 | 仅 `reports` 请求；看板区不重复请求 |
| DP-DYFX-UI-022 | 只读 | 无维护按钮 | UI 测试 | Playwright+Chrome | §3.2 | 已登录 | 扫描页面 | 无新增/修改/解除/删除疫情或检测 |
| DP-DYFX-UI-023 | 错误 | 业务接口失败重试 | UI 测试 | Playwright+Chrome | §7.3 | Mock `dashboard` 500 | 进入或切年 | 失败提示+重试；不长期显示上年数据 |
| DP-DYFX-UI-024 | 联动 | 后台补录后刷新 | UI 集成 | Playwright+Chrome | DYFX-12 | 2026 原空 | 后台补检测/上报→F5 或重进 | 对应区块出现新数据 |
| DP-DYFX-UI-025 | 权限 | 无菜单不可进 | UI 测试 | Playwright+Chrome | 安全 | 无大屏菜单账号 | 登录查侧栏/直链 | 无入口或 403 |
| DP-DYFX-UI-026 | 端到端 | 按年查阅全流程 | UI 集成 | Playwright+Chrome | §4、DYFX-01～12 | 2026 完整样本 | 登录→进大屏→默认年→切年→悬停图表→翻页 | 十区块（除气象源）正确；无控制台报错 |
| DP-DYFX-UI-027 | 刷新 | 手动/轮播刷新 | UI 测试 | Playwright+Chrome | §7.4 | 已打开；后台改数据 | 点刷新或等待 1～5 分钟 | 展示更新为最新 |

---

## Playwright 实施提示

```javascript
// playwright.config.ts 片段
use: { channel: 'chrome', headless: false }

// 登录后 storageState
await page.goto('/#/bigScreen/epidemicRisk/index'); // 以实际路由为准

// 切年：监听双请求
await Promise.all([
  page.waitForResponse('**/bigScreen/epidemicRisk/dashboard**'),
  page.waitForResponse('**/bigScreen/epidemicRisk/reports**'),
  yearPicker.selectOption('2026'),
]);

// 空态（按页面文案调整）
await expect(page.getByText(/暂无.*检测|本年度暂无实验室检测/)).toBeVisible();

// 列表翻页仅 reports
await page.getByRole('button', { name: '下一页' }).click();
await page.waitForResponse('**/bigScreen/epidemicRisk/reports**');

// 气象 Mock 失败（UI-004）
await page.route('**/weather/**', route => route.fulfill({ status: 500 }));
```

---

## 覆盖对照

| 类别 | 单元 UT | 接口 API | 界面 UI |
| --- | --- | --- | --- |
| 正常流程 | UT-003～006、008、012、016 | API-001～010、014、023～025 | UI-001～002、008～017、019、021、026 |
| 异常流程 | UT-002、005、007、009、017 | API-011～013、016～017、027～028、034～035 | UI-005～007、023、025 |
| 业务约束 | UT-010～015、020～021 | API-004～009、020～021、029～031、036 | UI-004～007、012～013、020、022、024 |

---

## 功能需求追溯（DYFX / 章节）

| 追溯 | 要点 | 主要用例 |
| --- | --- | --- |
| DYFX-01 | 默认当前年 | UI-001；API-001 |
| DYFX-02 | 切年一致 | API-020；UI-002～003 |
| DYFX-03 | 缺月=0、12 月 | UT-003；API-002；UI-009 |
| DYFX-04 | 样本来源占比 | UT-006；API-004；UI-010 |
| DYFX-05 | 年度检出率 | UT-004～005；API-003；UI-008 |
| DYFX-06 | 风险等级饼图 | UT-008；API-005；UI-011 |
| DYFX-07 | 检疫点 | UT-014；API-007、021；UI-012～013 |
| DYFX-08 | 地区去重 | UT-010～011；API-008；UI-012 |
| DYFX-09 | 列表分页 | API-023～025；UI-019、021 |
| DYFX-10 | 解除时效平均 | UT-012～013；API-009～010；UI-016 |
| DYFX-11 | 风险因子 | UT-016～017；API-014～015；UI-017～018 |
| DYFX-12 | 后台刷新 | API-032～033；UI-024、027 |
| DYFX-13 | 气象前端 | UI-004 |
| §2.4 | 上报日/解除日 | UT-013；API-010、026 |
| §2.5 | 地区口径 | UT-010～011 |
| §3.2 | 只读 | UT-020～021；API-031、036；UI-022 |
| §5.6 | 无详情 | UT-021；API-030；UI-020 |
| §7.1 | 空态 | UT-007、009；API-011～013；UI-005～007 |

---

## 修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初版：单元 22、接口 36、UI 27；覆盖 DYFX-01～13 与正常/异常/约束；Playwright+Chrome；Base `/bigScreen/epidemicRisk` |
