大屏 — 疫病风险统计 — 技术方案
依据:同目录 大屏疫病风险功能需求.md;数据源为《实验室检测技术方案》《疫情上报技术方案》《检疫站管理技术方案》《风险因子设置技术方案》既有表。本模块为大屏只读看板,无业务台账 CRUD;气象数据不由本模块提供。
1. 技术架构
| 项 |
说明 |
| 后端 |
RuoYi v3.9.2(springboot2 分支):JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| 数据库 |
MySQL 5.7.39,InnoDB,utf8mb4 |
| 前端 |
大屏独立页面;切换年份拉取看板主数据,疫情列表分页单独请求;气象由前端调公开接口 |
| 代码包 |
com.ruoyi.web.modules.screen(EpidemicRiskScreenController / IEpidemicRiskScreenService / vo / support) |
分层:Controller → IEpidemicRiskScreenService(口径编排、聚合)→ 扩展 Mapper / 复用既有 Service 只读查询。
| 场景 |
行为 |
进入 / 切换 statYear |
调用 §3.1(检测汇总、疫情统计、检疫态势、风险因子等) |
| 疫情列表翻页 |
仅调用 §3.2 |
| 数据权限 |
全县数据,不按部门/用户过滤 |
| 汇总口径 |
与功能需求 §2 一致;样本来源按 Y;实验室检测趋势为滚动 12 月、缺月补 0;解除时效为按疫病类型算术平均天数 |
| 检疫点 |
实时主数据快照(与统计年份无关) |
| 性能 |
默认实时聚合;可选 §2.3 缓存表 |
依赖表(只读)
| 表 |
用途 |
biz_lab_detection |
样本来源、年度/月度检测量与阳性、检出率 |
biz_epidemic_report |
风险等级、类型、途径、列表、地区去重、解除时效 |
biz_quarantine_station |
可用/停用检疫点数(del_flag=0) |
biz_risk_factor_weight |
五项权重(单行 id=1) |
2. 数据库设计
2.1 本模块业务表
无新增业务台账表。 DDL 以各业务模块 sql/*.sql 为准。
2.2 查询口径(按统计年份 Y)
实验室检测 biz_lab_detection
| 项 |
条件 / 说明 |
| 按年(样本来源) |
selectByTestYear(Y);test_date 在 Y 年内 |
| 滚动 12 月(趋势区) |
selectByTestDateBetween(rangeStart, rangeEnd);锚点 = HomeScreenSupport.currentYearMonth();窗口 [anchor−11 月 1 日, rollingWindowEnd] |
| 样本来源汇总 |
基于 Y 年记录 GROUP BY sample_source,SUM(test_quantity) |
| 趋势区合计 |
滚动窗口内 SUM(test_quantity)、SUM(positive_count) |
| 按月趋势 |
按 YEAR(test_date)+MONTH(test_date) 聚合;EpidemicRiskScreenSupport.buildLabDetection(rows, anchor) 补全 12 槽位,含 statYear、month |
sample_source:1 场地抽检 / 2 疫情上报送检 / 3 调运检疫 / 4 日常检测。
疫情上报 biz_epidemic_report
| 统计用途 |
SQL 条件要点 |
| 按上报日(饼图、列表、类型、途径等) |
report_date 在 Y 年内 |
| 防控中地区 |
report_date 在 Y 年内 AND release_date IS NULL |
| 已解除地区、解除时效 |
release_date IS NOT NULL AND release_date 在 Y 年内 |
| 未解除判定 |
release_date IS NULL |
| 地区去重 |
对 affected_location_track DISTINCT 计数(应用层亦可) |
枚举(入库值,展示名见功能需求 §2.6)
| 字段 |
值 |
含义 |
risk_level |
1 / 2 / 3 |
高危 / 中危 / 低危 |
epidemic_type |
1~4 |
病毒 / 细菌 / 寄生虫 / 其他 |
transmission_route |
1~4 |
调运 / 本地扩散 / 环境 / 其他未知 |
解除时效(平均天):对满足「已解除且解除日在 Y」的记录,DATEDIFF(release_date, report_date) 按 epidemic_type 分组后求 AVG(四类型固定返回,无记录时 avgDays=null)。
检疫站 biz_quarantine_station
| 项 |
条件 |
| 范围 |
del_flag = '0' |
| 可用检疫点 |
operate_status = 1(正常) |
| 停用检疫点 |
operate_status IN (2, 3)(停业、注销) |
不按 statYear 过滤;取当前库内快照。
风险因子 biz_risk_factor_weight
| 项 |
条件 |
| 读取 |
SELECT * FROM biz_risk_factor_weight WHERE id = 1 |
| 无记录 |
返回 hasRiskFactorConfig=false,前端走空态 |
2.3 可选表 biz_epidemic_risk_screen_cache(性能优化)
非本期必建。
| 字段 |
类型 |
说明 |
id |
bigint(20) |
主键 |
stat_year |
int(11) |
统计年份 |
payload_json |
mediumtext |
§3.1 响应 JSON(不含分页列表) |
expire_time |
datetime |
过期时间 |
create_time |
datetime |
写入时间 |
索引:UNIQUE uk_stat_year (stat_year)。TTL 建议 1~5 分钟。
2.4 索引建议(既有表)
| 表 |
建议 |
biz_lab_detection |
沿用 idx_test_date、idx_sample_source |
biz_epidemic_report |
沿用 idx_report_date、idx_release_date、idx_risk_level |
biz_quarantine_station |
沿用 idx_publish 等价 operate_status 索引(见检疫站 DDL) |
2.5 Mapper 扩展(建议)
| Mapper |
方法 |
说明 |
BizLabDetectionMapper |
selectByTestYear(int statYear) |
当年全部检测行(聚合在 Service) |
BizLabDetectionMapper |
selectDistinctTestYears() |
可选年份 |
BizEpidemicReportMapper |
selectByReportYear(int statYear) |
上报日在 Y 年内 |
BizEpidemicReportMapper |
selectRelievedByReleaseYear(int statYear) |
已解除且解除日在 Y |
BizEpidemicReportMapper |
selectActiveControlByReportYear(int statYear) |
上报日在 Y 且未解除 |
BizEpidemicReportMapper |
selectDistinctReportYears() |
可选年份 |
BizQuarantineStationMapper |
countByOperateStatus(int status) |
按运营状态计数 |
BizRiskFactorWeightMapper |
selectConfig() |
读 id=1(可复用既有查询) |
3. 接口设计
统一响应:AjaxResult(code / msg / data);疫情列表用 TableDataInfo(rows / total)。
权限标识(示例):bigScreen:epidemicRisk:query
Base Path:/bigScreen/epidemicRisk
| # |
说明 |
Method |
URI |
权限 |
| 3.1 |
看板主数据 |
GET |
/bigScreen/epidemicRisk/dashboard |
bigScreen:epidemicRisk:query |
| 3.2 |
疫情上报分页列表 |
GET |
/bigScreen/epidemicRisk/reports |
同上 |
前端:切换 statYear → 3.1 + 3.2(pageNum=1);仅翻页 → 3.2。
3.1 看板主数据
Query
| 参数 |
类型 |
必填 |
说明 |
statYear |
string |
Y |
四位年份;非法 → 业务异常(复用 AchievementReportValidation.parseStatYear 或同等校验) |
forceRefresh |
boolean |
N |
默认 false;true 跳过 §2.3 缓存 |
响应 data 结构(节选)
| 字段 |
说明 |
statYear |
回显 |
availableYears |
int[],检测年与上报年并集 + 当前年,降序 |
hasLabData |
该年是否存在 ≥1 条检测记录 |
hasEpidemicData |
该年按上报日是否存在 ≥1 条疫情上报 |
labDetection |
见 §3.1.1 |
sampleSourceStats |
见 §3.1.2 |
riskLevelStats |
风险等级饼图 §3.1.3 |
epidemicSituation |
检疫点 + 地区 §3.1.4 |
epidemicTypeStats |
疫病类型占比 |
transmissionRouteStats |
传播途径数量与占比 |
relieveDurationByType |
按类型平均解除天数 §3.1.5 |
riskFactorWeights |
五项权重 §3.1.6 |
3.1.1 labDetection
| 字段 |
说明 |
testQuantityTotal |
滚动 12 月窗口内检测量合计 |
positiveCountTotal |
滚动 12 月窗口内阳性合计 |
positiveRate |
检出率 0~1;testQuantityTotal=0 时为 null 或 0(与产品约定) |
monthly |
长度 12;滚动最近 12 月;每项含 statYear、month、testQuantity、positiveCount;缺月为 0 |
3.1.2 sampleSourceStats[]
| 字段 |
说明 |
sampleSource |
1~4 |
sampleSourceName |
中文名 |
testQuantity |
份 |
ratio |
占当年检测量合计,0~1 |
固定返回 4 项(无数据时 testQuantity=0、ratio=0)。
3.1.3 riskLevelStats[]
| 字段 |
说明 |
riskLevel |
1 / 2 / 3 |
riskLevelName |
高危 / 中危 / 低危 |
count |
条数 |
ratio |
占当年按上报日纳入总数 |
固定 3 项。
3.1.4 epidemicSituation
| 字段 |
说明 |
availableQuarantinePointCount |
正常运营检疫站数 |
disabledQuarantinePointCount |
停业+注销检疫站数 |
activeControlAreaCount |
防控中地区数(涉疫点位去重) |
releasedAreaCount |
已解除地区数(涉疫点位去重) |
3.1.5 relieveDurationByType[]
| 字段 |
说明 |
epidemicType |
1~4 |
epidemicTypeName |
中文名 |
avgRelieveDays |
平均解除天数;该类型无已解除记录时为 null |
recordCount |
参与平均的条数(可选,便于前端展示) |
3.1.6 riskFactorWeights
| 字段 |
说明 |
hasRiskFactorConfig |
是否存在 id=1 配置 |
items |
固定 5 项:factorCode、factorName、weight(decimal) |
factorCode 建议:breedingDensity、trafficMobility、quarantineIntensity、meteorologicalSuitability、pastDiseaseLevel。
3.2 疫情上报分页列表
Query
| 参数 |
类型 |
必填 |
说明 |
statYear |
string |
Y |
同 3.1 |
pageNum |
int |
N |
默认 1 |
pageSize |
int |
N |
默认 8 |
响应
TableDataInfo:rows 为 §3.2.1,total 为当年按上报日纳入的总条数。
不提供 GET /{id} 大屏详情接口。
3.2.1 rows[]
| 字段 |
说明 |
id |
主键 |
reportDate |
yyyy-MM-dd |
transmissionRoute / transmissionRouteName |
编码 + 展示名 |
epidemicType / epidemicTypeName |
编码 + 展示名 |
epidemicName |
疫病名称 |
riskLevel / riskLevelName |
编码 + 展示名 |
affectedLocationTrack |
涉疫点位/轨迹 |
relieveStatus |
0 未解除 / 1 已解除 |
releaseDate |
已解除时有值 |
默认排序:report_date DESC, create_time DESC, id DESC。
3.3 服务端逻辑(摘要)
1. year = parseStatYear(statYear)
2. labRows = selectByTestYear(year)
3. reportRows = selectByReportYear(year)
4. relievedRows = selectRelievedByReleaseYear(year)
5. activeRows = selectActiveControlByReportYear(year)
6. 组装 labDetection、sampleSourceStats(固定4类)
7. 组装 riskLevelStats(固定3类)、epidemicTypeStats、transmissionRouteStats
8. epidemicSituation = 检疫站 count + 地区 distinct(activeRows/relievedRows)
9. relieveDurationByType = AVG(DATEDIFF) GROUP BY epidemic_type(固定4类)
10. riskFactorWeights = selectConfig id=1
11. availableYears = union(distinct test years, distinct report years, current year)
12. return AjaxResult.success(vo)
枚举展示名:EpidemicRiskScreenSupport 集中维护 code→name,与功能需求 §2.6 一致。
4. 菜单与权限(示例)
| 类型 |
名称 |
权限标识 |
| 菜单 |
大屏疫病风险 |
bigScreen:epidemicRisk:query |
SQL 示例:sql/big_screen_epidemic_risk_perm.sql(挂载「大屏」父菜单下)。
5. 交付清单
6. 修订记录
| 版本 |
日期 |
说明 |
| 1.0 |
2026-05-25 |
初稿:无新表;双接口;对齐功能需求 v1.1(解除时效为平均天数);气象不在本模块 |