diff --git a/employee-app/weight-management/doc/screenshots/height-scale-report.jpg b/employee-app/weight-management/doc/screenshots/height-scale-report.jpg
index eee7251..01ff0e7 100644
Binary files a/employee-app/weight-management/doc/screenshots/height-scale-report.jpg and b/employee-app/weight-management/doc/screenshots/height-scale-report.jpg differ
diff --git a/employee-app/weight-management/height-scale-report.html b/employee-app/weight-management/height-scale-report.html
index 1af758a..14935c5 100644
--- a/employee-app/weight-management/height-scale-report.html
+++ b/employee-app/weight-management/height-scale-report.html
@@ -87,7 +87,7 @@ function goBack() {
}
/* ========================================================================
- * 身高秤报告数据
+ * 体重秤报告数据
* 字段名沿用统一后的命名:脂肪率→体脂率、脂肪量→体脂肪
* ======================================================================== */
var report = {
@@ -183,7 +183,7 @@ var changeText = (report.weightChange < 0 ? '' : '+') + fmtVal(report.weightChan
document.getElementById('reportHeader').innerHTML =
'' +
'
' +
'' +
diff --git a/index.html b/index.html
index cc6ebe9..3e9af86 100644
--- a/index.html
+++ b/index.html
@@ -255,6 +255,7 @@ const SITE_MAP = [
{ file:'post-unit-count.html', label:'单位体检人数统计' },
{ file:'post-unit-cost-stat.html', label:'单位体检费用统计' },
{ file:'post-unit-item-stat.html', label:'单位体检项目统计' },
+ { file:'post-result-comprehensive-stat.html', label:'结果动态综合统计' },
{ file:'post-hospital-count.html', label:'医院体检人数统计' },
{ file:'post-doctor-count.html', label:'医生检查人数统计' },
{ file:'post-item-stat.html', label:'医院体检项目统计' },
@@ -707,7 +708,7 @@ const SITE_MAP = [
{ file:'weight-detail-v2.html', label:'体重明细' },
{ file:'report-detail.html', label:'测量报告详情' },
{ file:'body-fat-report.html', label:'体脂报告' },
- { file:'height-scale-report.html', label:'身高测量报告' },
+ { file:'height-scale-report.html', label:'体重秤报告' },
{ file:'diet-advice-v2.html', label:'膳食建议' },
{ file:'exercise-advice-v2.html', label:'运动建议' },
{ file:'weight-record-detail-v2.html', label:'体重记录明细' },
diff --git a/web-admin/health-checkup/doc/CHANGELOG.md b/web-admin/health-checkup/doc/CHANGELOG.md
index 63a4e04..f2e8372 100644
--- a/web-admin/health-checkup/doc/CHANGELOG.md
+++ b/web-admin/health-checkup/doc/CHANGELOG.md
@@ -1,5 +1,15 @@
# 健康体检模块 CHANGELOG
+## [Unreleased] 2026-09-20
+
+### Added
+- 检后「体检统计汇总」分组新增「结果动态综合统计」页面 `post-result-comprehensive-stat.html`:以 2×2 网格展示 4 张堆积柱状图,统计维度固定为性别/年龄/部门/岗位,每张图自带「项目」「维度」下拉可独立切换,查看该维度各取值下的正常/异常人数及占比——竖向堆积柱状图(X 轴为维度取值、Y 轴为人数,每柱正常在下绿/异常在上红堆叠,柱顶标总数、段内标百分比、悬停显示明细);纯手写 SVG,无第三方图表库;体检项目下拉 12 项数据驱动,异常判定按年龄/性别/岗位浮动、哈希保证结果稳定;4 个面板互相独立,默认项目均为血常规、维度分别为性别/年龄/部门/岗位
+- 23 个检后页面侧边栏「体检统计汇总」分组批量同步新增「结果动态综合统计」菜单项(紧邻「单位体检项目统计」之后)
+- `index.html` SITE_MAP 健康体检模块新增「结果动态综合统计」入口(紧邻「单位体检项目统计」之后)
+- `PRD.md`:补全缺失的「单位体检项目统计(post-unit-item-stat.html)」文档,新增「结果动态综合统计」导航节点/页面清单条目/逐页说明(52、53 节),页面清单与逐页说明 52 节及之后编号整体顺延 +2(原 52–68 → 54–70)
+- `PRD.md` 按实际页面补全 6 个此前未入册的页面文档并配截图——检中「体检预约跟踪(mid-appointment-track2.html,4 页签贯穿应检→已选→已预约→已参检)」、检后常规体检「单位群体报告(post-group-report.html,10 张概览卡含较上年趋势 + 6 个报告卡片)」、检后新增「体检影像管理」分组 4 页(用户体检信息/用户影像文件分类/用户影像文件详细/文件处理日志);导航树新增「体检影像管理」分组节点,页面清单与逐页说明编号顺延(33–45 → 34–46、46–67 → 48–69、68–70 → 74–76,新增 33/47/70–73 六节)
+- `screenshot-prd.js` TASKS 新增 6 页并重拍截图 `mid-appointment-track2 / post-group-report / post-imc-user / post-imc-class / post-imc-info / post-imc-log`
+
## [Unreleased] 2026-09-18
### Added
diff --git a/web-admin/health-checkup/doc/PRD.md b/web-admin/health-checkup/doc/PRD.md
index 0050398..830ba1c 100644
--- a/web-admin/health-checkup/doc/PRD.md
+++ b/web-admin/health-checkup/doc/PRD.md
@@ -13,6 +13,7 @@
│ ├── 基础配置 → config-material-notice.html
│ ├── 检前 → pre-hospital-scope.html
│ ├── 检中 → mid-appointment-track.html
+│ │ ├── 体检预约跟踪 → mid-appointment-track2.html
│ ├── 检后 → post-unit-count.html
│ ├── 前置机管理 → agent-device.html
│ └── 异常事件 → exception-dirty.html
@@ -93,6 +94,7 @@
├── 检后(侧边栏)
│ ├── 常规体检
│ │ ├── 常规体检报告 → post-report-employee.html
+│ │ ├── 单位群体报告 → post-group-report.html
│ │ ├── 员工体检大表 → post-employee-master.html
│ │ ├── 大病人员信息 → post-illness-personnel.html
│ │ ├── 指标异常通知 → post-indicator-notify.html
@@ -102,6 +104,8 @@
│ │ │ └── Tab:二级单位 / 三级单位 / 体检医院
│ │ ├── 单位体检费用统计 → post-unit-cost-stat.html
│ │ │ └── Tab:二级单位 / 三级单位
+│ │ ├── 单位体检项目统计 → post-unit-item-stat.html
+│ │ ├── 结果动态综合统计 → post-result-comprehensive-stat.html
│ │ ├── 医院体检人数统计 → post-hospital-count.html
│ │ ├── 医生检查人数统计 → post-doctor-count.html
│ │ ├── 医院体检项目统计 → post-item-stat.html
@@ -117,10 +121,15 @@
│ │ ├── 胃肠镜体检报告 → post-report-gastro.html
│ │ └── 胃肠镜体检统计 → post-gastro-stat.html
│ │ └── Tab:二级单位 / 三级单位
-│ └── 冠脉CTA体检
+│ ├── 冠脉CTA体检
│ ├── 冠脉CTA体检报告 → post-cta-report.html
│ └── 冠脉CTA体检统计 → post-cta-stat.html
│ └── Tab:二级单位 / 三级单位
+│ └── 体检影像管理
+│ ├── 用户体检信息 → post-imc-user.html
+│ ├── 用户影像文件分类 → post-imc-class.html
+│ ├── 用户影像文件详细 → post-imc-info.html
+│ └── 文件处理日志 → post-imc-log.html
│
├── 前置机管理(侧边栏)
│ └── 常规体检前置服务 → agent-device.html
@@ -196,57 +205,65 @@
| 序号 | 页面/弹窗 | 文件 | 类型 |
|------|-----------|------|------|
| 32 | 体检预约 | mid-appointment-track.html | 页面 |
-| 33 | 已选项目 | mid-selected-items.html | 页面 |
-| 34 | 已检员工 | mid-participation.html | 页面 |
-| 35 | 单位预约人数统计 | mid-unit-appointment.html | 页面 |
-| 36 | 医院实时预约人数 | mid-hospital-realtime.html | 页面 |
-| 37 | 医生实时检查情况 | mid-doctor-realtime.html | 页面 |
-| 38 | 医院预约人数统计 | mid-hospital-appointment.html | 页面 |
-| 39 | 签约单位应检人数 | mid-unit-expected.html | 页面 |
-| 40 | 员工预约跟踪(胃肠镜) | mid-gastro-appointment-track.html | 页面 |
-| 41 | 单位预约统计(胃肠镜) | mid-gastro-unit-appointment.html | 页面 |
-| 42 | 胃肠镜问卷信息 | mid-gastro-questionnaire.html | 页面 |
-| 43 | 员工预约跟踪(冠脉CTA) | mid-cta-appointment-track.html | 页面 |
-| 44 | 单位预约统计(冠脉CTA) | mid-cta-unit-appointment.html | 页面 |
+| 33 | 体检预约跟踪 | mid-appointment-track2.html | 页面 |
+| 34 | 已选项目 | mid-selected-items.html | 页面 |
+| 35 | 已检员工 | mid-participation.html | 页面 |
+| 36 | 单位预约人数统计 | mid-unit-appointment.html | 页面 |
+| 37 | 医院实时预约人数 | mid-hospital-realtime.html | 页面 |
+| 38 | 医生实时检查情况 | mid-doctor-realtime.html | 页面 |
+| 39 | 医院预约人数统计 | mid-hospital-appointment.html | 页面 |
+| 40 | 签约单位应检人数 | mid-unit-expected.html | 页面 |
+| 41 | 员工预约跟踪(胃肠镜) | mid-gastro-appointment-track.html | 页面 |
+| 42 | 单位预约统计(胃肠镜) | mid-gastro-unit-appointment.html | 页面 |
+| 43 | 胃肠镜问卷信息 | mid-gastro-questionnaire.html | 页面 |
+| 44 | 员工预约跟踪(冠脉CTA) | mid-cta-appointment-track.html | 页面 |
+| 45 | 单位预约统计(冠脉CTA) | mid-cta-unit-appointment.html | 页面 |
### 五、检后(侧边栏:检后)
| 序号 | 页面/弹窗 | 文件 | 类型 |
|------|-----------|------|------|
-| 45 | 常规体检报告 | post-report-employee.html | 页面 |
-| 46 | 员工体检大表 | post-employee-master.html | 页面 |
-| 47 | 大病人员信息 | post-illness-personnel.html | 页面 |
-| 48 | 指标异常通知 | post-indicator-notify.html | 页面 |
-| 49 | 体检报告未匹配项目 | post-report-unmatched.html | 页面 |
-| 50 | 单位体检人数统计 | post-unit-count.html | 页面 |
-| 51 | 单位体检费用统计 | post-unit-cost-stat.html | 页面 |
-| 52 | 医院体检人数统计 | post-hospital-count.html | 页面 |
-| 53 | 医生检查人数统计 | post-doctor-count.html | 页面 |
-| 54 | 医院体检项目统计 | post-item-stat.html | 页面 |
-| 55 | 防癌筛查人数统计 | post-cancer-screening.html | 页面 |
-| 56 | 系统标准化项目统计 | post-standard-stat.html | 页面 |
-| 57 | 签约医院人数统计 | post-contracted-hospital.html | 页面 |
-| 58 | 重点指标异常统计 | post-key-indicator-stat.html | 页面 |
-| 59 | 病种信息配置 | post-disease-info.html | 页面 |
-| 60 | 体检结论关联病种 | post-conclusion-disease.html | 页面 |
-| 61 | 员工病种信息 | post-auto-select-disease.html | 页面 |
-| 62 | 胃肠镜体检报告 | post-report-gastro.html | 页面 |
-| 63 | 胃肠镜体检统计 | post-gastro-stat.html | 页面 |
-| 64 | 冠脉CTA体检报告 | post-cta-report.html | 页面 |
-| 65 | 冠脉CTA体检统计 | post-cta-stat.html | 页面 |
+| 46 | 常规体检报告 | post-report-employee.html | 页面 |
+| 47 | 单位群体报告 | post-group-report.html | 页面 |
+| 48 | 员工体检大表 | post-employee-master.html | 页面 |
+| 49 | 大病人员信息 | post-illness-personnel.html | 页面 |
+| 50 | 指标异常通知 | post-indicator-notify.html | 页面 |
+| 51 | 体检报告未匹配项目 | post-report-unmatched.html | 页面 |
+| 52 | 单位体检人数统计 | post-unit-count.html | 页面 |
+| 53 | 单位体检费用统计 | post-unit-cost-stat.html | 页面 |
+| 54 | 单位体检项目统计 | post-unit-item-stat.html | 页面 |
+| 55 | 结果动态综合统计 | post-result-comprehensive-stat.html | 页面 |
+| 56 | 医院体检人数统计 | post-hospital-count.html | 页面 |
+| 57 | 医生检查人数统计 | post-doctor-count.html | 页面 |
+| 58 | 医院体检项目统计 | post-item-stat.html | 页面 |
+| 59 | 防癌筛查人数统计 | post-cancer-screening.html | 页面 |
+| 60 | 系统标准化项目统计 | post-standard-stat.html | 页面 |
+| 61 | 签约医院人数统计 | post-contracted-hospital.html | 页面 |
+| 62 | 重点指标异常统计 | post-key-indicator-stat.html | 页面 |
+| 63 | 病种信息配置 | post-disease-info.html | 页面 |
+| 64 | 体检结论关联病种 | post-conclusion-disease.html | 页面 |
+| 65 | 员工病种信息 | post-auto-select-disease.html | 页面 |
+| 66 | 胃肠镜体检报告 | post-report-gastro.html | 页面 |
+| 67 | 胃肠镜体检统计 | post-gastro-stat.html | 页面 |
+| 68 | 冠脉CTA体检报告 | post-cta-report.html | 页面 |
+| 69 | 冠脉CTA体检统计 | post-cta-stat.html | 页面 |
+| 70 | 用户体检信息 | post-imc-user.html | 页面 |
+| 71 | 用户影像文件分类 | post-imc-class.html | 页面 |
+| 72 | 用户影像文件详细 | post-imc-info.html | 页面 |
+| 73 | 文件处理日志 | post-imc-log.html | 页面 |
### 六、前置机管理(侧边栏:前置机管理)
| 序号 | 页面/弹窗 | 文件 | 类型 |
|------|-----------|------|------|
-| 66 | 常规体检前置服务(含设备详情/编辑设备/日志查看/升级管理/接口测试/操作审计/重启确认弹窗) | agent-device.html | 页面 |
+| 74 | 常规体检前置服务(含设备详情/编辑设备/日志查看/升级管理/接口测试/操作审计/重启确认弹窗) | agent-device.html | 页面 |
### 七、异常事件(侧边栏:异常事件)
| 序号 | 页面/弹窗 | 文件 | 类型 |
|------|-----------|------|------|
-| 67 | 系统脏数据 | exception-dirty.html | 页面 |
-| 68 | 结果异常 | exception-result.html | 页面 |
+| 75 | 系统脏数据 | exception-dirty.html | 页面 |
+| 76 | 结果异常 | exception-result.html | 页面 |
---
@@ -978,7 +995,27 @@
---
-#### 33. 已选项目(mid-selected-items.html)
+#### 33. 体检预约跟踪(mid-appointment-track2.html)
+
+
+
+**功能说明:** 以 4 个页签纵向贯穿「应检 → 已选项目 → 已预约 → 已参检」的完整预约跟踪流程,支持批量状态流转与逐项置检/弃检。
+
+**Tab 切换:** 所有员工 / 已选项目员工 / 已预约员工 / 已参检员工
+
+**筛选条件:** 体检年份(年份选择控件,默认当年)、单位部门、医院选择、姓名、员工编号、身份证号,另有性别/年龄范围/机构分类/是否上市员工/防癌项/体检状态/预约状态/前置机预约状态(仅所有员工页签);已参检页签额外含体检编码、系统体检状态、医院体检状态、体检日期起止;各页签均带查询/重置
+
+**操作按钮:** 所有员工——导出列表数据、查看导出任务、同步医院体检预约信息;已选项目员工——导出列表/项目/预约数据、查看导出任务;已预约员工——置为已体检、置为未体检、取消预约、导出列表/项目/预约数据、查看导出任务;已参检员工——导出项目状态、导出体检指引单、查看导出任务
+
+**表格列(按页签):** 所有员工单级表头(姓名/员工编号/性别/年龄/身份证号/单位/部门/机构分类/体检编码/用工形式/婚姻状态/防癌项/是否上市员工/预约状态/前置机预约状态/预约日期/体检状态/体检日期/体检年份/体检计划/操作);已选项目员工两级表头(体检明细费用下分必检/选检/妇科/防癌筛查费用 4 子列,另含体检项目数/体检总费用/提交项目日期等);已预约员工单级表头(含体检编码/预约日期);已参检员工单级表头(含系统体检状态/医院体检状态/已检项/全部)
+
+**详情弹窗(4 个页签各 1 个):** 所有员工「预约跟踪详情」(基本信息 + 预约与体检信息);已选项目员工(信息卡 + 已选项目列表含费用合计);已预约/已参检员工(信息卡 + 3 个 Tab:员工体检表信息/已体检项目/未体检项目,支持逐项置为已检/未检/弃检)
+
+**业务规则:** 状态彩色标签(未预约橙/已预约绿/已取消红/未体检橙/体检中与已体检蓝);前置机预约状态独立枚举(未预约/预约成功/已取消预约/预约失败/预约中/取消预约失败);已预约页签批量置为已体检/未体检/取消预约需先勾选行;已参检员工区分系统体检状态与医院体检状态双口径。
+
+---
+
+#### 34. 已选项目(mid-selected-items.html)

@@ -1000,7 +1037,7 @@
---
-#### 34. 已检员工(mid-participation.html)
+#### 35. 已检员工(mid-participation.html)

@@ -1020,7 +1057,7 @@
---
-#### 35. 单位预约人数统计(mid-unit-appointment.html)
+#### 36. 单位预约人数统计(mid-unit-appointment.html)

@@ -1036,7 +1073,7 @@
---
-#### 36. 医院实时预约人数(mid-hospital-realtime.html)
+#### 37. 医院实时预约人数(mid-hospital-realtime.html)

@@ -1050,7 +1087,7 @@
---
-#### 37. 医生实时检查情况(mid-doctor-realtime.html)
+#### 38. 医生实时检查情况(mid-doctor-realtime.html)

@@ -1064,7 +1101,7 @@
---
-#### 38. 医院预约人数统计(mid-hospital-appointment.html)
+#### 39. 医院预约人数统计(mid-hospital-appointment.html)

@@ -1078,7 +1115,7 @@
---
-#### 39. 签约单位应检人数(mid-unit-expected.html)
+#### 40. 签约单位应检人数(mid-unit-expected.html)

@@ -1094,7 +1131,7 @@
### 胃肠镜体检
-#### 40. 员工预约跟踪(胃肠镜)(mid-gastro-appointment-track.html)
+#### 41. 员工预约跟踪(胃肠镜)(mid-gastro-appointment-track.html)

@@ -1114,7 +1151,7 @@
---
-#### 41. 单位预约统计(胃肠镜)(mid-gastro-unit-appointment.html)
+#### 42. 单位预约统计(胃肠镜)(mid-gastro-unit-appointment.html)

@@ -1130,7 +1167,7 @@
---
-#### 42. 胃肠镜问卷信息(mid-gastro-questionnaire.html)
+#### 43. 胃肠镜问卷信息(mid-gastro-questionnaire.html)

@@ -1148,7 +1185,7 @@
### 冠脉CTA体检
-#### 43. 员工预约跟踪(冠脉CTA)(mid-cta-appointment-track.html)
+#### 44. 员工预约跟踪(冠脉CTA)(mid-cta-appointment-track.html)

@@ -1157,7 +1194,7 @@
---
-#### 44. 单位预约统计(冠脉CTA)(mid-cta-unit-appointment.html)
+#### 45. 单位预约统计(冠脉CTA)(mid-cta-unit-appointment.html)

@@ -1170,7 +1207,7 @@
### 常规体检
-#### 45. 常规体检报告(post-report-employee.html)
+#### 46. 常规体检报告(post-report-employee.html)

@@ -1190,7 +1227,25 @@
---
-#### 46. 员工体检大表(post-employee-master.html)
+#### 47. 单位群体报告(post-group-report.html)
+
+
+
+**功能说明:** 选定某单位与体检年份后,以概览指标卡 + 图表 + 表格呈现该单位群体体检的受检/检出/异常/疾病/专项筛查情况,并支持导出 CSV。
+
+**筛选条件:** 体检年份(年份选择控件,默认当年)、单位(左侧列表,含单位名称模糊搜索)
+
+**操作按钮:** 导出群体报告(导出 CSV)
+
+**概览指标卡(5 列 × 2 行共 10 张):** 应检人数、已检人数、受检率(绿)、检出率(橙)、异常人数(红)、重点指标异常(红)、复查率、数据完整率、平均年龄、未见异常(绿);每张卡下方带「较上年」趋势标注(率类 ±X.Xpp、人数/年龄类整数 + 单位,按指标方向判定绿 good/红 bad/灰 flat)
+
+**报告卡片(6 个):** ① 近三年趋势(受检率/检出率双折线图);② 异常率 × 年龄/性别(表:年龄区间/男性异常率/女性异常率/合计异常率/异常人数,含合计行);③ 异常指标排名(横向条形,按检出人数降序,top1 红/top2 橙/top3 绿、其余蓝,附上年对照与趋势);④ 重点指标异常拆解(表:重点指标/异常人数/检出率/较上年,5 项:血压/血脂/空腹血糖/高尿酸/超重 BMI);⑤ 疾病(病种)分布(按 8 类病种分组归类,表列:病种/人数/占比/较上年);⑥ 专项筛查结果(防癌筛查 Septin9、CA724、冠脉 CTA、胃肠镜 4 项,阳性/异常率 + 已筛人数 + 较上年)
+
+**业务规则:** 受检率 = 已检 ÷ 应检、检出率 = 异常 ÷ 已检,各率保留 1 位小数、除数为 0 显示 0.0%;同单位同一年数据恒定(确定性伪随机);报告头元信息含体检年份/承检医院/体检计划起止/同比基准上一年。
+
+---
+
+#### 48. 员工体检大表(post-employee-master.html)

@@ -1211,7 +1266,7 @@
---
-#### 47. 大病人员信息(post-illness-personnel.html)
+#### 49. 大病人员信息(post-illness-personnel.html)

@@ -1235,7 +1290,7 @@
---
-#### 48. 指标异常通知(post-indicator-notify.html)
+#### 50. 指标异常通知(post-indicator-notify.html)

@@ -1251,7 +1306,7 @@
---
-#### 49. 体检报告未匹配项目(post-report-unmatched.html)
+#### 51. 体检报告未匹配项目(post-report-unmatched.html)

@@ -1267,7 +1322,7 @@
### 体检统计汇总
-#### 50. 单位体检人数统计(post-unit-count.html)
+#### 52. 单位体检人数统计(post-unit-count.html)

@@ -1291,7 +1346,7 @@
---
-#### 51. 单位体检费用统计(post-unit-cost-stat.html)
+#### 53. 单位体检费用统计(post-unit-cost-stat.html)

@@ -1317,7 +1372,39 @@
---
-#### 52. 医院体检人数统计(post-hospital-count.html)
+#### 54. 单位体检项目统计(post-unit-item-stat.html)
+
+
+
+**功能说明:** 按"单位 × 体检医院 × 体检项目"维度统计各体检项目的已选/已检/异常人数及患病率,人数列可点击下钻查看对应人员明细。
+
+**筛选条件:** 体检年份(年份日历选择控件,默认当年)、单位(下拉)、医院(下拉)、项目名称(输入)、项目编码(输入)
+
+**操作按钮:** 导出列表数据、查看导出任务
+
+**表格列:** 序号、单位、体检医院、体检项目名称、项目编码、已选人数、已检人数、异常人数、患病率
+
+**业务规则:** 患病率 = 异常人数 ÷ 已检人数,患病率 ≥10% 标红;已选/已检/异常三列数字为蓝色链接,点击打开对应口径人员列表弹窗(列:序号、姓名、员工编号、部门、体检医院、体检日期、体检状态/体检结果/异常结果)。
+
+---
+
+#### 55. 结果动态综合统计(post-result-comprehensive-stat.html)
+
+
+
+**功能说明:** 以 2×2 网格展示 4 张堆积柱状图,统计维度固定为性别/年龄/部门/岗位;每张图自带「项目」「维度」两个下拉,可独立切换体检项目与统计维度,查看该维度各取值下的正常/异常人数及占比。
+
+**筛选条件:** 体检年份(年份日历选择控件,默认当年)、单位(下拉,默认第一采油厂)
+
+**图表面板:** 每个面板顶部为标题 + 项目下拉(12 项)+ 维度下拉(性别/年龄/部门/岗位)+ 正常/异常图例,下方为竖向堆积柱状图。
+
+**图表展示:** 竖向堆积柱状图——X 轴为所选维度取值(性别→男/女、年龄→各年龄段、部门→各部门、岗位→各岗位),Y 轴为人数;每根柱子正常在下(绿)/异常在上(红)堆叠,柱顶标总数、段内标百分比,悬停显示明细。
+
+**业务规则:** 4 个面板互相独立,默认项目均为血常规、维度分别为性别/年龄/部门/岗位;异常率 = 异常人数 ÷ 受检人数;维度取值(性别男/女、年龄 5 档、部门 6 个、岗位 6 个)。
+
+---
+
+#### 56. 医院体检人数统计(post-hospital-count.html)

@@ -1331,7 +1418,7 @@
---
-#### 53. 医生检查人数统计(post-doctor-count.html)
+#### 57. 医生检查人数统计(post-doctor-count.html)

@@ -1345,7 +1432,7 @@
---
-#### 54. 医院体检项目统计(post-item-stat.html)
+#### 58. 医院体检项目统计(post-item-stat.html)

@@ -1359,7 +1446,7 @@
---
-#### 55. 防癌筛查人数统计(post-cancer-screening.html)
+#### 59. 防癌筛查人数统计(post-cancer-screening.html)

@@ -1373,7 +1460,7 @@
---
-#### 56. 系统标准化项目统计(post-standard-stat.html)
+#### 60. 系统标准化项目统计(post-standard-stat.html)

@@ -1387,7 +1474,7 @@
---
-#### 57. 签约医院人数统计(post-contracted-hospital.html)
+#### 61. 签约医院人数统计(post-contracted-hospital.html)

@@ -1401,7 +1488,7 @@
---
-#### 58. 重点指标异常统计(post-key-indicator-stat.html)
+#### 62. 重点指标异常统计(post-key-indicator-stat.html)

@@ -1421,7 +1508,7 @@
### 病种信息管理
-#### 59. 病种信息配置(post-disease-info.html)
+#### 63. 病种信息配置(post-disease-info.html)

@@ -1441,7 +1528,7 @@
---
-#### 60. 体检结论关联病种(post-conclusion-disease.html)
+#### 64. 体检结论关联病种(post-conclusion-disease.html)

@@ -1461,7 +1548,7 @@
---
-#### 61. 员工病种信息(post-auto-select-disease.html)
+#### 65. 员工病种信息(post-auto-select-disease.html)

@@ -1484,7 +1571,7 @@
### 胃肠镜体检
-#### 62. 胃肠镜体检报告(post-report-gastro.html)
+#### 66. 胃肠镜体检报告(post-report-gastro.html)

@@ -1519,7 +1606,7 @@
---
-#### 63. 胃肠镜体检统计(post-gastro-stat.html)
+#### 67. 胃肠镜体检统计(post-gastro-stat.html)

@@ -1542,7 +1629,7 @@
### 冠脉CTA体检
-#### 64. 冠脉CTA体检报告(post-cta-report.html)
+#### 68. 冠脉CTA体检报告(post-cta-report.html)

@@ -1572,7 +1659,7 @@
---
-#### 65. 冠脉CTA体检统计(post-cta-stat.html)
+#### 69. 冠脉CTA体检统计(post-cta-stat.html)

@@ -1582,9 +1669,85 @@
---
+### 体检影像管理
+
+#### 70. 用户体检信息(post-imc-user.html)
+
+
+
+**功能说明:** 以「人」为维度聚合展示用户体检影像信息,行内可展开查看该人各项检查项目的影像与报告处理情况。
+
+**筛选条件:** 姓名、身份证号、体检年份(年份选择控件,默认当年)、医院名称
+
+**操作按钮:** 批量删除
+
+**表格列:** 复选框、序号、展开箭头列、单位信息、姓名、身份证号、体检年份、医院名称、体检编号、创建日期、操作(删除)
+
+**展开子表列:** 序号、检查项目名称、处理状态、影像信息、影像报告;影像信息列渲染「预览」链接(无数据显示「暂无」)、影像报告列渲染「查看」链接(无数据显示「无文件」)、子表无数据显示「暂无检查项目数据」
+
+**业务规则:** 姓名/身份证号/医院名称为模糊匹配、体检年份精确匹配;分页 10/20/50 条/页;删除/批量删除带确认。
+
+---
+
+#### 71. 用户影像文件分类(post-imc-class.html)
+
+
+
+**功能说明:** 按「检查项目」维度展示影像文件与报告文件的类型分类、处理状态与结果。
+
+**筛选条件:** 影像分类(超声/CT/MRI/X射线/心电)、检查项目名称、处理状态
+
+**操作按钮:** 批量删除
+
+**表格列:** 复选框、序号、影像分类、检查项目名称、影像文件类型、报告文件类型、处理状态、检查结果、错误信息、出报告时间、创建日期、操作(详情 + 删除)
+
+**详情弹窗:** 标题「用户影像文件分类详情」,字段:用户体检信息ID、影像分类、检查项目名称、影像文件类型、报告文件类型、处理状态、检查结果、错误信息、出报告时间、创建日期
+
+**业务规则:** 检查结果/错误信息超 18 字符截断并悬停显示全文、空值显示「—」;影像文件类型 dcm/非DICOM、报告文件类型 pdf/png/jpg。
+
+---
+
+#### 72. 用户影像文件详细(post-imc-info.html)
+
+
+
+**功能说明:** 文件级别的影像/报告明细,展示单个文件的存储地址、DICOM 实例与研究/患者标识。
+
+**筛选条件:** 文件类型(影像/报告)、患者ID、研究实例ID
+
+**操作按钮:** 批量删除
+
+**表格列:** 复选框、序号、文件类型(影像蓝标签/报告紫标签)、影像序号、错误信息、文件地址(下载链接)、dcm实例ID、研究实例ID、患者ID、研究ID、创建日期、操作(详情 + 删除)
+
+**详情弹窗:** 标题「用户影像文件详细」,字段:用户影像文件分类ID、文件类型、影像序号、错误信息、文件地址、dcm实例ID、研究实例ID、患者ID、研究ID、创建日期
+
+**业务规则:** 错误信息超 18 字符截断并悬停全文;患者ID/dcm实例ID/错误信息可为空(空显示「—」,报告的 dcm实例ID 恒为空)。
+
+---
+
+#### 73. 文件处理日志(post-imc-log.html)
+
+
+
+**功能说明:** 展示影像压缩包的传输、解析全过程日志(时间线 + 状态 + 原始 json)。
+
+**筛选条件:** 身份证号、体检年份(年份选择控件)、体检编号、影像分类(超声/CT/MRI/X射线/心电)、处理状态
+
+**操作按钮:** 批量删除
+
+**表格列:** 复选框、序号、医院名称、姓名、身份证号、体检年份、体检编号、影像分类、json数据、文件地址(下载链接)、文件大小(MB)、处理状态、错误信息、传输开始时间、传输完成时间、解析开始时间、解析完成时间、操作(详情 + 删除)
+
+**详情弹窗:** 标题「文件处理日志详情」,字段含医院名称/姓名/身份证号/体检年份/体检编号/影像分类/json 数据(代码块展示)/文件地址/文件大小(MB)/处理状态/错误信息/传输开始/传输完成/解析开始/解析完成时间
+
+**业务规则:** json 数据超 24 字符截断为等宽字体并悬停全文、详情弹窗内 json 代码块可滚动;错误信息超 18 字符截断;空时间显示「—」;示例数据按传输开始时间倒序。
+
+**数据字典(四页通用):** 处理状态 1 新建(蓝)/2 待解析(灰)/3 失败(红)/4 解析中(橙)/5 成功(绿)/6 失败待重试(橙)/7 最终失败(红)。
+
+---
+
## 六、前置机管理
-### 66. 常规体检前置服务(agent-device.html)
+### 74. 常规体检前置服务(agent-device.html)

@@ -1625,7 +1788,7 @@
## 七、异常事件
-### 67. 系统脏数据(exception-dirty.html)
+### 75. 系统脏数据(exception-dirty.html)

@@ -1643,7 +1806,7 @@
---
-### 68. 结果异常(exception-result.html)
+### 76. 结果异常(exception-result.html)

diff --git a/web-admin/health-checkup/doc/screenshot-prd.js b/web-admin/health-checkup/doc/screenshot-prd.js
index 176cb5c..0058667 100644
--- a/web-admin/health-checkup/doc/screenshot-prd.js
+++ b/web-admin/health-checkup/doc/screenshot-prd.js
@@ -55,6 +55,7 @@ const TASKS = [
{ page: 'pre-special-cta.html', output: 'pre-special-cta.jpg' },
// 四、检中 · 常规体检
{ page: 'mid-appointment-track.html', output: 'mid-appointment-track.jpg' },
+ { page: 'mid-appointment-track2.html', output: 'mid-appointment-track2.jpg' },
{ page: 'mid-selected-items.html', output: 'mid-selected-items.jpg' },
{ page: 'mid-participation.html', output: 'mid-participation.jpg' },
{ page: 'mid-unit-appointment.html', output: 'mid-unit-appointment.jpg' },
@@ -71,6 +72,7 @@ const TASKS = [
{ page: 'mid-cta-unit-appointment.html', output: 'mid-cta-unit-appointment.jpg' },
// 五、检后 · 常规体检
{ page: 'post-report-employee.html', output: 'post-report-employee.jpg' },
+ { page: 'post-group-report.html', output: 'post-group-report.jpg' },
{ page: 'post-employee-master.html', output: 'post-employee-master.jpg' },
{ page: 'post-illness-personnel.html', output: 'post-illness-personnel.jpg' },
{ page: 'post-indicator-notify.html', output: 'post-indicator-notify.jpg' },
@@ -78,6 +80,8 @@ const TASKS = [
// 五、检后 · 体检统计汇总
{ page: 'post-unit-count.html', output: 'post-unit-count.jpg' },
{ page: 'post-unit-cost-stat.html', output: 'post-unit-cost-stat.jpg' },
+ { page: 'post-unit-item-stat.html', output: 'post-unit-item-stat.jpg' },
+ { page: 'post-result-comprehensive-stat.html', output: 'post-result-comprehensive-stat.jpg' },
{ page: 'post-hospital-count.html', output: 'post-hospital-count.jpg' },
{ page: 'post-doctor-count.html', output: 'post-doctor-count.jpg' },
{ page: 'post-item-stat.html', output: 'post-item-stat.jpg' },
@@ -95,6 +99,11 @@ const TASKS = [
// 五、检后 · 冠脉CTA体检
{ page: 'post-cta-report.html', output: 'post-cta-report.jpg' },
{ page: 'post-cta-stat.html', output: 'post-cta-stat.jpg' },
+ // 五、检后 · 体检影像管理
+ { page: 'post-imc-user.html', output: 'post-imc-user.jpg' },
+ { page: 'post-imc-class.html', output: 'post-imc-class.jpg' },
+ { page: 'post-imc-info.html', output: 'post-imc-info.jpg' },
+ { page: 'post-imc-log.html', output: 'post-imc-log.jpg' },
// 六、异常事件
{ page: 'exception-dirty.html', output: 'exception-dirty.jpg' },
{ page: 'exception-result.html', output: 'exception-result.jpg' },
diff --git a/web-admin/health-checkup/doc/screenshots/mid-appointment-track2.jpg b/web-admin/health-checkup/doc/screenshots/mid-appointment-track2.jpg
new file mode 100644
index 0000000..e528ab2
Binary files /dev/null and b/web-admin/health-checkup/doc/screenshots/mid-appointment-track2.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-cancer-screening.jpg b/web-admin/health-checkup/doc/screenshots/post-cancer-screening.jpg
index 6a6f782..8baef47 100644
Binary files a/web-admin/health-checkup/doc/screenshots/post-cancer-screening.jpg and b/web-admin/health-checkup/doc/screenshots/post-cancer-screening.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-contracted-hospital.jpg b/web-admin/health-checkup/doc/screenshots/post-contracted-hospital.jpg
index a811a4b..a78b72f 100644
Binary files a/web-admin/health-checkup/doc/screenshots/post-contracted-hospital.jpg and b/web-admin/health-checkup/doc/screenshots/post-contracted-hospital.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-doctor-count.jpg b/web-admin/health-checkup/doc/screenshots/post-doctor-count.jpg
index db1bdf5..825c742 100644
Binary files a/web-admin/health-checkup/doc/screenshots/post-doctor-count.jpg and b/web-admin/health-checkup/doc/screenshots/post-doctor-count.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-group-report.jpg b/web-admin/health-checkup/doc/screenshots/post-group-report.jpg
new file mode 100644
index 0000000..e55677b
Binary files /dev/null and b/web-admin/health-checkup/doc/screenshots/post-group-report.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-hospital-count.jpg b/web-admin/health-checkup/doc/screenshots/post-hospital-count.jpg
index 0a52df1..61efa80 100644
Binary files a/web-admin/health-checkup/doc/screenshots/post-hospital-count.jpg and b/web-admin/health-checkup/doc/screenshots/post-hospital-count.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-imc-class.jpg b/web-admin/health-checkup/doc/screenshots/post-imc-class.jpg
new file mode 100644
index 0000000..72e2189
Binary files /dev/null and b/web-admin/health-checkup/doc/screenshots/post-imc-class.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-imc-info.jpg b/web-admin/health-checkup/doc/screenshots/post-imc-info.jpg
new file mode 100644
index 0000000..8ecdee5
Binary files /dev/null and b/web-admin/health-checkup/doc/screenshots/post-imc-info.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-imc-log.jpg b/web-admin/health-checkup/doc/screenshots/post-imc-log.jpg
new file mode 100644
index 0000000..14c89da
Binary files /dev/null and b/web-admin/health-checkup/doc/screenshots/post-imc-log.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-imc-user.jpg b/web-admin/health-checkup/doc/screenshots/post-imc-user.jpg
new file mode 100644
index 0000000..8bdd7bd
Binary files /dev/null and b/web-admin/health-checkup/doc/screenshots/post-imc-user.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-item-stat.jpg b/web-admin/health-checkup/doc/screenshots/post-item-stat.jpg
index 89f52a7..efe48e7 100644
Binary files a/web-admin/health-checkup/doc/screenshots/post-item-stat.jpg and b/web-admin/health-checkup/doc/screenshots/post-item-stat.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-key-indicator-stat.jpg b/web-admin/health-checkup/doc/screenshots/post-key-indicator-stat.jpg
index ac64f66..9324a84 100644
Binary files a/web-admin/health-checkup/doc/screenshots/post-key-indicator-stat.jpg and b/web-admin/health-checkup/doc/screenshots/post-key-indicator-stat.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-result-comprehensive-stat.jpg b/web-admin/health-checkup/doc/screenshots/post-result-comprehensive-stat.jpg
new file mode 100644
index 0000000..0815db0
Binary files /dev/null and b/web-admin/health-checkup/doc/screenshots/post-result-comprehensive-stat.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-standard-stat.jpg b/web-admin/health-checkup/doc/screenshots/post-standard-stat.jpg
index 44eb61d..2e06f77 100644
Binary files a/web-admin/health-checkup/doc/screenshots/post-standard-stat.jpg and b/web-admin/health-checkup/doc/screenshots/post-standard-stat.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-unit-cost-stat.jpg b/web-admin/health-checkup/doc/screenshots/post-unit-cost-stat.jpg
index 7d5dd1d..11efca9 100644
Binary files a/web-admin/health-checkup/doc/screenshots/post-unit-cost-stat.jpg and b/web-admin/health-checkup/doc/screenshots/post-unit-cost-stat.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-unit-count.jpg b/web-admin/health-checkup/doc/screenshots/post-unit-count.jpg
index 3746f18..87756ae 100644
Binary files a/web-admin/health-checkup/doc/screenshots/post-unit-count.jpg and b/web-admin/health-checkup/doc/screenshots/post-unit-count.jpg differ
diff --git a/web-admin/health-checkup/doc/screenshots/post-unit-item-stat.jpg b/web-admin/health-checkup/doc/screenshots/post-unit-item-stat.jpg
new file mode 100644
index 0000000..daf5b48
Binary files /dev/null and b/web-admin/health-checkup/doc/screenshots/post-unit-item-stat.jpg differ
diff --git a/web-admin/health-checkup/post-auto-select-disease.html b/web-admin/health-checkup/post-auto-select-disease.html
index 1d3ca0d..bf02d1b 100644
--- a/web-admin/health-checkup/post-auto-select-disease.html
+++ b/web-admin/health-checkup/post-auto-select-disease.html
@@ -158,6 +158,7 @@
+
diff --git a/web-admin/health-checkup/post-cancer-screening.html b/web-admin/health-checkup/post-cancer-screening.html
index d6a38da..8c4cde9 100644
--- a/web-admin/health-checkup/post-cancer-screening.html
+++ b/web-admin/health-checkup/post-cancer-screening.html
@@ -142,6 +142,7 @@
+
diff --git a/web-admin/health-checkup/post-conclusion-disease.html b/web-admin/health-checkup/post-conclusion-disease.html
index 0802946..fc63a11 100644
--- a/web-admin/health-checkup/post-conclusion-disease.html
+++ b/web-admin/health-checkup/post-conclusion-disease.html
@@ -168,6 +168,7 @@
+
diff --git a/web-admin/health-checkup/post-contracted-hospital.html b/web-admin/health-checkup/post-contracted-hospital.html
index abacd70..d6d5669 100644
--- a/web-admin/health-checkup/post-contracted-hospital.html
+++ b/web-admin/health-checkup/post-contracted-hospital.html
@@ -132,6 +132,7 @@
+
diff --git a/web-admin/health-checkup/post-cta-report.html b/web-admin/health-checkup/post-cta-report.html
index 701fb6c..f1391b5 100644
--- a/web-admin/health-checkup/post-cta-report.html
+++ b/web-admin/health-checkup/post-cta-report.html
@@ -199,6 +199,7 @@
+
diff --git a/web-admin/health-checkup/post-cta-stat.html b/web-admin/health-checkup/post-cta-stat.html
index 1f168d7..f3c6130 100644
--- a/web-admin/health-checkup/post-cta-stat.html
+++ b/web-admin/health-checkup/post-cta-stat.html
@@ -158,6 +158,7 @@
+
diff --git a/web-admin/health-checkup/post-disease-info.html b/web-admin/health-checkup/post-disease-info.html
index a52dafb..164e01e 100644
--- a/web-admin/health-checkup/post-disease-info.html
+++ b/web-admin/health-checkup/post-disease-info.html
@@ -166,6 +166,7 @@
+
diff --git a/web-admin/health-checkup/post-doctor-count.html b/web-admin/health-checkup/post-doctor-count.html
index 3b7b450..3a73bf9 100644
--- a/web-admin/health-checkup/post-doctor-count.html
+++ b/web-admin/health-checkup/post-doctor-count.html
@@ -142,6 +142,7 @@
+
diff --git a/web-admin/health-checkup/post-employee-master.html b/web-admin/health-checkup/post-employee-master.html
index 4905aa4..bba21e1 100644
--- a/web-admin/health-checkup/post-employee-master.html
+++ b/web-admin/health-checkup/post-employee-master.html
@@ -158,6 +158,7 @@
+
diff --git a/web-admin/health-checkup/post-gastro-stat.html b/web-admin/health-checkup/post-gastro-stat.html
index 790cc3d..f690f51 100644
--- a/web-admin/health-checkup/post-gastro-stat.html
+++ b/web-admin/health-checkup/post-gastro-stat.html
@@ -158,6 +158,7 @@
+
diff --git a/web-admin/health-checkup/post-group-report.html b/web-admin/health-checkup/post-group-report.html
index dc5d451..cf06dee 100644
--- a/web-admin/health-checkup/post-group-report.html
+++ b/web-admin/health-checkup/post-group-report.html
@@ -90,7 +90,7 @@
.report-head__meta{display:flex;align-items:center;gap:24px;margin-top:10px;font-size:var(--font-sm);color:var(--text-secondary);flex-wrap:wrap;}
.report-head__meta b{color:var(--text-primary);font-weight:500;}
/* 概览指标卡 */
- .overview-cards{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin-bottom:16px;}
+ .overview-cards{display:grid;grid-template-columns:repeat(5,1fr);gap:12px;margin-bottom:16px;}
.ov-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:18px 12px;text-align:center;}
.ov-card__value{font-size:var(--font-xxl);font-weight:600;color:var(--text-primary);line-height:1.2;}
.ov-card__value--primary{color:var(--primary);}
@@ -98,6 +98,10 @@
.ov-card__value--warning{color:var(--warning);}
.ov-card__value--danger{color:var(--danger);}
.ov-card__label{font-size:var(--font-xs);color:var(--text-placeholder);margin-top:8px;}
+ .ov-card__trend{font-size:var(--font-xs);color:var(--text-placeholder);margin-top:6px;font-variant-numeric:tabular-nums;}
+ .trend-good{color:var(--success);}
+ .trend-bad{color:var(--danger);}
+ .trend-flat{color:var(--text-placeholder);}
/* 报告卡片 */
.report-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);margin-bottom:16px;overflow:hidden;}
.report-card__header{padding:14px 20px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:8px;}
@@ -123,8 +127,9 @@
.bar-row__fill.top1{background:linear-gradient(90deg,#FF9C6E,#FF4D4F);}
.bar-row__fill.top2{background:linear-gradient(90deg,#FFD591,#FAAD14);}
.bar-row__fill.top3{background:linear-gradient(90deg,#95DE64,#52C41A);}
- .bar-row__val{width:140px;flex-shrink:0;font-size:var(--font-sm);color:var(--text-secondary);font-variant-numeric:tabular-nums;}
+ .bar-row__val{width:210px;flex-shrink:0;font-size:var(--font-sm);color:var(--text-secondary);font-variant-numeric:tabular-nums;}
.bar-row__val b{color:var(--text-primary);font-weight:600;}
+ .bar-row__delta{font-size:var(--font-xs);color:var(--text-placeholder);margin-top:2px;}
/* 专项筛查卡片项 */
.screen-item{display:flex;align-items:center;padding:13px 0;border-bottom:1px solid #F0F0F0;}
.screen-item:first-child{padding-top:0;}
@@ -132,7 +137,11 @@
.screen-item__name{width:180px;flex-shrink:0;font-size:var(--font-sm);color:var(--text-primary);}
.screen-item__val{font-size:var(--font-base);font-weight:600;color:var(--danger);margin-right:6px;font-variant-numeric:tabular-nums;}
.screen-item__unit{font-size:var(--font-sm);color:var(--text-secondary);}
- .screen-item__rate{margin-left:auto;font-size:var(--font-sm);color:var(--text-placeholder);font-variant-numeric:tabular-nums;}
+ .screen-item__rate{margin-left:auto;font-size:var(--font-sm);color:var(--text-placeholder);font-variant-numeric:tabular-nums;text-align:right;}
+ .screen-item__rate .sub{font-size:var(--font-xs);margin-top:3px;}
+ /* 趋势图例 */
+ .trend-legend{display:flex;gap:18px;font-size:var(--font-xs);color:var(--text-secondary);margin-bottom:10px;}
+ .trend-legend i{display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:5px;vertical-align:-1px;}
@@ -185,6 +194,7 @@
+
@@ -274,6 +284,8 @@
/* 确定性伪随机(0-1),保证同一单位每次打开数据一致 */
function pseudo(i){var x=Math.sin(i*127.1)*43758.5453;return x-Math.floor(x);}
function fmt(n){return String(n).replace(/\B(?=(\d{3})+(?!\d))/g,',');}
+function pct(a,b){return b?((a/b)*100).toFixed(1)+'%':'0.0%';}
+function pct1(n){return (n==null?'0.0':n.toFixed(1))+'%';}
var UNITS=['公司机关','第一采油厂','第二采油厂','第三采油厂','第八采油厂','第九采油厂','第十一采油厂','采气一厂','水电厂','公用事业公司','运输公司','伴生气综合利用项目部','质量安全环保技术监督中心'];
var HOSPITALS=['宝石花医院','延安医院','西安高新医院','长安心血管医院','宁夏宝石花','CQ总医院'];
@@ -282,6 +294,8 @@ var HOSPITALS=['宝石花医院','延安医院','西安高新医院','长安心
var AGE_BANDS=['35岁以下','35岁至44岁','45岁及以上'];
/* 异常指标排名(名称 / 排名着色 class) */
var INDICATORS=['血脂异常','血压升高','超重(肥胖)','高尿酸','脂肪肝','空腹血糖升高','甲状腺结节','肺部结节','肝功能异常','心电图异常'];
+/* 重点指标(管理层关注的核心指标,逐项拆解) */
+var KEY_INDICATORS=['血压异常','血脂异常','空腹血糖升高','高尿酸','超重(BMI)'];
/* 疾病(病种)分布,按病种类别分组 */
var DISEASE_CATS=[
{name:'血液及动脉病种',items:['高脂血','高血压','痛风(高尿酸)','动脉斑块']},
@@ -296,24 +310,55 @@ var DISEASE_CATS=[
var state={unitIdx:0, year:'2026', keyword:''};
-/* 某单位某年的群体基础数据(确定性生成) */
+/* 某单位某年的群体基础数据(确定性生成,显式传单位/年份) */
function yearSeed(idx,year){return idx*13.7+parseInt(year,10)*5.3;}
-function unitData(idx){
- var s=yearSeed(idx,state.year);
+function unitData(idx,year){
+ var s=yearSeed(idx,year);
var total=500+Math.floor(pseudo(s+1.3)*7500); // 应检人数 500~8000
var examined=Math.round(total*(0.75+pseudo(s+2.1)*0.20)); // 已检人数
var abnormal=Math.round(examined*(0.22+pseudo(s+3.7)*0.38)); // 异常人数
var keyAbn=Math.round(abnormal*(0.25+pseudo(s+4.9)*0.30)); // 重点指标异常人数
- var cancerPos=Math.round(total*(0.008+pseudo(s+5.3)*0.022)); // 防癌筛查阳性人数
- var ctaAbn=Math.round(examined*(0.012+pseudo(s+6.1)*0.038)); // 冠脉CTA异常人数
+ var healthy=examined-abnormal; // 未见异常人数
+ var recheckAdvised=Math.round(abnormal*(0.55+pseudo(s+12.3)*0.25));// 建议复查人数
+ var recheckDone=Math.round(recheckAdvised*(0.60+pseudo(s+13.1)*0.30)); // 已完成复查人数
+ var completeCnt=Math.round(examined*(0.90+pseudo(s+14.7)*0.09)); // 数据完整人数
+ var avgAge=34+Math.round(pseudo(s+15.2)*16); // 平均年龄 34~50
+ var cancerScreened=Math.round(examined*(0.55+pseudo(s+16.1)*0.30));// 防癌筛查已筛人数
+ var cancerPos=Math.round(cancerScreened*(0.05+pseudo(s+16.7)*0.09)); // Septin9 阳性
+ var ca724Pos=Math.round(cancerScreened*(0.04+pseudo(s+17.3)*0.08)); // CA724 阳性
+ var ctaScreened=Math.round(examined*(0.20+pseudo(s+18.1)*0.25)); // 冠脉CTA已检人数
+ var ctaAbn=Math.round(ctaScreened*(0.08+pseudo(s+18.9)*0.14)); // 冠脉CTA异常人数
+ var gastroScreened=Math.round(examined*(0.18+pseudo(s+20.5)*0.22)); // 胃肠镜已检人数
+ var gastroAbn=Math.round(gastroScreened*(0.10+pseudo(s+21.1)*0.20));// 胃肠镜异常人数
return {
- name:UNITS[idx], total:total, examined:examined, abnormal:abnormal, keyAbn:keyAbn,
- cancerPos:cancerPos, ctaAbn:ctaAbn, hospital:HOSPITALS[idx%HOSPITALS.length]
+ name:UNITS[idx], total:total, examined:examined, abnormal:abnormal, keyAbn:keyAbn, healthy:healthy,
+ recheckAdvised:recheckAdvised, recheckDone:recheckDone, completeCnt:completeCnt, avgAge:avgAge,
+ cancerScreened:cancerScreened, cancerPos:cancerPos, ca724Pos:ca724Pos,
+ ctaScreened:ctaScreened, ctaAbn:ctaAbn, gastroScreened:gastroScreened, gastroAbn:gastroAbn,
+ hospital:HOSPITALS[idx%HOSPITALS.length]
+ };
+}
+/* 汇总数值统计(含各类率,用于同比对比) */
+function computeStats(idx,year){
+ var d=unitData(idx,year);
+ var ag=ageGender(idx,year);
+ var male=ag.reduce(function(a,r){return a+r.male;},0);
+ var female=ag.reduce(function(a,r){return a+r.female;},0);
+ return {
+ total:d.total, examined:d.examined, attendRate:d.examined/d.total*100,
+ abnormal:d.abnormal, detectRate:d.abnormal/d.examined*100, keyAbn:d.keyAbn, healthy:d.healthy,
+ recheckAdvised:d.recheckAdvised, recheckDone:d.recheckDone,
+ recheckRate:d.recheckAdvised?d.recheckDone/d.recheckAdvised*100:0,
+ completeCnt:d.completeCnt, completeRate:d.examined?d.completeCnt/d.examined*100:0,
+ avgAge:d.avgAge, male:male, female:female,
+ cancerScreened:d.cancerScreened, cancerPos:d.cancerPos, ca724Pos:d.ca724Pos,
+ ctaScreened:d.ctaScreened, ctaAbn:d.ctaAbn, gastroScreened:d.gastroScreened, gastroAbn:d.gastroAbn
};
}
/* 年龄×性别分布 */
-function ageGender(d){
- var s=yearSeed(state.unitIdx,state.year);
+function ageGender(idx,year){
+ var d=unitData(idx,year);
+ var s=yearSeed(idx,year);
var a35=Math.round(d.examined*(0.26+pseudo(s+7.7)*0.10));
var a44=Math.round(d.examined*(0.32+pseudo(s+8.3)*0.08));
var a45=d.examined-a35-a44;
@@ -325,8 +370,9 @@ function ageGender(d){
];
}
/* 异常指标排名(人数近似递减) */
-function indicatorRank(d){
- var s=yearSeed(state.unitIdx,state.year);
+function indicatorRank(idx,year){
+ var d=unitData(idx,year);
+ var s=yearSeed(idx,year);
var list=INDICATORS.map(function(name,ki){
var share=(0.05+pseudo(s+ki*2.9)*0.16)*(INDICATORS.length-ki)/INDICATORS.length;
return {name:name, cnt:Math.max(3,Math.round(d.examined*share))};
@@ -334,9 +380,41 @@ function indicatorRank(d){
list.sort(function(a,b){return b.cnt-a.cnt;});
return list;
}
+/* 重点指标异常拆解(人次,同一人可有多项) */
+function keyIndicatorDetail(idx,year){
+ var d=unitData(idx,year);
+ var s=yearSeed(idx,year);
+ var list=KEY_INDICATORS.map(function(name,ki){
+ var share=(0.10+pseudo(s+ki*3.5+0.7)*0.15)*(KEY_INDICATORS.length-ki)/KEY_INDICATORS.length;
+ return {name:name, cnt:Math.max(1,Math.round(d.keyAbn*share))};
+ });
+ list.sort(function(a,b){return b.cnt-a.cnt;});
+ return list;
+}
+/* 异常率×年龄/性别 交叉(异常人数归一化到总体异常人数) */
+function ageGenderAbnormal(idx,year){
+ var d=unitData(idx,year);
+ var ag=ageGender(idx,year);
+ var s=yearSeed(idx,year);
+ var rows=ag.map(function(r,bi){
+ var mAbn=Math.round(r.male*(0.15+pseudo(s+bi*4.7+2.3)*0.35));
+ var fAbn=Math.round(r.female*(0.12+pseudo(s+bi*4.7+3.9)*0.32));
+ return {band:r.band, male:r.male, female:r.female, maleAbn:mAbn, femaleAbn:fAbn};
+ });
+ var sumAbn=rows.reduce(function(a,r){return a+r.maleAbn+r.femaleAbn;},0);
+ if(sumAbn>0){var k=d.abnormal/sumAbn;rows.forEach(function(r){r.maleAbn=Math.round(r.maleAbn*k);r.femaleAbn=Math.round(r.femaleAbn*k);});}
+ rows.forEach(function(r){
+ r.total=r.male+r.female; r.totalAbn=r.maleAbn+r.femaleAbn;
+ r.maleRate=r.male?r.maleAbn/r.male*100:0;
+ r.femaleRate=r.female?r.femaleAbn/r.female*100:0;
+ r.rate=r.total?r.totalAbn/r.total*100:0;
+ });
+ return rows;
+}
/* 疾病(病种)分布:按病种类别分组,类别与病种均按人数降序 */
-function diseaseDist(d){
- var s=yearSeed(state.unitIdx,state.year);
+function diseaseDist(idx,year){
+ var d=unitData(idx,year);
+ var s=yearSeed(idx,year);
var groups=DISEASE_CATS.map(function(cat,ci){
var items=cat.items.map(function(name,ii){
var share=(0.018+pseudo(s+ci*3.3+ii*1.9)*0.11)*(DISEASE_CATS.length-ci)/DISEASE_CATS.length;
@@ -348,6 +426,25 @@ function diseaseDist(d){
groups.sort(function(a,b){return b.items[0].cnt-a.items[0].cnt;});
return groups;
}
+/* 体检计划周期(随年份与单位动态) */
+function planPeriod(idx,year){
+ var s=yearSeed(idx,year);
+ var sm=4+Math.floor(pseudo(s+19.1)*3);
+ var sd=5+Math.floor(pseudo(s+19.2)*20);
+ var em=sm+2, ed=10+Math.floor(pseudo(s+19.3)*20);
+ function p(n){return (n<10?'0':'')+n;}
+ return year+'-'+p(sm)+'-'+p(sd)+' 至 '+year+'-'+p(em)+'-'+p(ed);
+}
+/* 同比变化(带方向着色):goodDir=up/down 表示"升是好事/降是好事",flat 中性 */
+function trendSpan(numDelta,isRate,goodDir,unit){
+ if(Math.abs(numDelta)<0.05)return '
— 持平 ';
+ var up=numDelta>0, arrow=up?'↑':'↓';
+ var txt=(up?'+':'')+(isRate?Math.abs(numDelta).toFixed(1)+'pp':fmt(Math.abs(Math.round(numDelta)))+(unit||''));
+ var cls='trend-flat';
+ if(goodDir==='up')cls=up?'trend-good':'trend-bad';
+ else if(goodDir==='down')cls=up?'trend-bad':'trend-good';
+ return '
'+arrow+' '+txt+' ';
+}
/* ============ 左侧单位列表 ============ */
function renderUnitList(){
@@ -356,7 +453,7 @@ function renderUnitList(){
if(!list.length){box.innerHTML='
未找到匹配单位
';return;}
var html=list.map(function(u){
var idx=UNITS.indexOf(u);
- var d=unitData(idx);
+ var d=unitData(idx,state.year);
return '
'
+'
'+u+'
'
+'
应检 '+fmt(d.total)+' 检出率 '+pct(d.abnormal,d.examined)+'
'
@@ -366,107 +463,230 @@ function renderUnitList(){
}
function filterUnits(kw){state.keyword=kw.trim();renderUnitList();}
function selectUnit(idx){state.unitIdx=idx;renderUnitList();renderReport();}
-function pct(a,b){return b?((a/b)*100).toFixed(1)+'%':'0.0%';}
+
+/* ============ 近三年趋势图(受检率 / 检出率 折线) ============ */
+function trendChartSvg(idx,years){
+ var attend=[],detect=[];
+ years.forEach(function(y){var s=computeStats(idx,y);attend.push(s.attendRate);detect.push(s.detectRate);});
+ var all=attend.concat(detect);
+ var min=Math.floor(Math.min.apply(null,all))-3, max=Math.ceil(Math.max.apply(null,all))+3;
+ var W=560,H=150,padL=38,padR=14,padT=14,padB=26;
+ var iw=W-padL-padR, ih=H-padT-padB;
+ function x(i){return padL+(years.length===1?iw/2:iw*i/(years.length-1));}
+ function y(v){return padT+ih*(1-(v-min)/(max-min));}
+ var grid='';
+ for(var g=0;g<=4;g++){
+ var gv=min+(max-min)*g/4, gy=y(gv).toFixed(1);
+ grid+='
'
+ +'
'+gv.toFixed(0)+' ';
+ }
+ function pline(arr,color){return '
';}
+ var dots='';
+ attend.forEach(function(v,i){dots+='
';});
+ detect.forEach(function(v,i){dots+='
';});
+ var labels='';
+ years.forEach(function(yr,i){
+ var active=yr===state.year;
+ labels+='
'+yr+' ';
+ });
+ return '
'+grid
+ +pline(attend,'#1890FF')+pline(detect,'#FAAD14')+dots+labels+' ';
+}
/* ============ 右侧群体分析报告 ============ */
function renderReport(){
- var d=unitData(state.unitIdx);
- var ag=ageGender(d);
- var rank=indicatorRank(d);
- var dist=diseaseDist(d);
- var maxCnt=rank[0].cnt;
+ var idx=state.unitIdx, year=state.year;
+ var prevYear=String(parseInt(year,10)-1);
+ var d=unitData(idx,year);
+ var pd=unitData(idx,prevYear);
+ var cur=computeStats(idx,year);
+ var prev=computeStats(idx,prevYear);
+ var rank=indicatorRank(idx,year);
+ var rankPrevMap={}; indicatorRank(idx,prevYear).forEach(function(r){rankPrevMap[r.name]={cnt:r.cnt,rate:r.cnt/unitData(idx,prevYear).examined*100};});
+ var keyList=keyIndicatorDetail(idx,year);
+ var keyPrevMap={}; keyIndicatorDetail(idx,prevYear).forEach(function(k){keyPrevMap[k.name]=k.cnt;});
+ var dist=diseaseDist(idx,year);
+ var distPrevMap={}; diseaseDist(idx,prevYear).forEach(function(g){g.items.forEach(function(x){distPrevMap[x.name]=x.cnt;});});
+ var cross=ageGenderAbnormal(idx,year);
+ var years=[String(parseInt(year,10)-2),prevYear,year];
var panel=document.getElementById('report-panel');
- /* 概览指标卡 */
+ /* 概览指标卡(含同比) */
var cards=[
- ['应检人数',fmt(d.total),''],
- ['已检人数',fmt(d.examined),'ov-card__value--primary'],
- ['受检率',pct(d.examined,d.total),'ov-card__value--success'],
- ['检出率',pct(d.abnormal,d.examined),'ov-card__value--warning'],
- ['异常人数',fmt(d.abnormal),'ov-card__value--danger'],
- ['重点指标异常',fmt(d.keyAbn),'ov-card__value--danger']
+ ['应检人数',fmt(cur.total),'',cur.total-prev.total,false,'flat','人'],
+ ['已检人数',fmt(cur.examined),'ov-card__value--primary',cur.examined-prev.examined,false,'flat','人'],
+ ['受检率',pct1(cur.attendRate),'ov-card__value--success',cur.attendRate-prev.attendRate,true,'up',''],
+ ['检出率',pct1(cur.detectRate),'ov-card__value--warning',cur.detectRate-prev.detectRate,true,'down',''],
+ ['异常人数',fmt(cur.abnormal),'ov-card__value--danger',cur.abnormal-prev.abnormal,false,'down','人'],
+ ['重点指标异常',fmt(cur.keyAbn),'ov-card__value--danger',cur.keyAbn-prev.keyAbn,false,'down','人'],
+ ['复查率',pct1(cur.recheckRate),'',cur.recheckRate-prev.recheckRate,true,'up',''],
+ ['数据完整率',pct1(cur.completeRate),'',cur.completeRate-prev.completeRate,true,'up',''],
+ ['平均年龄',cur.avgAge+'岁','',cur.avgAge-prev.avgAge,false,'flat','岁'],
+ ['未见异常',fmt(cur.healthy),'ov-card__value--success',cur.healthy-prev.healthy,false,'up','人']
].map(function(c){
- return '
';
+ return '
'+c[1]+'
'+c[0]+'
较上年 '+trendSpan(c[3],c[4],c[5],c[6])+'
';
}).join('');
- /* 年龄性别分布表 */
- var agRows=ag.map(function(r){
- return '
'+r.band+' '+fmt(r.male)+' '+fmt(r.female)+' '+fmt(r.male+r.female)+' '+pct(r.male+r.female,d.examined)+' ';
- }).join('');
- var agTotal=ag.reduce(function(a,r){return a+r.male+r.female;},0);
- var agMale=ag.reduce(function(a,r){return a+r.male;},0);
- var agFemale=ag.reduce(function(a,r){return a+r.female;},0);
-
- /* 异常指标条形图 */
+ /* 异常指标条形图(带上年对照) */
+ var maxCnt=rank[0].cnt;
var bars=rank.map(function(r,i){
var cls=i===0?'top1':(i===1?'top2':(i===2?'top3':''));
+ var pv=rankPrevMap[r.name]||{cnt:0,rate:0};
+ var delta=r.cnt-pv.cnt;
return '
'
+'
'+r.name+'
'
+'
'
- +'
'+fmt(r.cnt)+' 人 · '+pct(r.cnt,d.examined)+'
'
+ +'
'+fmt(r.cnt)+' 人 · '+pct(r.cnt,d.examined)+'
上年 '+pct1(pv.rate)+' · '+trendSpan(delta,false,'down','人')+'
'
+'
';
}).join('');
- /* 疾病分布表 */
+ /* 重点指标异常拆解 */
+ var keyRows=keyList.map(function(k){
+ var pv=keyPrevMap[k.name]||0;
+ return '
'+k.name+' '+fmt(k.cnt)+' '+pct(k.cnt,d.examined)+' '+trendSpan(k.cnt-pv,false,'down','人')+' ';
+ }).join('');
+
+ /* 异常率×年龄/性别 交叉 */
+ var crossRows=cross.map(function(r){
+ return '
'+r.band+' '+pct1(r.maleRate)+' '+pct1(r.femaleRate)+' '+pct1(r.rate)+' '+fmt(r.totalAbn)+' ';
+ }).join('');
+ var crossTotalAbn=cross.reduce(function(a,r){return a+r.totalAbn;},0);
+ var crossMaleAbn=cross.reduce(function(a,r){return a+r.maleAbn;},0);
+ var crossFemaleAbn=cross.reduce(function(a,r){return a+r.femaleAbn;},0);
+ var crossMale=cross.reduce(function(a,r){return a+r.male;},0);
+ var crossFemale=cross.reduce(function(a,r){return a+r.female;},0);
+ var crossMaleRate=crossMale?crossMaleAbn/crossMale*100:0;
+ var crossFemaleRate=crossFemale?crossFemaleAbn/crossFemale*100:0;
+
+ /* 疾病分布(带较上年) */
var distRows='';
dist.forEach(function(g){
- distRows+='
'+g.cat+' ';
+ distRows+='
'+g.cat+' ';
g.items.forEach(function(x){
- distRows+='
'+x.name+' '+fmt(x.cnt)+' '+pct(x.cnt,d.examined)+' ';
+ var pv=distPrevMap[x.name]||0;
+ distRows+='
'+x.name+' '+fmt(x.cnt)+' '+pct(x.cnt,d.examined)+' '+trendSpan(x.cnt-pv,false,'down','人')+' ';
});
});
+ /* 专项筛查(阳性率按实际受检人数计算) */
+ var screenHtml=''
+ +'
防癌筛查 · Septin9
'+fmt(d.cancerPos)+' 人阳性 '
+ +'
阳性率 '+pct(d.cancerPos,d.cancerScreened)+' · 已筛 '+fmt(d.cancerScreened)+' 人
较上年 '+trendSpan(d.cancerPos-pd.cancerPos,false,'down','人')+'
'
+ +'
防癌筛查 · CA724
'+fmt(d.ca724Pos)+' 人阳性 '
+ +'
阳性率 '+pct(d.ca724Pos,d.cancerScreened)+' · 已筛 '+fmt(d.cancerScreened)+' 人
较上年 '+trendSpan(d.ca724Pos-pd.ca724Pos,false,'down','人')+'
'
+ +'
冠脉CTA
'+fmt(d.ctaAbn)+' 人异常 '
+ +'
异常率 '+pct(d.ctaAbn,d.ctaScreened)+' · 已检 '+fmt(d.ctaScreened)+' 人
较上年 '+trendSpan(d.ctaAbn-pd.ctaAbn,false,'down','人')+'
'
+ +'
胃肠镜
'+fmt(d.gastroAbn)+' 人异常 '
+ +'
异常率 '+pct(d.gastroAbn,d.gastroScreened)+' · 已检 '+fmt(d.gastroScreened)+' 人
较上年 '+trendSpan(d.gastroAbn-pd.gastroAbn,false,'down','人')+'
';
+
+ /* 近三年趋势 */
+ var trendLegend='
受检率 检出率
';
+
panel.innerHTML=
'
'
+'
'+d.name+' · 群体分析报告
'
+'
'
- +'体检年份:'+state.year+' '
+ +'体检年份:'+year+' '
+'承检医院:'+d.hospital+' '
- +'体检计划:2026-06-23 至 2026-08-31 '
+ +'体检计划:'+planPeriod(idx,year)+' '
+ +'同比基准:'+prevYear+' 年 '
+'
'
+'
'+cards+'
'
+'
'
- +''
+ +''
+ +'
'+trendLegend+trendChartSvg(idx,years)+'
'
+
+ +'
'
+ +''
+'
'
- +'年龄区间 男 女 合计 占比 '
- +''+agRows
- +'合计 '+fmt(agMale)+' '+fmt(agFemale)+' '+fmt(agTotal)+' 100% '
+ +'年龄区间 男性异常率 女性异常率 合计异常率 异常人数 '
+ +' '+crossRows
+ +'合计 '+pct1(crossMaleRate)+' '+pct1(crossFemaleRate)+' '+pct1(cur.detectRate)+' '+fmt(crossTotalAbn)+' '
+'
'
+'
'
+'
'
- +''
+ +''
+'
'
- +'病种 人数 占比 '
+ +'重点指标 异常人数 检出率 较上年 '
+ +''+keyRows+'
'
+
+ +'
'
+ +''
+ +'
'
+ +'病种 人数 占比 较上年 '
+''+distRows+'
'
+'
'
- +''
- +'
'
- +'
防癌筛查 · Septin9
'+d.cancerPos+' 人阳性 占应检 '+pct(d.cancerPos,d.total)+' '
- +'
防癌筛查 · CA724
'+Math.max(1,Math.round(d.cancerPos*0.8))+' 人阳性 占应检 '+pct(Math.round(d.cancerPos*0.8),d.total)+' '
- +'
冠脉CTA
'+d.ctaAbn+' 人异常 占已检 '+pct(d.ctaAbn,d.examined)+' '
- +'
';
+ +''
+ +'
'+screenHtml+'
';
}
/* 导出群体报告(CSV,Excel 兼容) */
function exportReport(){
- var d=unitData(state.unitIdx);
- var rank=indicatorRank(d);
- var dist=diseaseDist(d);
- var rows=[['单位群体报告',''],['单位',d.name],['体检年份',state.year],['承检医院',d.hospital],[],
- ['应检人数',d.total],['已检人数',d.examined],['受检率',pct(d.examined,d.total)],['检出率',pct(d.abnormal,d.examined)],['异常人数',d.abnormal],['重点指标异常人数',d.keyAbn],[],
- ['异常指标排名','人数'],[]].concat(rank.map(function(r){return [r.name,r.cnt];})).concat([[],['疾病(病种)分布','人数']]);
- dist.forEach(function(g){g.items.forEach(function(x){rows.push([g.cat+' · '+x.name,x.cnt]);});});
+ var idx=state.unitIdx, year=state.year;
+ var prevYear=String(parseInt(year,10)-1);
+ var d=unitData(idx,year), pd=unitData(idx,prevYear);
+ var cur=computeStats(idx,year), prev=computeStats(idx,prevYear);
+ var rank=indicatorRank(idx,year);
+ var rankPrevMap={}; indicatorRank(idx,prevYear).forEach(function(r){rankPrevMap[r.name]=r.cnt;});
+ var keyList=keyIndicatorDetail(idx,year);
+ var keyPrevMap={}; keyIndicatorDetail(idx,prevYear).forEach(function(k){keyPrevMap[k.name]=k.cnt;});
+ var dist=diseaseDist(idx,year);
+ var distPrevMap={}; diseaseDist(idx,prevYear).forEach(function(g){g.items.forEach(function(x){distPrevMap[x.name]=x.cnt;});});
+ var cross=ageGenderAbnormal(idx,year);
+ var years=[String(parseInt(year,10)-2),prevYear,year];
+
+ var rows=[];
+ rows.push(['单位群体报告',''],['单位',d.name],['体检年份',year],['承检医院',d.hospital],['体检计划',planPeriod(idx,year)],['同比基准',prevYear+'年'],[]);
+ rows.push(['概览指标','今年','上年','较上年']);
+ rows.push(['应检人数',d.total,pd.total,d.total-pd.total]);
+ rows.push(['已检人数',d.examined,pd.examined,d.examined-pd.examined]);
+ rows.push(['受检率(%)',cur.attendRate.toFixed(1),prev.attendRate.toFixed(1),(cur.attendRate-prev.attendRate).toFixed(1)]);
+ rows.push(['检出率(%)',cur.detectRate.toFixed(1),prev.detectRate.toFixed(1),(cur.detectRate-prev.detectRate).toFixed(1)]);
+ rows.push(['异常人数',d.abnormal,pd.abnormal,d.abnormal-pd.abnormal]);
+ rows.push(['重点指标异常人数',d.keyAbn,pd.keyAbn,d.keyAbn-pd.keyAbn]);
+ rows.push(['复查率(%)',cur.recheckRate.toFixed(1),prev.recheckRate.toFixed(1),(cur.recheckRate-prev.recheckRate).toFixed(1)]);
+ rows.push(['数据完整率(%)',cur.completeRate.toFixed(1),prev.completeRate.toFixed(1),(cur.completeRate-prev.completeRate).toFixed(1)]);
+ rows.push(['平均年龄',cur.avgAge,prev.avgAge,cur.avgAge-prev.avgAge]);
+ rows.push(['未见异常人数',d.healthy,pd.healthy,d.healthy-pd.healthy]);
+ rows.push([]);
+
+ rows.push(['异常率×年龄/性别','男性异常率(%)','女性异常率(%)','合计异常率(%)','异常人数']);
+ cross.forEach(function(r){rows.push([r.band,r.maleRate.toFixed(1),r.femaleRate.toFixed(1),r.rate.toFixed(1),r.totalAbn]);});
+ rows.push([]);
+
+ rows.push(['异常指标排名','人数','检出率','上年人数','较上年']);
+ rank.forEach(function(r){var pv=rankPrevMap[r.name]||0;rows.push([r.name,r.cnt,pct(r.cnt,d.examined),pv,r.cnt-pv]);});
+ rows.push([]);
+
+ rows.push(['重点指标异常','异常人数','检出率','上年人数','较上年']);
+ keyList.forEach(function(k){var pv=keyPrevMap[k.name]||0;rows.push([k.name,k.cnt,pct(k.cnt,d.examined),pv,k.cnt-pv]);});
+ rows.push([]);
+
+ rows.push(['疾病(病种)分布','人数','占比','上年人数','较上年']);
+ dist.forEach(function(g){g.items.forEach(function(x){var pv=distPrevMap[x.name]||0;rows.push([g.cat+' · '+x.name,x.cnt,pct(x.cnt,d.examined),pv,x.cnt-pv]);});});
+ rows.push([]);
+
+ rows.push(['专项筛查结果','阳性/异常','率','已筛/已检','较上年']);
+ rows.push(['防癌筛查 Septin9',d.cancerPos,pct(d.cancerPos,d.cancerScreened),'已筛 '+d.cancerScreened,d.cancerPos-pd.cancerPos]);
+ rows.push(['防癌筛查 CA724',d.ca724Pos,pct(d.ca724Pos,d.cancerScreened),'已筛 '+d.cancerScreened,d.ca724Pos-pd.ca724Pos]);
+ rows.push(['冠脉CTA',d.ctaAbn,pct(d.ctaAbn,d.ctaScreened),'已检 '+d.ctaScreened,d.ctaAbn-pd.ctaAbn]);
+ rows.push(['胃肠镜',d.gastroAbn,pct(d.gastroAbn,d.gastroScreened),'已检 '+d.gastroScreened,d.gastroAbn-pd.gastroAbn]);
+ rows.push([]);
+
+ rows.push(['近三年趋势','受检率(%)','检出率(%)']);
+ years.forEach(function(y){var s=computeStats(idx,y);rows.push([y+'年',s.attendRate.toFixed(1),s.detectRate.toFixed(1)]);});
+
var csv=rows.map(function(r){return r.map(function(c){return '"'+String(c).replace(/"/g,'""')+'"';}).join(',');}).join('\r\n');
var a=document.createElement('a');
a.href=URL.createObjectURL(new Blob([csv],{type:'text/csv;charset=utf-8'}));
- a.download=d.name+'_'+state.year+'年_群体分析报告.csv';
+ a.download=d.name+'_'+year+'年_群体分析报告.csv';
document.body.appendChild(a);a.click();document.body.removeChild(a);
setTimeout(function(){URL.revokeObjectURL(a.href);},1000);
}
diff --git a/web-admin/health-checkup/post-hospital-count.html b/web-admin/health-checkup/post-hospital-count.html
index 455ee1d..2b0f045 100644
--- a/web-admin/health-checkup/post-hospital-count.html
+++ b/web-admin/health-checkup/post-hospital-count.html
@@ -142,6 +142,7 @@
+
diff --git a/web-admin/health-checkup/post-illness-personnel.html b/web-admin/health-checkup/post-illness-personnel.html
index f5a80d9..bb77f94 100644
--- a/web-admin/health-checkup/post-illness-personnel.html
+++ b/web-admin/health-checkup/post-illness-personnel.html
@@ -168,6 +168,7 @@
+
diff --git a/web-admin/health-checkup/post-indicator-notify.html b/web-admin/health-checkup/post-indicator-notify.html
index 271d819..2a6d4af 100644
--- a/web-admin/health-checkup/post-indicator-notify.html
+++ b/web-admin/health-checkup/post-indicator-notify.html
@@ -140,6 +140,7 @@
+
diff --git a/web-admin/health-checkup/post-item-stat.html b/web-admin/health-checkup/post-item-stat.html
index 1042e18..598e137 100644
--- a/web-admin/health-checkup/post-item-stat.html
+++ b/web-admin/health-checkup/post-item-stat.html
@@ -132,6 +132,7 @@
+
diff --git a/web-admin/health-checkup/post-key-indicator-stat.html b/web-admin/health-checkup/post-key-indicator-stat.html
index 0bea391..48a1955 100644
--- a/web-admin/health-checkup/post-key-indicator-stat.html
+++ b/web-admin/health-checkup/post-key-indicator-stat.html
@@ -165,6 +165,7 @@
+
diff --git a/web-admin/health-checkup/post-report-employee.html b/web-admin/health-checkup/post-report-employee.html
index c9a6f2f..3a7894e 100644
--- a/web-admin/health-checkup/post-report-employee.html
+++ b/web-admin/health-checkup/post-report-employee.html
@@ -168,6 +168,7 @@
+
diff --git a/web-admin/health-checkup/post-report-gastro.html b/web-admin/health-checkup/post-report-gastro.html
index 65edf8d..edab211 100644
--- a/web-admin/health-checkup/post-report-gastro.html
+++ b/web-admin/health-checkup/post-report-gastro.html
@@ -218,6 +218,7 @@
+
diff --git a/web-admin/health-checkup/post-report-unmatched.html b/web-admin/health-checkup/post-report-unmatched.html
index 32494d7..3636ed3 100644
--- a/web-admin/health-checkup/post-report-unmatched.html
+++ b/web-admin/health-checkup/post-report-unmatched.html
@@ -151,6 +151,7 @@
+
diff --git a/web-admin/health-checkup/post-result-comprehensive-stat.html b/web-admin/health-checkup/post-result-comprehensive-stat.html
new file mode 100644
index 0000000..1f53811
--- /dev/null
+++ b/web-admin/health-checkup/post-result-comprehensive-stat.html
@@ -0,0 +1,459 @@
+
+
+
+
+
+
健康体检 - 结果动态综合统计 | 健康CQ原型
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 单位:
+
+ 请选择 第一采油厂 第二采油厂 第三采油厂
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web-admin/health-checkup/post-standard-stat.html b/web-admin/health-checkup/post-standard-stat.html
index 4332e1c..0c46a9e 100644
--- a/web-admin/health-checkup/post-standard-stat.html
+++ b/web-admin/health-checkup/post-standard-stat.html
@@ -142,6 +142,7 @@
+
diff --git a/web-admin/health-checkup/post-unit-cost-stat.html b/web-admin/health-checkup/post-unit-cost-stat.html
index fc9ad91..e16a7f1 100644
--- a/web-admin/health-checkup/post-unit-cost-stat.html
+++ b/web-admin/health-checkup/post-unit-cost-stat.html
@@ -161,6 +161,7 @@
+
diff --git a/web-admin/health-checkup/post-unit-count.html b/web-admin/health-checkup/post-unit-count.html
index 4be6336..253aebc 100644
--- a/web-admin/health-checkup/post-unit-count.html
+++ b/web-admin/health-checkup/post-unit-count.html
@@ -172,6 +172,7 @@
+
diff --git a/web-admin/health-checkup/post-unit-item-stat.html b/web-admin/health-checkup/post-unit-item-stat.html
index 3dcb344..5d5a529 100644
--- a/web-admin/health-checkup/post-unit-item-stat.html
+++ b/web-admin/health-checkup/post-unit-item-stat.html
@@ -152,6 +152,7 @@
+
diff --git a/web-admin/weight-management/archive-personal-weight-detail.html b/web-admin/weight-management/archive-personal-weight-detail.html
index 1899db2..f4a8ec0 100644
--- a/web-admin/weight-management/archive-personal-weight-detail.html
+++ b/web-admin/weight-management/archive-personal-weight-detail.html
@@ -324,18 +324,18 @@ var sportRecords = [
/* 体重记录 */
var weightRecords = [
- {time:'2026-07-01 08:30',weight:81.8,bmi:28.1,fatRate:25.6,waist:93.9,source:'身高秤'},
+ {time:'2026-07-01 08:30',weight:81.8,bmi:28.1,fatRate:25.6,waist:93.9,source:'体重秤'},
{time:'2026-06-28 07:45',weight:82.1,bmi:28.2,fatRate:25.8,waist:94.2,source:'体脂仪'},
{time:'2026-06-25 18:20',weight:82.5,bmi:28.4,fatRate:26.1,waist:94.8,source:'蓝牙称'},
- {time:'2026-06-22 08:10',weight:82.9,bmi:28.5,fatRate:26.3,waist:95.1,source:'身高秤'},
+ {time:'2026-06-22 08:10',weight:82.9,bmi:28.5,fatRate:26.3,waist:95.1,source:'体重秤'},
{time:'2026-06-19 20:00',weight:83.2,bmi:28.6,fatRate:26.6,waist:95.5,source:'自记'},
{time:'2026-06-16 09:00',weight:83.7,bmi:28.8,fatRate:26.9,waist:96.0,source:'体脂仪'},
{time:'2026-06-13 07:30',weight:84.1,bmi:28.9,fatRate:27.2,waist:96.4,source:'蓝牙称'},
- {time:'2026-06-10 18:00',weight:84.5,bmi:29.1,fatRate:27.5,waist:96.7,source:'身高秤'},
+ {time:'2026-06-10 18:00',weight:84.5,bmi:29.1,fatRate:27.5,waist:96.7,source:'体重秤'},
{time:'2026-06-07 08:45',weight:84.9,bmi:29.2,fatRate:27.8,waist:97.2,source:'体脂仪'},
{time:'2026-06-04 19:30',weight:85.2,bmi:29.3,fatRate:28.1,waist:97.6,source:'自记'},
{time:'2026-06-01 08:00',weight:85.6,bmi:29.4,fatRate:28.4,waist:98.2,source:'蓝牙称'},
- {time:'2026-05-28 07:15',weight:85.9,bmi:29.5,fatRate:28.7,waist:98.7,source:'身高秤'}
+ {time:'2026-05-28 07:15',weight:85.9,bmi:29.5,fatRate:28.7,waist:98.7,source:'体重秤'}
];
var pageSize = 10;
@@ -464,7 +464,7 @@ function renderWeight(){
var totalPages = Math.ceil(filtered.length / pageSize) || 1;
document.getElementById('weightPageInfo').textContent = '共 ' + filtered.length + ' 条';
document.getElementById('weightPageNum').textContent = '第 ' + (weightPage + 1) + '/' + totalPages + ' 页';
- var srcTag = {身高秤:'tag-blue',体脂仪:'tag-orange',蓝牙称:'tag-green',自记:'tag-gray'};
+ var srcTag = {体重秤:'tag-blue',体脂仪:'tag-orange',蓝牙称:'tag-green',自记:'tag-gray'};
var html = '';
pageData.forEach(function(d,i){
html += '
';
diff --git a/web-admin/weight-management/doc/PRD.md b/web-admin/weight-management/doc/PRD.md
index 0014f94..2fb4707 100644
--- a/web-admin/weight-management/doc/PRD.md
+++ b/web-admin/weight-management/doc/PRD.md
@@ -252,7 +252,7 @@
**运动记录Tab表格列:** 时间、运动类型、运动时长/数据、消耗热量(千卡)、来源(标签:穿戴/微信/自记/器械)
-**体重记录Tab表格列:** 时间、体重(kg)、BMI、体脂率(%)、腰围(cm)、来源(标签:身高秤/体脂仪/蓝牙称/自记)
+**体重记录Tab表格列:** 时间、体重(kg)、BMI、体脂率(%)、腰围(cm)、来源(标签:体重秤/体脂仪/蓝牙称/自记)
**业务规则:**
- 变化正值红色标注(体重增加),负值绿色标注(体重减少)
@@ -891,7 +891,7 @@
**运动记录Tab表格列:** 时间、运动类型、运动时长/数据、消耗热量(千卡)、来源(标签:穿戴/微信/自记/器械)
-**体重记录Tab表格列:** 时间、体重(kg)、BMI、体脂率(%)、腰围(cm)、来源(标签:身高秤/体脂仪/蓝牙称/自记)
+**体重记录Tab表格列:** 时间、体重(kg)、BMI、体脂率(%)、腰围(cm)、来源(标签:体重秤/体脂仪/蓝牙称/自记)
**交互说明:**
- 面包屑支持返回总览记录
@@ -1144,7 +1144,7 @@
**员工匿名 Tab:** 仅含使用日期筛选,表格列为姓名、使用时间 + 同上10项监测数据列 + 更多信息
-**详情弹窗(监测数据详情 - **员工姓名**,3组指标,对齐员工端身高秤报告):**
+**详情弹窗(监测数据详情 - **员工姓名**,3组指标,对齐员工端体重秤报告):**
- **基础指标:** 身高(cm)、体重(kg)、BMI、体脂率(%)
- **身体成分:** 体脂肪(kg)、水分率(%)、水分量(kg)、肌肉率(%)、肌肉量(kg)、骨量(kg)、去脂体重(kg)
- **体态分析:** 内脏脂肪、体型、理想体重(kg)、超重百分比(%)、体表面积(m²)
diff --git a/web-admin/weight-management/history-personnel-detail.html b/web-admin/weight-management/history-personnel-detail.html
index ebbfef3..ebc8498 100644
--- a/web-admin/weight-management/history-personnel-detail.html
+++ b/web-admin/weight-management/history-personnel-detail.html
@@ -328,18 +328,18 @@ var sportRecords = [
/* 体重记录 */
var weightRecords = [
- {time:'2026-07-01 08:30',weight:81.8,bmi:28.1,fatRate:25.6,waist:93.9,source:'身高秤'},
+ {time:'2026-07-01 08:30',weight:81.8,bmi:28.1,fatRate:25.6,waist:93.9,source:'体重秤'},
{time:'2026-06-28 07:45',weight:82.1,bmi:28.2,fatRate:25.8,waist:94.2,source:'体脂仪'},
{time:'2026-06-25 18:20',weight:82.5,bmi:28.4,fatRate:26.1,waist:94.8,source:'蓝牙称'},
- {time:'2026-06-22 08:10',weight:82.9,bmi:28.5,fatRate:26.3,waist:95.1,source:'身高秤'},
+ {time:'2026-06-22 08:10',weight:82.9,bmi:28.5,fatRate:26.3,waist:95.1,source:'体重秤'},
{time:'2026-06-19 20:00',weight:83.2,bmi:28.6,fatRate:26.6,waist:95.5,source:'自记'},
{time:'2026-06-16 09:00',weight:83.7,bmi:28.8,fatRate:26.9,waist:96.0,source:'体脂仪'},
{time:'2026-06-13 07:30',weight:84.1,bmi:28.9,fatRate:27.2,waist:96.4,source:'蓝牙称'},
- {time:'2026-06-10 18:00',weight:84.5,bmi:29.1,fatRate:27.5,waist:96.7,source:'身高秤'},
+ {time:'2026-06-10 18:00',weight:84.5,bmi:29.1,fatRate:27.5,waist:96.7,source:'体重秤'},
{time:'2026-06-07 08:45',weight:84.9,bmi:29.2,fatRate:27.8,waist:97.2,source:'体脂仪'},
{time:'2026-06-04 19:30',weight:85.2,bmi:29.3,fatRate:28.1,waist:97.6,source:'自记'},
{time:'2026-06-01 08:00',weight:85.6,bmi:29.4,fatRate:28.4,waist:98.2,source:'蓝牙称'},
- {time:'2026-05-28 07:15',weight:85.9,bmi:29.5,fatRate:28.7,waist:98.7,source:'身高秤'}
+ {time:'2026-05-28 07:15',weight:85.9,bmi:29.5,fatRate:28.7,waist:98.7,source:'体重秤'}
];
var pageSize = 10;
@@ -445,7 +445,7 @@ function renderWeight(){
var totalPages = Math.ceil(weightRecords.length / pageSize) || 1;
document.getElementById('weightPageInfo').textContent = '共 ' + weightRecords.length + ' 条';
document.getElementById('weightPageNum').textContent = '第 ' + (weightPage + 1) + '/' + totalPages + ' 页';
- var srcTag = {身高秤:'tag-blue',体脂仪:'tag-orange',蓝牙称:'tag-green',自记:'tag-gray'};
+ var srcTag = {体重秤:'tag-blue',体脂仪:'tag-orange',蓝牙称:'tag-green',自记:'tag-gray'};
var html = '';
pageData.forEach(function(d,i){
html += ' ';