职业病健康检查系统

当前版本:加载中… 版本记录 ▸

职业病健康检查体检系统

软件设计说明书

(完整版底稿)

版本号:V1.0

编制日期:2026年10月

目 录

目 录 2

第1章 引言 11

1.1 编写目的 11

1.2 项目背景 11

1.3 项目目标 11

1.4 适用范围 12

1.5 读者对象 12

1.6 参考依据 12

1.7 术语与缩略词 13

1.8 文档组织结构 13

1.9 与相关系统的关系 14

1.10 系统建设历程与版本更新 14

第2章 总体概述 15

2.1 业务概述 15

2.2 系统建设目标 16

2.3 系统设计原则 16

2.3.1 合规性原则 16

2.3.2 安全性原则 16

2.3.3 可扩展原则 17

2.3.4 易用性原则 17

2.3.5 稳定性原则 17

2.4 系统技术架构 17

2.5 部署架构 18

2.6 运行环境 19

2.6.1 服务端配置 19

2.6.2 服务端软件环境 19

2.6.3 客户端环境 20

2.8 网络端口与服务清单 20

2.9 日志清单 20

2.10 第三方依赖组件 20

2.8 系统代码组织结构 21

2.9 技术选型说明 21

2.11 关键配置项说明 22

第3章 业务需求分析 22

3.1 业务角色梳理 22

3.2 角色用例分析 23

3.2.1 关键用例详述 25

3.2.2 页面-接口-数据表映射 31

3.3 完整业务流程 32

3.3.1 企业批量人员建档流程 32

3.3.2 体检预约、签到分诊流程 33

3.3.3 各科室录入检查结果流程 34

3.3.4 一级审核、二级复审流程 35

3.3.5 体检报告生成、预览、打印、归档流程 36

3.3.6 异常指标随访、复检提醒流程 37

3.3.7 登记单状态机 38

3.4 业务约束与合规要求 39

3.5 业务痛点与系统解决方案对照 39

3.6 业务单据流转说明 40

3.7 系统数据流说明 41

第4章 系统功能模块总体设计 42

4.1 系统模块总图 42

4.2 模块总览 43

4.3 模块间数据交互 43

4.5 功能页面逐页说明 43

4.5.1 工作台 Dashboard 43

4.5.2 个人体检(劳动者档案) 44

4.5.3 单位体检 44

4.5.4 体检指南 45

4.5.5 团体预约 45

4.5.6 体检登记 45

4.5.7 科室录入 45

4.5.8 主检结论 46

4.5.9 总检审核 46

4.5.10 报告中心 46

4.5.11 报告智能解读 47

4.5.12 解读知识库 47

4.5.13 通知书 47

4.5.14 附件管理 48

4.5.15 汇总报表 48

4.5.16 基础档案 48

4.5.17 菜单与角色授权 49

4.5.18 操作日志 49

4.5.19 加密狗授权 49

4.5.20 数据安全 49

4.5.21 租户管理 50

4.5.22 关于本系统 50

4.5.23 国家标准 50

4.5.24 项目规则 50

4.5.25 质控与危急值 51

4.5.26 智能导检 51

4.5.27 收费与结算 51

4.5.28 报告模板 51

4.5.29 系统设置 52

4.5.30 版本记录 52

4.5.31 第三方接口配置 52

4.6 模块依赖关系说明 52

第5章 各模块详细设计 53

5.1 基础数据管理模块详细设计 53

5.2 从业人员档案管理模块详细设计 60

5.3 职业危害因素与用人单位管理模块详细设计 64

5.4 体检项目与套餐管理模块详细设计 71

5.5 体检登记与分诊模块详细设计 79

5.6 体检结果录入模块详细设计 86

5.7 体检报告多级审核模块详细设计 90

5.8 体检报告生成与归档模块详细设计 94

5.9 统计分析与预警模块详细设计 99

5.10 用户、角色与权限管理模块详细设计 106

5.11 系统日志审计模块详细设计 111

5.12 数据安全与国密加密模块详细设计 114

第6章 数据库详细设计 118

6.1 数据库设计原则 118

6.2 实体关系总图 118

6.3 核心数据表结构 119

6.3.1 biz_adapter_config(AdapterConfig) 119

6.3.2 sys_attach(Attach) 120

6.3.3 base_dept(BaseDept) 120

6.3.4 base_dict(BaseDict) 121

6.3.5 biz_conclusion(Conclusion) 121

6.3.6 biz_conclusion_audit(ConclusionAudit) 122

6.3.7 biz_conclusion_task(ConclusionTask) 122

6.3.8 doctor_sign_template(DoctorSignTemplate) 122

6.3.9 biz_employer(Employer) 123

6.3.10 base_exam_item(ExamItem) 123

6.3.11 exam_item_knowledge(ExamItemKnowledge) 124

6.3.12 base_package(ExamPackage) 126

6.3.13 biz_register(ExamRegister) 126

6.3.14 exam_report_interpret(ExamReportInterpret) 127

6.3.15 exam_report_interpret_log(ExamReportInterpretLog) 128

6.3.16 biz_exam_result(ExamResult) 129

6.3.17 biz_exam_result_amend(ExamResultAmend) 129

6.3.18 base_hazard_factor(HazardFactor) 130

6.3.19 biz_lab_result(LabResult) 130

6.3.20 biz_notice(Notice) 131

6.3.21 sys_oper_log(OperLog) 131

6.3.22 base_package_item(PackageItem) 131

6.3.23 biz_register_hazard(RegisterHazard) 132

6.3.24 biz_report(Report) 132

6.3.25 biz_review_config(ReviewConfig) 132

6.3.26 seq_rule(SeqRule) 132

6.3.27 base_std_disease(StdDisease) 133

6.3.28 base_std_disease_category(StdDiseaseCategory) 133

6.3.29 base_std_exam_item(StdExamItem) 133

6.3.30 base_std_exam_rule(StdExamRule) 134

6.3.31 base_std_hazard(StdHazard) 134

6.3.32 base_std_hazard_disease(StdHazardDisease) 134

6.3.33 sys_menu(SysMenu) 135

6.3.34 sys_role(SysRole) 135

6.3.35 sys_role_menu(SysRoleMenu) 135

6.3.36 sys_tenant(SysTenant) 136

6.3.37 sys_user(SysUser) 136

6.3.38 biz_worker(Worker) 136

6.4 表间关联关系 137

6.5 索引设计 138

6.6 数据存储与备份策略 138

6.7 枚举值字典 138

6.8 初始化种子数据 139

6.9 数据生命周期管理 140

6.10 种子数据明细 140

第7章 接口详细设计 165

7.1 接口规范 165

7.2 内部接口清单 165

7.2.1 AdapterConfigController(2 项) 165

7.2.2 AttachController(4 项) 165

7.2.3 BaseDataController(29 项) 166

7.2.4 ConclusionController(13 项) 168

7.2.5 DoctorSignController(8 项) 169

7.2.6 FinanceController(20 项) 169

7.2.7 GuideController(15 项) 170

7.2.8 InterpretController(10 项) 171

7.2.9 ItemRuleController(10 项) 171

7.2.10 ModuleController(7 项) 172

7.2.11 ModuleLibController(7 项) 173

7.2.12 OccConfigController(5 项) 173

7.2.13 OccLabController(2 项) 173

7.2.14 OccLoginBgController(4 项) 174

7.2.15 OccMenuController(4 项) 174

7.2.16 OccNoticeController(3 项) 174

7.2.17 OccTenantController(4 项) 175

7.2.18 OccVersionController(2 项) 175

7.2.19 OccupationalAuthController(3 项) 175

7.2.20 OccupationalWorkerController(6 项) 175

7.2.21 OpenInterpretController(1 项) 176

7.2.22 OperLogController(1 项) 176

7.2.23 QualityController(13 项) 176

7.2.24 RegisterController(11 项) 177

7.2.25 ReportController(2 项) 178

7.2.26 ReportTemplateController(7 项) 178

7.2.27 ResultController(4 项) 178

7.2.28 StatController(4 项) 179

7.2.29 StdCatalogController(9 项) 179

7.2.30 UserManageController(6 项) 180

7.3 关键接口说明 180

7.4 关键接口入参与出参 181

7.5 关键接口报文示例 182

第8章 系统安全设计 184

8.1 身份认证安全 184

8.2 权限访问安全 185

8.3 数据存储安全(国密加密) 185

8.4 传输安全 185

8.5 日志审计安全 186

8.6 防篡改与防越权设计 186

8.7 认证与鉴权时序 186

8.8 安全威胁与对策矩阵 187

8.9 安全配置基线清单 188

8.10 十大核心安全防护机制逐项设计 188

8.10.1 独立授权验证服务器与软加密狗模拟 SDK 189

8.10.2 菜单权限与行级数据权限的多角色隔离 190

8.10.3 后端越权访问检查与前端空壳化渲染 190

8.10.4 账号安全策略(密码哈希、复杂度、错误锁定、会话超时) 191

8.10.5 全链路不可篡改操作审计日志 192

8.10.6 HTTPS 传输加密 193

8.10.7 TDE 数据库透明加密 193

8.10.8 敏感明文查看的单独权限控制 194

8.10.9 敏感数据脱敏展示 195

8.10.10 SM3 业务记录完整性校验(防篡改) 195

第9章 性能设计 196

9.1 并发性能指标 196

9.2 查询性能优化 196

9.3 批量导入处理机制 197

9.4 大数据量统计优化 197

9.5 性能指标与容量规划 197

9.6 容量测算 197

9.7 性能验收测试场景 198

第10章 出错处理设计 198

10.1 异常分类 198

10.2 业务异常处理 198

10.3 数据库异常与事务回滚 198

10.4 前端异常提示 199

10.5 错误码表 199

10.6 典型异常场景处理对照 200

10.7 前端输入校验规则清单 200

第11章 系统维护设计 201

11.1 数据备份机制 201

11.2 系统参数可视化配置 201

11.3 日志留存管理 201

11.4 版本管理 201

11.5 发布与升级操作规程 203

11.6 日常运维清单 203

11.7 故障应急处理预案 203

第12章 附录 204

附录A 界面原型图汇总 204
附录B 数据字典简表 209
附录C 国密算法应用说明 212
附录D 业务表单样例 212
附录E 随访与周期体检预警规则 214
附录F GBZ 188 危害因素与必检项目对照表 214
附录G 界面控件说明 215
附录I 角色-菜单可见性矩阵 216
附录K 报告 PDF 版式说明 218
附录L 职业健康专业名词说明 219
附录M 版本发布记录(摘自版本更新记录表) 219
附录N 交付与验收清单 220

第1章 引言

1.1 编写目的

本说明书对职业病健康检查体检系统(以下简称「本系统」)的总体结构、业务流程、功能模块、数据库、接口、安全性、性能与维护设计作出完整描述,作为软件著作权登记的技术材料,同时作为系统开发、测试、部署与验收阶段的设计依据。本文档内容与本系统当前已完成并实际运行的功能一致,所涉及的数据库表、接口、页面均来自系统实际代码。

1.2 项目背景

依据《中华人民共和国职业病防治法》及《职业健康监护技术规范》(GBZ 188)的要求,用人单位应当为接触职业病危害因素的劳动者组织上岗前、在岗期间、离岗时及应急健康检查,承担职业健康检查的机构需要对体检全过程的档案建立、登记分诊、结果录入、结论审核、报告出具与数据统计实施规范化管理。传统人工或半信息化方式存在档案检索困难、套餐与应检项目口径不一、结果录入与审核缺乏质控留痕、报告编制工作量大、周期体检到期无人提醒、敏感个人信息保护不足等问题。为解决上述问题,建设单位组织开发本系统,实现职业健康检查业务的全程信息化与数据安全合规管理。

1.3 项目目标

本系统的建设目标为:

● 建立覆盖接害因素、体检模块、体检套餐、科室项目的标准配置体系,实现按 GBZ 188 规范口径的应检项目管理;

● 实现劳动者一人一档、身份证号唯一去重与敏感信息加密存储,保障个人信息安全;

● 实现团体预约、登记发号、签到分诊、科室录入、状态跟踪的全流程线上化;

● 实现主检结论多级审核(初审、复审)与签发留痕,保障结论质量可控可溯;

● 实现报告 PDF 自动生成、版本化管理与复查/转诊/调离通知书自动出具;

● 实现多维度统计分析、随访名单与周期体检到期预警;

● 实现 SM2/SM3/SM4 国密算法可选加密、多级权限隔离与操作日志全程审计,满足政府采购与信息安全合规要求。

1.4 适用范围

本文档适用于承担职业健康检查的医疗机构(体检机构)及卫生监督管理相关人员,描述的系统功能范围限于职业病健康检查业务,包括基础数据管理、从业人员档案管理、职业危害因素与用人单位管理、体检项目与套餐管理、体检登记与分诊、体检结果录入、报告多级审核、报告生成与归档、统计分析与预警、用户角色权限管理、日志审计、数据安全与国密加密十二个功能域。本文档不涉及系统未实现的功能。

1.5 读者对象

本文档的预期读者为:软件著作权登记审查人员、招投标评审专家、体检机构管理与业务人员、系统运维人员、后续开发与测试人员。

1.6 参考依据

本系统的设计与实现参考下列法律法规与技术标准:

表 1-1 设计参考依据清单

| 序号 | 标准/法规名称 | 文号/编号 |

| 1 | 《中华人民共和国职业病防治法》 | 2018年修正 |

| 2 | 《职业健康监护技术规范》 | GBZ 188-2014 |

| 3 | 《职业健康检查管理办法》 | 国家卫生计生委令 |

| 4 | 《用人单位职业健康监护监督管理办法》 | 国家安全监管总局令第49号 |

| 5 | 《信息安全技术 网络安全等级保护基本要求》 | GB/T 22239-2019 |

| 6 | SM2椭圆曲线公钥密码算法 | GB/T 32918 |

| 7 | SM3密码杂凑算法 | GB/T 32905 |

| 8 | SM4分组密码算法 | GB/T 32907 |

1.7 术语与缩略词

表 1-2 术语与缩略词表

| 术语/缩略词 | 说明 |

| 职业健康检查 | 对接触职业病危害因素的劳动者进行的医学检查,含上岗前、在岗期间、离岗时、应急检查 |

| 接害因素 | 劳动者在作业中接触的职业病危害因素,如粉尘、噪声、苯、铅、高温等 |

| 主检结论 | 主检医师汇总各科检查结果出具的总体结论,分为未见异常、复查、疑似职业病、职业禁忌证四类 |

| 复查通知书 | 对结论为复查的劳动者出具的通知文书,明确复查项目与期限 |

| 调离通知书 | 对职业禁忌证人员出具的调离相应作业岗位的通知文书 |

| JWT | JSON Web Token,本系统登录鉴权令牌 |

| BCrypt | 口令哈希算法,用于用户密码加密存储 |

| SM2/SM3/SM4 | 国家商用密码算法:SM2 椭圆曲线非对称加密签名、SM3 密码杂凑、SM4 分组密码 |

| 乐观锁 | 通过版本号字段防止并发覆盖更新的并发控制机制 |

| 软锁 | 登记单领单锁定机制,记录锁持有人与时间,防止多人同时编辑 |

| 多租户 | 一套系统同时服务多个体检机构,业务数据按租户标识隔离 |

| CSV(BOM) | 带 UTF-8 BOM 头的逗号分隔文件,保证 Excel 打开中文不乱码 |

1.8 文档组织结构

本文档共 12 章:

第 1 章引言说明编写目的、背景与术语;

第 2 章给出系统总体概述、技术架构与运行环境;

第 3 章分析业务角色、用例与完整业务流程;

第 4 章给出功能模块总体结构;

第 5 章按统一格式详述十二个功能模块的设计(功能、输入、处理、输出、界面与接口);

第 6 章详述数据库设计(全部表结构、索引与备份策略);

第 7 章详述接口设计;

第 8 章为系统安全设计;

第 9 章为性能设计;

第 10 章为出错处理设计;

第 11 章为系统维护设计;

第 12 章为附录(界面原型、数据字典、国密算法应用说明与业务表单样例)。

1.9 与相关系统的关系

本系统在设计上保持独立完整运行能力,同时为机构既有系统预留标准对接通道:

表 1-3 与相关系统的关系

| 相关系统 | 关系说明 | 对接方式 |

| 体检机构既有 HIS/门诊系统 | 人群基本信息与科室号别来源 | 通过第三方适配器(AdapterRegistry)按配置对接,本系统独立运行不依赖 |

| 实验室 LIS 系统 | 检验结果自动回传 | 检验结果 source=lis 通道,适配器配置化接入 |

| 用人单位 HR 系统 | 体检名单批量交换 | 批量导入名单(模板化),导出结果 CSV 供回传 |

| 平台主服务(工具箱/门户) | 统一部署运行时 | 本系统作为功能子包随主服务部署,独立数据库与认证体系,互不影响 |

1.10 系统建设历程与版本更新

系统当前版本为 V2.5.0030(版本库登记时间 2026-10-03 02:33:11)。自 V1.1.0000 基础版本上线以来,系统按「小步快跑、每版可用」的方式持续迭代,全部版本更新记录由版本更新记录表(sys_version_log)逐条登记,可在系统「版本记录」页面查阅。主版本演进节点归纳如下:

表 1-4 系统建设历程(主版本节点)

| 版本阶段 | 主要建设内容 |

| V1.1.0000(2026-09-26) | 基础版本上线:登录鉴权、劳动者建档、体检登记、科室/检验结果录入、主检结论、状态机、工作台统计等基础业务链路。 |

| V1.2 系列(2026-09-26 至 09-28) | 业务模块补齐;国家标准知识库接入;登录页与稳定性优化;权限体系修正与安全加固;新增版本记录页面。 |

| V2.0.0000(2026-09-28) | 重大扩充:体检业务全流程模块落地。 |

| V2.1—V2.4(2026-09-28) | 财务结算与报告模板;模块级权限基座;界面重构(导航折叠与单页化);第三方接口配置。 |

| V2.5.0000—V2.5.0012(2026-09-28 至 09-29) | 总检多级审核、派单与匿名体检;体检指南;团体预约;体检模块库;基础档案迁入系统设置;员工检查指引单。 |

| V2.5.0013—V2.5.0019(2026-09-29 至 09-30) | 科室录入完善;检查项目数据字典扩充(八大类 576 项);医生原笔迹手写签名模板;报告智能解读模块上线。 |

| V2.5.0027—V2.5.0030(2026-10-03) | 交互优化(点名称打开编辑框);菜单与角色授权按页面模块授权;数据安全新增国密加密可选功能(SM2/SM3/SM4)。 |

开发阶段(V0.x,未纳入版本记录表)完成了基础链路与多租户体系的建设:登录鉴权(JWT+BCrypt+失败锁定)、劳动者建档(身份证解析+摘要去重)、体检登记(自动发号+软锁+乐观锁)、结果录入(参考区间自动判异常)、状态机与主检结论、报告 PDF 与通知书、多租户数据隔离、菜单角色授权等,为 V1.1.0000 正式上线奠定基础。

第2章 总体概述

2.1 业务概述

职业健康检查业务围绕用人单位与劳动者展开。用人单位委托体检机构对本单位接触职业病危害因素的劳动者进行健康检查;体检机构按劳动者接触的危害因素与体检类别(上岗前、在岗期间、离岗时、应急)确定应检项目,组织实施检查并出具结论与报告。本系统将上述业务划分为五个阶段:

● 准备阶段:维护用人单位、劳动者档案、接害因素、体检模块与套餐,建立团体预约;

● 登记阶段:劳动者到检签到,创建体检登记单,系统发号、关联套餐、生成应检项目并分诊到科室;

● 检查阶段:各科室医生依次录入检查结果与检验结果,系统自动比对参考区间、标记异常与敏感项异常,全程状态可跟踪;

● 结论阶段:主检医师出具主检小结与结论类型,经一级初审、二级复审后签发;

● 报告阶段:系统自动生成报告 PDF 与通知书文书(复查/转诊/调离),版本化归档,并提供统计、随访与到期预警。

四类体检类别的业务要点如下:

表 2-0 四类体检类别业务要点

| 体检类别 | 对象 | 业务要点 | 系统支持 |

| 上岗前体检 | 拟从事接害作业的新录用及转岗人员 | 排查职业禁忌证,建立接害前基线健康档案 | PRE 类别套餐、禁忌证结论联动调离通知书 |

| 在岗期间体检 | 在岗接害人员 | 按因素周期(cycle_months)定期检查,早期发现健康损害 | 周期到期预警、复查通知书、随访名单 |

| 离岗时体检 | 脱离接害岗位的人员 | 离岗健康结论,明确劳动关系双方的责任边界 | OFFJOB 类别套餐、离岗报告归档 |

| 应急健康检查 | 急性职业病危害事故接触者 | 事故后紧急医学检查与健康评估 | EMERG 类别、快速批量登记 |

2.2 系统建设目标

系统建设目标包括业务目标与合规目标两个层面。业务层面:实现职业健康检查「档案—登记—检查—结论—报告」全流程线上化,消除纸质流转,登记单全程状态可跟踪,报告自动生成,统计口径统一。合规层面:满足《职业病防治法》与 GBZ 188 对健康监护档案、检查项目、周期与结论处置的要求;满足政府采购对多级权限、国密加密、日志审计的信息安全要求;满足《个人信息保护法》对敏感个人信息的加密存储与访问控制要求。

2.3 系统设计原则

2.3.1 合规性原则

检查项目、套餐配置、检查周期、结论类型与通知书类型均依据 GBZ 188-2014 设置;系统内置国家标准目录维护「危害因素—目标疾病—必检项目」的映射规则;业务表单与报告内容覆盖职业健康检查报告的法定要素。

2.3.2 安全性原则

系统在身份认证(JWT + BCrypt + 失败锁定)、访问控制(菜单/接口/数据/字段四级隔离)、数据存储(SM4 字段加密、SM3 完整性校验、SM2 签名,可选开关)、审计追溯(操作日志与敏感访问审计不可篡改)四个层面实施纵深防御,敏感个人信息全程加密落盘。

2.3.3 可扩展原则

系统采用模块化设计:后端以独立子包组织(com.eqs.occupational),按控制器/服务/实体/数据访问分层;体检项目-模块-套餐三级配置支持机构按自身科室设置灵活组合;第三方接口适配器(AdapterRegistry)为 LIS/HIS 等外部系统预留标准接入通道;多租户架构支持机构规模化接入。

2.3.4 易用性原则

前端页面按业务角色组织导航,登录后仅渲染被授权菜单;登记、录入、审核等高频操作提供待办队列与快捷入口;智能导检按应检项目给出建议检查顺序;异常结果自动标红提示,减少人工核对负担。

2.3.5 稳定性原则

登记单采用状态机约束流转并用软锁与乐观锁防止并发冲突;基础数据逻辑删除保证历史引用完整;报告版本化留存;关键操作事务化并支持异常回滚,保障数据一致性。

2.4 系统技术架构

本系统采用前后端分离架构。前端为 Vue 3 单页应用(Element Plus 组件库、Vite 构建、Hash 路由),构建产物由 Nginx 提供静态服务;后端为 Java Spring Boot 应用(端口 8080),以独立功能子包(com.eqs.occupational)形式组织职业病体检业务的全部控制器、服务、实体与数据访问组件,通过 MyBatis-Plus 访问 MySQL 8.0 数据库(peis_db,utf8mb4 编码);前后端同源部署,浏览器请求经 Nginx 反向代理(/api/occupational-exam/ 前缀)转发至后端,无跨域问题。国密加密组件以可插拔方式嵌入数据访问层(MyBatis 类型处理器)与响应层,可整体开关。系统技术架构如图 2-1 所示。

下图展示系统五层技术架构,自上而下为客户端层、接入层、应用层、数据安全层与数据层,国密组件以可插拔方式独立成层,支持整体开关。

图 2-1 系统技术架构图

各层职责说明:客户端层面向体检登记员、科室医生、主检医师、机构管理员与平台超管五类角色提供浏览器访问入口;接入层由 Nginx 承担静态资源服务与 API 反向代理;应用层按功能域划分为认证鉴权、登记分诊、结果录入、结论审核、报告 PDF、统计分析、通知书、附件管理、租户管理与菜单授权十个子域;数据安全层汇集 SM4/SM3/SM2 国密组件与密钥管理、敏感访问审计;数据层包含业务数据库、文件存储与密钥文件。

2.5 部署架构

系统部署于应用服务器,部署组件包括:Nginx(静态资源与反向代理)、web-main 主服务(Spring Boot,含职业病体检子包)、MySQL 8.0 数据库(peis_db 业务库)、文件存储目录(报告 PDF、通知书、附件)与 SM4 密钥文件。数据备份采用数据库定时全量备份与文件目录备份相结合的方式。部署拓扑如图 2-2 所示。

下图展示生产环境部署拓扑,涵盖客户端区、Nginx 接入、主服务、数据库、文件存储、密钥文件与备份链路。

图 2-2 系统部署拓扑图

2.6 运行环境

2.6.1 服务端配置

表 2-1 服务端硬件配置

| 项目 | 最低配置 | 推荐配置 |

| CPU | 4 核 | 8 核 |

| 内存 | 8 GB | 16 GB |

| 磁盘 | 100 GB(含数据与备份空间) | 500 GB SSD |

| 网络 | 百兆内网 | 千兆内网 |

2.6.2 服务端软件环境

表 2-2 服务端软件环境

| 软件 | 版本要求 | 用途 |

| 操作系统 | Linux(CentOS 7+/Ubuntu 20+)或 Windows Server 2016+ | 运行环境 |

| JDK | Java 17 | 后端运行时 |

| MySQL | 8.0(utf8mb4) | 业务数据库 |

| Nginx | 1.20+ | 静态资源与反向代理 |

2.6.3 客户端环境

客户端为主流桌面浏览器:Google Chrome 90+、Microsoft Edge 90+ 及同内核国产浏览器,页面采用响应式布局自适应分辨率,无需安装任何客户端插件。

2.8 网络端口与服务清单

表 2-4 端口与服务清单

| 端口/位置 | 服务/组件 | 说明 |

| 80 / 443 | Nginx | 浏览器访问入口(HTTPS 推荐) |

| 8080 | web-main 主服务(含本系统子包) | 业务 API(经 Nginx 反代对外) |

| 3306 | MySQL 8.0 | 仅限本机/内网访问,不对公网开放 |

| — | 文件目录 files/occupational | 报告、通知书、附件存储 |

| — | 密钥文件 sm4_keys.json | SM4 密钥与开关,限服务账号可读 |

2.9 日志清单

表 2-5 系统日志清单

| 日志 | 位置 | 内容 |

| 服务运行日志 | 主服务日志文件 | 启动、请求异常、数据源状态 |

| Nginx 访问/错误日志 | nginx logs 目录 | 访问轨迹与代理错误 |

| 业务操作日志 | sys_oper_log 表 | 业务操作与安全事件审计 |

| 敏感访问审计 | sys_oper_log(敏感类别) | 明文查看/导出留痕 |

| 国密配置日志 | sys_oper_log(模块=数据安全) | 开关与密钥操作留痕 |

2.10 第三方依赖组件

表 2-3 第三方依赖组件清单

| 组件 | 版本 | 用途 |

| Vue 3 / Vite / Element Plus | 3.x / 5.x / 2.x | 前端框架与组件库 |

| Spring Boot / MyBatis-Plus | 2.7.x / 3.5.x | 后端框架与 ORM |

| java-jwt(com.auth0) | 4.4.0 | JWT 令牌签发与校验 |

| iText | 5.x(STSong 中文字体) | 报告与通知书 PDF 生成 |

| BCrypt(spring-security-crypto) | 随 Spring Boot | 口令哈希 |

| Bouncy Castle | 1.7x | SM2/SM3/SM4 国密算法实现 |

2.8 系统代码组织结构

表 2-6 系统代码组织结构

| 目录/包 | 内容说明 |

| com.eqs.occupational.controller | 业务控制器(登记、结果、结论、报告、统计、用户、租户、菜单、日志、国密配置等 40 个) |

| com.eqs.occupational.service | 核心服务(PDF 生成、登记、序列发号) |

| com.eqs.occupational.security | 数据安全组件(SM2/SM3/SM4、密钥管理、脱敏、会话、敏感审计等 21 个类) |

| com.eqs.occupational.entity / mapper | 实体与数据访问(MyBatis-Plus) |

| com.eqs.occupational.adapter | 第三方接口适配器(LIS/HIS 对接桩与注册器) |

| com.eqs.occupational.dongle | 加密狗授权(文件狗/硬件狗双实现) |

| web/src/views | 前端页面(Vue3,31 个业务页面) |

| web/src/router | permission | 路由与权限(动态菜单、路由守卫、模块/加密狗门禁) |

2.9 技术选型说明

前端选用 Vue 3:组合式 API 便于按业务域拆分页面组件,Element Plus 提供成熟的表格、表单与弹窗组件,适配体检业务大量列表录入场景;Vite 构建产物为纯静态文件,由 Nginx 直接服务,部署简单且与后端解耦。后端选用 Spring Boot:生态成熟、事务与数据访问支持完善,与既有主服务共用运行时降低运维成本;MyBatis-Plus 在保留 SQL 控制力的同时提供通用 CRUD 与乐观锁插件,契合单据类业务。数据库选用 MySQL 8.0:utf8mb4 支持全字符集存储,InnoDB 事务与行级锁满足登记单并发控制需求。国密算法实现基于 Bouncy Castle,以类型处理器方式嵌入 ORM 层,加解密对业务代码透明,支撑「可选开关」的设计要求。报告生成选用 iText 并内置 STSong 中文字体,保证跨平台部署 PDF 不缺字。

2.11 关键配置项说明

表 2-7 关键配置项说明

| 配置项 | 说明 | 示例 |

| spring.datasource.peis.* | 业务库 peis_db 连接配置(地址/账号/密码注入) | jdbc:mysql://127.0.0.1:3306/peis_db |

| peis.jwt-secret / peis.jwt-hours | JWT 签名密钥与令牌有效期(小时) | 随部署环境注入 |

| peis.file-dir | 报告/通知书/附件存储目录 | /var/www/java-backend/files/occupational |

| occ.sm4.keyfile | SM4 密钥文件路径(含开关与多版本密钥) | /opt/hdc/keys/sm4_keys.json |

| occ.sm4.backupdir | 密钥与加密相关备份目录 | /opt/hdc/backup |

| nginx location ^~ /api/occupational-exam/ | API 反向代理至 8080 | proxy_pass http://127.0.0.1:8080 |

| DB_PASSWORD | 数据库口令(secrets 注入,不落明文) | 由 secrets 文件提供 |

本章小结:本章梳理了七类业务角色与十八个关键用例,给出了建档、登记分诊、结果录入、两级审核、报告归档、随访预警六大完整业务流程与登记单状态机,并逐条对照了业务约束、合规要求与业务痛点,为后续模块设计提供了业务基准。

第3章 业务需求分析

3.1 业务角色梳理

表 3-1 业务角色一览

| 角色 | 职责 | 主要操作 |

| 企业对接人 | 受用人单位委托对接体检机构 | 提交批量体检名单、预约体检、接收通知书与报告 |

| 体检登记员 | 现场登记与分诊 | 建档、批量导入、签到登记、团体预约、导检引导 |

| 科室医生 | 执行科室检查 | 查看待检队列、录入检查结果、提交完成 |

| 主检医师 | 出具并维护主检结论 | 汇总结果、录入小结与结论、提交审核、按退回意见修改 |

| 审核医师(初审/复审) | 结论质控 | 一级初审、二级复审、通过/退回、签发 |

| 机构管理员 | 机构级系统管理 | 用户管理、菜单授权、基础档案维护、日志查询、加密开关 |

| 平台超级管理员 | 平台级治理 | 租户(机构)开通与停用、机构管理员密码重置、跨租户查询 |

各角色的职责边界与协作关系详述如下:企业对接人是用人单位的窗口,负责名单组织与结果接收,不直接操作系统业务单据;体检登记员是系统业务起点,负责建档、导入、签到、登记与导检,其操作质量直接决定档案唯一性与应检项目的准确性;科室医生只对本科室应检项目负责,录入时受套餐过滤与唯一约束保护;主检医师对结论质量负第一责任,审核医师独立行使质控职责,两者不得为同一人;机构管理员拥有机构内全部配置权限但不参与业务单据的业务判定;平台超管只做机构治理,不干预机构内业务数据。该职责划分实现「业务操作、质量判定、系统治理」三权分立。

3.2 角色用例分析

机构管理员承担机构级配置与治理职责,其用例覆盖用户、权限、基础档案、日志与数据安全配置,如图 3-1 所示;科室医生与登记员的用例覆盖建档、登记、录入与查询,如图 3-2 所示;主检医师与审核人的用例覆盖结论、审核、签发与统计查询,如图 3-3 所示。

图 3-1 机构管理员用例图

图 3-2 科室医生/登记员用例图

图 3-3 主检医师/审核人用例图

3.2.1 关键用例详述

选取业务链条上的十个关键用例详细说明如下(主流程、扩展流程与后置条件均与系统实现一致)。

表 3-4 用例 UC-01 劳动者建档用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-01 劳动者建档 |

| 参与者 | 登记员 |

| 前置条件 | 已登录且具备档案管理权限;加密开关状态已确定 |

| 主流程 | 1. 登记员进入个人体检页面,点击新建档案;2. 录入姓名与身份证号;3. 系统校验身份证并解析性别、出生日期;4. 计算 SHA-256 摘要查重;5. 录入单位、工种、接害工龄、健康史;6. 提交保存。 |

| 扩展流程 | 3a. 身份证非法:提示格式错误;4a. 摘要命中:提示已有档案并引导关联;5a. 单位不存在:先到用人单位档案新增。 |

| 后置条件 | 档案入库(敏感字段按开关加密),返回档案编号;操作写入日志。 |

表 3-5 用例 UC-02 批量导入建档用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-02 批量导入建档 |

| 参与者 | 登记员 |

| 前置条件 | 企业名单已按模板整理 |

| 主流程 | 1. 进入批量导入;2. 上传名单数据;3. 系统逐行校验(身份证、必填);4. 命中查重规则的行为关联或跳过;5. 提交后返回成功/失败明细。 |

| 扩展流程 | 3a. 行校验失败:失败明细标注原因,成功行正常入库;4a. 重复行:默认关联既有档案。 |

| 后置条件 | 返回导入统计(总数/成功/失败)与失败原因清单。 |

表 3-6 用例 UC-03 团体预约与批量登记用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-03 团体预约与批量登记 |

| 参与者 | 登记员 |

| 前置条件 | 用人单位档案已建立;套餐已配置 |

| 主流程 | 1. 新建团体预约(单位、类别、日期);2. 录入/导入预约名单;3. 到检日按名单逐人签到;4. 系统批量创建登记单并发号;5. 按套餐生成应检项目并分诊。 |

| 扩展流程 | 4a. 个别人员建档失败:返回逐单失败原因,不影响其他人;5a. 名单中接害因素与套餐不匹配:提示调整。 |

| 后置条件 | 批量登记结果(成功单数、失败明细),各科室待检队列出现新单据。 |

表 3-7 用例 UC-04 体检登记发号用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-04 体检登记发号 |

| 参与者 | 登记员 |

| 前置条件 | 劳动者档案存在 |

| 主流程 | 1. 选择劳动者与体检类别;2. 选择套餐与本次接害因素;3. 提交创建登记单;4. 系统从序列表原子发放 TJ 编号;5. 生成应检项目集合。 |

| 扩展流程 | 2a. 因素无对应套餐:提示先配置套餐;4a. 发号失败重试由事务保障唯一性。 |

| 后置条件 | 登记单创建成功,状态 REGISTERED,进入待检队列。 |

表 3-8 用例 UC-05 科室结果录入用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-05 科室结果录入 |

| 参与者 | 科室医生 |

| 前置条件 | 登记单已分诊到本科室且未被他人软锁 |

| 主流程 | 1. 打开科室录入待检队列;2. 领取登记单(加软锁,状态 CHECKING);3. 按套餐过滤的应检项目逐项录入;4. 数值型自动比对参考区间;5. 敏感项异常自动标红;6. 保存并提交完成(状态 CHECKED)。 |

| 扩展流程 | 2a. 单据被他人占用:提示持有人;4a. 超区间:自动判异常;6a. 存在未录必检项:阻止提交完成。 |

| 后置条件 | 结果入库(带项目名快照与医生留痕),登记单流转至 CHECKED。 |

表 3-9 用例 UC-06 主检结论出具用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-06 主检结论出具 |

| 参与者 | 主检医师 |

| 前置条件 | 登记单状态 CHECKED |

| 主流程 | 1. 打开主检工作台选中登记单;2. 查看各科结果与异常/敏感项汇总;3. 录入主检小结与结论类型;4. 保存结论;5. 提交审核任务。 |

| 扩展流程 | 3a. 结论与敏感项异常矛盾:界面提示复核;5a. 可指定审核人或进入公共池。 |

| 后置条件 | 结论保存(与登记单一对一),审核任务创建。 |

表 3-10 用例 UC-07 一级初审用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-07 一级初审 |

| 参与者 | 审核医师 |

| 前置条件 | 存在待初审任务 |

| 主流程 | 1. 打开总检审核工作台;2. 核对结论与各科结果一致性;3. 通过:按配置流转二级复审或直接签发;4. 退回:填写意见。 |

| 扩展流程 | 3a. 未配置二级复审:初审通过即签发;4a. 退回后主检医师修改再提交,重新进入初审。 |

| 后置条件 | 任务状态更新,审核历史新增一轮记录。 |

表 3-11 用例 UC-08 二级复审与签发用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-08 二级复审与签发 |

| 参与者 | 授权复审人 |

| 前置条件 | 审核配置启用二级复审;初审已通过 |

| 主流程 | 1. 复审人打开待复审任务;2. 复核结论;3. 通过并签发:记录签发人与时间;4. 状态 SIGNED。 |

| 扩展流程 | 3a. 复审退回:携带意见回到主检医师;4a. 签发后如需修改须重出报告流程。 |

| 后置条件 | 结论生效,触发报告 PDF 生成。 |

表 3-12 用例 UC-09 报告生成与重出用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-09 报告生成与重出 |

| 参与者 | 主检医师/管理员 |

| 前置条件 | 结论已签发 |

| 主流程 | 1. 触发生成接口;2. 系统汇总数据生成 PDF;3. REP 编号入库;4. 异常结论联动通知书生成;5. 预览/下载。 |

| 扩展流程 | 2a. SM3 校验失败的字段:阻止出报告并告警;5a. 重出:version+1,旧版本留存。 |

| 后置条件 | 报告与通知书 PDF 落盘,报告中心可查可下载。 |

表 3-13 用例 UC-10 周期体检到期预警用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-10 周期体检到期预警 |

| 参与者 | 机构管理员 |

| 前置条件 | 接害因素已配置检查周期 |

| 主流程 | 1. 打开汇总报表随访查询;2. 按因素周期计算到期名单;3. 输出即将到期/已到期人员;4. 通知企业安排体检。 |

| 扩展流程 | 2a. 人员离岗/离职:名单中过滤或标注。 |

| 后置条件 | 到期预警名单(可导出),随访闭环记录。 |

表 3-14 用例 UC-11 体检模块配置用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-11 体检模块配置 |

| 参与者 | 机构管理员 |

| 前置条件 | 项目库与科室已维护 |

| 主流程 | 1. 进入体检模块页签;2. 新建模块并绑定归属科室;3. 勾选包含项目;4. 保存并核验模块-项目关系。 |

| 扩展流程 | 3a. 含已停用项目:保存时提示剔除。 |

| 后置条件 | 模块可供套餐引用。 |

表 3-15 用例 UC-12 菜单与角色授权用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-12 菜单与角色授权 |

| 参与者 | 机构管理员 |

| 前置条件 | 角色与菜单种子存在 |

| 主流程 | 1. 进入菜单与角色授权页;2. 选择角色;3. 勾选菜单(父子联动);4. 保存;5. 目标用户重新登录或刷新验证。 |

| 扩展流程 | 3a. 仅勾子菜单:系统联动勾父目录。 |

| 后置条件 | 授权即时生效;操作留痕。 |

表 3-16 用例 UC-13 租户开通用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-13 租户开通 |

| 参与者 | 平台超管 |

| 前置条件 | 平台级权限 |

| 主流程 | 1. 进入租户管理;2. 录入机构名称与管理员账号;3. 提交开通;4. 交付机构管理员初始口令(BCrypt 存储)。 |

| 扩展流程 | 2a. 名称重复:提示调整。 |

| 后置条件 | 新机构可独立登录使用,数据与其他租户隔离。 |

表 3-17 用例 UC-14 附件上传用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-14 附件上传 |

| 参与者 | 登记员/医生 |

| 前置条件 | 存在关联业务单号 |

| 主流程 | 1. 进入附件管理;2. 选择业务单号与附件类型;3. 上传 jpg/png/pdf(≤10MB);4. 预览或软删作废。 |

| 扩展流程 | 3a. 超限或类型不符:预校验拦截。 |

| 后置条件 | 附件挂接单号,可追溯。 |

表 3-18 用例 UC-15 危急值处理用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-15 危急值处理 |

| 参与者 | 检验/质控人员 |

| 前置条件 | 存在危急值记录 |

| 主流程 | 1. 质控页登记危急值(对象、项目、数值);2. 通知责任医生;3. 医生处理并填写意见;4. 质控确认闭环。 |

| 扩展流程 | 3a. 超时未处理:页内持续警示。 |

| 后置条件 | 闭环记录留存。 |

表 3-19 用例 UC-16 收费与结算用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-16 收费与结算 |

| 参与者 | 机构财务/管理员 |

| 前置条件 | 体检单据已产生 |

| 主流程 | 1. 进入收费与结算;2. 按登记单/单位登记费用项目与金额;3. 按单位维度汇总对账;4. 导出对账数据。 |

| 扩展流程 | 3a. 差异:按单据逐笔核对。 |

| 后置条件 | 对账数据可导出留存。 |

表 3-20 用例 UC-17 系统参数配置用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-17 系统参数配置 |

| 参与者 | 机构管理员 |

| 前置条件 | 管理员权限 |

| 主流程 | 1. 进入系统设置;2. 维护机构名称、体检指南、登录底图;3. 保存;4. 前端即时呈现(医生角色只读)。 |

| 扩展流程 | — |

| 后置条件 | 参数生效无需重启。 |

表 3-21 用例 UC-18 报告智能解读用例描述

| 项目 | 内容 |

| 用例名称 | 用例 UC-18 报告智能解读 |

| 参与者 | 主检医师 |

| 前置条件 | 报告已生成 |

| 主流程 | 1. 进入报告智能解读;2. 选择报告;3. 系统基于项目知识库生成解读要点;4. 医生复核修正后留存。 |

| 扩展流程 | 3a. 无匹配知识:仅呈现结果要点。 |

| 后置条件 | 解读记录与日志留存。 |

3.2.2 页面-接口-数据表映射

表 3-14 页面-接口-数据表映射矩阵

| 页面 | 主要控制器 | 涉及数据表 |

| 工作台 | StatController | biz_register / biz_conclusion |

| 个人体检(劳动者档案) | OccupationalWorkerController | biz_worker / biz_employer |

| 单位体检 | OccupationalWorkerController / RegisterController | biz_worker / biz_register |

| 体检指南 | GuideController | base_dict / 系统参数 |

| 团体预约 | RegisterController | biz_register / biz_register_hazard |

| 体检登记 | RegisterController | biz_register / base_package / biz_register_hazard |

| 科室录入 | ResultController / OccLabController | biz_exam_result / biz_lab_result / base_exam_item |

| 主检结论 | ConclusionController | biz_conclusion / conclusion_task |

| 总检审核 | ConclusionController | conclusion_task / conclusion_audit / review_config |

| 报告中心 | ReportController | biz_report / biz_register |

| 报告智能解读 | InterpretController | exam_report_interpret / exam_item_knowledge |

| 解读知识库 | InterpretController | exam_item_knowledge |

| 通知书 | OccNoticeController | biz_notice |

| 附件管理 | AttachController | sys_attach |

| 汇总报表 | StatController | biz_register / biz_conclusion / biz_worker |

| 基础档案 | BaseDataController / ModuleLibController / StdCatalogController | base_* 全系 / std_* 系 |

| 菜单与角色授权 | OccMenuController | sys_menu / sys_role / sys_role_menu |

| 操作日志 | OperLogController | sys_oper_log |

| 加密狗授权 | DongleController | 授权文件 / 日志 |

| 数据安全 | SecurityController / GmConfigController | 国密配置 / sys_oper_log |

| 租户管理 | OccTenantController | sys_tenant / sys_user |

| 用户管理 | UserManageController | sys_user / sys_user_role |

| 系统设置 | OccConfigController / OccLoginBgController | 系统参数 |

| 版本记录 | OccVersionController | 版本信息 |

| 第三方接口配置 | AdapterConfigController | adapter_config |

| 质控与危急值 | QualityController | 危急值记录 |

| 收费与结算 | FinanceController | 费用记录 |

| 报告模板 | ReportTemplateController | 模板配置 |

| 项目规则 | ItemRuleController | std_exam_rule / base_exam_item |

| 国家标准 | StdCatalogController | std_* 系 |

| 智能导检 | RegisterController(/guide) | biz_register / base_package_item |

3.3 完整业务流程

3.3.1 企业批量人员建档流程

企业对接人按系统模板整理劳动者花名册(姓名、身份证号、工种、接害因素),登记员通过批量导入接口提交。系统逐行校验身份证号合法性并解析出生日期与性别,计算身份证 SHA-256 摘要执行唯一性查重:命中已有档案的关联既有记录并补充本次接害信息,未命中的新建档案;敏感字段按加密开关状态决定 SM4 加密或明文落盘。导入完成后返回成功/失败明细,失败行标注原因供修正重导。流程如图 3-4 所示。

下图展示企业批量建档流程,含身份证解析、摘要查重与失败明细回流。

图 3-4 企业批量人员建档流程图

3.3.2 体检预约、签到分诊流程

机构与企业确定体检计划后建立团体预约单(用人单位、体检类别、计划日期)。劳动者到检后由登记员核验身份并创建个人体检登记单:系统按「年月日+当日序号」规则自动发放 TJ 编号,登记单关联套餐与本次接害因素,生成应检项目集合,并按项目所属科室自动分诊。各科室待检队列实时可见,医生领单后进入检查环节。流程如图 3-5 所示。

下图展示从团体预约到科室分诊的登记链路,登记单自动发号并生成应检项目。

图 3-5 体检预约、签到与分诊流程图

3.3.3 各科室录入检查结果流程

科室医生从本科室待检队列选取登记单,系统按套餐精确过滤本科室应检项目。医生录入文本或数值结果:数值型即时与参考区间比对自动判定;文本型由医生勾选异常标志;职业敏感项异常自动升级为敏感项异常标记并标红。全部应检项目录入完成后提交,登记单流转至 CHECKED 状态。流程如图 3-6 所示。

下图展示科室结果录入流程,含参考区间自动判定与敏感项异常升级。

图 3-6 科室检查结果录入流程图

3.3.4 一级审核、二级复审流程

主检医师对 CHECKED 状态的登记单出具主检小结与结论类型,提交审核任务。一级初审核对结论与检查结果一致性:通过则按审核配置进入二级复审或直接签发;退回则携带意见回到主检医师修改。二级复审通过后执行签发,签发人与签发时间落库。审核历史记录每一轮动作,全程可追溯。流程如图 3-7 所示。

下图展示初审、复审与退回回路,审核历史逐轮留痕。

图 3-7 主检结论一级审核、二级复审流程图

3.3.5 体检报告生成、预览、打印、归档流程

结论签发触发报告生成:服务端汇总登记、档案、结果、结论数据生成报告 PDF(REP 编号),异常结论同步生成通知书 PDF。报告中心提供在线预览与下载;重新生成时版本号加一,历史版本留存;完成后登记单归档(ARCHIVED),PDF 与附件统一目录存储。流程如图 3-8 所示。

下图展示报告生成、通知书联动与版本化归档流程。

图 3-8 体检报告生成、预览、打印与归档流程图

3.3.6 异常指标随访、复检提醒流程

汇总报表的随访查询按结论类型筛出复查、疑似职业病、职业禁忌证名单;机构对复查人员出具复查通知书并跟踪复检登记;系统按接害因素的检查周期计算到期应检名单,输出周期体检到期预警,提醒机构通知企业安排体检,形成随访闭环。流程如图 3-9 所示。

下图展示随访名单提取、复查通知书送达与周期到期预警的闭环。

图 3-9 异常指标随访与复检提醒流程图

3.3.7 登记单状态机

登记单状态是全流程跟踪的主线,状态机如图 3-10 所示。状态流转仅允许沿合法路径推进,后端对越序流转返回业务异常并记录日志;软锁与乐观锁保证多人并发操作同一登记单时的数据一致性。

下图展示登记单六态状态机与取消分支,越序流转由后端统一拦截。

图 3-10 体检登记单状态机图

3.4 业务约束与合规要求

表 3-2 业务约束与合规要求对照

| 约束类别 | 约束内容 | 系统落实方式 |

| 检查规范 | 按 GBZ 188 确定应检项目与检查周期 | 国家标准目录 + 套餐按因素×类别配置 + 周期字段到期预警 |

| 档案要求 | 劳动者职业健康监护档案一人一档 | 身份证 SHA-256 唯一索引去重,档案关联历次体检 |

| 结论处置 | 复查/疑似职业病/职业禁忌证按规定处置 | 四类结论 + 复查/转诊/调离通知书自动生成 |

| 周期体检 | 在岗人员按因素周期复检 | cycle_months 到期预警名单 |

| 信息保护 | 身份证号等敏感个人信息加密与访问控制 | SM4 加密存储 + 字段权限脱敏 + 明文查看审计 |

| 责任追溯 | 检查、审核、签发全程留痕 | 操作日志 + 审核历史 + 敏感访问审计,仅增不改 |

3.5 业务痛点与系统解决方案对照

表 3-3 业务痛点与解决方案对照表

| 业务痛点 | 系统解决方案 |

| 纸质档案检索困难,历史体检记录难以关联 | 劳动者电子档案 + 登记单全流程线上化 + 归档检索接口 |

| 套餐口径不一,应检项目靠人工记忆 | 项目-模块-套餐三级配置,登记单自动生成应检项目集合,应检/已录进度可视 |

| 结果录入重复、异常靠人眼核对 | 参考区间自动比对、敏感项异常自动标红、唯一约束防重复录入 |

| 结论质量依赖个人,缺乏质控 | 审核任务分派 + 一级初审/二级复审 + 审核历史全程留痕 |

| 报告编制工作量大、格式不统一 | 报告 PDF 按模板自动生成、版本化管理、通知书联动出具 |

| 周期体检到期无人提醒 | 按因素检查周期自动计算到期名单并预警 |

| 敏感信息明文存放存在泄露风险 | 国密 SM4 字段加密(可选开关)、SM3 防篡改、字段权限脱敏、明文查看审计 |

| 多人操作冲突、数据覆盖 | 登记单软锁 + 乐观锁 version + 状态机越序拦截 |

3.6 业务单据流转说明

系统四类核心单据的产生、流转与留存规则如下:

表 3-14 业务单据流转说明

| 单据 | 产生环节 | 流转路径 | 控制机制 | 去向 |

| 体检登记单 biz_register | 登记员创建 | 状态机 REGISTERED→CHECKING→CHECKED→CONCLUDED→SIGNED→ARCHIVED | 软锁+乐观锁;取消仅限检查前 | 状态驱动全部待办队列 |

| 主检结论 biz_conclusion | 主检医师出具 | 草稿→提交→初审→(复审)→签发 | 与登记单一对一;职责分离 | 签发触发报告 |

| 审核任务 conclusion_task | 结论提交时生成 | 待审→通过/退回 | 审核历史逐轮留痕 | 退回回主检医师 |

| 报告 biz_report | 签发触发 | GENERATED→(重出版本+1)→SIGNED/CANCELED | REP 编号唯一;版本化 | 预览/下载/归档 |

| 通知书 biz_notice | 异常结论联动生成 | 生成→送达 | NTC 编号唯一 | 复查/转诊/调离三类 |

3.7 系统数据流说明

系统顶层数据流为:企业对接人提供体检名单与单位信息,经建档处理后形成劳动者档案与用人单位档案;登记环节将档案、套餐、因素组合为体检登记单;科室录入环节产生检查/检验结果并回流到登记单状态;主检与审核环节消费结果数据产生结论与审核记录;报告环节消费结论产生报告 PDF 与通知书;统计环节聚合登记、结果、结论数据产生报表、随访名单与预警;全部环节的写操作汇入操作日志与敏感审计。数据流经国密组件时,敏感字段在存储侧加密、在使用侧按授权解密,密钥由密钥文件统一管理。

本章小结:本章给出五域三十一页面的模块总图与总览,说明了模块间数据交互、依赖关系与页面-接口-数据表映射,第 5 章将按统一格式展开每个模块的详细设计。

第4章 系统功能模块总体设计

4.1 系统模块总图

系统按业务职能划分为业务办理域、报告文书域、基础数据域、统计分析域与系统支撑域五个域,共三十一功能页面。模块总图如图 4-1 所示。

下图按五个功能域组织系统全部功能页面,域内模块高内聚、域间通过数据表与接口协作。

图 4-1 系统功能模块总图

4.2 模块总览

表 4-1 模块总览表

| 功能域 | 模块 | 主要功能 |

| 业务办理域 | 团体预约 / 体检登记 / 科室录入 / 智能导检 / 主检结论 / 总检审核 | 预约、建档登记、发号分诊、结果录入、结论出具与多级审核 |

| 报告文书域 | 报告中心 / 通知书 / 报告模板 / 附件管理 / 报告智能解读 | PDF 生成预览下载、三类通知书、模板配置、附件、报告解读辅助 |

| 基础数据域 | 基础档案 / 用人单位 / 劳动者档案 / 国家标准 / 项目规则 / 体检模块库 | 因素、项目、套餐、科室、字典、标准目录、模块库 |

| 统计分析域 | 工作台 / 汇总报表 / 收费结算 / 质控与危急值 | 在办指标、四维统计、费用对账、危急值闭环 |

| 系统支撑域 | 用户管理 / 菜单角色授权 / 租户管理 / 操作日志 / 数据安全 / 系统设置 / 加密狗授权 | 账号权限、多租户、审计、国密加密、参数配置 |

4.3 模块间数据交互

模块间的核心数据交互关系为:基础数据域向业务办理域提供套餐与应检项目规则;登记模块向录入模块提供待检队列与应检项目集合;录入模块向审核模块提供结果与异常标记;审核模块向报告模块提供签发结论;报告模块向统计模块提供报告与结论数据;系统支撑域的权限、租户、日志与加密组件横向服务于全部业务模块。各模块详细设计见第 5 章。

4.5 功能页面逐页说明

系统前端共 31 个功能页面,逐页说明功能定位、主要控件、典型操作、数据来源与访问权限如下:

4.5.1 工作台 Dashboard

功能定位:机构运营总览:今日各环节在办量与本月完成量一目了然,是在办业务的驾驶舱。

主要控件:指标卡×4(今日登记/检查中/待审核/本月已完成)。

典型操作:

● 查看在办单据列表。

● 点击单据跳转对应环节。

● 按状态筛选。

数据来源:biz_register / biz_conclusion;访问权限:全部业务角色。

4.5.2 个人体检(劳动者档案)

功能定位:劳动者一人一档的建档与维护入口,支持单人建档与批量导入,身份证自动解析去重。

主要控件:档案列表、新建/编辑弹窗、批量导入、检索栏。

典型操作:

● 建档。

● 导入名单。

● 修正失败行。

● 关联既有档案。

● 查看掩码/授权明文。

数据来源:biz_worker / biz_employer;访问权限:登记员及以上。

4.5.3 单位体检

功能定位:以用人单位为维度的体检组织视图,查看单位下人员的体检安排与进度。

主要控件:单位列表、单位详情、人员进度表。

典型操作:

● 按单位筛选人员。

● 查看人均进度。

● 发起单位维度统计。

数据来源:biz_employer / biz_worker / biz_register;访问权限:登记员及以上。

4.5.4 体检指南

功能定位:面向机构的体检须知与注意事项展示,内容由系统参数在线维护。

主要控件:图文指南页。

典型操作:

● 阅读指南内容(管理员在系统设置中维护)。

数据来源:系统参数;访问权限:全部角色。

4.5.5 团体预约

功能定位:企业团体体检的预约与名单管理入口,预约单关联批量登记。

主要控件:预约单列表、新建预约弹窗、名单维护。

典型操作:

● 新建预约(单位/类别/日期)。

● 导入名单。

● 到检签到触发批量登记。

数据来源:biz_register / biz_employer;访问权限:登记员及以上。

4.5.6 体检登记

功能定位:日常登记主页面:创建登记单、发号、分诊与全程状态跟踪。

主要控件:登记单列表、新建登记、团体批量登记、检索区。

典型操作:

● 创建登记单。

● 领取/释放软锁。

● 状态流转。

● 查看应检进度。

数据来源:biz_register / base_package / biz_register_hazard;访问权限:登记员及以上。

4.5.7 科室录入

功能定位:各科室医生的结果录入工作区,按套餐精确过滤应检项目。

主要控件:待检队列、项目录入表格、保存/提交按钮。

典型操作:

● 领单。

● 录入文本/数值结果。

● 查看自动判定。

● 提交完成。

数据来源:biz_exam_result / biz_lab_result / base_exam_item;访问权限:科室医生。

4.5.8 主检结论

功能定位:主检医师出具结论的工作区,汇总各科结果与异常项。

主要控件:结论表单(小结/类型/复查建议)、异常项汇总。

典型操作:

● 录入小结。

● 选择结论类型。

● 保存并提交审核。

数据来源:biz_conclusion / biz_exam_result;访问权限:主检医师。

4.5.9 总检审核

功能定位:初审/复审的质控工作台,处理审核任务并留痕。

主要控件:任务列表、结论详情、通过/退回/签发按钮。

典型操作:

● 核对一致性。

● 初审。

● 复审。

● 签发。

● 查看审核历史。

数据来源:conclusion_task / conclusion_audit / review_config;访问权限:审核医师/主检。

4.5.10 报告中心

功能定位:报告 PDF 的生成、预览、下载与版本管理。

主要控件:报告列表、检索区、预览/下载/重出按钮。

典型操作:

● 生成报告(校验签发)。

● 预览 PDF。

● 下载。

● 重出版本+1。

数据来源:biz_report / biz_register;访问权限:主检/管理员。

4.5.11 报告智能解读

功能定位:基于项目知识库对报告要点做辅助解读,供医生复核使用。

主要控件:解读页、知识条目引用、复核修正。

典型操作:

● 选择报告。

● 生成解读。

● 修正保存。

数据来源:exam_report_interpret / exam_item_knowledge;访问权限:主检医师。

4.5.12 解读知识库

功能定位:维护项目级解读知识与提示文案的知识管理页。

主要控件:知识条目列表、编辑弹窗。

典型操作:

● 新增/编辑知识。

● 按项目关联。

数据来源:exam_item_knowledge;访问权限:主检/管理员。

4.5.13 通知书

功能定位:复查/转诊/调离三类文书的管理与下载。

主要控件:通知书列表、类型页签、预览/下载。

典型操作:

● 查看文书。

● 下载 PDF。

● 核对送达。

数据来源:biz_notice;访问权限:主检/管理员。

4.5.14 附件管理

功能定位:病历等佐证材料的上传与维护,按业务单号挂接。

主要控件:附件列表、上传控件、预览。

典型操作:

● 上传(类型/大小校验)。

● 预览。

● 软删作废。

数据来源:sys_attach;访问权限:登记员及以上。

4.5.15 汇总报表

功能定位:四维度统计分析与随访、预警名单输出。

主要控件:维度页签、过滤区、统计表、导出按钮。

典型操作:

● 切换维度。

● 设置区间。

● 导出 CSV。

● 查随访名单。

● 看到期预警。

数据来源:biz_register / biz_conclusion / biz_worker;访问权限:管理员/主检。

4.5.16 基础档案

功能定位:因素/项目/模块/套餐/科室/字典的标准配置中心。

主要控件:多页签、列表、编辑弹窗。

典型操作:

● 维护各基础档案。

● 配置模块与套餐。

● 核对标准映射。

数据来源:base_* 全系;访问权限:管理员(医生只读)。

4.5.17 菜单与角色授权

功能定位:角色-菜单授权管理,驱动侧栏动态渲染。

主要控件:角色选择、菜单树勾选、保存。

典型操作:

● 按角色勾选菜单。

● 保存即时生效。

数据来源:sys_menu / sys_role_menu;访问权限:管理员。

4.5.18 操作日志

功能定位:全系统操作留痕的检索审计页。

主要控件:检索区、日志列表、明细展开。

典型操作:

● 按操作人/模块/时间检索。

● 核查敏感访问记录。

数据来源:sys_oper_log;访问权限:管理员。

4.5.19 加密狗授权

功能定位:模块级授权管理(文件狗/硬件狗),控制功能开通。

主要控件:授权状态、模块开关。

典型操作:

● 查看授权。

● 按授权开通模块。

数据来源:授权文件 / 日志;访问权限:管理员。

4.5.20 数据安全

功能定位:国密加密的配置与审计中心。

主要控件:加密开关、算法配置、密钥信息、审计表。

典型操作:

● 开关加密。

● 配置密钥。

● 轮换。

● 核查审计。

数据来源:国密配置 / sys_oper_log;访问权限:管理员。

4.5.21 租户管理

功能定位:平台超管治理多机构(开通/停用/重置)。

主要控件:租户列表、开通弹窗、状态操作。

典型操作:

● 开通机构。

● 停用。

● 重置机构管理员密码。

数据来源:sys_tenant / sys_user;访问权限:平台超管。

4.5.22 关于本系统

功能定位:系统版本与说明页,内嵌设计方案文档与实时版本接口。

主要控件:版本信息、说明页。

典型操作:

● 查看当前版本与功能说明。

数据来源:版本接口;访问权限:管理员/平台管理员。

4.5.23 国家标准

功能定位:GBZ 188 标准目录浏览:因素、疾病、必检项目规则。

主要控件:标准目录树、规则列表。

典型操作:

● 浏览标准条目。

● 核对套餐配置依据。

数据来源:std_* 系;访问权限:全部角色。

4.5.24 项目规则

功能定位:机构级项目规则配置,覆盖标准推荐。

主要控件:规则列表、编辑。

典型操作:

● 按因素配置机构级必检规则。

数据来源:std_exam_rule / base_exam_item;访问权限:管理员。

4.5.25 质控与危急值

功能定位:检验危急值登记、通知与闭环跟踪。

主要控件:危急值列表、登记表单、处理记录。

典型操作:

● 登记危急值。

● 通知医生。

● 确认闭环。

数据来源:危急值记录;访问权限:检验/质控。

4.5.26 智能导检

功能定位:按登记单给出建议检查顺序,减少排队。

主要控件:单号输入、顺序表。

典型操作:

● 输入登记单号。

● 获取导检建议。

数据来源:biz_register / base_package_item;访问权限:登记员/医生。

4.5.27 收费与结算

功能定位:体检业务的费用登记与单位对账。

主要控件:费用列表、登记表单、对账汇总。

典型操作:

● 登记费用。

● 按单位对账。

● 导出。

数据来源:费用记录;访问权限:财务/管理员。

4.5.28 报告模板

功能定位:报告 PDF 版式与内容的模板配置。

主要控件:模板列表、编辑器。

典型操作:

● 配置报告分区与字段呈现。

数据来源:模板配置;访问权限:管理员。

4.5.29 系统设置

功能定位:机构名称、体检指南、登录底图等参数维护。

主要控件:参数表单。

典型操作:

● 管理员编辑保存。

● 医生只读。

数据来源:系统参数;访问权限:管理员(医生只读)。

4.5.30 版本记录

功能定位:系统发布历史登记与查看。

主要控件:版本列表。

典型操作:

● 查看历次发布内容。

数据来源:版本信息;访问权限:全部角色。

4.5.31 第三方接口配置

功能定位:LIS/HIS 等适配器的参数配置与连通测试。

主要控件:适配器列表、参数表单、测试按钮。

典型操作:

● 配置对接参数。

● 执行连通测试。

数据来源:adapter_config;访问权限:管理员。

4.6 模块依赖关系说明

模块间依赖遵循单向分层:业务办理域依赖基础数据域(套餐/项目/因素)与系统支撑域(鉴权/租户/日志/加密);报告文书域依赖业务办理域产生的结论数据;统计分析域为只读聚合,不反向修改业务数据;报告文书与统计分析均不直接依赖彼此。国密加密组件位于数据访问层,对全部模块透明,开关状态不改变模块间调用关系。该依赖结构保证任一业务模块可独立升级而不影响整体。

第5章 各模块详细设计

本章按统一格式描述各模块的功能描述、输入参数、业务处理逻辑、输出结果、页面原型说明与接口设计。接口清单摘自系统实际代码(控制器与路由映射),数据库表结构详见第 6 章。

5.1 基础数据管理模块详细设计

5.1.1 功能描述

基础数据管理模块是全系统业务运行的数据基座,负责维护职业健康检查业务所依赖的各类静态与半静态基础档案,包括:职业病危害因素(接害因素)库、检查项目库、体检套餐库、科室名录、数据字典、国家标准目录(GBZ 188 等职业健康监护技术规范对应的项目规则)以及体检模块库。该模块采用「危害因素 → 体检模块 → 科室项目」三层业务架构:管理员先维护科室与项目,再将项目组合为体检模块并绑定归属科室,体检套餐仅引用模块而不重复创建项目,从而保证「一处定义、处处引用」,避免项目库冗余与口径不一致。

5.1.2 输入参数

管理员在基础档案页面的操作指令(新增/编辑/停用/删除)、各基础实体的业务字段(因素编码、因素名称、目标疾病、检查周期、依据条款;项目编码、项目名称、所属科室、值类型、单位、参考区间上下限、职业敏感项标志;套餐名称、对应因素、体检类别、规范版本等)、分页与查询条件。

5.1.3 业务处理逻辑

1. 请求进入后端后先由认证拦截器校验 JWT 合法性,并从令牌中解析用户身份、角色与租户标识(tenant_id);

2. 对写操作校验当前用户是否具有管理员角色,非管理员角色仅允许查询(医生角色在页面上按只读呈现,后端同样拦截写请求);

3. 新增记录时校验编码唯一性(因素编码、项目编码等均设唯一索引),校验数值型项目的参考区间上下限合法性(下限不得大于上限);

4. 编辑操作采用乐观锁机制防止并发覆盖,删除采用逻辑删除(del_flag 标记),保证历史体检单据中对基础数据的引用可追溯;

5. 体检模块库维护模块与项目的多对多关系(base_module_item),套餐与模块的引用关系单独建表(base_package_module),引用关系变更时校验引用完整性;

6. 国家标准目录维护危害因素—目标疾病—必检项目的映射规则(std_hazard / std_disease / std_exam_rule 系列表),供套餐配置时按 GBZ 188 自动推荐应检项目;

7. 全部操作写入操作日志(模块、动作、业务单号、IP、明细)。

5.1.4 输出结果

各基础实体列表(分页)、操作成功/失败响应、字典下拉数据;基础数据变更后即时反映到体检登记的套餐过滤与应检项目生成逻辑中。

关键输出样例:

factor_code F06 / factor_name 电焊烟尘 / cycle_months 12 / basis GBZ188-2014 …

item_code I12 / item_name 心电图 / dept 内科 / abnormal_flag 0

package_code PKG0148 / package_name 电焊烟尘作业套餐(在岗期间)

5.1.5 页面原型说明

前端「基础档案」页面按页签组织接害因素、检查项目、体检套餐、科室、字典、国家标准、体检模块库等子页签,管理员角色可编辑,医生角色打开为只读;列表支持关键字检索与分页,编辑弹窗带字段级校验。

界面布局说明:页面采用左侧固定导航 + 顶部当前位置栏 + 右侧内容区的经典后台布局,内容区顶部为操作工具栏(新增、批量、导出等高频按钮),中部为过滤检索区,主体为数据表格区;表格支持分页、关键字过滤与状态筛选,行内操作按钮按当前行状态动态显示。弹窗类操作(新建、编辑、审核意见)均以模态弹窗承载,表单字段带必填与格式校验提示。

交互说明:列表数据异步分页加载,不整页刷新;表单提交带防重复点击处理;操作结果以消息条即时反馈(成功/警告/错误分级);批量操作返回逐行结果明细;打印与导出场景适配 A4 纸张版式。

5.1.6 接口设计

表 5-1 基础数据管理模块接口清单(55项)

| 方法 | 接口路径 | 处理方法 | 功能说明 |

| GET | /api/occupational-exam/base/hazard-factors | factors | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/hazard-factors | addFactor | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| PUT | /api/occupational-exam/base/hazard-factors/{id} | updFactor | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| DELETE | /api/occupational-exam/base/hazard-factors/{id} | delFactor | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| GET | /api/occupational-exam/base/items | items | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/items | addItem | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| PUT | /api/occupational-exam/base/items/{id} | updItem | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| DELETE | /api/occupational-exam/base/items/{id} | delItem | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| GET | /api/occupational-exam/base/packages | packages | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/packages | addPackage | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| PUT | /api/occupational-exam/base/packages/{id} | updPackage | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| DELETE | /api/occupational-exam/base/packages/{id} | delPackage | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| GET | /api/occupational-exam/base/packages/{id}/items | packageItems | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/packages/{id}/items | savePackageItems | 套餐项目明细:查看 |

| GET | /api/occupational-exam/base/depts | depts | 套餐项目明细:整体覆盖保存 |

| POST | /api/occupational-exam/base/depts | addDept | 套餐项目明细:整体覆盖保存 |

| PUT | /api/occupational-exam/base/depts/{id} | updDept | 套餐项目明细:整体覆盖保存 |

| PUT | /api/occupational-exam/base/depts/{id}/items | saveDeptItems | 套餐项目明细:整体覆盖保存 |

| DELETE | /api/occupational-exam/base/depts/{id} | delDept | 科室负责的检查项目:整体覆盖分配(勾选 = 归属该科室;未勾选且原属该科室的置空) |

| GET | /api/occupational-exam/base/depts/{id}/doctors | deptDoctors | 科室负责的检查项目:整体覆盖分配(勾选 = 归属该科室;未勾选且原属该科室的置空) |

| GET | /api/occupational-exam/base/dicts | dicts | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| POST | /api/occupational-exam/base/dicts | addDict | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| PUT | /api/occupational-exam/base/dicts/{id} | updDict | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| DELETE | /api/occupational-exam/base/dicts/{id} | delDict | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| GET | /api/occupational-exam/base/employers | employers | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| POST | /api/occupational-exam/base/employers | addEmployer | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| PUT | /api/occupational-exam/base/employers/{id} | updEmployer | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| DELETE | /api/occupational-exam/base/employers/{id} | delEmployer | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| GET | /api/occupational-exam/base/all | all | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| GET | /api/occupational-exam/item-rule/rel | rels | 第7轮:项目规则引擎(性别属性 / 项目互斥 / 项目联动) 第8轮:登记增强(登记单项目明细 / 弃项标记 / 复用历史订单项目) 数据落 peis_db:base_item_rel(规则)、biz_register_item(登记单项目明细) |

| POST | /api/occupational-exam/item-rule/rel | addRel | 规则列表:可按主项目过滤 |

| DELETE | /api/occupational-exam/item-rule/rel/{id} | delRel | 新增规则(mutex 互斥 / link 联动),双向一致:互斥与联动都视为对称关系 |

| GET | /api/occupational-exam/item-rule/items | items | 删除规则(连同对称那条一起删) |

| POST | /api/occupational-exam/item-rule/check | check | 可选项目(按性别过滤,返回性别属性) |

| GET | /api/occupational-exam/item-rule/register-items | registerItems | 校验选中项目:性别不符 / 互斥冲突 / 联动建议缺项。 body: { gender: 1|2, itemIds: [..] } 返回: { genderBlocked:[], mutexConflicts:[{itemId,itemName,conflictId,conflictName}], linkSuggest:[{itemId,itemName,suggestId,suggestName}] } |

| POST | /api/occupational-exam/item-rule/register-items/generate | generateItems | 查询某登记单的项目明细 |

| POST | /api/occupational-exam/item-rule/register-item/add | addItem | 按套餐生成登记单项目明细(重复调用不会重复插入) |

| POST | /api/occupational-exam/item-rule/register-item/abandon | abandon | 加项(含校验:性别不符、互斥冲突直接拒绝) |

| POST | /api/occupational-exam/item-rule/register-items/copy-history | copyHistory | 弃项标记 / 取消弃项 |

| GET | /api/occupational-exam/modlib/modules | modules | 写入时强制租户(非超管必须有租户) |

| POST | /api/occupational-exam/modlib/modules | saveModule | 写入时强制租户(非超管必须有租户) |

| DELETE | /api/occupational-exam/modlib/modules/{id} | delModule | 写入时强制租户(非超管必须有租户) |

| GET | /api/occupational-exam/modlib/modules/{id}/items | moduleItems | 写入时强制租户(非超管必须有租户) |

| POST | /api/occupational-exam/modlib/modules/{id}/items | setModuleItems | 写入时强制租户(非超管必须有租户) |

| GET | /api/occupational-exam/modlib/packages/{id}/modules | packageModules | 写入时强制租户(非超管必须有租户) |

| POST | /api/occupational-exam/modlib/packages/{id}/modules | setPackageModules | 写入时强制租户(非超管必须有租户) |

| GET | /api/occupational-exam/std/stats | stats | 国家标准知识库接入层 —— 将 base_std_ 6 张标准表(职业病目录 / GBZ 188 监护规范) 与本系统业务档案打通。 <p><b>两类能力:</b> <ol> <li><b>查询</b>:法定病种目录、接害因素档案、检查规则与项目,供登记页 / 结论页 下拉与自动带出({@code /suggest-items})使用;</li> <li><b>一键导入</b>:把国标因素、检查项目、GBZ188 套餐灌进业务表 base_hazard_factor / base_exam_item / base_package(+base_package_item), 幂等可重复执行(已存在的跳过或覆盖重建,不会重复造数据)。</li> </ol> <p>标准数据 tenant_id=1(全体共享),导入时写入当前操作租户。 |

| GET | /api/occupational-exam/std/categories | categories | 标准库数据量概览(页面头部展示) |

| GET | /api/occupational-exam/std/diseases | diseases | 12 大类职业病目录 |

| GET | /api/occupational-exam/std/hazards | hazards | 病种目录:可按大类、关键词检索 |

| GET | /api/occupational-exam/std/hazards/{code} | hazardDetail | 接害因素档案:可按类别(粉尘/化学物/物理因素…)、关键词检索 |

| GET | /api/occupational-exam/std/hazards/{code}/rules | rules | 因素详情:档案 + 全部检查规则 + 每条规则的项目 + 对应法定职业病 |

| GET | /api/occupational-exam/std/rules/{id}/items | ruleItems | 某因素的检查规则 |

| GET | /api/occupational-exam/std/hazards/{code}/diseases | hazardDiseases | 某规则下的必检/选检项目 |

| GET | /api/occupational-exam/std/suggest-items | suggestItems | 某因素对应的法定职业病 |

5.1.7 界面字段清单

表 5-1-A 基础档案页字段清单

| 字段 | 控件 | 必填 | 校验/说明 |

| 因素编码 | 文本框 | 是 | 唯一性校验 |

| 因素名称 | 文本框 | 是 | — |

| 目标疾病 | 文本框 | 否 | — |

| 检查周期(月) | 数字框 | 是 | 正整数 |

| 依据条款 | 文本框 | 否 | 关联 GBZ 188 条目 |

| 项目编码/名称 | 文本框 | 是 | 唯一性校验 |

| 所属科室 | 下拉 | 是 | 科室字典 |

| 值类型 | 下拉 | 是 | 数值/文本 |

| 参考区间上下限 | 数字框 | 数值型必填 | 下限≤上限 |

| 职业敏感项 | 开关 | 否 | 影响异常判定级别 |

| 套餐名称/因素/类别 | 选择器 | 是 | 模块引用校验 |

| 套餐编号 | 自动生成 | 否 | PKG 留空自动发号 |

5.1.8 业务规则

● 因素编码、项目编码全局唯一,采用数据库唯一约束兜底;

● 数值型项目必须提供参考区间上下限,且下限 ≤ 上限;

● 基础数据删除一律逻辑删除(del_flag),被引用数据只能停用;

● 套餐编号留空时按 PKG 规则自动生成连续编号;

● 模块绑定归属科室,套餐只引用模块,不允许跨级挂项目造成口径分裂;

● 非管理员角色的写请求在页面与后端同时拦截(医生只读)。

5.1.9 操作步骤

登录系统,进入「基础档案」页面(管理员可见编辑按钮,医生只读);

切换到「接害因素」页签:点击新增,录入因素编码(如 F06)、名称、目标疾病、检查周期与 GBZ 188 依据条款,保存;

切换到「检查项目」页签:新增项目,选择所属科室、值类型;数值型项目录入单位与参考区间上下限,勾选是否职业敏感项;

切换到「体检模块」页签:新建模块并绑定归属科室,从项目库勾选该项目集合,保存;

切换到「体检套餐」页签:新建套餐,选择危害因素与体检类别,勾选引用的模块,编号留空自动生成 PKG 编号,保存;

在「国家标准」页签核对因素-疾病-必检项目映射,必要时在「项目规则」页签调整机构级规则;

在「字典」页签维护下拉枚举(体检类别、结论类型等)。

5.1.10 异常场景与处理

● 编码重复保存被唯一约束拦截:改用系统建议编码或查询既有记录复用;

● 参考区间下限大于上限:保存时被校验拦截,修正后重试;

● 删除已被套餐引用的因素/项目:系统仅允许停用,保证历史单据引用完整;

● 误停用项目导致套餐缺项:在套餐详情查看缺失提示,恢复启用即可。

图 5-8 基础档案页界面原型

5.2 从业人员档案管理模块详细设计

5.2.1 功能描述

从业人员(劳动者)档案管理模块面向职业健康监护对象建立「一人一档」的健康监护档案。档案核心字段包括姓名、身份证号、性别、出生日期、所属用人单位、工种、接害工龄、职业健康史/接触史、住址与联系电话。系统对身份证号执行三重处理:合法性校验与出生日期/性别解析、SHA-256 摘要计算(用于唯一性去重,摘要列建唯一索引)、SM4 加密落盘(密文列存储,密文带 SM4V1: 前缀标识)。职业健康史、联系电话等敏感字段同样 SM4 加密存储,并可选启用 SM3 摘要完整性校验(摘要存 gm_digest 列,读取时校验防篡改)。档案与用人单位、接害因素建立关联,支持按单位维度批量维护。

5.2.2 输入参数

劳动者姓名、身份证号、用人单位、工种、接害工龄、职业健康史、住址、联系电话;批量导入时的 Excel/结构化名单数据;查询条件(姓名、单位、工种、身份证检索词)与分页参数。

5.2.3 业务处理逻辑

1. 新建档案时首先校验身份证号格式与校验位,从身份证号解析出生日期与性别并自动填充;

2. 计算身份证号 SHA-256 摘要,以摘要列唯一索引执行查重:命中重复时提示已存在档案并关联既有记录,避免同一劳动者重复建档;

3. 加密开关开启时,姓名、身份证号、职业健康史等敏感字段经 SM4 加密后写入数据库(Sm4TypeHandler 在 MyBatis 读写两侧透明加解密);关闭时直接明文写入,业务功能不受影响;

4. SM3 校验开启时对原文字段计算国密 SM3 摘要并另存 gm_digest 列,读取时重新计算比对,不一致即标记完整性异常(gmIntact=false),实现防篡改监测;

5. 批量导入接口逐行校验名单数据,返回成功/失败明细,失败行标注原因(身份证非法、必填缺失等),支持修正后重导;

6. 档案查询按角色实施字段权限控制:无权限角色看到的是脱敏后的字段值(DataMaskService 按 sys_field_perm 配置执行 read/write/mask 三级字段权限);

7. 档案编辑、删除(逻辑删除)、明文查看等敏感操作均记录敏感访问审计日志。

5.2.4 输出结果

劳动者档案列表(分页、脱敏后)、建档成功/失败明细、档案详情(授权用户可见解密后字段)、敏感访问审计记录。

关键输出样例:

worker_id 1042 / worker_name 张*(SM4密文存储) / id_card_hash 9f8a…(唯一)

import_result {total: 86, success: 84, failed: 2, failures: [{row:17, reason:身份证校验位错误}, …]}

5.2.5 页面原型说明

「个人体检」页面提供档案列表、新建/编辑弹窗、批量导入入口与检索栏;身份证号在列表中默认掩码显示,授权用户点击查看明文时后端记录审计日志。

界面布局说明:页面采用左侧固定导航 + 顶部当前位置栏 + 右侧内容区的经典后台布局,内容区顶部为操作工具栏(新增、批量、导出等高频按钮),中部为过滤检索区,主体为数据表格区;表格支持分页、关键字过滤与状态筛选,行内操作按钮按当前行状态动态显示。弹窗类操作(新建、编辑、审核意见)均以模态弹窗承载,表单字段带必填与格式校验提示。

交互说明:列表数据异步分页加载,不整页刷新;表单提交带防重复点击处理;操作结果以消息条即时反馈(成功/警告/错误分级);批量操作返回逐行结果明细;打印与导出场景适配 A4 纸张版式。

5.2.6 接口设计

表 5-2 从业人员档案管理模块接口清单(6项)

| 方法 | 接口路径 | 处理方法 | 功能说明 |

| GET | /api/occupational-exam/workers | list | 劳动者档案:身份证 SM4 加密 + SHA256 指纹去重 + 动态数据脱敏(data:unmask 权限可见明文) |

| POST | /api/occupational-exam/workers | create | 劳动者档案:身份证 SM4 加密 + SHA256 指纹去重 + 动态数据脱敏(data:unmask 权限可见明文) |

| GET | /api/occupational-exam/workers/{id} | get | 劳动者档案:身份证 SM4 加密 + SHA256 指纹去重 + 动态数据脱敏(data:unmask 权限可见明文) |

| PUT | /api/occupational-exam/workers/{id} | update | 劳动者档案:身份证 SM4 加密 + SHA256 指纹去重 + 动态数据脱敏(data:unmask 权限可见明文) |

| DELETE | /api/occupational-exam/workers/{id} | delete | 修改档案:仅允许更新非身份字段(姓名/工种/接害工龄/住址/既往史),身份证与出生日期由身份证派生、不可改 |

| POST | /api/occupational-exam/workers/import | importExcel | 动态脱敏:身份证(保留前3后4)/ 手机号(保留前3后4);有权限返回明文。 字段解密已由 Sm4TypeHandler→GmCrypto 门面在读库时统一完成;这里补充 SM3 摘要完整性校验。 |

5.2.7 界面字段清单

表 5-2-A 劳动者档案字段清单

| 字段 | 控件 | 必填 | 校验/说明 |

| 姓名 | 文本框 | 是 | SM4 加密列 |

| 身份证号 | 文本框 | 是 | 校验位校验;SHA-256 去重;SM4 加密列 |

| 性别 | 自动解析 | 是 | 由身份证解析 |

| 出生日期 | 自动解析 | 是 | 由身份证解析 |

| 用人单位 | 选择器 | 是 | 关联单位档案 |

| 工种 | 文本框 | 是 | — |

| 接害工龄(年) | 数字框 | 否 | 一位小数 |

| 职业健康史 | 多行文本 | 否 | SM4 加密列 |

| 住址 | 文本框 | 否 | — |

| 联系电话 | 文本框 | 否 | SM4 加密列;脱敏展示 |

5.2.8 业务规则

● 身份证号必须通过格式与校验位检查,性别、出生日期由系统解析,禁止手工填写冲突值;

● 身份证 SHA-256 摘要列唯一索引,重复建档被拦截并引导关联;

● 敏感字段加密与否完全由加密开关决定,两态数据结构一致(明文/密文同列);

● SM3 摘要列在启用校验后对新写入数据强制计算;

● 档案删除为软删,历史体检记录仍可追溯;

● 批量导入逐行校验,失败行不阻断成功行。

5.2.9 操作步骤

进入「个人体检」页面,点击新建档案;

录入姓名与身份证号,系统自动解析性别、出生日期;

选择用人单位(或先到用人单位页签新增),录入工种、接害工龄;

录入职业健康史、住址、联系电话;

提交保存:系统计算身份证 SHA-256 摘要查重,通过后入库(敏感字段按加密开关加密);

批量场景:点击批量导入,上传名单,查看成功/失败明细,修正失败行后重导;

检索场景:按姓名/单位/工种/身份证检索词查询,列表身份证默认掩码。

5.2.10 异常场景与处理

● 身份证校验失败:核对号码与校验位;

● 提示重复建档:点击提示中的既有档案查看,按「补充接害信息」方式关联而非重建;

● 批量导入部分行失败:按失败原因(身份证非法、必填缺失)修正后仅重导失败行;

● 无权限查看明文:列表显示掩码,需要明文时申请授权并留痕。

5.3 职业危害因素与用人单位管理模块详细设计

5.3.1 功能描述

本模块维护职业健康检查业务的两大前置档案:用人单位档案与职业病危害因素(接害因素)档案。用人单位档案记录单位名称、统一社会信用代码、联系人与电话,是团体体检、汇总统计与通知书送达的组织维度。接害因素档案依据《职业健康监护技术规范》(GBZ 188)维护因素编码、因素名称(粉尘、噪声、苯、铅、高温等)、对应目标疾病(职业性尘肺病、职业性噪声聋、职业性苯中毒等)、检查周期(月)与规范依据条款,并通过标准目录关联每种因素对应的必检项目规则。检查周期字段是周期体检到期预警的计算依据。

5.3.2 输入参数

用人单位名称、信用代码、联系人、电话;危害因素编码、名称、目标疾病、检查周期(月)、依据条款;两类档案的增删改查指令与查询条件。

5.3.3 业务处理逻辑

1. 用人单位名称设置唯一约束,防止重复建档;信用代码格式校验;

2. 危害因素编码唯一,检查周期为正整数(月),依据条款关联 GBZ 188 具体条目;

3. 因素与检查项目通过标准规则表(std_hazard_disease / std_exam_rule)建立映射,套餐配置界面按因素自动带出推荐项目;

4. 因素被体检套餐、登记单引用后不可物理删除,只能停用,保证历史单据引用完整;

5. 汇总统计模块按因素维度聚合体检人数、异常人数与合格率,依赖本模块维护的因素档案。

5.3.4 输出结果

用人单位列表与详情、危害因素列表与详情、因素-项目推荐规则;为登记分诊、套餐配置、统计预警提供组织维度与危害维度数据。

关键输出样例:

employer_id 23 / employer_name 惠达诚制造有限公司 / credit_code 91…X0K

factor F02 / target_disease 职业性噪声聋 / cycle_months 12

5.3.5 页面原型说明

「用人单位」页面与「基础档案-接害因素」页签分别管理两类档案;因素列表展示目标疾病与检查周期,供管理员评估体检安排周期。

界面布局说明:页面采用左侧固定导航 + 顶部当前位置栏 + 右侧内容区的经典后台布局,内容区顶部为操作工具栏(新增、批量、导出等高频按钮),中部为过滤检索区,主体为数据表格区;表格支持分页、关键字过滤与状态筛选,行内操作按钮按当前行状态动态显示。弹窗类操作(新建、编辑、审核意见)均以模态弹窗承载,表单字段带必填与格式校验提示。

交互说明:列表数据异步分页加载,不整页刷新;表单提交带防重复点击处理;操作结果以消息条即时反馈(成功/警告/错误分级);批量操作返回逐行结果明细;打印与导出场景适配 A4 纸张版式。

5.3.6 接口设计

表 5-3 职业危害因素与用人单位管理模块接口清单(29项)

| 方法 | 接口路径 | 处理方法 | 功能说明 |

| GET | /api/occupational-exam/base/hazard-factors | factors | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/hazard-factors | addFactor | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| PUT | /api/occupational-exam/base/hazard-factors/{id} | updFactor | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| DELETE | /api/occupational-exam/base/hazard-factors/{id} | delFactor | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| GET | /api/occupational-exam/base/items | items | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/items | addItem | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| PUT | /api/occupational-exam/base/items/{id} | updItem | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| DELETE | /api/occupational-exam/base/items/{id} | delItem | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| GET | /api/occupational-exam/base/packages | packages | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/packages | addPackage | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| PUT | /api/occupational-exam/base/packages/{id} | updPackage | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| DELETE | /api/occupational-exam/base/packages/{id} | delPackage | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| GET | /api/occupational-exam/base/packages/{id}/items | packageItems | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/packages/{id}/items | savePackageItems | 套餐项目明细:查看 |

| GET | /api/occupational-exam/base/depts | depts | 套餐项目明细:整体覆盖保存 |

| POST | /api/occupational-exam/base/depts | addDept | 套餐项目明细:整体覆盖保存 |

| PUT | /api/occupational-exam/base/depts/{id} | updDept | 套餐项目明细:整体覆盖保存 |

| PUT | /api/occupational-exam/base/depts/{id}/items | saveDeptItems | 套餐项目明细:整体覆盖保存 |

| DELETE | /api/occupational-exam/base/depts/{id} | delDept | 科室负责的检查项目:整体覆盖分配(勾选 = 归属该科室;未勾选且原属该科室的置空) |

| GET | /api/occupational-exam/base/depts/{id}/doctors | deptDoctors | 科室负责的检查项目:整体覆盖分配(勾选 = 归属该科室;未勾选且原属该科室的置空) |

| GET | /api/occupational-exam/base/dicts | dicts | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| POST | /api/occupational-exam/base/dicts | addDict | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| PUT | /api/occupational-exam/base/dicts/{id} | updDict | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| DELETE | /api/occupational-exam/base/dicts/{id} | delDict | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| GET | /api/occupational-exam/base/employers | employers | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| POST | /api/occupational-exam/base/employers | addEmployer | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| PUT | /api/occupational-exam/base/employers/{id} | updEmployer | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| DELETE | /api/occupational-exam/base/employers/{id} | delEmployer | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| GET | /api/occupational-exam/base/all | all | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

5.3.7 界面字段清单

表 5-3-A 用人单位与因素字段清单

| 字段 | 控件 | 必填 | 校验/说明 |

| 单位名称 | 文本框 | 是 | 唯一约束 |

| 统一社会信用代码 | 文本框 | 是 | 格式校验 |

| 联系人/电话 | 文本框 | 否 | — |

| 因素编码 | 文本框 | 是 | 唯一约束 |

| 因素名称 | 文本框 | 是 | 粉尘/噪声/苯/铅/高温等 |

| 目标疾病 | 文本框 | 是 | 对应职业病名称 |

| 检查周期(月) | 数字框 | 是 | 到期预警依据 |

| 依据条款 | 文本框 | 否 | GBZ 188 条目 |

5.3.8 业务规则

● 用人单位名称唯一,信用代码格式校验;

● 因素检查周期为正整数(月),依据条款关联 GBZ 188 具体条目;

● 因素与目标疾病、必检项目的映射遵循国家标准目录;

● 被套餐/登记单引用的因素不可物理删除。

5.3.9 操作步骤

进入「用人单位」页面,点击新增单位,录入名称、统一社会信用代码、联系人与电话;

在单位详情维护该单位下属工种与对应接害因素;

进入「基础档案-接害因素」,维护因素编码、名称、目标疾病、检查周期与依据条款;

在「国家标准」页签核对该因素的必检项目映射;

汇总统计页按单位/因素维度验证档案数据完整性。

5.3.10 异常场景与处理

● 单位名称重复:唯一约束拦截,检索复用既有单位;

● 因素被引用后无法删除:改为停用,新建单据不再可选;

● 检查周期录入非正整数:校验拦截。

图 5-9 用人单位管理页界面原型

5.4 体检项目与套餐管理模块详细设计

5.4.1 功能描述

体检项目与套餐管理模块实现「项目 → 模块 → 套餐」三级组合配置。检查项目库(base_exam_item)定义项目编码、名称、所属科室、值类型(数值/文本)、单位、参考区间与职业敏感项标志(abnormal_flag),职业敏感项(如电测听、纯音听力、尿铅、胸部高千伏 X 线)在结果判定时具有独立的异常标记级别。体检模块库(base_exam_module / base_module_item)将项目组合为可复用的检测模块并绑定归属科室。体检套餐(base_package / base_package_item / base_package_module)按「危害因素 × 体检类别(上岗前/在岗期间/离岗时/应急)」组合模块形成完整套餐,套餐编号(PKG 编码)由系统自动生成,规范版本字段记录依据的 GBZ 188 版本。

5.4.2 输入参数

项目编码/名称/科室/值类型/单位/参考区间/敏感项标志;模块名称、归属科室、模块包含的项目集合;套餐名称、危害因素、体检类别、模块引用集合。

5.4.3 业务处理逻辑

1. 项目新增时按科室归口,数值型项目必须录入参考区间上下限;职业敏感项标志决定结果录入页的异常判定与标红级别;

2. 模块保存时校验所含项目均存在且未停用,模块与项目为多对多关系;

3. 套餐保存时校验引用的模块有效,套餐与项目关系表同步维护;套餐编号留空时系统按 PKG 规则自动生成连续编号;

4. 套餐与危害因素、体检类别关联后,登记分诊环节即可按「登记单的接害因素 + 体检类别」精确定位应检项目集合(base_package_item),实现应检/已录进度对比;

5. 项目库修改不影响历史结果——结果表保存项目名称快照(item_snapshot),防止项目更名后历史报告口径失真。

5.4.4 输出结果

项目库列表、模块列表、套餐列表(含编号与依据版本)、套餐-项目映射;为登记分诊提供应检项目集合,为结果录入提供参考区间与敏感项判定依据。

关键输出样例:

package PKG0002 / items [内科检查, 电测听, 纯音听力(左), 纯音听力(右), 血常规]

module M07 电测听模块 / dept 电测听室 / items [电测听, 纯音听力(左), 纯音听力(右)]

5.4.5 页面原型说明

「基础档案」中项目、模块、套餐三个页签;套餐配置界面从模块库勾选组合,显示套餐编号列;存量套餐按规则补齐 PKG 编号。

界面布局说明:页面采用左侧固定导航 + 顶部当前位置栏 + 右侧内容区的经典后台布局,内容区顶部为操作工具栏(新增、批量、导出等高频按钮),中部为过滤检索区,主体为数据表格区;表格支持分页、关键字过滤与状态筛选,行内操作按钮按当前行状态动态显示。弹窗类操作(新建、编辑、审核意见)均以模态弹窗承载,表单字段带必填与格式校验提示。

交互说明:列表数据异步分页加载,不整页刷新;表单提交带防重复点击处理;操作结果以消息条即时反馈(成功/警告/错误分级);批量操作返回逐行结果明细;打印与导出场景适配 A4 纸张版式。

5.4.6 接口设计

表 5-4 体检项目与套餐管理模块接口清单(36项)

| 方法 | 接口路径 | 处理方法 | 功能说明 |

| GET | /api/occupational-exam/base/hazard-factors | factors | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/hazard-factors | addFactor | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| PUT | /api/occupational-exam/base/hazard-factors/{id} | updFactor | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| DELETE | /api/occupational-exam/base/hazard-factors/{id} | delFactor | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| GET | /api/occupational-exam/base/items | items | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/items | addItem | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| PUT | /api/occupational-exam/base/items/{id} | updItem | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| DELETE | /api/occupational-exam/base/items/{id} | delItem | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| GET | /api/occupational-exam/base/packages | packages | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/packages | addPackage | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| PUT | /api/occupational-exam/base/packages/{id} | updPackage | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| DELETE | /api/occupational-exam/base/packages/{id} | delPackage | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| GET | /api/occupational-exam/base/packages/{id}/items | packageItems | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/packages/{id}/items | savePackageItems | 套餐项目明细:查看 |

| GET | /api/occupational-exam/base/depts | depts | 套餐项目明细:整体覆盖保存 |

| POST | /api/occupational-exam/base/depts | addDept | 套餐项目明细:整体覆盖保存 |

| PUT | /api/occupational-exam/base/depts/{id} | updDept | 套餐项目明细:整体覆盖保存 |

| PUT | /api/occupational-exam/base/depts/{id}/items | saveDeptItems | 套餐项目明细:整体覆盖保存 |

| DELETE | /api/occupational-exam/base/depts/{id} | delDept | 科室负责的检查项目:整体覆盖分配(勾选 = 归属该科室;未勾选且原属该科室的置空) |

| GET | /api/occupational-exam/base/depts/{id}/doctors | deptDoctors | 科室负责的检查项目:整体覆盖分配(勾选 = 归属该科室;未勾选且原属该科室的置空) |

| GET | /api/occupational-exam/base/dicts | dicts | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| POST | /api/occupational-exam/base/dicts | addDict | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| PUT | /api/occupational-exam/base/dicts/{id} | updDict | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| DELETE | /api/occupational-exam/base/dicts/{id} | delDict | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| GET | /api/occupational-exam/base/employers | employers | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| POST | /api/occupational-exam/base/employers | addEmployer | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| PUT | /api/occupational-exam/base/employers/{id} | updEmployer | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| DELETE | /api/occupational-exam/base/employers/{id} | delEmployer | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| GET | /api/occupational-exam/base/all | all | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| GET | /api/occupational-exam/modlib/modules | modules | 写入时强制租户(非超管必须有租户) |

| POST | /api/occupational-exam/modlib/modules | saveModule | 写入时强制租户(非超管必须有租户) |

| DELETE | /api/occupational-exam/modlib/modules/{id} | delModule | 写入时强制租户(非超管必须有租户) |

| GET | /api/occupational-exam/modlib/modules/{id}/items | moduleItems | 写入时强制租户(非超管必须有租户) |

| POST | /api/occupational-exam/modlib/modules/{id}/items | setModuleItems | 写入时强制租户(非超管必须有租户) |

| GET | /api/occupational-exam/modlib/packages/{id}/modules | packageModules | 写入时强制租户(非超管必须有租户) |

| POST | /api/occupational-exam/modlib/packages/{id}/modules | setPackageModules | 写入时强制租户(非超管必须有租户) |

5.4.7 界面字段清单

表 5-4-A 项目/模块/套餐字段清单

| 字段 | 控件 | 必填 | 校验/说明 |

| 项目编码/名称 | 文本框 | 是 | 唯一性校验 |

| 所属科室 | 下拉 | 是 | 科室字典 |

| 值类型/单位 | 下拉/文本 | 是 | 数值型含单位 |

| 参考区间 | 数字区间 | 数值型必填 | 自动判定依据 |

| 模块名称/归属科室 | 选择器 | 是 | 模块-项目多对多 |

| 套餐名称 | 文本框 | 是 | — |

| 危害因素/体检类别 | 选择器 | 是 | 定位套餐键 |

| 规范版本 | 文本 | 自动 | GBZ188-2014 |

5.4.8 业务规则

● 套餐与危害因素、体检类别强关联,登记时按两者精确定位套餐;

● 项目更名不影响历史结果(结果表保存项目名快照);

● 套餐引用的模块必须有效(未停用),保存时校验;

● 规范版本字段随套餐保存,报告可追溯依据版本。

5.4.9 操作步骤

进入「基础档案-检查项目」页签维护项目库(编码、科室、值类型、参考区间、敏感项标志);

进入「体检模块」页签新建模块,绑定归属科室,勾选项目集合;

进入「体检套餐」页签新建套餐:选因素、选类别、引用模块;

套餐编号留空提交,系统自动生成 PKG 连续编号;

查看套餐详情核对模块-项目构成与规范版本(GBZ188-2014)。

5.4.10 异常场景与处理

● 套餐缺项:检查引用模块中的项目是否被停用;

● 编号生成冲突:序列由系统统一管理,重试即可;

● 项目更名:直接修改项目库,历史结果以快照为准,无需处理历史数据。

5.5 体检登记与分诊模块详细设计

5.5.1 功能描述

体检登记与分诊模块是日常业务的主入口,覆盖团体预约、个人登记、签到分诊与状态跟踪。登记单(biz_register)是贯穿全流程的业务主单据:系统按「TJyyyyMMdd-nnnnnn」规则通过序列表(seq_rule)自动发放唯一登记单号;登记单关联劳动者档案、用人单位、体检套餐与本次接害因素,生成应检项目清单。登记单采用六态状态机(REGISTERED→CHECKING→CHECKED→CONCLUDED→SIGNED→ARCHIVED,另含 CANCELED),状态流转由后端 transition 接口统一校验,越序流转被拒绝并留痕。并发控制采用双重机制:登记单行级软锁(lock_by/lock_time,医生领单后加锁、释放或超时自动解锁)与乐观锁 version 字段。智能导检接口按登记单的应检项目与各科室排队情况返回建议检查顺序。

5.5.2 输入参数

劳动者标识、体检类别(上岗前/在岗期间/离岗时/应急)、体检日期、套餐选择、本次接害因素集合;团体批量登记时的单位与人员名单;登记单查询条件(单号/姓名/状态/日期区间);状态流转指令与领单/退单指令。

5.5.3 业务处理逻辑

1. 团体预约建立单位级预约单,明确体检类别与计划日期,批量登记接口按名单逐人创建登记单并复用单人登记的全部校验逻辑;

2. 创建登记单时生成 TJ 编号(序列表原子递增),写入登记单与接害因素关联表(biz_register_hazard),并按套餐生成应检项目集合;

3. 状态流转接口校验源状态与目标状态的合法性(仅允许沿状态机相邻前进或按规则取消),非法流转返回业务异常并记录日志;

4. 领单接口为登记单加行级软锁,写入锁持有人与时间;同单冲突时其他医生收到占用提示;编辑保存以 version 乐观锁提交,版本冲突提示刷新重试;

5. 各科室待检队列按「科室 × 状态」过滤登记单,分诊护士与医生可实时查看每人的当前科室与检查进度,实现未检/检测中/已完成/待审核全程跟踪;

6. 归档检索接口支持对已归档单据按关键字检索历史记录。

5.5.4 输出结果

登记单(含编号、状态、应检项目进度)、团体登记批量结果、各科室待检队列、导检建议、状态流转结果;登记单状态变化实时反映在工作台统计与科室队列。

关键输出样例:

register {reg_no: TJ20261003-000112, status: REGISTERED, package: PKG0002, factors: [噪声]}

batch {created: 72, failed: 2, failures: [...]}

guide [登记科→检验科→电测听室→放射科→肺功能室]

5.5.5 页面原型说明

「体检登记」页面提供新建登记、团体批量登记入口与多条件检索列表;列表显示单号、姓名、单位、工种、套餐、状态与领单人;「智能导检」页展示建议检查顺序。

界面布局说明:页面采用左侧固定导航 + 顶部当前位置栏 + 右侧内容区的经典后台布局,内容区顶部为操作工具栏(新增、批量、导出等高频按钮),中部为过滤检索区,主体为数据表格区;表格支持分页、关键字过滤与状态筛选,行内操作按钮按当前行状态动态显示。弹窗类操作(新建、编辑、审核意见)均以模态弹窗承载,表单字段带必填与格式校验提示。

交互说明:列表数据异步分页加载,不整页刷新;表单提交带防重复点击处理;操作结果以消息条即时反馈(成功/警告/错误分级);批量操作返回逐行结果明细;打印与导出场景适配 A4 纸张版式。

图 5-1 体检预约、签到与分诊界面流程

5.5.6 接口设计

表 5-5 体检登记与分诊模块接口清单(26项)

| 方法 | 接口路径 | 处理方法 | 功能说明 |

| GET | /api/occupational-exam/guide/depts | depts | 第14轮:智能导检(科室配置 / 入队出队 / 插队 / VIP 优先 / 医生呼叫下一位 / 未到检标记) 第15轮:报告领取签收台账 |

| POST | /api/occupational-exam/guide/dept | saveDept | 导检科室列表 |

| POST | /api/occupational-exam/guide/dept/online | online | 新增/修改科室 |

| DELETE | /api/occupational-exam/guide/dept/{id} | delDept | 科室在线/离线切换 |

| GET | /api/occupational-exam/guide/queue | queue | 删除科室 |

| POST | /api/occupational-exam/guide/enqueue | enqueue | 队列看板:按科室分组返回候检/已呼叫/完成 |

| POST | /api/occupational-exam/guide/call-next | callNext | 入队(可从登记单直接入队;重复入队不重复插入) |

| POST | /api/occupational-exam/guide/jump | jump | 医生呼叫下一位:取本科室排序最前的候检者,置为已呼叫 |

| POST | /api/occupational-exam/guide/vip | vip | 插队(把某人提到本科室最前:priority 设为当前最大+1) |

| POST | /api/occupational-exam/guide/finish | finish | VIP 标记 |

| POST | /api/occupational-exam/guide/mark | mark | 完成检查(同步登记单状态推进) |

| DELETE | /api/occupational-exam/guide/queue/{id} | dequeue | 标记未到检 / 暂停 |

| GET | /api/occupational-exam/guide/calls | calls | 出队(从队列移除) |

| GET | /api/occupational-exam/guide/receives | receives | 呼叫记录 |

| POST | /api/occupational-exam/guide/receive | receive | 签收台账 |

| POST | /api/occupational-exam/registers | create | 体检登记单:创建/列表/详情/状态流转/加锁解锁 |

| GET | /api/occupational-exam/registers | list | 体检登记单:创建/列表/详情/状态流转/加锁解锁 |

| GET | /api/occupational-exam/registers/pending | pending | 体检登记单:创建/列表/详情/状态流转/加锁解锁 |

| GET | /api/occupational-exam/registers/archived-search | archivedSearch | 待录入名单(需求③):返回指定科室「已登记但尚未录入完成」的登记单。 仅排除已归档/已取消;对每个登记单,按套餐过滤出该科室的应检项目, 若该科室仍有未录入项(recorded < expected)则纳入列表,并附带劳动者姓名。 |

| PUT | /api/occupational-exam/registers/{id} | update | 登记单对应劳动者姓名(含匿名脱敏) |

| GET | /api/occupational-exam/registers/{id} | detail | 编辑登记单:保存「体检登记」页编辑框里的修改(已签发/归档/取消的单据拒绝修改) |

| GET | /api/occupational-exam/registers/{id}/guide | guide | 读取原始行(供完整性校验;列名取规范化字段清单) |

| POST | /api/occupational-exam/registers/{id}/transition | transition | 体检指引单数据(供打印/批量打印):登记单 + 劳动者 + 单位 + 套餐 + 按科室分组的应检项目。 员工拿着这张单去各科室检查,科室医生在「已完成」栏打勾。 |

| POST | /api/occupational-exam/registers/batch | batchCreate | 体检指引单数据(供打印/批量打印):登记单 + 劳动者 + 单位 + 套餐 + 按科室分组的应检项目。 员工拿着这张单去各科室检查,科室医生在「已完成」栏打勾。 |

| POST | /api/occupational-exam/registers/{id}/lock | lock | 团体预约批量登记(设计方案 模块4 P0): 传 employerId + packageId + examType + factorIds + workerIds[],逐个生成登记单。 已有未完结登记单的劳动者自动跳过。 |

| POST | /api/occupational-exam/registers/{id}/unlock | unlock | 团体预约批量登记(设计方案 模块4 P0): 传 employerId + packageId + examType + factorIds + workerIds[],逐个生成登记单。 已有未完结登记单的劳动者自动跳过。 |

5.5.7 界面字段清单

表 5-5-A 体检登记字段清单

| 字段 | 控件 | 必填 | 校验/说明 |

| 劳动者 | 选择器 | 是 | 档案查重后关联 |

| 体检类别 | 下拉 | 是 | 四类 |

| 体检套餐 | 选择器 | 是 | 按因素过滤 |

| 接害因素 | 多选 | 是 | 关联登记单 |

| 体检日期 | 日期 | 是 | — |

| 登记单号 | 自动 | 自动 | TJyyyyMMdd-nnnnnn |

| 状态 | 自动 | 自动 | 状态机 |

| 备注 | 多行文本 | 否 | — |

5.5.8 业务规则

● 登记单号由序列表原子发放,格式 TJyyyyMMdd-nnnnnn,全局唯一;

● 状态机只允许合法流转,越序请求返回业务异常并留痕;

● 领单软锁:lock_by/lock_time 记录持有人,重复领单被拦截,超时自动释放;

● 保存提交携带乐观锁 version,版本冲突提示刷新重试;

● 应检项目集合由套餐精确过滤生成,科室队列按科室×状态过滤;

● 取消(CANCELED)仅允许在检查开始前的状态执行。

5.5.9 操作步骤

团体体检:进入「团体预约」新建预约单(单位、类别、日期),导入名单;

到检日逐人签到:登记员核验身份证,创建体检登记单(选类别、套餐、本次接害因素);

系统发放 TJ 编号并生成应检项目集合,自动按科室分诊;

个人体检:直接为到检劳动者创建登记单;

医生在「科室录入」领取登记单(软锁)开始检查;

需要引导时打开「智能导检」,按登记单号获取建议检查顺序;

登记单列表随时跟踪每人的当前状态与科室。

5.5.10 异常场景与处理

● 发号失败:事务回滚后重试,编号仍保持连续唯一;

● 领单提示被占用:查看持有人,协调释放或等待超时自动解锁;

● 保存提示版本冲突:刷新后基于最新数据修改再提交;

● 误建登记单:在检查开始前取消(CANCELED)。

图 5-15 智能导检页界面原型

5.6 体检结果录入模块详细设计

5.6.1 功能描述

体检结果录入模块供各临床与医技科室医生录入检查结果,结果分两类存储:科室检查结果(biz_exam_result,文本/数值)与检验结果(biz_lab_result,数值 + 单位 + 参考区间快照,来源标记手工/导入/LIS 接口)。系统在保存时执行自动异常判定:数值型结果与项目参考区间比对,超出区间判异常;文本型结果由医生勾选异常标志;判定为异常的职业敏感项(abnormal_flag=1 的项目,如纯音听力、尿铅)标记为「敏感项异常」(abnormal=2),录入界面即时标红并提示,作为主检结论的重点提示信息。每条结果记录录入医生与时间,登记单与项目维度设唯一约束防止重复录入。

5.6.2 输入参数

登记单号、科室、项目、结果文本/数值、单位;检验结果的数值与参考区间快照;医生提交的保存与完成指令;科室待检队列查询条件。

5.6.3 业务处理逻辑

1. 医生从本科室待检队列选取登记单,系统按该登记单的套餐精确过滤出本科室应检项目(非全项目列表),并显示已录/应录进度;

2. 数值型结果录入后即时与参考区间比对,自动回填正常/异常判定;文本型结果由医生填写并勾选异常标志;

3. 保存时校验登记单处于可录入状态(CHECKING),登记单与项目唯一约束防止重复行;结果保存项目名称快照;

4. 敏感项异常自动置 abnormal=2 并在界面标红,主检结论工作台汇总全部异常项与敏感项异常项;

5. 全部应检项目录入完成后,医生提交完成,登记单状态流转至 CHECKED,进入主检结论环节;

6. 检验结果支持 LIS 适配器接口来源(source=lis),为第三方检验系统对接预留标准通道。

5.6.4 输出结果

科室结果与检验结果记录、异常/敏感项异常标记、已录/应录进度、科室完成状态;结果数据汇入主检结论与报告生成环节。

关键输出样例:

result {reg_no: TJ…112, item: 纯音听力(左), value: 38, unit: dB, abnormal: 2}

progress {required: 5, entered: 5, dept: 电测听室}

5.6.5 页面原型说明

「科室录入」页面左侧为本科室待检队列,右侧为选中登记单的应检项目录入表格,异常项自动标红;保存/提交完成后单据流转至下一状态。

界面布局说明:页面采用左侧固定导航 + 顶部当前位置栏 + 右侧内容区的经典后台布局,内容区顶部为操作工具栏(新增、批量、导出等高频按钮),中部为过滤检索区,主体为数据表格区;表格支持分页、关键字过滤与状态筛选,行内操作按钮按当前行状态动态显示。弹窗类操作(新建、编辑、审核意见)均以模态弹窗承载,表单字段带必填与格式校验提示。

交互说明:列表数据异步分页加载,不整页刷新;表单提交带防重复点击处理;操作结果以消息条即时反馈(成功/警告/错误分级);批量操作返回逐行结果明细;打印与导出场景适配 A4 纸张版式。

图 5-2 科室结果录入界面流程

5.6.6 接口设计

表 5-6 体检结果录入模块接口清单(6项)

| 方法 | 接口路径 | 处理方法 | 功能说明 |

| GET | /api/occupational-exam/lab/{registerId} | listOf | 检验结果(设计方案 模块6):手工录入 + Excel/LIS 导入预留。 保存时按项目参考区间快照自动判定异常;source=manual/import/lis。 |

| POST | /api/occupational-exam/lab/{registerId} | save | 某登记单的检验项目 + 已录结果(应录=套餐内数值型项目) |

| GET | /api/occupational-exam/results/items/{registerId} | itemsOf | 科室检查结果录入:录入前必须持锁;保存后解锁。按科室隔离录入权限。 |

| POST | /api/occupational-exam/results/save/{registerId} | save | 取某登记单某项目的最新一条归档修订(revision 最大);无则返回 null |

| POST | /api/occupational-exam/results/amend/{registerId} | amend | 批量保存某登记单的结果(要求先 lock) |

| GET | /api/occupational-exam/results/{registerId} | listOf | 归档后修订(需求⑤):已归档记录被修改时,原 biz_exam_result 记录不得删除/更改,必须保留备查; 本次修改仅新增一条「替换显示」的修订记录(biz_exam_result_amend)。 限制:仅 ARCHIVED 状态允许;按科室隔离写入(医生只能修订本科室项目);无需持锁。 请求体:{ "reason": "修订说明", "items": [ {itemId, resultText, resultValue, abnormal}, ... ] } |

5.6.7 界面字段清单

表 5-6-A 结果录入字段清单

| 字段 | 控件 | 必填 | 校验/说明 |

| 登记单号 | 自动带出 | 是 | 软锁保护 |

| 应检项目 | 列表 | 自动 | 套餐精确过滤 |

| 结果文本 | 文本框 | 文本型必填 | — |

| 结果数值 | 数字框 | 数值型必填 | 自动比对参考区间 |

| 异常标志 | 自动/勾选 | 自动 | 0/1/2 三级 |

| 参考区间快照 | 自动 | 自动 | 检验结果随行保存 |

| 医生/时间 | 自动 | 自动 | 录入留痕 |

5.6.8 业务规则

● 仅 CHECKING 状态允许录入结果;

● 登记单×项目唯一约束,重复保存被拦截;

● 数值型结果自动与参考区间比对,判定不依赖人工;

● 职业敏感项异常升级为敏感项异常(abnormal=2)并标红;

● 结果保存项目名快照与医生工号、时间;

● 全部应检项目完成后方可提交 CHECKED。

5.6.9 操作步骤

进入「科室录入」,查看本科室待检队列;

领取登记单,系统按套餐过滤出本科室应检项目并显示进度;

逐项录入:文本结果直接填写,数值结果录入数值;

系统即时比对参考区间回填判定,敏感项异常自动标红;

全部应检项目录入完成后点击提交完成,登记单流转 CHECKED。

5.6.10 异常场景与处理

● 提交被阻止:提示存在未完成必检项,补录后重试;

● 录入重复行:唯一约束拦截,改为编辑既有结果;

● 参考区间异常但医生判断正常:保留系统判定,异常说明在主检小结中阐明。

5.7 体检报告多级审核模块详细设计

5.7.1 功能描述

多级审核模块实现主检结论出具、审核任务分派、一级初审与二级复审、结论签发的完整质控链路。主检医师在科室检查全部完成后汇总各科结果出具主检小结,并给出四种结论类型之一:目前未见异常(NORMAL)、复查(RECHECK)、疑似职业病(SUSPECTED)、职业禁忌证(CONTRAINDICATION)。审核链路以审核任务(conclusion_task)承载,支持指定审核人;审核配置表(review_config)控制是否启用二级复审及复审人;审核历史(conclusion_audit)完整记录每一轮提交、退回、通过的动作人与时间,实现审核全程可追溯。签发动作为结论生效的最终节点,签发人、签发时间落库,并触发报告 PDF 生成。

5.7.2 输入参数

登记单号、主检小结、结论类型、复查项目建议;审核任务的分派对象;初审/复审意见(通过/退回 + 意见文本);审核配置(是否二级复审、复审人);审核任务查询条件。

5.7.3 业务处理逻辑

1. 主检工作台列出 CHECKED 状态的登记单,主检医师录入小结与结论类型保存(biz_conclusion 与登记单一对一);

2. 提交审核生成审核任务,可指定审核人或进入公共审核池,任务状态跟踪待审/通过/退回;

3. 一级初审核对主检小结与各科检查结果、异常项的一致性:通过则按配置进入二级复审或直接签发;退回则携带意见回到主检医师修改后重新提交;

4. 二级复审由授权复审人执行,复审通过执行签发:结论状态置 SIGNED、记录签发人与签发时间,登记单状态同步流转;

5. 每一轮提交/审核动作写入审核历史表,含动作类型、动作人、时间与意见,界面可查看完整审核轨迹;

6. 审核配置仅管理员可修改,控制质控流程的严格程度以适配不同机构的质控要求。

5.7.4 输出结果

主检结论记录、审核任务与状态、审核历史轨迹、签发结果;签发事件触发报告生成模块。退回场景附退回意见并可追溯每一轮修改。

关键输出样例:

conclusion {reg_no: TJ…098, type: RECHECK, summary: 双耳高频听力下降…, chief: 钱医师}

task {id: 208, state: PENDING_REVIEW, assignee: 李医师}

audit [{action: 提交, by: 钱医师, at: 10-02 15:40}, {action: 初审通过, by: 李医师, at: 16:02}, {action: 签发, by: 王主检, at: 16:41}]

5.7.5 页面原型说明

「主检结论」页提供结论录入表单(结论类型单选、小结编辑、复查建议);「总检审核」工作台列出待初审/待复审任务,支持通过/退回操作与审核轨迹查看。

界面布局说明:页面采用左侧固定导航 + 顶部当前位置栏 + 右侧内容区的经典后台布局,内容区顶部为操作工具栏(新增、批量、导出等高频按钮),中部为过滤检索区,主体为数据表格区;表格支持分页、关键字过滤与状态筛选,行内操作按钮按当前行状态动态显示。弹窗类操作(新建、编辑、审核意见)均以模态弹窗承载,表单字段带必填与格式校验提示。

交互说明:列表数据异步分页加载,不整页刷新;表单提交带防重复点击处理;操作结果以消息条即时反馈(成功/警告/错误分级);批量操作返回逐行结果明细;打印与导出场景适配 A4 纸张版式。

图 5-3 结论多级审核界面流程

5.7.6 接口设计

表 5-7 体检报告多级审核模块接口清单(13项)

| 方法 | 接口路径 | 处理方法 | 功能说明 |

| GET | /api/occupational-exam/conclusion/{registerId} | get | 主检结论 + 第17轮增强:总检任务池/派单、多级审核状态机(1/2/3 级 + 打回重审)、 历史报告对比、OFD 报告生成适配、CA 电子签章适配、匿名体检脱敏展示。 |

| POST | /api/occupational-exam/conclusion/{registerId} | save | 主检工作台:结果 + 结论 + 审核配置级别 + 审核流水 |

| POST | /api/occupational-exam/conclusion/{registerId}/sign | sign | 保存主检结论(新建为草稿;进入审核流程后仅草稿/打回态可改;已签发不可改),并自动建派单任务池 |

| GET | /api/occupational-exam/conclusion/tasks | tasks | 签发(兼容旧流程:未进入多级审核流程的历史数据可直接签;已进入流程的必须走审核到终审) |

| GET | /api/occupational-exam/conclusion/assignees | assignees | 总检任务池:已检完(CHECKED/CONCLUDED)待总检的登记单 + 派单/结论状态(含匿名脱敏) |

| POST | /api/occupational-exam/conclusion/task/assign | assign | 可派单医师:本租户启用账号中角色含 chief/doctor/admin(总检派单下拉专用,只返回安全字段) |

| POST | /api/occupational-exam/conclusion/{registerId}/submit | submit | 派单:指定主检医师(新增/更新任务池) |

| POST | /api/occupational-exam/conclusion/{registerId}/audit | audit | 提交审核:草稿/打回 → 一级审核 |

| GET | /api/occupational-exam/conclusion/{registerId}/history | history | 多级审核:通过(推进/终审签发)或打回(回草稿) |

| GET | /api/occupational-exam/conclusion/review-config | getReviewConfig | 历史报告对比:同一劳动者的历史结论(排除当前单) |

| POST | /api/occupational-exam/conclusion/review-config | saveReviewConfig | 审核级别配置查询 |

| POST | /api/occupational-exam/conclusion/{registerId}/ofd | generateOfd | 审核级别配置保存(1~3 级) |

| POST | /api/occupational-exam/conclusion/{registerId}/ca-sign | caSign | OFD 报告生成适配(第17轮适配层,真实 OFD 版式引擎后续接入) |

5.7.7 界面字段清单

表 5-7-A 结论与审核字段清单

| 字段 | 控件 | 必填 | 校验/说明 |

| 主检小结 | 多行文本 | 是 | 汇总说明 |

| 结论类型 | 单选 | 是 | 四类 |

| 复查建议 | 文本 | 复查时必填 | 进入通知书 |

| 审核意见 | 文本 | 退回必填 | 写入审核历史 |

| 主检医师/审核人 | 自动 | 自动 | 职责分离校验 |

| 签发人/签发时间 | 自动 | 自动 | 签发落库 |

5.7.8 业务规则

● 结论与登记单一对一,重复出结论被唯一约束拦截;

● 提交审核后才允许审核人操作;初审人/复审人与主检医师不得为同一人(职责分离);

● 退回必须携带意见;每一轮动作写入审核历史;

● 复审启用与否由审核配置决定;签发后结论不可修改,只能走重出流程;

● 签发动作记录签发人、签发时间并触发报告生成。

5.7.9 操作步骤

主检医师进入「主检结论」,选中 CHECKED 登记单;

查看各科结果与异常项汇总,录入主检小结、选择结论类型、填写复查建议;

保存结论后提交审核(可指定审核人);

审核人进入「总检审核」工作台,核对结论与结果一致性;

初审通过:按配置进入二级复审或直接签发;退回:填写意见退回主检医师;

复审通过后签发:记录签发人与时间,触发报告生成。

5.7.10 异常场景与处理

● 结论与敏感项异常矛盾:保存时提示复核;

● 审核人发现数据不一致:退回并写明退回原因;

● 签发后发现错误:走报告重出与结论更正流程,全部动作留痕。

5.8 体检报告生成与归档模块详细设计

5.8.1 功能描述

报告生成与归档模块在结论签发后自动生成个人职业健康检查报告 PDF:服务端汇总登记信息、劳动者档案(含解密后的授权字段)、用人单位、各科检查结果、检验结果与主检结论,按报告模板渲染为结构化报告文档,采用 iText 生成 PDF(内置中文字体,跨平台部署无缺字)。报告编号按「REP」序列唯一发放;重新生成报告时版本号自动加一并保留历史版本,实现报告重出版本化管理。对复查、疑似职业病、职业禁忌证结论,系统同步生成对应的复查通知书、转诊建议或调离通知书文书(biz_notice,编号 NTC 序列),PDF 一并落盘。报告与通知书文件统一存储于文件目录(files/occupational),数据库仅存相对路径,附件管理模块支持病历等资料上传(jpg/png/pdf,单文件不超过 10MB,软删作废)。

5.8.2 输入参数

签发后的登记单号(触发生成)、报告模板配置、报告查询条件、附件上传的文件与业务单号、通知书类型与生成指令。

5.8.3 业务处理逻辑

1. 生成接口接收登记单号,校验该登记单结论已签发,防止未签发先出报告;

2. 汇总登记单、劳动者(SM4 密文字段解密后渲染,SM3 校验通过方可使用)、用人单位、结果、结论数据,按模板生成 PDF,写入文件目录并在 biz_report 登记报告号、路径与版本;

3. 重出报告时版本号 +1,旧版本文件保留,报告中标注版本号,历史可追溯;

4. 异常结论自动联动通知书生成:RECHECK→复查通知书、SUSPECTED→转诊建议、CONTRAINDICATION→调离通知书,编号 NTC 序列唯一;

5. 报告中心提供在线预览与下载,下载接口校验登录态与权限;

6. 附件上传校验文件类型(jpg/png/pdf)与大小上限(10MB),挂接业务单号存储,删除为软删作废。

5.8.4 输出结果

报告 PDF 文件与报告记录(版本化)、通知书 PDF 与通知书记录、附件档案;报告中心列表与预览/下载服务;归档数据支撑后续检索与统计。

关键输出样例:

report {report_no: REP20261002-000034, version: 2, status: SIGNED, pdf: /files/occupational/…pdf}

notice {notice_no: NTC20261002-000006, type: RECHECK, pdf: …pdf}

5.8.5 页面原型说明

「报告中心」页面按报告号/登记单号/状态检索,提供预览、下载、重出操作;「通知书」页管理三类文书;「附件管理」页维护业务附件。

界面布局说明:页面采用左侧固定导航 + 顶部当前位置栏 + 右侧内容区的经典后台布局,内容区顶部为操作工具栏(新增、批量、导出等高频按钮),中部为过滤检索区,主体为数据表格区;表格支持分页、关键字过滤与状态筛选,行内操作按钮按当前行状态动态显示。弹窗类操作(新建、编辑、审核意见)均以模态弹窗承载,表单字段带必填与格式校验提示。

交互说明:列表数据异步分页加载,不整页刷新;表单提交带防重复点击处理;操作结果以消息条即时反馈(成功/警告/错误分级);批量操作返回逐行结果明细;打印与导出场景适配 A4 纸张版式。

图 5-4 报告生成与归档界面流程

5.8.6 接口设计

表 5-8 体检报告生成与归档模块接口清单(16项)

| 方法 | 接口路径 | 处理方法 | 功能说明 |

| POST | /api/occupational-exam/attaches/upload | upload | 附件管理:病历/委托资料等,挂登记单号 bizNo,上传下载鉴权 + 租户隔离 |

| GET | /api/occupational-exam/attaches | list | 上传附件 |

| GET | /api/occupational-exam/attaches/{id}/download | download | 上传附件 |

| DELETE | /api/occupational-exam/attaches/{id} | remove | 上传附件 |

| GET | /api/occupational-exam/notices | list | 生成通知书(结论签发后;RECHECK 类型建议先有复查类结论) |

| GET | /api/occupational-exam/notices/{id} | get | 生成通知书(结论签发后;RECHECK 类型建议先有复查类结论) |

| GET | /api/occupational-exam/notices/{id}/download | download | 生成通知书(结论签发后;RECHECK 类型建议先有复查类结论) |

| GET | /api/occupational-exam/reports | list | 生成报告(要求登记单已签发) |

| GET | /api/occupational-exam/reports/{id}/download | download | 报告列表(可按登记单过滤) |

| GET | /api/occupational-exam/report-template/placeholders | placeholders | 第9轮:报告模板管理与多套模板适配 - 模板支持按业务类型(occupational 职业病 / health 普通体检 / common 通用兜底)切换 - 渲染时自动替换 ${占位符},供报告预览 / PDF 生成使用 |

| GET | /api/occupational-exam/report-template/list | list | 可用占位符说明 |

| GET | /api/occupational-exam/report-template/{id} | detail | 模板列表 |

| POST | /api/occupational-exam/report-template/save | save | 模板列表 |

| POST | /api/occupational-exam/report-template/delete | delete | 新增 / 修改模板 |

| GET | /api/occupational-exam/report-template/match | match | 删除(软删) |

| POST | /api/occupational-exam/report-template/render | render | 按登记单自动匹配模板: 优先取登记单业务类型对应的默认启用模板,其次同类型启用模板,再退到 common 默认模板。 |

5.8.7 界面字段清单

表 5-8-A 报告与附件字段清单

| 字段 | 控件 | 必填 | 校验/说明 |

| 报告编号 | 自动 | 自动 | REP 序列 |

| 报告版本 | 自动 | 自动 | 重出+1 |

| PDF 路径 | 自动 | 自动 | 文件目录相对路径 |

| 通知书编号/类型 | 自动 | 自动 | NTC 序列;三类 |

| 附件类型 | 下拉 | 是 | 病历/委托/其他 |

| 附件文件 | 上传控件 | 是 | jpg/png/pdf ≤10MB |

5.8.8 业务规则

● 未签发结论不允许生成报告;

● 报告号 REP、通知书号 NTC 由序列表发号,全局唯一;

● 重出报告版本 +1,旧版本文件与记录保留;

● 复查/疑似/禁忌证结论强制联动对应通知书;

● 附件限制 jpg/png/pdf、≤10MB,按业务单号挂接、软删作废;

● 报告文件存文件目录,数据库只存相对路径。

5.8.9 操作步骤

结论签发后进入「报告中心」,或由系统自动触发报告生成;

系统汇总登记、档案、结果、结论数据生成 PDF(REP 编号);

异常结论自动生成复查/转诊/调离通知书 PDF(NTC 编号);

在报告中心预览、下载报告;需要更正时执行重出(版本 +1);

在「附件管理」上传病历等佐证材料(≤10MB);

全部完成后登记单归档(ARCHIVED)。

5.8.10 异常场景与处理

● 生成失败:检查结论签发状态与文件目录写权限,重试;

● SM3 校验失败告警:按提示核查对应记录完整性,排除篡改后再出报告;

● 报告内容与结论不一致:重出报告并核查结论版本。

图 5-11 通知书管理页界面原型

5.9 统计分析与预警模块详细设计

5.9.1 功能描述

统计分析与预警模块面向机构管理与企业客户双视角提供体检业务的量化视图:工作台总览(overview)统计今日登记、检查中、待审核、已完成等核心在办指标;汇总报表(summary)按状态、结论、用人单位、危害因素四个维度聚合体检人数、异常人数与各工种/因素合格率,并支持导出 CSV(UTF-8 BOM 编码,Excel 直接打开不乱码);随访查询(followup)按结论类型筛出复查、疑似职业病、职业禁忌证人员名单,作为异常指标随访与复检提醒的工作清单;周期体检到期预警依据危害因素的检查周期(cycle_months)计算在岗人员下次应检时间,输出到期应检名单。质控与危急值模块对检验危急值提供登记与处理跟踪闭环;收费结算模块提供体检业务的费用登记与对账数据(含按单位维度的结算汇总)。

5.9.2 输入参数

统计维度选择(状态/结论/单位/因素)、日期区间、单位与因素过滤条件、导出指令;随访名单的类型过滤;质控危急值的登记与处理记录;收费项目的费用登记数据。

5.9.3 业务处理逻辑

1. 总览统计基于登记单状态聚合,SQL 层面按租户过滤后 GROUP BY 完成,避免全量捞出内存计算;

2. 四维汇总按维度参数动态组装聚合查询,输出各维度的人数分布与合格率(合格率 = 未见异常人数 / 已检人数);

3. CSV 导出在服务端流式生成,写入 UTF-8 BOM 头,保证 Excel 打开中文不乱码;导出动作记录操作日志;

4. 随访查询联接结论表与劳动者档案,输出随访对象、结论、接害因素与联系方式(联系方式按字段权限脱敏);

5. 到期预警按「上次体检日期 + 因素检查周期」滚动计算,输出即将到期与已到期名单,提醒机构通知企业安排周期体检;

6. 危急值记录处理状态流转(登记→通知→处理→闭环),未闭环危急值在质控页持续警示。

5.9.4 输出结果

工作台指标卡片、四维汇总报表与 CSV 文件、随访名单、到期预警名单、危急值处理台账、收费对账数据;统计结果支撑机构质控管理与企业合规证明。

关键输出样例:

summary {factor: 噪声, planned: 274, checked: 261, normal: 233, recheck: 25, suspect: 2, contraindication: 1, pass_rate: 89.3%}

followup [{reg_no: TJ…098, worker: 赵*, type: 复查, phone: 138****2211}]

due_soon [{worker: 陈*, factor: 粉尘, last: 2025-10-15, due: 2026-10-15}]

5.9.5 页面原型说明

「汇总报表」页提供四维度切换、过滤条件与导出按钮;「工作台」展示核心指标卡与在办单据;「质控与危急值」「收费与结算」独立页面管理对应业务。

界面布局说明:页面采用左侧固定导航 + 顶部当前位置栏 + 右侧内容区的经典后台布局,内容区顶部为操作工具栏(新增、批量、导出等高频按钮),中部为过滤检索区,主体为数据表格区;表格支持分页、关键字过滤与状态筛选,行内操作按钮按当前行状态动态显示。弹窗类操作(新建、编辑、审核意见)均以模态弹窗承载,表单字段带必填与格式校验提示。

交互说明:列表数据异步分页加载,不整页刷新;表单提交带防重复点击处理;操作结果以消息条即时反馈(成功/警告/错误分级);批量操作返回逐行结果明细;打印与导出场景适配 A4 纸张版式。

图 5-7 汇总报表界面原型

5.9.6 接口设计

表 5-9 统计分析与预警模块接口清单(37项)

| 方法 | 接口路径 | 处理方法 | 功能说明 |

| GET | /api/occupational-exam/finance/orders | orders | 第10轮:收费/支付/折扣权限基础数据模型与接口 第11轮:整单收费、明细收费、多次混合缴费、退费、日结月结 第12轮:发票管理(开票/作废/重打/公对公) |

| GET | /api/occupational-exam/finance/order/{id} | orderDetail | 收费单列表 |

| POST | /api/occupational-exam/finance/order/create | createOrder | 收费单详情(含明细、流水、退费、发票) |

| POST | /api/occupational-exam/finance/order/add-item | addItem | 按登记单生成收费单(未弃项的登记项目自动转收费明细) |

| POST | /api/occupational-exam/finance/order/discount | discount | 单项加项收费(登记后追加收费项目) |

| POST | /api/occupational-exam/finance/order/cancel | cancelOrder | 整单折扣(受账号最低折扣权限限制) |

| POST | /api/occupational-exam/finance/pay | pay | 作废收费单(仅未收费、或未开/已收费但允许作废的草稿单) |

| POST | /api/occupational-exam/finance/refund | refund | 收款(支持多次混合支付)。 payType=CREDIT(先检后付/单位挂账)允许暂不结清,其余不允许超收。 |

| GET | /api/occupational-exam/finance/refunds | refunds | 退费:FULL 全额退 / PART 按项目部分退(已执行项目禁止退费) |

| GET | /api/occupational-exam/finance/invoices | invoices | 退费台账 |

| POST | /api/occupational-exam/finance/invoice/issue | invoiceIssue | 发票列表 |

| POST | /api/occupational-exam/finance/invoice/void | invoiceVoid | 开票 |

| POST | /api/occupational-exam/finance/invoice/reprint | invoiceReprint | 发票作废 |

| GET | /api/occupational-exam/finance/discount-perms | discountPerms | 发票重打:生成一张新记录(保留原发票号与金额),原发票自动作废留痕 |

| POST | /api/occupational-exam/finance/discount-perm/save | saveDiscountPerm | 发票重打:生成一张新记录(保留原发票号与金额),原发票自动作废留痕 |

| GET | /api/occupational-exam/finance/my-min-rate | myMinRate | 发票重打:生成一张新记录(保留原发票号与金额),原发票自动作废留痕 |

| GET | /api/occupational-exam/finance/daily-settle | dailySettle | 当前登录账号允许的最低折扣率 |

| POST | /api/occupational-exam/finance/daily-settle/close | closeDaily | 日结统计(某日收入、退费、支付方式分布) |

| GET | /api/occupational-exam/finance/monthly-report | monthlyReport | 日结(对当日进行结账留痕,幂等覆盖) |

| GET | /api/occupational-exam/finance/registers | registers | 月结统计(按日汇总 + 支付方式 + 合计) |

| POST | /api/occupational-exam/quality/arrive | arrive | 第12轮:标本采集/送检/交接全流程 + 到检确认(防替检拍照) 第13轮:危急值阈值配置 + 检验结果自动判危急 + 告警处理台账 |

| GET | /api/occupational-exam/quality/arrive/{registerId} | arriveInfo | 到检确认(可附带拍照路径,防替检) |

| GET | /api/occupational-exam/quality/samples | samples | 到检状态查询(登记单列表附带) |

| POST | /api/occupational-exam/quality/sample/collect | collect | 标本台账列表 |

| POST | /api/occupational-exam/quality/sample/send | send | 标本采集 |

| POST | /api/occupational-exam/quality/sample/receive | receive | 标本送检 |

| POST | /api/occupational-exam/quality/sample/reject | reject | 标本接收(检验科签收) |

| GET | /api/occupational-exam/quality/critical/rules | rules | 标本拒收(必须填原因) |

| POST | /api/occupational-exam/quality/critical/rule | saveRule | 阈值规则列表 |

| DELETE | /api/occupational-exam/quality/critical/rule/{id} | delRule | 新增/修改阈值规则 |

| GET | /api/occupational-exam/quality/critical/records | records | 删除阈值规则 |

| POST | /api/occupational-exam/quality/critical/eval | eval | 告警台账 |

| POST | /api/occupational-exam/quality/critical/handle | handle | 评估检验结果是否触发危急值(检验结果保存后调用)。 body: { registerId, itemId, value } —— value 为数值 命中阈值则写入 biz_critical_record(同项目未处理的不重复写入) |

| GET | /api/occupational-exam/stat/overview | overview | 工作台统计 + 汇总报表(按状态/结论/单位/因素多维汇总,支持 CSV 导出) |

| GET | /api/occupational-exam/stat/summary | summary | 工作台统计 + 汇总报表(按状态/结论/单位/因素多维汇总,支持 CSV 导出) |

| GET | /api/occupational-exam/stat/summary/export | export | 汇总报表:start/end(登记日期,含)、employerId、factorId 过滤。 返回 byStatus / byConclusion / byEmployer / byFactor 四个维度。 |

| GET | /api/occupational-exam/stat/followup | followup | 汇总报表 CSV 导出(Excel 可直接打开,UTF-8 BOM) |

5.9.7 界面字段清单

表 5-9-A 统计筛选字段清单

| 字段 | 控件 | 必填 | 校验/说明 |

| 统计维度 | 页签 | 是 | 状态/结论/单位/因素 |

| 日期区间 | 日期范围 | 否 | 默认当月 |

| 单位/因素过滤 | 选择器 | 否 | — |

| 随访类型 | 下拉 | 否 | 复查/疑似/禁忌证 |

| 危急值记录 | 表单 | 是 | 登记→处理→闭环 |

| 费用项目/金额 | 表单 | 结算必填 | 对账汇总 |

5.9.8 业务规则

● 统计口径:合格率 = 未见异常人数 ÷ 已检人数;

● 全部统计在 SQL 层聚合并强制租户过滤;

● CSV 导出统一 UTF-8 BOM,导出动作写日志;

● 随访名单按结论类型过滤,联系方式按字段权限脱敏;

● 到期预警按「最近体检日期 + 因素周期」滚动计算;

● 危急值处理必须闭环(登记→通知→处理→确认)。

5.9.9 操作步骤

工作台查看今日在办指标;

进入「汇总报表」,选择维度(状态/结论/单位/因素)与日期区间查看统计;

点击导出 CSV,文件直接可被 Excel 打开(UTF-8 BOM);

随访查询按结论类型筛选名单,逐一跟踪复检安排;

查看周期体检到期预警名单,通知企业安排体检;

质控页处理危急值闭环;收费结算页维护费用与对账。

5.9.10 异常场景与处理

● 统计数字与预期不符:核对筛选条件与租户范围;

● CSV 中文乱码:系统已带 BOM,需用 Excel 直接打开而非文本工具;

● 到期名单含已离职人员:在档案中停用后自动剔除。

5.10 用户、角色与权限管理模块详细设计

5.10.1 功能描述

权限管理模块实现「平台超管—机构管理员—业务角色」三级治理与「用户—角色—菜单—字段」四级访问控制。系统支持多租户(SaaS 化部署):租户即体检机构(sys_tenant),平台超级管理员(platadmin)跨租户管理全部机构(开通、停用、重置机构管理员密码);机构管理员(admin)管理本机构用户与菜单授权;业务角色(主检医师 chief、科室医生 doctor、登记员等)按菜单授权获得页面与接口访问能力。业务数据表统一携带 tenant_id 字段,数据访问层通过租户作用域工具(TenantScope)自动注入过滤条件,列表强制过滤、详情越权访问拦截,实现租户间数据完全隔离。字段权限表(sys_field_perm)按「角色 × 表 × 字段」配置 read/write/mask 三级权限,敏感字段对无权角色自动脱敏。

5.10.2 输入参数

登录凭证(用户名/密码);用户管理指令(新增、调整科室、重置密码、启用/禁用);角色菜单授权勾选集合;租户管理指令(新增机构、停用、重置密码);角色与字段权限配置。

5.10.3 业务处理逻辑

1. 登录接口验证 BCrypt 口令哈希;连续失败达到阈值锁定账号一段时间(fail_count/lock_until),防御暴力破解;验证通过签发 JWT(携带用户身份、角色、租户标识 tid 与有效期);

2. 认证拦截器(AuthInterceptor)拦截本系统全部业务接口,校验令牌合法性并注入身份上下文;

3. 菜单种子与角色菜单关系(sys_menu / sys_role_menu)驱动前端侧栏动态渲染:登录后获取 /menus/mine,仅渲染被授权菜单;路由守卫对地址栏直输做第二道拦截;

4. 后端接口按角色与权限码二次鉴权,前端隐藏不等于放行;

5. 租户作用域自动注入:所有业务查询强制追加 tenant_id 条件,越权访问他租户数据返回无权限;平台超管令牌携带跨租户标记可查询全局;

6. 字段权限在查询出口执行:DataMaskService 依据配置对手机号、身份证等字段掩码输出;

7. 用户与租户的全部管理操作记录操作日志,密码重置不留明文、只写 BCrypt 哈希。

5.10.4 输出结果

JWT 令牌、动态菜单树、授权结果、用户/租户管理结果、脱敏后的业务数据;权限体系保障菜单、接口、数据、字段四个层面的分级隔离。

关键输出样例:

login {token: eyJhbGciOi…, roles: [chief,doctor], tenant: 1, menus: [...]}

grant {role: doctor, menus: [1,2,3,4,8]}

5.10.5 页面原型说明

「菜单与角色授权」页以树形勾选为角色配置菜单;「用户管理」页维护机构内账号;「租户管理」页面向平台超管;「数据安全」页含字段权限与审计入口。

界面布局说明:页面采用左侧固定导航 + 顶部当前位置栏 + 右侧内容区的经典后台布局,内容区顶部为操作工具栏(新增、批量、导出等高频按钮),中部为过滤检索区,主体为数据表格区;表格支持分页、关键字过滤与状态筛选,行内操作按钮按当前行状态动态显示。弹窗类操作(新建、编辑、审核意见)均以模态弹窗承载,表单字段带必填与格式校验提示。

交互说明:列表数据异步分页加载,不整页刷新;表单提交带防重复点击处理;操作结果以消息条即时反馈(成功/警告/错误分级);批量操作返回逐行结果明细;打印与导出场景适配 A4 纸张版式。

图 5-5 多级权限隔离模型

5.10.6 接口设计

表 5-10 用户、角色与权限管理模块接口清单(17项)

| 方法 | 接口路径 | 处理方法 | 功能说明 |

| GET | /api/occupational-exam/menus/tree | tree | 模块显隐查询(V2.5.0029 页面模块授权) |

| GET | /api/occupational-exam/menus/mine | mine | 当前用户可见的模块 key 集合(含总开关 enabled=1 过滤) |

| GET | /api/occupational-exam/menus/roles | roles | 当前用户可见菜单(前端侧栏按此渲染) |

| GET | /api/occupational-exam/menus/role/{roleCode} | roleMenus | 保存角色菜单授权 |

| GET | /api/occupational-exam/tenants | list | 租户新建管理员默认密码 |

| PUT | /api/occupational-exam/tenants/{id}/status | toggle | 建机构:同事务插租户 + 机构管理员账号 |

| POST | /api/occupational-exam/tenants/{id}/reset-password | resetPwd | 启用/停用(停用后该机构全部账号无法登录) |

| GET | /api/occupational-exam/tenants/{id} | detail | 重置该机构某账号密码(平台超管代为重置) |

| POST | /api/occupational-exam/auth/login | login | 登录 / 当前用户 |

| GET | /api/occupational-exam/auth/me | me | 取来访真实 IP(经 nginx 转发时取 X-Forwarded-For 首段) |

| POST | /api/occupational-exam/auth/password | changePwd | 取来访真实 IP(经 nginx 转发时取 X-Forwarded-For 首段) |

| GET | /api/occupational-exam/users | list | 业务角色白名单(防提权到 platform_admin) |

| POST | /api/occupational-exam/users | create | 业务角色白名单(防提权到 platform_admin) |

| PUT | /api/occupational-exam/users/{id}/dept | updateDept | 业务角色白名单(防提权到 platform_admin) |

| DELETE | /api/occupational-exam/users/{id} | delete | 变更 / 解除科室归属(deptId 为空表示从科室移除,不删除账号) |

| PUT | /api/occupational-exam/users/{id} | update | 删除医生账号(软删除,保留历史数据关联) |

| POST | /api/occupational-exam/users/{id}/reset-password | resetPwd | 修改姓名/角色/状态/科室 |

5.10.7 界面字段清单

表 5-10-A 用户与租户字段清单

| 字段 | 控件 | 必填 | 校验/说明 |

| 登录名 | 文本框 | 是 | 唯一 |

| 姓名/科室 | 选择 | 是 | — |

| 角色 | 多选 | 是 | admin/chief/doctor… |

| 状态 | 开关 | 是 | 启用/禁用 |

| 租户名称/管理员 | 表单 | 开通必填 | 自动建管理员 |

| 菜单勾选集 | 树形多选 | 授权必填 | 父子联动 |

5.10.8 业务规则

● 口令仅存 BCrypt 哈希,重置不回显任何明文;

● 登录连续失败锁定,锁定期间拒绝认证;

● 菜单授权改动即时生效,无需重启;授权子菜单必须同时授权父目录;

● 前端隐藏菜单 ≠ 放行:后端按角色与权限码二次鉴权;

● 业务查询强制租户过滤,越权访问留痕并拒绝;

● 字段权限在查询出口统一执行,掩码格式统一(如身份证显示前 4 后 4)。

5.10.9 操作步骤

管理员进入「用户管理」新增用户,分配角色与科室;

进入「菜单与角色授权」为角色勾选菜单(父子联动);

平台超管在「租户管理」开通机构,自动创建机构管理员;

忘记密码由管理员执行重置,用户凭新口令登录后可再修改;

权限调整即时生效:用户刷新页面即可见新菜单。

5.10.10 异常场景与处理

● 用户看不到某菜单:检查角色授权是否包含该菜单及其父目录;

● 账号被锁:等待锁定期满或由管理员处理;

● 越权提示:确认当前登录账号与所属租户。

图 5-13 用户管理页界面原型

5.11 系统日志审计模块详细设计

5.11.1 功能描述

日志审计模块对系统内的关键操作实施全程留痕,审计范围覆盖:登录登出(含失败锁定事件)、业务单据的新增/修改/状态流转、基础数据变更、用户与权限变更、报告生成与下载、敏感数据访问(SensitiveAuditLogger 专门记录敏感字段的明文查看、导出等行为)。日志表(sys_oper_log)记录操作人、所属模块、动作类型、关联业务单号、明细(变更前后摘要)、来源 IP 与时间,并建立时间索引支撑按时间段检索。日志仅增不改不删,保证审计记录不可篡改、可追溯;操作日志页面面向管理员提供按模块、操作人、时间区间的组合检索。

5.11.2 输入参数

系统各模块自动产生的日志事件(无需人工录入);日志查询条件(模块、操作人、业务单号、时间区间)与分页参数。

5.11.3 业务处理逻辑

1. 业务代码在关键动作处写入日志(模块、动作、单号、明细),登录/鉴权失败事件同样留痕;

2. 敏感访问审计独立记录:查看敏感字段明文、数据导出等操作额外写入审计明细,包含访问对象与授权依据;

3. 日志写入与业务事务解耦,日志失败不影响业务主流程;

4. 日志表不提供修改与删除接口,物理上保证留痕不可篡改;

5. 查询接口按管理员权限开放,支持组合条件与分页,配合时间索引快速检索。

5.11.4 输出结果

操作日志记录与检索列表、敏感访问审计台账;为安全审计、责任追溯与等保合规提供证据链。

关键输出样例:

oper_log {time: 10-03 09:15:22, user: 王医生, module: 科室录入, action: 结果保存, biz: TJ…112, ip: 192.168.1.31}

sensitive_log {action: 查看明文, object: biz_worker:1042, grant: 授权通过}

5.11.5 页面原型说明

「操作日志」页面提供模块/操作人/时间区间组合筛选的日志列表,明细列展开查看变更摘要。

界面布局说明:页面采用左侧固定导航 + 顶部当前位置栏 + 右侧内容区的经典后台布局,内容区顶部为操作工具栏(新增、批量、导出等高频按钮),中部为过滤检索区,主体为数据表格区;表格支持分页、关键字过滤与状态筛选,行内操作按钮按当前行状态动态显示。弹窗类操作(新建、编辑、审核意见)均以模态弹窗承载,表单字段带必填与格式校验提示。

交互说明:列表数据异步分页加载,不整页刷新;表单提交带防重复点击处理;操作结果以消息条即时反馈(成功/警告/错误分级);批量操作返回逐行结果明细;打印与导出场景适配 A4 纸张版式。

5.11.6 接口设计

表 5-11 系统日志审计模块接口清单(1项)

| 方法 | 接口路径 | 处理方法 | 功能说明 |

| GET | /api/occupational-exam/oper-logs | list | 操作日志查询(设计方案 模块1 系统管理:操作日志/登录日志) |

5.11.7 界面字段清单

表 5-11-A 日志检索字段清单

| 字段 | 控件 | 必填 | 校验/说明 |

| 操作人 | 文本 | 否 | — |

| 模块 | 下拉 | 否 | 业务模块枚举 |

| 时间区间 | 日期范围 | 否 | 时间索引 |

| 业务单号 | 文本 | 否 | 精确关联 |

| 明细 | 展开查看 | 自动 | 变更摘要 |

5.11.8 业务规则

● 日志表不提供修改/删除接口,物理不可篡改;

● 登录失败、越权访问等安全事件同样入日志;

● 敏感数据明文查看、导出单独走敏感审计;

● 日志写入失败不阻断业务主流程;

● 日志检索强制管理员权限。

5.11.9 操作步骤

管理员进入「操作日志」页面;

按操作人、模块、时间区间组合筛选;

查看明细了解每次操作的业务单号与变更摘要;

对敏感访问记录(明文查看/导出)单独核查。

5.11.10 异常场景与处理

● 查询缓慢:缩小时间区间(时间索引已建立);

● 日志缺失:确认对应操作是否在系统上线该功能之前发生。

图 5-12 操作日志页界面原型

5.12 数据安全与国密加密模块详细设计

5.12.1 功能描述

数据安全与国密加密模块提供基于国家商用密码算法(SM2/SM3/SM4)的可选数据加密能力,是本系统数据安全设计的核心。模块支持管理员在「数据安全」页面手动开关加密:开启后,劳动者姓名、身份证号、职业健康史、联系电话等敏感字段在写入数据库前经 SM4 加密(密文前缀 SM4V1: 标识版本),读取时对授权用户自动解密;关闭后系统直接明文读写,业务功能不受任何影响。SM3 用于敏感字段完整性校验:启用时对原文字段计算摘要另存 gm_digest 列,读取时重算比对,监测数据是否被篡改。SM2 用于报告签发等关键场景的非对称签名,密钥对由密钥管理器统一管理。SM4 密钥以密钥文件形式管理(sm4_keys.json),支持多版本密钥与轮换(rotate),旧密文按密钥标识解密,密钥文件指纹用于完整性核验。此外,系统提供安全通道(GmSecureChannel)与加密狗授权(DongleProvider,文件狗/硬件狗双实现)增强授权与传输侧防护。

5.12.2 输入参数

管理员在数据安全页面的开关指令(启用/停用加密、算法选择)、SM4 密钥(十六进制)与密钥标识、SM2 密钥对配置、密钥轮换指令、加密狗授权管理指令;业务侧敏感字段的读写请求。

5.12.3 业务处理逻辑

1. 加密配置(开关状态、算法、密钥)持久化于配置表,服务启动时加载(GmConfigService.reload),运行期修改即时生效;

2. 写路径:加密开启时,MyBatis 类型处理器(Sm4TypeHandler)对标注了 SM4 的实体字段在落盘前加密;密文前缀 SM4V1: 用于识别密文与密钥版本;

3. 读路径:查询结果经响应处理(Sm4ResponseAdvice)与类型处理器解密,仅授权角色获得明文;无权角色经 DataMaskService 掩码输出;明文查看动作写入敏感审计;

4. 开关关闭:类型处理器与响应处理直接透传明文,全部业务功能不受影响,实现「加密可选、业务无感」;

5. SM3 校验:启用时写入侧计算摘要存 gm_digest,读取侧重算比对,不一致在结果对象上标记完整性异常(gmIntact=false)并告警;

6. 密钥管理:密钥文件含多版本密钥与激活标识,轮换时新写入使用新密钥、历史密文按旧密钥标识解密,保证平滑轮换;密钥文件指针纹记录于状态页供核对;

7. SM2 签名:报告签发场景对关键数据计算签名并随报告存储,验证方可使用公钥核验签发来源与数据完整性;

8. 加密狗授权:按模块维度控制功能开通(菜单隐藏 + 路由拦截双闸),授权信息变更留痕。

5.12.4 输出结果

加密后的密文数据列、解密后的授权明文、SM3 完整性校验结果、SM2 签名值、加密状态页数据、密钥指纹与版本信息、授权控制结果。

关键输出样例:

gm_status {enabled: true, algorithm: SM4, key_versions: 3, active: k2, fingerprint: 3FA9…C21B}

integrity {checked: 213, intact: 213, broken: 0}

signature {report: REP…034, algorithm: SM2, verify: PASS}

5.12.5 页面原型说明

「数据安全」页面集中展示加密开关、算法、密钥指纹、SM3/SM2 状态与敏感访问审计;「加密狗授权」页管理模块级授权。

界面布局说明:页面采用左侧固定导航 + 顶部当前位置栏 + 右侧内容区的经典后台布局,内容区顶部为操作工具栏(新增、批量、导出等高频按钮),中部为过滤检索区,主体为数据表格区;表格支持分页、关键字过滤与状态筛选,行内操作按钮按当前行状态动态显示。弹窗类操作(新建、编辑、审核意见)均以模态弹窗承载,表单字段带必填与格式校验提示。

交互说明:列表数据异步分页加载,不整页刷新;表单提交带防重复点击处理;操作结果以消息条即时反馈(成功/警告/错误分级);批量操作返回逐行结果明细;打印与导出场景适配 A4 纸张版式。

图 5-6 国密加密开关控制逻辑

5.12.6 接口设计

5.12.7 界面字段清单

表 5-12-A 国密配置字段清单

| 字段 | 控件 | 必填 | 校验/说明 |

| 加密开关 | 开关 | 是 | 保存即时生效 |

| 算法选择 | 下拉 | 是 | SM4/SM3/SM2 独立开关 |

| SM4 密钥 | 文本(十六进制) | 开启必填 | 密钥文件托管 |

| 密钥版本/指纹 | 自动 | 自动 | 轮换与核对 |

| SM2 公私钥 | 文件/文本 | 签名必填 | 密钥管理器 |

| 审计查询 | 表格 | 自动 | 敏感访问记录 |

5.12.8 业务规则

● 加密开关即时生效,关闭后全链路透传明文,业务无感;

● 密文统一 SM4V1: 前缀标识,兼容多版本密钥;

● 密钥轮换只影响新写入,历史密文按密钥标识解密;

● SM3 校验失败的读取结果被标记并告警,不静默放行;

● 明文查看(解密出口)必须留敏感审计;

● 密钥文件权限收窄至服务账号,指纹登记供人工核对。

5.12.9 操作步骤

管理员进入「数据安全」页面查看当前加密状态、算法与密钥指纹;

开启加密:确认 SM4 密钥(或使用默认密钥文件),保存后立即生效;

开启 SM3 完整性校验:此后新写入数据自动计算摘要;

配置 SM2 签名密钥对用于报告签发签名;

密钥轮换:录入新密钥与标识,历史密文按旧标识解密;

关闭加密:一键关闭,系统全链路明文读写,业务不受影响。

5.12.10 异常场景与处理

● 开启后旧数据仍为明文:属预期,可由维护任务批量加密回填;

● 密文前缀缺失:该记录早于加密开启,按明文处理;

● SM3 校验告警:立即核查对应记录是否被直接改库,恢复后重算摘要。

本章小结:本章给出全部业务表的字段结构、表说明、建表语句、枚举字典、种子数据、索引设计、生命周期与备份策略,全部内容与系统实体定义一一对应。

第6章 数据库详细设计

6.1 数据库设计原则

业务库 peis_db 采用 MySQL 8.0、utf8mb4 字符集。设计遵循以下原则:业务表统一携带租户字段 tenant_id 实现多租户数据隔离;业务单据表设置逻辑删除标记 del_flag 与时间戳字段;单据编号(登记单 TJ、报告 REP、通知书 NTC)由序列表 seq_rule 统一发号;唯一性约束以数据库索引落实(身份证摘要、登记单号、报告号等);敏感字段以密文列存储并配 SM3 摘要列;查询热点字段建立复合索引(状态+日期等)。

6.2 实体关系总图

系统核心实体覆盖权限域(租户、用户、角色、菜单、字段权限)、基础档案域(用人单位、劳动者、危害因素、项目、套餐、科室)、业务单据域(登记单、结果、检验结果、结论、审核任务、报告、通知书、附件)与支撑域(操作日志、序列规则),实体关系如图 6-1 所示。

下图展示核心实体及其关系,标注了 SM4 加密列(★)与唯一索引字段。

图 6-1 核心实体关系(E-R)总图

6.3 核心数据表结构

本系统数据表结构依据后端实体类(MyBatis-Plus 注解)逐表整理,共 38 张业务表、合计 417 个字段。字段类型为 Java 类型与数据库类型的对应描述,标注「SM4」的字段为加密落盘字段。各表结构如下。

6.3.1 biz_adapter_config(AdapterConfig)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | adapter_type | String | VARCHAR(200) | — |

| 3 | adapter_name | String | VARCHAR(200) | — |

| 4 | enabled | Integer | INT | — |

| 5 | base_url | String | VARCHAR(200) | — |

| 6 | app_key | String | VARCHAR(200) | — |

| 7 | app_secret | String | VARCHAR(200) | — |

| 8 | extra_params | String | VARCHAR(200) | — |

| 9 | remark | String | VARCHAR(200) | — |

| 10 | tenant_id | Long | BIGINT | — |

| 11 | create_by | String | VARCHAR(200) | — |

| 12 | create_time | Date | VARCHAR | — |

| 13 | update_time | Date | VARCHAR | — |

| 14 | del_flag | Integer | INT | — |

6.3.2 sys_attach(Attach)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | biz_no | String | VARCHAR(200) | — |

| 3 | tenant_id | Long | BIGINT | — |

| 4 | attach_type | String | VARCHAR(200) | 影像/附件关联信息:文件原名(SM4 落盘加密)【SM4 加密】 |

| 5 | origin_name | String | VARCHAR(200) | 影像/附件关联信息:文件原名(SM4 落盘加密)【SM4 加密】 |

| 6 | store_path | String | VARCHAR(200) | — |

| 7 | file_size | Long | BIGINT | — |

| 8 | upload_by | Long | BIGINT | — |

| 9 | create_time | LocalDateTime | DATETIME | — |

| 10 | del_flag | Integer | INT | — |

表说明:附件表,按业务单号(biz_no)挂接病历、委托资料等文件,限制类型 jpg/png/pdf、单文件不超过 10MB,删除为软删作废。

6.3.3 base_dept(BaseDept)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | dept_name | String | VARCHAR(200) | — |

| 4 | sort_order | Integer | INT | — |

| 5 | remark | String | VARCHAR(200) | — |

| 6 | del_flag | Integer | INT | — |

表说明:科室表,预置内科、外科、五官科、电测听室、放射科、肺功能室、检验科等科室,科室是结果录入与待检队列的组织维度。

6.3.4 base_dict(BaseDict)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | dict_type | String | VARCHAR(200) | — |

| 4 | dict_key | String | VARCHAR(200) | — |

| 5 | dict_value | String | VARCHAR(200) | — |

| 6 | sort_order | Integer | INT | — |

表说明:数据字典表,维护体检类别、结论类型等枚举的编码-名称映射,供下拉选择与报表翻译。

6.3.5 biz_conclusion(Conclusion)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | register_id | Long | BIGINT | NORMAL/RECHECK/SUSPECTED/CONTRAINDICATION |

| 4 | conclusion_type | String | VARCHAR(200) | NORMAL/RECHECK/SUSPECTED/CONTRAINDICATION |

| 5 | summary | String | VARCHAR(200) | — |

| 6 | chief_doctor_id | Long | BIGINT | — |

| 7 | chief_doctor_name | String | VARCHAR(200) | — |

| 8 | reviewer_id | Long | BIGINT | — |

| 9 | reviewer_name | String | VARCHAR(200) | — |

| 10 | sign_time | LocalDateTime | DATETIME | DRAFT/L1/L2/L3/APPROVED/REJECTED/SIGNED |

| 11 | audit_status | String | VARCHAR(200) | DRAFT/L1/L2/L3/APPROVED/REJECTED/SIGNED |

| 12 | current_level | Integer | INT | 当前审核级别 0草稿 1/2/3 |

| 13 | reject_reason | String | VARCHAR(200) | — |

| 14 | create_time | LocalDateTime | DATETIME | — |

表说明:主检结论表,与登记单一对一;conclusion_type 取四类结论;签发人、审核人与签发时间在签发时落库。

6.3.6 biz_conclusion_audit(ConclusionAudit)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | conclusion_id | Long | BIGINT | — |

| 4 | register_id | Long | BIGINT | 1/2/3 审核级别 |

| 5 | audit_level | Integer | INT | 1/2/3 审核级别 |

| 6 | action | String | VARCHAR(200) | SUBMIT/PASS/REJECT/SIGN |

| 7 | auditor_id | Long | BIGINT | — |

| 8 | auditor_name | String | VARCHAR(200) | — |

| 9 | opinion | String | VARCHAR(200) | — |

| 10 | create_time | LocalDateTime | DATETIME | — |

6.3.7 biz_conclusion_task(ConclusionTask)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | register_id | Long | BIGINT | — |

| 4 | worker_id | Long | BIGINT | — |

| 5 | worker_name | String | VARCHAR(200) | — |

| 6 | reg_no | String | VARCHAR(200) | — |

| 7 | assignee_id | Long | BIGINT | — |

| 8 | assignee_name | String | VARCHAR(200) | PENDING 待派单 / ASSIGNED 已派单 / DONE 已完成 |

| 9 | status | String | VARCHAR(200) | PENDING 待派单 / ASSIGNED 已派单 / DONE 已完成 |

| 10 | create_time | LocalDateTime | DATETIME | — |

| 11 | assign_time | LocalDateTime | DATETIME | — |

| 12 | finish_time | LocalDateTime | DATETIME | — |

6.3.8 doctor_sign_template(DoctorSignTemplate)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | 关联医生账号ID(sys_user.id)【主键】 |

| 2 | doctor_id | Long | BIGINT | 关联医生账号ID(sys_user.id)【SM4 加密】 |

| 3 | sign_img_path | String | VARCHAR(200) | 签名文件服务器内部路径(SM4 落盘加密,禁止前端直连)【SM4 加密】 |

| 4 | img_width | Integer | INT | 报告签名框内渲染宽(px) 默认180 |

| 5 | img_height | Integer | INT | 报告签名框内渲染高(px) 默认80 |

| 6 | img_size | Integer | INT | 加密存储后体积(KB) |

| 7 | offset_x | Integer | INT | 签名框内水平偏移坐标(锁定) |

| 8 | offset_y | Integer | INT | 签名框内垂直偏移坐标(锁定) |

| 9 | is_enable | Integer | INT | 是否启用 1启用 0停用 |

| 10 | ca_bound | Integer | INT | 是否已绑定 CA 证书 1是(模式B)0否(模式A 直接渲染PNG) |

| 11 | tenant_id | Long | BIGINT | — |

| 12 | create_time | LocalDateTime | DATETIME | — |

| 13 | update_time | LocalDateTime | DATETIME | — |

表说明:医师签名模板表,保存主检/审核医师的签名图样,报告 PDF 呈现签名。

6.3.9 biz_employer(Employer)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | employer_name | String | VARCHAR(200) | — |

| 4 | credit_code | String | VARCHAR(200) | — |

| 5 | contact | String | VARCHAR(200) | — |

| 6 | phone | String | VARCHAR(200) | — |

| 7 | bank_name | String | VARCHAR(200) | — |

| 8 | bank_account | String | VARCHAR(200) | — |

| 9 | create_time | LocalDateTime | DATETIME | — |

表说明:用人单位表,单位名称唯一约束;是团体体检、汇总统计与通知书送达的组织维度。

6.3.10 base_exam_item(ExamItem)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | item_code | String | VARCHAR(200) | — |

| 4 | item_name | String | VARCHAR(200) | — |

| 5 | dept | String | VARCHAR(200) | 检查类别:检验/影像/超声/心电/内镜/病理/功能/体格检查 |

| 6 | category | String | VARCHAR(200) | 检查类别:检验/影像/超声/心电/内镜/病理/功能/体格检查 |

| 7 | specimen | String | VARCHAR(200) | 标本或检查部位 |

| 8 | abbr | String | VARCHAR(200) | 常用缩写 |

| 9 | value_type | String | VARCHAR(200) | — |

| 10 | unit | String | VARCHAR(200) | 计价单位(次/项/部位) |

| 11 | charge_unit | String | VARCHAR(200) | 计价单位(次/项/部位) |

| 12 | medical_code | String | VARCHAR(200) | 国家或医保收费项目目录编码(未核对留空) |

| 13 | is_core | Integer | INT | 1=常见必备项 0=可选扩展项 |

| 14 | ref_low | BigDecimal | DECIMAL(12,2) | — |

| 15 | ref_high | BigDecimal | DECIMAL(12,2) | — |

| 16 | abnormal_flag | Integer | INT | — |

表说明:检查项目表,定义项目所属科室、值类型(数值/文本)、单位、参考区间上下限;abnormal_flag 标记职业敏感项,敏感项异常在结果判定中单独升级标记。

6.3.11 exam_item_knowledge(ExamItemKnowledge)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | 关联 base_exam_item.id(可空:允许仅按编码维护) |

| 3 | item_id | Long | BIGINT | 关联 base_exam_item.id(可空:允许仅按编码维护) |

| 4 | item_code | String | VARCHAR(200) | — |

| 5 | item_name | String | VARCHAR(200) | — |

| 6 | category | String | VARCHAR(200) | — |

| 7 | dept | String | VARCHAR(200) | — |

| 8 | unit | String | VARCHAR(200) | number / text |

| 9 | value_type | String | VARCHAR(200) | number / text |

| 10 | ref_low | BigDecimal | DECIMAL(12,2) | 正常参考区间 |

| 11 | ref_high | BigDecimal | DECIMAL(12,2) | 轻度异常绝对阈值(优先于百分比) |

| 12 | mild_low | BigDecimal | DECIMAL(12,2) | 轻度异常绝对阈值(优先于百分比) |

| 13 | mild_high | BigDecimal | DECIMAL(12,2) | 中度异常绝对阈值 |

| 14 | mod_low | BigDecimal | DECIMAL(12,2) | 中度异常绝对阈值 |

| 15 | mod_high | BigDecimal | DECIMAL(12,2) | 未配绝对值时的百分比阈值(偏离参考区间的百分比) |

| 16 | mild_pct | BigDecimal | DECIMAL(12,2) | 未配绝对值时的百分比阈值(偏离参考区间的百分比) |

| 17 | mod_pct | BigDecimal | DECIMAL(12,2) | 危急值(命中直接判重度) |

| 18 | crit_low | BigDecimal | DECIMAL(12,2) | 危急值(命中直接判重度) |

| 19 | crit_high | BigDecimal | DECIMAL(12,2) | — |

| 20 | interpret_normal | String | VARCHAR(200) | — |

| 21 | interpret_mild | String | VARCHAR(200) | — |

| 22 | interpret_moderate | String | VARCHAR(200) | — |

| 23 | interpret_severe | String | VARCHAR(200) | — |

| 24 | health_advice | String | VARCHAR(200) | 是否职业病重点项目 1=是(强制人工复核) |

| 25 | occ_key | Integer | INT | 是否职业病重点项目 1=是(强制人工复核) |

| 26 | enabled | Integer | INT | 启停 1启用 0停用 |

| 27 | remark | String | VARCHAR(200) | — |

| 28 | create_by | Long | BIGINT | — |

| 29 | create_time | LocalDateTime | DATETIME | — |

| 30 | update_time | LocalDateTime | DATETIME | — |

表说明:项目知识库表,维护项目解读知识与异常提示文案,供结果录入与报告解读引用。

6.3.12 base_package(ExamPackage)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | package_name | String | VARCHAR(200) | — |

| 4 | factor_id | Long | BIGINT | — |

| 5 | exam_type | String | VARCHAR(200) | — |

| 6 | version | String | VARCHAR(200) | — |

| 7 | package_code | String | VARCHAR(200) | — |

表说明:体检套餐表,按「危害因素×体检类别」组织,version 字段记录依据的规范版本(GBZ188-2014)。

6.3.13 biz_register(ExamRegister)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | reg_no | String | VARCHAR(200) | — |

| 3 | tenant_id | Long | BIGINT | — |

| 4 | worker_id | Long | BIGINT | — |

| 5 | employer_id | Long | BIGINT | — |

| 6 | package_id | Long | BIGINT | — |

| 7 | exam_type | String | VARCHAR(200) | — |

| 8 | reg_date | LocalDate | DATE | REGISTERED/CHECKING/CHECKED/CONCLUDED/SIGNED/ARCHIVED/CANCELED |

| 9 | status | String | VARCHAR(200) | REGISTERED/CHECKING/CHECKED/CONCLUDED/SIGNED/ARCHIVED/CANCELED |

| 10 | version | Integer | INT | 行级软锁:解锁要写 null,必须 IGNORED 策略,否则 updateById 跳过 null 字段导致锁永远清不掉 |

| 11 | lock_by | Long | BIGINT | 行级软锁:解锁要写 null,必须 IGNORED 策略,否则 updateById 跳过 null 字段导致锁永远清不掉 |

| 12 | lock_time | LocalDateTime | DATETIME | — |

| 13 | remark | String | VARCHAR(200) | — |

| 14 | create_by | Long | BIGINT | — |

| 15 | create_time | LocalDateTime | DATETIME | — |

| 16 | update_time | LocalDateTime | DATETIME | — |

| 17 | del_flag | Integer | INT | 1=匿名体检(报告/列表脱敏展示) |

表说明:体检登记单表,业务主单据。reg_no 由序列表发号(TJyyyyMMdd-nnnnnn);status 承载六态状态机;version 乐观锁;lock_by/lock_time 行级软锁;(status,reg_date) 复合索引支撑在办查询。

6.3.14 exam_report_interpret(ExamReportInterpret)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | report_id | Long | BIGINT | — |

| 4 | register_id | Long | BIGINT | — |

| 5 | worker_id | Long | BIGINT | 劳动者姓名快照(SM4 落盘加密)【SM4 加密】 |

| 6 | worker_name | String | VARCHAR(200) | 劳动者姓名快照(SM4 落盘加密)【SM4 加密】 |

| 7 | id_card_hash | String | VARCHAR(200) | 身份证 SHA256,对外接口按此查询 |

| 8 | report_no | String | VARCHAR(200) | NOT_GENERATED/AUTO_PENDING/PENDING_REVIEW/REVIEWED/REJECTED/LOCKED |

| 9 | status | String | VARCHAR(200) | NOT_GENERATED/AUTO_PENDING/PENDING_REVIEW/REVIEWED/REJECTED/LOCKED |

| 10 | abnormal_level | String | VARCHAR(200) | NORMAL/MILD/MODERATE/SEVERE【SM4 加密】 |

| 11 | abnormal_summary | String | VARCHAR(200) | 异常摘要(SM4 落盘加密)【SM4 加密】 |

| 12 | draft_content | String | VARCHAR(200) | 机器生成初稿(SM4 落盘加密)【SM4 加密】 |

| 13 | final_content | String | VARCHAR(200) | 复核后终稿(SM4 落盘加密)【SM4 加密】 |

| 14 | version | Integer | INT | 1=报告已归档锁定,禁止修改 |

| 15 | locked | Integer | INT | 1=报告已归档锁定,禁止修改 |

| 16 | generate_by | Long | BIGINT | — |

| 17 | generate_by_name | String | VARCHAR(200) | — |

| 18 | generate_time | LocalDateTime | DATETIME | — |

| 19 | reviewer_id | Long | BIGINT | — |

| 20 | reviewer_name | String | VARCHAR(200) | — |

| 21 | review_time | LocalDateTime | DATETIME | — |

| 22 | reject_reason | String | VARCHAR(200) | — |

| 23 | create_time | LocalDateTime | DATETIME | — |

| 24 | update_time | LocalDateTime | DATETIME | — |

表说明:报告智能解读记录表,保存对报告的解读内容与上下文,供医生参考。

6.3.15 exam_report_interpret_log(ExamReportInterpretLog)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | report_id | Long | BIGINT | — |

| 4 | register_id | Long | BIGINT | — |

| 5 | worker_id | Long | BIGINT | — |

| 6 | worker_name | String | VARCHAR(200) | — |

| 7 | id_card_hash | String | VARCHAR(200) | — |

| 8 | report_no | String | VARCHAR(200) | AUTO_GEN/EDIT/REVIEW_PASS/REJECT/REGEN/LOCK/DELETE_ITEM |

| 9 | oper_type | String | VARCHAR(200) | AUTO_GEN/EDIT/REVIEW_PASS/REJECT/REGEN/LOCK/DELETE_ITEM |

| 10 | version | Integer | INT | — |

| 11 | draft_content | String | VARCHAR(200) | — |

| 12 | final_content | String | VARCHAR(200) | — |

| 13 | generate_time | LocalDateTime | DATETIME | — |

| 14 | review_time | LocalDateTime | DATETIME | — |

| 15 | doctor_id | Long | BIGINT | — |

| 16 | doctor_name | String | VARCHAR(200) | — |

| 17 | remark | String | VARCHAR(200) | — |

| 18 | create_time | LocalDateTime | DATETIME | — |

表说明:解读操作日志表,记录解读查看/生成的审计轨迹。

6.3.16 biz_exam_result(ExamResult)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | register_id | Long | BIGINT | — |

| 4 | item_id | Long | BIGINT | — |

| 5 | dept | String | VARCHAR(200) | 职业病体检指标结论(SM4 落盘加密)【SM4 加密】 |

| 6 | result_text | String | VARCHAR(200) | 职业病体检指标结论(SM4 落盘加密)【SM4 加密】 |

| 7 | result_value | BigDecimal | DECIMAL(12,2) | — |

| 8 | abnormal | Integer | INT | — |

| 9 | item_snapshot | String | VARCHAR(200) | — |

| 10 | doctor_id | Long | BIGINT | — |

| 11 | doctor_name | String | VARCHAR(200) | — |

| 12 | create_time | LocalDateTime | DATETIME | — |

| 13 | update_time | LocalDateTime | DATETIME | — |

表说明:科室检查结果表,登记单×项目唯一约束防重复录入;result_text/result_value 按值类型二选一;abnormal 取值 0 正常/1 异常/2 敏感项异常;item_snapshot 保存项目名快照防项目库变动影响历史。

6.3.17 biz_exam_result_amend(ExamResultAmend)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | register_id | Long | BIGINT | — |

| 4 | item_id | Long | BIGINT | — |

| 5 | dept | String | VARCHAR(200) | — |

| 6 | result_text | String | VARCHAR(200) | — |

| 7 | result_value | BigDecimal | DECIMAL(12,2) | — |

| 8 | abnormal | Integer | INT | — |

| 9 | item_snapshot | String | VARCHAR(200) | 修订版本号:同一 register+item 下自增,display 取最大 revision |

| 10 | revision | Integer | INT | 修订版本号:同一 register+item 下自增,display 取最大 revision |

| 11 | original_result_id | Long | BIGINT | 被修订的原始 biz_exam_result.id(溯源,原记录永不改动) |

| 12 | amend_reason | String | VARCHAR(200) | — |

| 13 | amended_by | Long | BIGINT | — |

| 14 | amended_name | String | VARCHAR(200) | — |

| 15 | create_time | LocalDateTime | DATETIME | — |

6.3.18 base_hazard_factor(HazardFactor)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | factor_code | String | VARCHAR(200) | — |

| 4 | factor_name | String | VARCHAR(200) | — |

| 5 | target_disease | String | VARCHAR(200) | — |

| 6 | cycle_months | Integer | INT | — |

| 7 | basis | String | VARCHAR(200) | — |

| 8 | create_time | LocalDateTime | DATETIME | — |

表说明:接害因素表,依据 GBZ 188 维护因素编码、名称、目标疾病、检查周期(月)与依据条款;检查周期是周期体检到期预警的计算依据。

6.3.19 biz_lab_result(LabResult)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | register_id | Long | BIGINT | — |

| 4 | item_id | Long | BIGINT | — |

| 5 | result_value | BigDecimal | DECIMAL(12,2) | — |

| 6 | unit | String | VARCHAR(200) | — |

| 7 | ref_low | BigDecimal | DECIMAL(12,2) | — |

| 8 | ref_high | BigDecimal | DECIMAL(12,2) | — |

| 9 | abnormal | Integer | INT | — |

| 10 | source | String | VARCHAR(200) | — |

| 11 | create_time | LocalDateTime | DATETIME | — |

表说明:检验结果表,记录数值、单位与参考区间快照(ref_low/ref_high),source 标记结果来源(manual 手工/import 导入/lis 接口),为检验系统对接预留。

6.3.20 biz_notice(Notice)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | register_id | Long | BIGINT | — |

| 3 | tenant_id | Long | BIGINT | RECHECK复查/TRANSFER转诊/RESTRAIN调离 |

| 4 | notice_type | String | VARCHAR(200) | RECHECK复查/TRANSFER转诊/RESTRAIN调离 |

| 5 | notice_no | String | VARCHAR(200) | — |

| 6 | content | String | VARCHAR(200) | — |

| 7 | pdf_path | String | VARCHAR(200) | — |

| 8 | create_time | LocalDateTime | DATETIME | — |

表说明:通知书表,notice_type 区分复查(RECHECK)/转诊(TRANSFER)/调离(RESTRAIN),编号按 NTC 序列发放,PDF 随记录落盘。

6.3.21 sys_oper_log(OperLog)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | user_id | Long | BIGINT | — |

| 4 | username | String | VARCHAR(200) | — |

| 5 | module | String | VARCHAR(200) | — |

| 6 | action | String | VARCHAR(200) | — |

| 7 | biz_no | String | VARCHAR(200) | — |

| 8 | detail | String | VARCHAR(200) | — |

| 9 | ip | String | VARCHAR(200) | — |

| 10 | create_time | LocalDateTime | DATETIME | — |

表说明:操作日志表,记录操作人、模块、动作、业务单号、明细与来源 IP,仅增不改不删,时间字段建索引支撑检索。

6.3.22 base_package_item(PackageItem)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | package_id | Long | BIGINT | — |

| 3 | item_id | Long | BIGINT | — |

表说明:套餐-项目关系表,登记分诊时按本表生成登记单的应检项目集合,实现应检/已录进度对比。

6.3.23 biz_register_hazard(RegisterHazard)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | register_id | Long | BIGINT | — |

| 3 | factor_id | Long | BIGINT | — |

表说明:登记单-接害因素关系表,记录本次体检针对的危害因素,登记时可多选。

6.3.24 biz_report(Report)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | register_id | Long | BIGINT | — |

| 3 | report_no | String | VARCHAR(200) | — |

| 4 | tenant_id | Long | BIGINT | — |

| 5 | pdf_path | String | VARCHAR(200) | — |

| 6 | version | Integer | INT | GENERATED/SIGNED/CANCELED |

| 7 | status | String | VARCHAR(200) | GENERATED/SIGNED/CANCELED |

| 8 | sign_time | LocalDateTime | DATETIME | — |

| 9 | create_time | LocalDateTime | DATETIME | — |

表说明:报告表,report_no 按 REP 序列唯一;pdf_path 存相对路径;version 支持重出版本化,历史版本文件保留。

6.3.25 biz_review_config(ReviewConfig)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | — |

| 3 | module | String | VARCHAR(200) | 审核级别数 1/2/3 |

| 4 | levels | Integer | INT | 审核级别数 1/2/3 |

| 5 | create_time | LocalDateTime | DATETIME | — |

| 6 | update_time | LocalDateTime | DATETIME | — |

6.3.26 seq_rule(SeqRule)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | seq_key | String | VARCHAR(200) | —【主键】 |

| 2 | seq_val | Long | BIGINT | — |

表说明:序列规则表,按业务前缀(TJ/REP/NTC)原子发号,保证单据编号连续唯一。

6.3.27 base_std_disease(StdDisease)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | disease_code | String | VARCHAR(200) | — |

| 3 | category_code | String | VARCHAR(200) | — |

| 4 | disease_name | String | VARCHAR(200) | — |

| 5 | open_clause | Integer | INT | — |

| 6 | scope_limit | String | VARCHAR(200) | — |

| 7 | hazard_keywords | String | VARCHAR(200) | — |

| 8 | diagnosis_basis | String | VARCHAR(200) | — |

| 9 | sort_no | Integer | INT | — |

| 10 | source_version | String | VARCHAR(200) | — |

| 11 | tenant_id | Long | BIGINT | — |

| 12 | create_time | LocalDateTime | DATETIME | — |

| 13 | update_time | LocalDateTime | DATETIME | — |

| 14 | del_flag | Integer | INT | — |

6.3.28 base_std_disease_category(StdDiseaseCategory)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | category_code | String | VARCHAR(200) | — |

| 3 | category_name | String | VARCHAR(200) | — |

| 4 | disease_count | Integer | INT | — |

| 5 | sort_no | Integer | INT | — |

| 6 | source_version | String | VARCHAR(200) | — |

| 7 | remark | String | VARCHAR(200) | — |

| 8 | tenant_id | Long | BIGINT | — |

| 9 | create_time | LocalDateTime | DATETIME | — |

| 10 | update_time | LocalDateTime | DATETIME | — |

| 11 | del_flag | Integer | INT | — |

6.3.29 base_std_exam_item(StdExamItem)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | rule_id | Long | BIGINT | — |

| 3 | item_code | String | VARCHAR(200) | — |

| 4 | item_name | String | VARCHAR(200) | — |

| 5 | item_kind | String | VARCHAR(200) | — |

| 6 | dept | String | VARCHAR(200) | — |

| 7 | sort_no | Integer | INT | — |

| 8 | tenant_id | Long | BIGINT | — |

| 9 | create_time | LocalDateTime | DATETIME | — |

| 10 | del_flag | Integer | INT | — |

6.3.30 base_std_exam_rule(StdExamRule)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | hazard_code | String | VARCHAR(200) | — |

| 3 | exam_type | String | VARCHAR(200) | — |

| 4 | exam_cycle_months | Integer | INT | — |

| 5 | is_mandatory | Integer | INT | — |

| 6 | target_disease | String | VARCHAR(200) | — |

| 7 | contraindication | String | VARCHAR(200) | — |

| 8 | standard_version | String | VARCHAR(200) | — |

| 9 | remark | String | VARCHAR(200) | — |

| 10 | tenant_id | Long | BIGINT | — |

| 11 | create_time | LocalDateTime | DATETIME | — |

| 12 | update_time | LocalDateTime | DATETIME | — |

| 13 | del_flag | Integer | INT | — |

6.3.31 base_std_hazard(StdHazard)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | hazard_code | String | VARCHAR(200) | — |

| 3 | hazard_name | String | VARCHAR(200) | — |

| 4 | hazard_type | String | VARCHAR(200) | — |

| 5 | gbz_section | String | VARCHAR(200) | — |

| 6 | standard_version | String | VARCHAR(200) | — |

| 7 | target_disease | String | VARCHAR(200) | — |

| 8 | exam_summary | String | VARCHAR(200) | — |

| 9 | in_service_cycle_months | Integer | INT | — |

| 10 | has_pre_exam | Integer | INT | — |

| 11 | has_off_exam | Integer | INT | — |

| 12 | has_emergency_exam | Integer | INT | — |

| 13 | remark | String | VARCHAR(200) | — |

| 14 | tenant_id | Long | BIGINT | — |

| 15 | create_time | LocalDateTime | DATETIME | — |

| 16 | update_time | LocalDateTime | DATETIME | — |

| 17 | del_flag | Integer | INT | — |

6.3.32 base_std_hazard_disease(StdHazardDisease)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | hazard_code | String | VARCHAR(200) | — |

| 3 | disease_code | String | VARCHAR(200) | — |

| 4 | relation | String | VARCHAR(200) | — |

| 5 | tenant_id | Long | BIGINT | — |

| 6 | create_time | LocalDateTime | DATETIME | — |

| 7 | del_flag | Integer | INT | — |

6.3.33 sys_menu(SysMenu)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | parent_id | Long | BIGINT | — |

| 3 | menu_name | String | VARCHAR(200) | — |

| 4 | path | String | VARCHAR(200) | — |

| 5 | perm_code | String | VARCHAR(200) | — |

| 6 | menu_type | Integer | INT | — |

| 7 | sort_order | Integer | INT | — |

| 8 | del_flag | Integer | INT | — |

表说明:菜单表,树形结构(parent_id),区分目录/菜单/按钮类型;perm_code 承载接口级权限码,前端侧栏由本表按角色过滤后动态渲染。

6.3.34 sys_role(SysRole)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | role_code | String | VARCHAR(200) | — |

| 3 | role_name | String | VARCHAR(200) | — |

| 4 | remark | String | VARCHAR(200) | — |

| 5 | del_flag | Integer | INT | — |

表说明:角色字典表,预置系统管理员(admin)、主检医师(chief)、科室医生(doctor)等角色,角色码是菜单授权与接口鉴权的基础。

6.3.35 sys_role_menu(SysRoleMenu)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | role_id | Long | BIGINT | — |

| 3 | menu_id | Long | BIGINT | — |

表说明:角色-菜单授权关系表,管理员勾选保存后即时生效;授权子菜单必须同时授权其父目录。

6.3.36 sys_tenant(SysTenant)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_code | String | VARCHAR(200) | — |

| 3 | tenant_name | String | VARCHAR(200) | — |

| 4 | contact | String | VARCHAR(200) | — |

| 5 | phone | String | VARCHAR(200) | — |

| 6 | status | Integer | INT | — |

| 7 | create_time | LocalDateTime | DATETIME | — |

| 8 | del_flag | Integer | INT | — |

表说明:租户表,一个租户对应一家体检机构。平台超级管理员(tenant_id=0)可跨租户管理;机构管理员账号随租户创建,业务数据全部以本表主键作为 tenant_id 隔离键。

6.3.37 sys_user(SysUser)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | username | String | VARCHAR(200) | — |

| 3 | password | String | VARCHAR(200) | — |

| 4 | real_name | String | VARCHAR(200) | — |

| 5 | dept_id | Long | BIGINT | — |

| 6 | tenant_id | Long | BIGINT | — |

| 7 | role_codes | String | VARCHAR(200) | — |

| 8 | status | Integer | INT | — |

| 9 | fail_count | Integer | INT | — |

| 10 | del_flag | Integer | INT | — |

| 11 | lock_until | LocalDateTime | DATETIME | — |

| 12 | create_time | LocalDateTime | DATETIME | — |

| 13 | update_time | LocalDateTime | DATETIME | — |

表说明:用户表,存储登录账号与 BCrypt 口令哈希。fail_count 与 lock_until 字段实现登录失败计数与锁定;role_codes 以逗号分隔存储多角色码;dept_id 关联科室用于结果录入的数据范围控制。

6.3.38 biz_worker(Worker)

| 序号 | 字段名 | Java 类型 | 数据库类型 | 说明 |

| 1 | id | Long | BIGINT | —【主键】 |

| 2 | tenant_id | Long | BIGINT | 人员姓名(SM4 落盘加密)【SM4 加密】 |

| 3 | worker_name | String | VARCHAR(200) | 人员姓名(SM4 落盘加密)【SM4 加密】 |

| 4 | id_card_hash | String | VARCHAR(200) | 身份证号码(SM4 落盘加密)【SM4 加密】 |

| 5 | id_card_enc | String | VARCHAR(200) | 身份证号码(SM4 落盘加密)【SM4 加密】 |

| 6 | gender | String | VARCHAR(200) | — |

| 7 | birth_date | LocalDate | DATE | — |

| 8 | employer_id | Long | BIGINT | — |

| 9 | job_type | String | VARCHAR(200) | — |

| 10 | hazard_years | BigDecimal | DECIMAL(12,2) | 职业健康史/接触史(SM4 落盘加密)【SM4 加密】 |

| 11 | medical_history | String | VARCHAR(200) | 职业健康史/接触史(SM4 落盘加密)【SM4 加密】 |

| 12 | address | String | VARCHAR(200) | 住址 |

| 13 | phone | String | VARCHAR(200) | 联系电话 |

| 14 | create_time | LocalDateTime | DATETIME | — |

表说明:劳动者档案表。id_card_hash 存身份证 SHA-256 摘要(唯一索引防重复建档);worker_name、id_card_enc、medical_history、phone 等敏感列 SM4 加密落盘;gm_digest 存 SM3 摘要供完整性校验。

6.4 表间关联关系

核心关联关系:biz_worker.employer_id → biz_employer.id(劳动者隶属单位);biz_register.worker_id → biz_worker.id、biz_register.package_id → base_package.id(登记单关联档案与套餐);biz_register_hazard(register_id, factor_id) 关联登记单与接害因素;biz_exam_result / biz_lab_result.register_id → biz_register.id(结果挂接登记单,item_id → base_exam_item.id);biz_conclusion.register_id 与登记单一对一;biz_report / biz_notice.register_id → biz_register.id;conclusion_task 挂接登记单与审核人;sys_user_role、sys_role_menu 分别维护用户-角色、角色-菜单关系;sys_field_perm 按「角色×表×字段」配置权限;全部业务表携带 tenant_id 隔离。

6.5 索引设计

表 6-1 关键索引设计

| 表 | 索引/约束 | 用途 |

| biz_worker | id_card_hash 唯一索引 | 身份证摘要查重,一人一档 |

| biz_worker | employer_id 普通索引 | 按单位检索人员 |

| biz_register | reg_no 唯一索引 | 登记单号唯一 |

| biz_register | (status, reg_date) 复合索引 | 按状态与日期检索在办单据 |

| biz_exam_result | (register_id, item_id) 唯一索引 | 防同一登记单同一项目重复录入 |

| biz_lab_result | (register_id, item_id) 唯一索引 | 检验结果防重 |

| biz_report | report_no 唯一索引 | 报告号唯一 |

| sys_oper_log | create_time 索引 | 日志按时间检索 |

| sys_user | username 唯一索引 | 登录名唯一 |

6.6 数据存储与备份策略

报告 PDF、通知书与附件存储于服务器文件目录(files/occupational),数据库仅存相对路径,避免大对象占用数据库空间;密钥文件独立存放并以指纹登记。数据备份采用:数据库每日定时全量备份(mysqldump),备份文件异地目录保存;文件目录定时增量备份;密钥文件单独备份并限制访问权限。备份保留周期按机构合规要求配置,恢复演练纳入运维规程。

6.7 枚举值字典

系统业务枚举统一由数据字典与代码常量管理,取值如下。

表 6-2 业务枚举值字典

| 枚举 | 取值 | 含义 | 使用位置 |

| 体检状态 status | REGISTERED / CHECKING / CHECKED / CONCLUDED / SIGNED / ARCHIVED / CANCELED | 已登记 / 检查中 / 检查完成 / 已出结论 / 已签发 / 已归档 / 已取消 | biz_register.status,状态机越序流转被后端拦截 |

| 体检类别 exam_type | PRE / ONJOB / OFFJOB / EMERG | 上岗前 / 在岗期间 / 离岗时 / 应急健康检查 | base_dict.exam_type,对应 GBZ 188 检查类别 |

| 结论类型 conclusion_type | NORMAL / RECHECK / SUSPECTED / CONTRAINDICATION | 目前未见异常 / 复查 / 疑似职业病 / 职业禁忌证 | biz_conclusion.conclusion_type,异常结论联动通知书 |

| 通知书类型 notice_type | RECHECK / TRANSFER / RESTRAIN | 复查通知书 / 转诊建议 / 调离通知书 | biz_notice.notice_type |

| 结果异常级别 abnormal | 0 / 1 / 2 | 正常 / 异常 / 敏感项异常 | biz_exam_result.abnormal,敏感项异常由 abnormal_flag=1 的项目触发 |

| 结果来源 source | manual / import / lis | 手工录入 / 批量导入 / LIS 接口 | biz_lab_result.source |

| 角色码 role_code | admin / chief / doctor | 系统管理员 / 主检医师 / 科室医生 | sys_role.role_code,可扩展登记员等角色 |

| 字段权限 perm | read / write / mask | 可读 / 可写 / 脱敏 | sys_field_perm.perm |

| 单据编号规则 | TJ / REP / NTC + yyyyMMdd - nnnnnn | 登记单 / 报告 / 通知书 | seq_rule 序列表原子发号 |

| 报告状态 status | GENERATED / SIGNED / CANCELED | 已生成 / 已签发 / 已作废 | biz_report.status |

6.8 初始化种子数据

系统部署时由初始化脚本(init.sql)写入以下种子数据,保证开箱可用。

表 6-3 初始化种子数据

| 数据类别 | 内容 | 数量 |

| sys_role 角色 | admin 系统管理员;chief 主检医师;doctor 科室医生 | 3 条 |

| base_dept 科室 | 内科、外科、五官科、电测听室、放射科、肺功能室、检验科 | 7 条 |

| base_hazard_factor 接害因素 | 粉尘(矽尘等)→职业性尘肺病;噪声→职业性噪声聋;苯→职业性苯中毒/白血病;铅→职业性铅中毒;高温→中暑(各带检查周期与 GBZ 188 依据条款) | 5 条 |

| base_exam_item 检查项目 | 内科检查、外科检查、五官检查、电测听、胸部X线(高千伏)、肺功能、血常规、肝功能、尿铅、纯音听力(左)、纯音听力(右)(电测听/胸片/肺功能/尿铅/纯音听力标记为职业敏感项,尿铅参考区间 0—0.07 mg/L,纯音听力上限 25 dB) | 11 条 |

| base_package 体检套餐 | 粉尘/噪声/苯/铅作业人员套餐(在岗期间) | 4 条 |

| base_package_item 套餐项目 | 按因素规范组合(如噪声套餐含内科、电测听、纯音听力双耳、血常规) | 16 条 |

| base_dict 字典 | 体检类别 4 项;结论类型 4 项 | 8 条 |

| sys_menu 菜单 | 工作台、劳动者档案、体检登记、科室录入、主检结论、报告中心、通知书、附件管理、汇总报表、系统管理(用户管理/菜单授权/关于)、租户管理、基础档案、用人单位、团体预约、操作日志、财务管理 | 19 项 |

| seq_rule 序列 | TJ / REP / NTC 发号序列 | 3 条 |

6.9 数据生命周期管理

各业务数据从产生、使用到归档的生命周期管理策略如下:

表 6-4 数据生命周期管理

| 数据对象 | 产生环节 | 使用环节 | 归档策略 | 清理策略 |

| 劳动者档案 | 建档/批量导入 | 登记、结论、报告引用 | 长期保存(健康监护档案要求) | 软删标记,不物理清除 |

| 体检登记单 | 登记发号 | 全流程跟踪 | 归档后转历史查询通道 | 保留,支持归档检索 |

| 检查/检验结果 | 科室录入 | 主检结论、报告 | 随报告归档 | 保留 |

| 主检结论与审核记录 | 结论/审核 | 签发、报告 | 报告归档 | 保留(审核证据链) |

| 报告/通知书 PDF | 签发触发生成 | 预览、下载、送达 | 版本化留存 | 文件目录长期保存 |

| 操作日志 | 系统自动记录 | 安全审计 | 按合规周期留存 | 仅增不改,到期按制度归档 |

| 登录会话(JWT) | 登录签发 | 请求鉴权 | 过期失效 | 无需清理 |

6.10 种子数据明细

初始化种子数据的真实取值如下:

None 表 6-5 科室种子(dept_name, sort_order)

| 科室种子 数据 |

| 内科, 1 |

| 外科, 2 |

| 五官科, 3 |

| 电测听室, 4 |

| 放射科, 5 |

| 肺功能室, 6 |

| 检验科, 7 |

None 表 6-6 字典种子(type, key, value)

| 字典种子 数据 |

| exam_type, PRE, 上岗前 |

| exam_type, ONJOB, 在岗期间 |

| exam_type, OFFJOB, 离岗时 |

| exam_type, EMERG, 应急健康检查 |

| conclusion, NORMAL, 目前未见异常 |

| conclusion, RECHECK, 复查 |

| conclusion, SUSPECTED, 疑似职业病 |

| conclusion, CONTRAINDICATION, 职业禁忌证 |

None 表 6-7 项目种子(code, name, dept, type, ref, 敏感)

| 项目种子 数据 |

| I01, 内科检查, 内科, text, —, 否 |

| I02, 外科检查, 外科, text, —, 否 |

| I03, 五官检查, 五官科, text, —, 否 |

| I04, 电测听, 电测听室, number(dB), —, 敏感 |

| I05, 胸部X线(高千伏), 放射科, text, —, 敏感 |

| I06, 肺功能, 肺功能室, text, —, 敏感 |

| I07, 血常规, 检验科, text, —, 否 |

| I08, 肝功能, 检验科, text, —, 否 |

| I09, 尿铅, 检验科, number(mg/L), 0—0.07, 敏感 |

| I10, 纯音听力(左), 电测听室, number(dB), ≤25, 敏感 |

| I11, 纯音听力(右), 电测听室, number(dB), ≤25, 敏感 |

None 表 6-8 因素种子(code, name, target, cycle, basis)

| 因素种子 数据 |

| F01, 粉尘(矽尘等), 职业性尘肺病, 12, GBZ188-2014 4.1 |

| F02, 噪声, 职业性噪声聋, 12, GBZ188-2014 8.1 |

| F03, 苯, 职业性苯中毒/白血病, 12, GBZ188-2014 5.1 |

| F04, 铅, 职业性铅中毒, 12, GBZ188-2014 5.2 |

| F05, 高温, 中暑, 12, GBZ188-2014 9.1 |

None 表 6-9 套餐种子(name, factor, exam_type)

| 套餐种子 数据 |

| 粉尘作业人员套餐(在岗期间), 粉尘, 在岗期间 |

| 噪声作业人员套餐(在岗期间), 噪声, 在岗期间 |

| 苯作业人员套餐(在岗期间), 苯, 在岗期间 |

| 铅作业人员套餐(在岗期间), 铅, 在岗期间 |

None 表 6-10 序列种子(seq_key)

| 序列种子 数据 |

| TJ 登记单号序列 |

| REP 报告号序列 |

| NTC 通知书号序列 |

None 表 6-11 菜单种子(id, name, path)

| 菜单种子 数据 |

| 1 工作台 /dashboard |

| 2 劳动者档案 /workers |

| 3 体检登记 /registers |

| 4 科室录入 /results |

| 5 主检结论 /conclusion |

| 6 报告中心 /reports |

| 7 通知书 /notices |

| 8 附件管理 /attaches |

| 9 汇总报表 /summary |

| 10 系统管理 /sys |

| 11 用户管理 /users |

| 12 菜单与角色授权 /rolemenu |

| 13 租户管理 /tenants |

| 14 关于本系统 /about |

| 15 基础档案 /basedata |

| 16 用人单位 /employers |

| 17 团体预约 /groupregister |

| 18 操作日志 /operlogs |

| 19 财务管理 /finance |

None 表 6-12 角色种子

| 角色种子 数据 |

| role_code, role_name, remark |

| admin, 系统管理员, 全部权限 |

| chief, 主检医师, 结论与签发 |

| doctor, 科室医生, 检查录入 |

为便于建库核对,以下同步给出各表对应的建表语句(由实体定义生成,与 init.sql 字段一致):

CREATE TABLE biz_adapter_config (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

adapter_type VARCHAR(200),

adapter_name VARCHAR(200),

enabled INT,

base_url VARCHAR(200),

app_key VARCHAR(200),

app_secret VARCHAR(200),

extra_params VARCHAR(200),

remark VARCHAR(200),

tenant_id BIGINT,

create_by VARCHAR(200),

create_time VARCHAR,

update_time VARCHAR,

del_flag INT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='第三方接口适配器配置';

| id | adapter_type | adapter_name | enabled | base_url | app_key | app_secret | extra_params | remark | tenant_id | create_by | create_time | update_time | del_flag |

| 1 | text | 示例值1 | 示例值1 | /files/occupational/… | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 1 | 示例值1 | 示例值1 | 示例值1 | 示例值1 |

| 2 | text | 示例值2 | 示例值2 | /files/occupational/… | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 1 | 示例值2 | 示例值2 | 示例值2 | 示例值2 |

CREATE TABLE sys_attach (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

biz_no VARCHAR(200),

tenant_id BIGINT,

attach_type VARCHAR(200) COMMENT '影像/附件关联信息:文件原名(SM4 落盘加密)',

origin_name VARCHAR(200) COMMENT '影像/附件关联信息:文件原名(SM4 落盘加密)',

store_path VARCHAR(200),

file_size BIGINT,

upload_by BIGINT,

create_time DATETIME,

del_flag INT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='附件(病历/委托资料等,挂登记单号)';

| id | biz_no | tenant_id | attach_type | origin_name | store_path | file_size | upload_by | create_time | del_flag |

| 1 | SY-001 | 1 | SM4V1:(密文) | SM4V1:(密文) | /files/occupational/… | 101 | 101 | 2026-10-01 09:11:00 | 示例值1 |

| 2 | SY-002 | 1 | SM4V1:(密文) | SM4V1:(密文) | /files/occupational/… | 102 | 102 | 2026-10-02 09:12:00 | 示例值2 |

CREATE TABLE base_dept (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

dept_name VARCHAR(200),

sort_order INT,

remark VARCHAR(200),

del_flag INT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='科室(设计方案 模块2 基础档案)';

| id | tenant_id | dept_name | sort_order | remark | del_flag |

| 1 | 1 | 示例值1 | 2 | 示例值1 | 示例值1 |

| 2 | 1 | 示例值2 | 4 | 示例值2 | 示例值2 |

CREATE TABLE base_dict (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

dict_type VARCHAR(200),

dict_key VARCHAR(200),

dict_value VARCHAR(200),

sort_order INT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字典(体检类别/结论类型/录入快捷短语等,设计方案 模块1 系统管理-字典)';

| id | tenant_id | dict_type | dict_key | dict_value | sort_order |

| 1 | 1 | text | 示例值1 | 示例值1 | 2 |

| 2 | 1 | text | 示例值2 | 示例值2 | 4 |

CREATE TABLE biz_conclusion (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

register_id BIGINT COMMENT 'NORMAL/RECHECK/SUSPECTED/CONTRAINDICATION',

conclusion_type VARCHAR(200) COMMENT 'NORMAL/RECHECK/SUSPECTED/CONTRAINDICATION',

summary VARCHAR(200),

chief_doctor_id BIGINT,

chief_doctor_name VARCHAR(200),

reviewer_id BIGINT,

reviewer_name VARCHAR(200),

sign_time DATETIME COMMENT 'DRAFT/L1/L2/L3/APPROVED/REJECTED/SIGNED',

audit_status VARCHAR(200) COMMENT 'DRAFT/L1/L2/L3/APPROVED/REJECTED/SIGNED',

current_level INT COMMENT '当前审核级别 0草稿 1/2/3',

reject_reason VARCHAR(200),

create_time DATETIME,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Conclusion';

| id | tenant_id | register_id | conclusion_type | summary | chief_doctor_id | chief_doctor_name | reviewer_id | reviewer_name | sign_time | audit_status | current_level | reject_reason | create_time |

| 1 | 1 | 101 | NORMAL | 示例值1 | 101 | 示例值1 | 101 | 示例值1 | 2026-10-01 09:11:00 | REGISTERED | 示例值1 | 示例值1 | 2026-10-01 09:11:00 |

| 2 | 1 | 102 | RECHECK | 示例值2 | 102 | 示例值2 | 102 | 示例值2 | 2026-10-02 09:12:00 | CHECKING | 示例值2 | 示例值2 | 2026-10-02 09:12:00 |

CREATE TABLE biz_conclusion_audit (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

conclusion_id BIGINT,

register_id BIGINT COMMENT '1/2/3 审核级别',

audit_level INT COMMENT '1/2/3 审核级别',

action VARCHAR(200) COMMENT 'SUBMIT/PASS/REJECT/SIGN',

auditor_id BIGINT,

auditor_name VARCHAR(200),

opinion VARCHAR(200),

create_time DATETIME,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='总检多级审核流水:每级审核(提交/通过/打回/签发)留痕';

| id | tenant_id | conclusion_id | register_id | audit_level | action | auditor_id | auditor_name | opinion | create_time |

| 1 | 1 | NORMAL | 101 | 示例值1 | 示例值1 | 101 | 示例值1 | 示例值1 | 2026-10-01 09:11:00 |

| 2 | 1 | RECHECK | 102 | 示例值2 | 示例值2 | 102 | 示例值2 | 示例值2 | 2026-10-02 09:12:00 |

CREATE TABLE biz_conclusion_task (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

register_id BIGINT,

worker_id BIGINT,

worker_name VARCHAR(200),

reg_no VARCHAR(200),

assignee_id BIGINT,

assignee_name VARCHAR(200) COMMENT 'PENDING 待派单 / ASSIGNED 已派单 / DONE 已完成',

status VARCHAR(200) COMMENT 'PENDING 待派单 / ASSIGNED 已派单 / DONE 已完成',

create_time DATETIME,

assign_time DATETIME,

finish_time DATETIME,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='总检派单任务池:已检完待总检的登记单 + 指派主检医师';

| id | tenant_id | register_id | worker_id | worker_name | reg_no | assignee_id | assignee_name | status | create_time | assign_time | finish_time |

| 1 | 1 | 101 | 101 | 王某 | TJ20261003-000111 | 101 | 示例值1 | REGISTERED | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 |

| 2 | 1 | 102 | 102 | 李某 | TJ20261003-000112 | 102 | 示例值2 | CHECKING | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 |

CREATE TABLE doctor_sign_template (

id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '关联医生账号ID(sys_user.id)',

doctor_id BIGINT COMMENT '关联医生账号ID(sys_user.id)',

sign_img_path VARCHAR(200) COMMENT '签名文件服务器内部路径(SM4 落盘加密,禁止前端直连)',

img_width INT COMMENT '报告签名框内渲染宽(px) 默认180',

img_height INT COMMENT '报告签名框内渲染高(px) 默认80',

img_size INT COMMENT '加密存储后体积(KB)',

offset_x INT COMMENT '签名框内水平偏移坐标(锁定)',

offset_y INT COMMENT '签名框内垂直偏移坐标(锁定)',

is_enable INT COMMENT '是否启用 1启用 0停用',

ca_bound INT COMMENT '是否已绑定 CA 证书 1是(模式B)0否(模式A 直接渲染PNG)',

tenant_id BIGINT,

create_time DATETIME,

update_time DATETIME,

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='医生原笔迹手写签名模板';

| id | doctor_id | sign_img_path | img_width | img_height | img_size | offset_x | offset_y | is_enable | ca_bound | tenant_id | create_time | update_time |

| 1 | SM4V1:(密文) | SM4V1:(密文) | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 1 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 |

| 2 | SM4V1:(密文) | SM4V1:(密文) | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 1 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 |

CREATE TABLE biz_employer (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

employer_name VARCHAR(200),

credit_code VARCHAR(200),

contact VARCHAR(200),

phone VARCHAR(200),

bank_name VARCHAR(200),

bank_account VARCHAR(200),

create_time DATETIME,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Employer';

| id | tenant_id | employer_name | credit_code | contact | phone | bank_name | bank_account | create_time |

| 1 | 1 | 惠达诚制造有限公司 | BI-001 | 示例值1 | 13810012211 | 示例值1 | 2 | 2026-10-01 09:11:00 |

| 2 | 1 | 建华化工有限公司 | BI-002 | 示例值2 | 13810022211 | 示例值2 | 4 | 2026-10-02 09:12:00 |

CREATE TABLE base_exam_item (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

item_code VARCHAR(200),

item_name VARCHAR(200),

dept VARCHAR(200) COMMENT '检查类别:检验/影像/超声/心电/内镜/病理/功能/体格检查',

category VARCHAR(200) COMMENT '检查类别:检验/影像/超声/心电/内镜/病理/功能/体格检查',

specimen VARCHAR(200) COMMENT '标本或检查部位',

abbr VARCHAR(200) COMMENT '常用缩写',

value_type VARCHAR(200),

unit VARCHAR(200) COMMENT '计价单位(次/项/部位)',

charge_unit VARCHAR(200) COMMENT '计价单位(次/项/部位)',

medical_code VARCHAR(200) COMMENT '国家或医保收费项目目录编码(未核对留空)',

is_core INT COMMENT '1=常见必备项 0=可选扩展项',

ref_low DECIMAL(12,2),

ref_high DECIMAL(12,2),

abnormal_flag INT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='ExamItem';

| id | tenant_id | item_code | item_name | dept | category | specimen | abbr | value_type | unit | charge_unit | medical_code | is_core | ref_low | ref_high | abnormal_flag |

| 1 | 1 | BA-001 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | text | 示例值1 | 示例值1 | BA-001 | 示例值1 | 11.07 | 11.07 | 示例值1 |

| 2 | 1 | BA-002 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | text | 示例值2 | 示例值2 | BA-002 | 示例值2 | 12.14 | 12.14 | 示例值2 |

CREATE TABLE exam_item_knowledge (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT COMMENT '关联 base_exam_item.id(可空:允许仅按编码维护)',

item_id BIGINT COMMENT '关联 base_exam_item.id(可空:允许仅按编码维护)',

item_code VARCHAR(200),

item_name VARCHAR(200),

category VARCHAR(200),

dept VARCHAR(200),

unit VARCHAR(200) COMMENT 'number / text',

value_type VARCHAR(200) COMMENT 'number / text',

ref_low DECIMAL(12,2) COMMENT '正常参考区间',

ref_high DECIMAL(12,2) COMMENT '轻度异常绝对阈值(优先于百分比)',

mild_low DECIMAL(12,2) COMMENT '轻度异常绝对阈值(优先于百分比)',

mild_high DECIMAL(12,2) COMMENT '中度异常绝对阈值',

mod_low DECIMAL(12,2) COMMENT '中度异常绝对阈值',

mod_high DECIMAL(12,2) COMMENT '未配绝对值时的百分比阈值(偏离参考区间的百分比)',

mild_pct DECIMAL(12,2) COMMENT '未配绝对值时的百分比阈值(偏离参考区间的百分比)',

mod_pct DECIMAL(12,2) COMMENT '危急值(命中直接判重度)',

crit_low DECIMAL(12,2) COMMENT '危急值(命中直接判重度)',

crit_high DECIMAL(12,2),

interpret_normal VARCHAR(200),

interpret_mild VARCHAR(200),

interpret_moderate VARCHAR(200),

interpret_severe VARCHAR(200),

health_advice VARCHAR(200) COMMENT '是否职业病重点项目 1=是(强制人工复核)',

occ_key INT COMMENT '是否职业病重点项目 1=是(强制人工复核)',

enabled INT COMMENT '启停 1启用 0停用',

remark VARCHAR(200),

create_by BIGINT,

create_time DATETIME,

update_time DATETIME,

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='检查项目解读知识库:参考上下限、异常分级阈值、自动解读文案、健康指导建议。

命中优先级:绝对值阈值(mild/mod/crit) > 百分比偏离(mild_pct/mod_pct) > 兜底规则。';

| id | tenant_id | item_id | item_code | item_name | category | dept | unit | value_type | ref_low | ref_high | mild_low | mild_high | mod_low | mod_high | mild_pct | mod_pct | crit_low | crit_high | interpret_normal | interpret_mild | interpret_moderate | interpret_severe | health_advice | occ_key | enabled | remark | create_by | create_time | update_time |

| 1 | 1 | 101 | EX-001 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | text | 11.07 | 11.07 | 11.07 | 11.07 | 11.07 | 11.07 | 11.07 | 11.07 | 11.07 | 11.07 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 101 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 |

| 2 | 1 | 102 | EX-002 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | text | 12.14 | 12.14 | 12.14 | 12.14 | 12.14 | 12.14 | 12.14 | 12.14 | 12.14 | 12.14 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 102 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 |

CREATE TABLE base_package (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

package_name VARCHAR(200),

factor_id BIGINT,

exam_type VARCHAR(200),

version VARCHAR(200),

package_code VARCHAR(200),

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='ExamPackage';

| id | tenant_id | package_name | factor_id | exam_type | version | package_code |

| 1 | 1 | 示例值1 | 101 | text | 示例值1 | PKG0001 |

| 2 | 1 | 示例值2 | 102 | text | 示例值2 | PKG0002 |

CREATE TABLE biz_register (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

reg_no VARCHAR(200),

tenant_id BIGINT,

worker_id BIGINT,

employer_id BIGINT,

package_id BIGINT,

exam_type VARCHAR(200),

reg_date DATE COMMENT 'REGISTERED/CHECKING/CHECKED/CONCLUDED/SIGNED/ARCHIVED/CANCELED',

status VARCHAR(200) COMMENT 'REGISTERED/CHECKING/CHECKED/CONCLUDED/SIGNED/ARCHIVED/CANCELED',

version INT COMMENT '行级软锁:解锁要写 null,必须 IGNORED 策略,否则 updateById 跳过 null 字段导致锁永远清不掉',

lock_by BIGINT COMMENT '行级软锁:解锁要写 null,必须 IGNORED 策略,否则 updateById 跳过 null 字段导致锁永远清不掉',

lock_time DATETIME,

remark VARCHAR(200),

create_by BIGINT,

create_time DATETIME,

update_time DATETIME,

del_flag INT COMMENT '1=匿名体检(报告/列表脱敏展示)',

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='体检登记单(核心单据):状态机 + 乐观锁 + 行级软锁';

| id | reg_no | tenant_id | worker_id | employer_id | package_id | exam_type | reg_date | status | version | lock_by | lock_time | remark | create_by | create_time | update_time | del_flag |

| 1 | TJ20261003-000111 | 1 | 101 | 101 | 101 | text | 1981-01-11 | REGISTERED | 示例值1 | 101 | 2026-10-01 09:11:00 | 示例值1 | 101 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 | 示例值1 |

| 2 | TJ20261003-000112 | 1 | 102 | 102 | 102 | text | 1982-02-12 | CHECKING | 示例值2 | 102 | 2026-10-02 09:12:00 | 示例值2 | 102 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 | 示例值2 |

CREATE TABLE exam_report_interpret (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

report_id BIGINT,

register_id BIGINT,

worker_id BIGINT COMMENT '劳动者姓名快照(SM4 落盘加密)',

worker_name VARCHAR(200) COMMENT '劳动者姓名快照(SM4 落盘加密)',

id_card_hash VARCHAR(200) COMMENT '身份证 SHA256,对外接口按此查询',

report_no VARCHAR(200) COMMENT 'NOT_GENERATED/AUTO_PENDING/PENDING_REVIEW/REVIEWED/REJECTED/LOCKED',

status VARCHAR(200) COMMENT 'NOT_GENERATED/AUTO_PENDING/PENDING_REVIEW/REVIEWED/REJECTED/LOCKED',

abnormal_level VARCHAR(200) COMMENT 'NORMAL/MILD/MODERATE/SEVERE',

abnormal_summary VARCHAR(200) COMMENT '异常摘要(SM4 落盘加密)',

draft_content VARCHAR(200) COMMENT '机器生成初稿(SM4 落盘加密)',

final_content VARCHAR(200) COMMENT '复核后终稿(SM4 落盘加密)',

version INT COMMENT '1=报告已归档锁定,禁止修改',

locked INT COMMENT '1=报告已归档锁定,禁止修改',

generate_by BIGINT,

generate_by_name VARCHAR(200),

generate_time DATETIME,

reviewer_id BIGINT,

reviewer_name VARCHAR(200),

review_time DATETIME,

reject_reason VARCHAR(200),

create_time DATETIME,

update_time DATETIME,

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报告智能解读主表(当前版本)。

状态机:NOT_GENERATED →(生成)→ AUTO_PENDING | PENDING_REVIEW

AUTO_PENDING / PENDING_REVIEW →(复核通过)→ REVIEWED

AUTO_PENDING / PENDING_REVIEW →(驳回)→ REJECTED →(重新生成)→ AUTO_PENDING | PENDING_REVIEW

REVIEWED →(报告归档)→ LOCKED(终态,禁止任何写入)';

| id | tenant_id | report_id | register_id | worker_id | worker_name | id_card_hash | report_no | status | abnormal_level | abnormal_summary | draft_content | final_content | version | locked | generate_by | generate_by_name | generate_time | reviewer_id | reviewer_name | review_time | reject_reason | create_time | update_time |

| 1 | 1 | 101 | 101 | SM4V1:(密文) | SM4V1:(密文) | 9f8a…c21b(摘要) | REP20261002-000031 | REGISTERED | SM4V1:(密文) | SM4V1:(密文) | SM4V1:(密文) | SM4V1:(密文) | 示例值1 | 示例值1 | 101 | 示例值1 | 2026-10-01 09:11:00 | 101 | 示例值1 | 2026-10-01 09:11:00 | 示例值1 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 |

| 2 | 1 | 102 | 102 | SM4V1:(密文) | SM4V1:(密文) | 9f8a…c21b(摘要) | REP20261002-000032 | CHECKING | SM4V1:(密文) | SM4V1:(密文) | SM4V1:(密文) | SM4V1:(密文) | 示例值2 | 示例值2 | 102 | 示例值2 | 2026-10-02 09:12:00 | 102 | 示例值2 | 2026-10-02 09:12:00 | 示例值2 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 |

CREATE TABLE exam_report_interpret_log (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

report_id BIGINT,

register_id BIGINT,

worker_id BIGINT,

worker_name VARCHAR(200),

id_card_hash VARCHAR(200),

report_no VARCHAR(200) COMMENT 'AUTO_GEN/EDIT/REVIEW_PASS/REJECT/REGEN/LOCK/DELETE_ITEM',

oper_type VARCHAR(200) COMMENT 'AUTO_GEN/EDIT/REVIEW_PASS/REJECT/REGEN/LOCK/DELETE_ITEM',

version INT,

draft_content VARCHAR(200),

final_content VARCHAR(200),

generate_time DATETIME,

review_time DATETIME,

doctor_id BIGINT,

doctor_name VARCHAR(200),

remark VARCHAR(200),

create_time DATETIME,

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='解读操作日志:初稿与终稿内容、生成/复核时间、操作医生、操作类型,永久留痕。

数据库层已加 BEFORE DELETE 触发器禁止删除,应用层同样不提供删除接口。';

| id | tenant_id | report_id | register_id | worker_id | worker_name | id_card_hash | report_no | oper_type | version | draft_content | final_content | generate_time | review_time | doctor_id | doctor_name | remark | create_time |

| 1 | 1 | 101 | 101 | 101 | 王某医生 | 9f8a…c21b(摘要) | REP20261002-000031 | text | 示例值1 | 示例值1 | 示例值1 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 | 101 | 示例值1 | 示例值1 | 2026-10-01 09:11:00 |

| 2 | 1 | 102 | 102 | 102 | 李某医生 | 9f8a…c21b(摘要) | REP20261002-000032 | text | 示例值2 | 示例值2 | 示例值2 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 | 102 | 示例值2 | 示例值2 | 2026-10-02 09:12:00 |

CREATE TABLE biz_exam_result (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

register_id BIGINT,

item_id BIGINT,

dept VARCHAR(200) COMMENT '职业病体检指标结论(SM4 落盘加密)',

result_text VARCHAR(200) COMMENT '职业病体检指标结论(SM4 落盘加密)',

result_value DECIMAL(12,2),

abnormal INT,

item_snapshot VARCHAR(200),

doctor_id BIGINT,

doctor_name VARCHAR(200),

create_time DATETIME,

update_time DATETIME,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='ExamResult';

| id | tenant_id | register_id | item_id | dept | result_text | result_value | abnormal | item_snapshot | doctor_id | doctor_name | create_time | update_time |

| 1 | 1 | 101 | 101 | SM4V1:(密文) | SM4V1:(密文) | 11.07 | 示例值1 | 示例值1 | 101 | 示例值1 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 |

| 2 | 1 | 102 | 102 | SM4V1:(密文) | SM4V1:(密文) | 12.14 | 示例值2 | 示例值2 | 102 | 示例值2 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 |

CREATE TABLE biz_exam_result_amend (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

register_id BIGINT,

item_id BIGINT,

dept VARCHAR(200),

result_text VARCHAR(200),

result_value DECIMAL(12,2),

abnormal INT,

item_snapshot VARCHAR(200) COMMENT '修订版本号:同一 register+item 下自增,display 取最大 revision',

revision INT COMMENT '修订版本号:同一 register+item 下自增,display 取最大 revision',

original_result_id BIGINT COMMENT '被修订的原始 biz_exam_result.id(溯源,原记录永不改动)',

amend_reason VARCHAR(200),

amended_by BIGINT,

amended_name VARCHAR(200),

create_time DATETIME,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='科室检查结果「归档后修订」记录表。

业务规则(需求⑤):已归档的体检记录被修改时,原记录(biz_exam_result)不得删除或更改,

必须继续保存在数据库中以备查阅;本次修改只新增一条「替换显示」的修订记录。

同一 (register_id, item_id) 允许多次修订,版本号 revision 自增,display 取最新版本。

original_result_id 指向被修订的原始 biz_exam_result.id,用于溯源审计。';

| id | tenant_id | register_id | item_id | dept | result_text | result_value | abnormal | item_snapshot | revision | original_result_id | amend_reason | amended_by | amended_name | create_time |

| 1 | 1 | 101 | 101 | 示例值1 | 示例值1 | 11.07 | 示例值1 | 示例值1 | 示例值1 | 101 | 示例值1 | 101 | 示例值1 | 2026-10-01 09:11:00 |

| 2 | 1 | 102 | 102 | 示例值2 | 示例值2 | 12.14 | 示例值2 | 示例值2 | 示例值2 | 102 | 示例值2 | 102 | 示例值2 | 2026-10-02 09:12:00 |

CREATE TABLE base_hazard_factor (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

factor_code VARCHAR(200),

factor_name VARCHAR(200),

target_disease VARCHAR(200),

cycle_months INT,

basis VARCHAR(200),

create_time DATETIME,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='HazardFactor';

| id | tenant_id | factor_code | factor_name | target_disease | cycle_months | basis | create_time |

| 1 | 1 | BA-001 | 示例值1 | 示例值1 | 12 | 示例值1 | 2026-10-01 09:11:00 |

| 2 | 1 | BA-002 | 示例值2 | 示例值2 | 12 | 示例值2 | 2026-10-02 09:12:00 |

CREATE TABLE biz_lab_result (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

register_id BIGINT,

item_id BIGINT,

result_value DECIMAL(12,2),

unit VARCHAR(200),

ref_low DECIMAL(12,2),

ref_high DECIMAL(12,2),

abnormal INT,

source VARCHAR(200),

create_time DATETIME,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='检验结果(设计方案 模块6:手工录入 + 导入预留,参考区间快照 + 异常自动判定)';

| id | tenant_id | register_id | item_id | result_value | unit | ref_low | ref_high | abnormal | source | create_time |

| 1 | 1 | 101 | 101 | 11.07 | 示例值1 | 11.07 | 11.07 | 示例值1 | 示例值1 | 2026-10-01 09:11:00 |

| 2 | 1 | 102 | 102 | 12.14 | 示例值2 | 12.14 | 12.14 | 示例值2 | 示例值2 | 2026-10-02 09:12:00 |

CREATE TABLE biz_notice (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

register_id BIGINT,

tenant_id BIGINT COMMENT 'RECHECK复查/TRANSFER转诊/RESTRAIN调离',

notice_type VARCHAR(200) COMMENT 'RECHECK复查/TRANSFER转诊/RESTRAIN调离',

notice_no VARCHAR(200),

content VARCHAR(200),

pdf_path VARCHAR(200),

create_time DATETIME,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='通知书(复查/转诊/调离)';

| id | register_id | tenant_id | notice_type | notice_no | content | pdf_path | create_time |

| 1 | 101 | 1 | text | NTC20261002-000001 | 示例值1 | /files/occupational/… | 2026-10-01 09:11:00 |

| 2 | 102 | 1 | text | NTC20261002-000002 | 示例值2 | /files/occupational/… | 2026-10-02 09:12:00 |

CREATE TABLE sys_oper_log (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

user_id BIGINT,

username VARCHAR(200),

module VARCHAR(200),

action VARCHAR(200),

biz_no VARCHAR(200),

detail VARCHAR(200),

ip VARCHAR(200),

create_time DATETIME,

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='OperLog';

| id | tenant_id | user_id | username | module | action | biz_no | detail | ip | create_time |

| 1 | 1 | 101 | 王某 | 示例值1 | 示例值1 | SY-001 | 示例值1 | 192.168.1.11 | 2026-10-01 09:11:00 |

| 2 | 1 | 102 | 李某 | 示例值2 | 示例值2 | SY-002 | 示例值2 | 192.168.1.12 | 2026-10-02 09:12:00 |

CREATE TABLE base_package_item (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

package_id BIGINT,

item_id BIGINT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='套餐-项目关联(套餐精确过滤的依据)';

| id | package_id | item_id |

| 1 | 101 | 101 |

| 2 | 102 | 102 |

CREATE TABLE biz_register_hazard (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

register_id BIGINT,

factor_id BIGINT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='RegisterHazard';

| id | register_id | factor_id |

| 1 | 101 | 101 |

| 2 | 102 | 102 |

CREATE TABLE biz_report (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

register_id BIGINT,

report_no VARCHAR(200),

tenant_id BIGINT,

pdf_path VARCHAR(200),

version INT COMMENT 'GENERATED/SIGNED/CANCELED',

status VARCHAR(200) COMMENT 'GENERATED/SIGNED/CANCELED',

sign_time DATETIME,

create_time DATETIME,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='体检报告(签发后生成 PDF,重出报告 version+1 保留旧版)';

| id | register_id | report_no | tenant_id | pdf_path | version | status | sign_time | create_time |

| 1 | 101 | REP20261002-000031 | 1 | /files/occupational/… | 示例值1 | REGISTERED | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 |

| 2 | 102 | REP20261002-000032 | 1 | /files/occupational/… | 示例值2 | CHECKING | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 |

CREATE TABLE biz_review_config (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT,

module VARCHAR(200) COMMENT '审核级别数 1/2/3',

levels INT COMMENT '审核级别数 1/2/3',

create_time DATETIME,

update_time DATETIME,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='多级审核级别配置:可按模块扩展(默认 CONCLUSION 总检,1/2/3 级)';

| id | tenant_id | module | levels | create_time | update_time |

| 1 | 1 | 示例值1 | 示例值1 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 |

| 2 | 1 | 示例值2 | 示例值2 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 |

CREATE TABLE seq_rule (

seq_key VARCHAR(200) PRIMARY KEY AUTO_INCREMENT,

seq_val BIGINT,

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='单据号序列(发号用 SELECT ... FOR UPDATE 行锁保证不重复)';

| seq_key | seq_val |

| 1 | 101 |

| 2 | 102 |

CREATE TABLE base_std_disease (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

disease_code VARCHAR(200),

category_code VARCHAR(200),

disease_name VARCHAR(200),

open_clause INT,

scope_limit VARCHAR(200),

hazard_keywords VARCHAR(200),

diagnosis_basis VARCHAR(200),

sort_no INT,

source_version VARCHAR(200),

tenant_id BIGINT,

create_time DATETIME,

update_time DATETIME,

del_flag INT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='法定职业病病种目录(2025 版 135 种,含开放性条款与限定范围)。';

| id | disease_code | category_code | disease_name | open_clause | scope_limit | hazard_keywords | diagnosis_basis | sort_no | source_version | tenant_id | create_time | update_time | del_flag |

| 1 | BA-001 | BA-001 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | BA-001 | 示例值1 | 1 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 | 示例值1 |

| 2 | BA-002 | BA-002 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | BA-002 | 示例值2 | 1 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 | 示例值2 |

CREATE TABLE base_std_disease_category (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

category_code VARCHAR(200),

category_name VARCHAR(200),

disease_count INT,

sort_no INT,

source_version VARCHAR(200),

remark VARCHAR(200),

tenant_id BIGINT,

create_time DATETIME,

update_time DATETIME,

del_flag INT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='职业病大类目录(国家卫健委 2025 版《职业病分类和目录》12 大类)。';

| id | category_code | category_name | disease_count | sort_no | source_version | remark | tenant_id | create_time | update_time | del_flag |

| 1 | BA-001 | 示例值1 | 2 | BA-001 | 示例值1 | 示例值1 | 1 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 | 示例值1 |

| 2 | BA-002 | 示例值2 | 4 | BA-002 | 示例值2 | 示例值2 | 1 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 | 示例值2 |

CREATE TABLE base_std_exam_item (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

rule_id BIGINT,

item_code VARCHAR(200),

item_name VARCHAR(200),

item_kind VARCHAR(200),

dept VARCHAR(200),

sort_no INT,

tenant_id BIGINT,

create_time DATETIME,

del_flag INT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='标准检查项目明细(GBZ 188 必检/选检),隶属 base_std_exam_rule。';

| id | rule_id | item_code | item_name | item_kind | dept | sort_no | tenant_id | create_time | del_flag |

| 1 | 101 | BA-001 | 示例值1 | 示例值1 | 示例值1 | BA-001 | 1 | 2026-10-01 09:11:00 | 示例值1 |

| 2 | 102 | BA-002 | 示例值2 | 示例值2 | 示例值2 | BA-002 | 1 | 2026-10-02 09:12:00 | 示例值2 |

CREATE TABLE base_std_exam_rule (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

hazard_code VARCHAR(200),

exam_type VARCHAR(200),

exam_cycle_months INT,

is_mandatory INT,

target_disease VARCHAR(200),

contraindication VARCHAR(200),

standard_version VARCHAR(200),

remark VARCHAR(200),

tenant_id BIGINT,

create_time DATETIME,

update_time DATETIME,

del_flag INT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='职业健康检查规则(GBZ 188):因素 × 检查类别(岗前/在岗/离岗/应急)。

周期多为条件式表述,exam_cycle_months 可能为 NULL,完整原文见 remark。';

| id | hazard_code | exam_type | exam_cycle_months | is_mandatory | target_disease | contraindication | standard_version | remark | tenant_id | create_time | update_time | del_flag |

| 1 | BA-001 | text | 12 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 1 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 | 示例值1 |

| 2 | BA-002 | text | 12 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 1 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 | 示例值2 |

CREATE TABLE base_std_hazard (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

hazard_code VARCHAR(200),

hazard_name VARCHAR(200),

hazard_type VARCHAR(200),

gbz_section VARCHAR(200),

standard_version VARCHAR(200),

target_disease VARCHAR(200),

exam_summary VARCHAR(200),

in_service_cycle_months INT,

has_pre_exam INT,

has_off_exam INT,

has_emergency_exam INT,

remark VARCHAR(200),

tenant_id BIGINT,

create_time DATETIME,

update_time DATETIME,

del_flag INT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='接害因素标准档案(GBZ 188 职业健康监护技术规范)。

hazard_code 沿用标准条款号(如 6.1 / 7.1),导入业务表时直接作为 factor_code,保持双向可关联。';

| id | hazard_code | hazard_name | hazard_type | gbz_section | standard_version | target_disease | exam_summary | in_service_cycle_months | has_pre_exam | has_off_exam | has_emergency_exam | remark | tenant_id | create_time | update_time | del_flag |

| 1 | BA-001 | 示例值1 | text | 示例值1 | 示例值1 | 示例值1 | 示例值1 | 12 | 示例值1 | 示例值1 | SM4V1:(密文) | 示例值1 | 1 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 | 示例值1 |

| 2 | BA-002 | 示例值2 | text | 示例值2 | 示例值2 | 示例值2 | 示例值2 | 12 | 示例值2 | 示例值2 | SM4V1:(密文) | 示例值2 | 1 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 | 示例值2 |

CREATE TABLE base_std_hazard_disease (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

hazard_code VARCHAR(200),

disease_code VARCHAR(200),

relation VARCHAR(200),

tenant_id BIGINT,

create_time DATETIME,

del_flag INT,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='危害因素 ↔ 法定职业病病种关联。';

| id | hazard_code | disease_code | relation | tenant_id | create_time | del_flag |

| 1 | BA-001 | BA-001 | 示例值1 | 1 | 2026-10-01 09:11:00 | 示例值1 |

| 2 | BA-002 | BA-002 | 示例值2 | 1 | 2026-10-02 09:12:00 | 示例值2 |

CREATE TABLE sys_menu (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

parent_id BIGINT,

menu_name VARCHAR(200),

path VARCHAR(200),

perm_code VARCHAR(200),

menu_type INT,

sort_order INT,

del_flag INT,

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='菜单(1=菜单 2=按钮)';

| id | parent_id | menu_name | path | perm_code | menu_type | sort_order | del_flag |

| 1 | 101 | 示例值1 | /files/occupational/… | SY-001 | text | 2 | 示例值1 |

| 2 | 102 | 示例值2 | /files/occupational/… | SY-002 | text | 4 | 示例值2 |

CREATE TABLE sys_role (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

role_code VARCHAR(200),

role_name VARCHAR(200),

remark VARCHAR(200),

del_flag INT,

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色';

| id | role_code | role_name | remark | del_flag |

| 1 | SY-001 | 示例值1 | 示例值1 | 示例值1 |

| 2 | SY-002 | 示例值2 | 示例值2 | 示例值2 |

CREATE TABLE sys_role_menu (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

role_id BIGINT,

menu_id BIGINT,

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色-菜单授权';

| id | role_id | menu_id |

| 1 | 101 | 101 |

| 2 | 102 | 102 |

CREATE TABLE sys_tenant (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_code VARCHAR(200),

tenant_name VARCHAR(200),

contact VARCHAR(200),

phone VARCHAR(200),

status INT,

create_time DATETIME,

del_flag INT,

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租户(体检机构)';

| id | tenant_code | tenant_name | contact | phone | status | create_time | del_flag |

| 1 | 1 | 1 | 示例值1 | 13810012211 | 示例值1 | 2026-10-01 09:11:00 | 示例值1 |

| 2 | 1 | 1 | 示例值2 | 13810022211 | 示例值2 | 2026-10-02 09:12:00 | 示例值2 |

CREATE TABLE sys_user (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

username VARCHAR(200),

password VARCHAR(200),

real_name VARCHAR(200),

dept_id BIGINT,

tenant_id BIGINT,

role_codes VARCHAR(200),

status INT,

fail_count INT,

del_flag INT,

lock_until DATETIME,

create_time DATETIME,

update_time DATETIME,

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='SysUser';

| id | username | password | real_name | dept_id | tenant_id | role_codes | status | fail_count | del_flag | lock_until | create_time | update_time |

| 1 | 王某 | $2a$10$…(BCrypt) | 王某 | 101 | 1 | SY-001 | 示例值1 | 2 | 示例值1 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 | 2026-10-01 09:11:00 |

| 2 | 李某 | $2a$10$…(BCrypt) | 李某 | 102 | 1 | SY-002 | 示例值2 | 4 | 示例值2 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 | 2026-10-02 09:12:00 |

CREATE TABLE biz_worker (

id BIGINT PRIMARY KEY AUTO_INCREMENT,

tenant_id BIGINT COMMENT '人员姓名(SM4 落盘加密)',

worker_name VARCHAR(200) COMMENT '人员姓名(SM4 落盘加密)',

id_card_hash VARCHAR(200) COMMENT '身份证号码(SM4 落盘加密)',

id_card_enc VARCHAR(200) COMMENT '身份证号码(SM4 落盘加密)',

gender VARCHAR(200),

birth_date DATE,

employer_id BIGINT,

job_type VARCHAR(200),

hazard_years DECIMAL(12,2) COMMENT '职业健康史/接触史(SM4 落盘加密)',

medical_history VARCHAR(200) COMMENT '职业健康史/接触史(SM4 落盘加密)',

address VARCHAR(200) COMMENT '住址',

phone VARCHAR(200) COMMENT '联系电话',

create_time DATETIME,

tenant_id BIGINT COMMENT '租户ID(多租户隔离)',

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Worker';

| id | tenant_id | worker_name | id_card_hash | id_card_enc | gender | birth_date | employer_id | job_type | hazard_years | medical_history | address | phone | create_time |

| 1 | 1 | SM4V1:(密文) | 9f8a…c21b(摘要) | SM4V1:(密文) | 男 | 1981-01-11 | 101 | text | SM4V1:(密文) | SM4V1:(密文) | 示例值1 | 13810012211 | 2026-10-01 09:11:00 |

| 2 | 1 | SM4V1:(密文) | 9f8a…c21b(摘要) | SM4V1:(密文) | 女 | 1982-02-12 | 102 | text | SM4V1:(密文) | SM4V1:(密文) | 示例值2 | 13810022211 | 2026-10-02 09:12:00 |

本章小结:本章给出接口统一规范、全部 216 项接口分组清单、关键接口入参出参与报文示例,接口路径与处理方法均摘自系统实际代码。

第7章 接口详细设计

7.1 接口规范

本系统全部业务接口以 /api/occupational-exam/ 为统一前缀,REST 风格(GET 查询、POST 新增/动作、PUT 更新、DELETE 删除)。统一响应结构为 { code, message, data }:code 为 0 表示成功,非 0 为业务异常码;message 为提示信息;data 为业务数据。请求与响应正文采用 JSON 编码(UTF-8)。除登录接口外全部接口要求携带 JWT 令牌(Authorization 头),后端认证拦截器统一校验;接口内部按租户标识自动过滤数据。

7.2 内部接口清单

系统共实现业务接口 216 项,按控制器分组列示如下。

7.2.1 AdapterConfigController(2 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/adapter/config/list | 当前租户(无则默认 1) |

| POST | /api/occupational-exam/adapter/test/{type} | 保存配置(upsert by 类型+租户) |

7.2.2 AttachController(4 项)

| 方法 | 路径 | 功能说明 |

| POST | /api/occupational-exam/attaches/upload | 附件管理:病历/委托资料等,挂登记单号 bizNo,上传下载鉴权 + 租户隔离 |

| GET | /api/occupational-exam/attaches | 上传附件 |

| GET | /api/occupational-exam/attaches/{id}/download | 上传附件 |

| DELETE | /api/occupational-exam/attaches/{id} | 上传附件 |

7.2.3 BaseDataController(29 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/base/hazard-factors | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/hazard-factors | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| PUT | /api/occupational-exam/base/hazard-factors/{id} | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| DELETE | /api/occupational-exam/base/hazard-factors/{id} | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| GET | /api/occupational-exam/base/items | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/items | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| PUT | /api/occupational-exam/base/items/{id} | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| DELETE | /api/occupational-exam/base/items/{id} | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| GET | /api/occupational-exam/base/packages | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/packages | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| PUT | /api/occupational-exam/base/packages/{id} | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| DELETE | /api/occupational-exam/base/packages/{id} | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| GET | /api/occupational-exam/base/packages/{id}/items | 基础档案:接害因素 / 检查项目 / 套餐(含明细) / 科室 / 字典 / 用人单位 全套 CRUD(设计方案 模块1/模块2,GBZ188 套餐全部可配置不硬编码)。 |

| POST | /api/occupational-exam/base/packages/{id}/items | 套餐项目明细:查看 |

| GET | /api/occupational-exam/base/depts | 套餐项目明细:整体覆盖保存 |

| POST | /api/occupational-exam/base/depts | 套餐项目明细:整体覆盖保存 |

| PUT | /api/occupational-exam/base/depts/{id} | 套餐项目明细:整体覆盖保存 |

| PUT | /api/occupational-exam/base/depts/{id}/items | 套餐项目明细:整体覆盖保存 |

| DELETE | /api/occupational-exam/base/depts/{id} | 科室负责的检查项目:整体覆盖分配(勾选 = 归属该科室;未勾选且原属该科室的置空) |

| GET | /api/occupational-exam/base/depts/{id}/doctors | 科室负责的检查项目:整体覆盖分配(勾选 = 归属该科室;未勾选且原属该科室的置空) |

| GET | /api/occupational-exam/base/dicts | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| POST | /api/occupational-exam/base/dicts | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| PUT | /api/occupational-exam/base/dicts/{id} | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| DELETE | /api/occupational-exam/base/dicts/{id} | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| GET | /api/occupational-exam/base/employers | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| POST | /api/occupational-exam/base/employers | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| PUT | /api/occupational-exam/base/employers/{id} | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| DELETE | /api/occupational-exam/base/employers/{id} | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

| GET | /api/occupational-exam/base/all | 科室下的医生(按科室ID过滤,用于科室编辑栏「医生管理」分区) |

7.2.4 ConclusionController(13 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/conclusion/{registerId} | 主检结论 + 第17轮增强:总检任务池/派单、多级审核状态机(1/2/3 级 + 打回重审)、 历史报告对比、OFD 报告生成适配、CA 电子签章适配、匿名体检脱敏展示。 |

| POST | /api/occupational-exam/conclusion/{registerId} | 主检工作台:结果 + 结论 + 审核配置级别 + 审核流水 |

| POST | /api/occupational-exam/conclusion/{registerId}/sign | 保存主检结论(新建为草稿;进入审核流程后仅草稿/打回态可改;已签发不可改),并自动建派单任务池 |

| GET | /api/occupational-exam/conclusion/tasks | 签发(兼容旧流程:未进入多级审核流程的历史数据可直接签;已进入流程的必须走审核到终审) |

| GET | /api/occupational-exam/conclusion/assignees | 总检任务池:已检完(CHECKED/CONCLUDED)待总检的登记单 + 派单/结论状态(含匿名脱敏) |

| POST | /api/occupational-exam/conclusion/task/assign | 可派单医师:本租户启用账号中角色含 chief/doctor/admin(总检派单下拉专用,只返回安全字段) |

| POST | /api/occupational-exam/conclusion/{registerId}/submit | 派单:指定主检医师(新增/更新任务池) |

| POST | /api/occupational-exam/conclusion/{registerId}/audit | 提交审核:草稿/打回 → 一级审核 |

| GET | /api/occupational-exam/conclusion/{registerId}/history | 多级审核:通过(推进/终审签发)或打回(回草稿) |

| GET | /api/occupational-exam/conclusion/review-config | 历史报告对比:同一劳动者的历史结论(排除当前单) |

| POST | /api/occupational-exam/conclusion/review-config | 审核级别配置查询 |

| POST | /api/occupational-exam/conclusion/{registerId}/ofd | 审核级别配置保存(1~3 级) |

| POST | /api/occupational-exam/conclusion/{registerId}/ca-sign | OFD 报告生成适配(第17轮适配层,真实 OFD 版式引擎后续接入) |

7.2.5 DoctorSignController(8 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/doctor-sign/{doctorId} | 报告渲染用:生成「签名占位框 + 手写签名」HTML 片段。 @param freeze true = 已签发/已归档报告:优先读取历史快照(保证归档签名不可篡改), 无快照则按当前模板生成并固化写入 report_sign_snapshot |

| GET | /api/occupational-exam/doctor-sign/{doctorId}/img | 模板信息(不返回服务器路径,只给前端渲染所需字段) |

| GET | /api/occupational-exam/doctor-sign/{doctorId}/render | 取签名图(base64 data URI,鉴权后返回;不暴露服务器路径) |

| GET | /api/occupational-exam/doctor-sign/{doctorId}/logs | 报告渲染用:一次性拿到可直接嵌入 HTML 的签名片段(含模式A/B标记) |

| POST | /api/occupational-exam/doctor-sign/{doctorId}/upload | 操作日志 |

| PUT | /api/occupational-exam/doctor-sign/{doctorId} | 上传 / 重新上传手写签名 |

| DELETE | /api/occupational-exam/doctor-sign/{doctorId} | 保存微调结果:锁定尺寸与偏移坐标 |

| POST | /api/occupational-exam/doctor-sign/{doctorId}/use | 删除模板 |

7.2.6 FinanceController(20 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/finance/orders | 第10轮:收费/支付/折扣权限基础数据模型与接口 第11轮:整单收费、明细收费、多次混合缴费、退费、日结月结 第12轮:发票管理(开票/作废/重打/公对公) |

| GET | /api/occupational-exam/finance/order/{id} | 收费单列表 |

| POST | /api/occupational-exam/finance/order/create | 收费单详情(含明细、流水、退费、发票) |

| POST | /api/occupational-exam/finance/order/add-item | 按登记单生成收费单(未弃项的登记项目自动转收费明细) |

| POST | /api/occupational-exam/finance/order/discount | 单项加项收费(登记后追加收费项目) |

| POST | /api/occupational-exam/finance/order/cancel | 整单折扣(受账号最低折扣权限限制) |

| POST | /api/occupational-exam/finance/pay | 作废收费单(仅未收费、或未开/已收费但允许作废的草稿单) |

| POST | /api/occupational-exam/finance/refund | 收款(支持多次混合支付)。 payType=CREDIT(先检后付/单位挂账)允许暂不结清,其余不允许超收。 |

| GET | /api/occupational-exam/finance/refunds | 退费:FULL 全额退 / PART 按项目部分退(已执行项目禁止退费) |

| GET | /api/occupational-exam/finance/invoices | 退费台账 |

| POST | /api/occupational-exam/finance/invoice/issue | 发票列表 |

| POST | /api/occupational-exam/finance/invoice/void | 开票 |

| POST | /api/occupational-exam/finance/invoice/reprint | 发票作废 |

| GET | /api/occupational-exam/finance/discount-perms | 发票重打:生成一张新记录(保留原发票号与金额),原发票自动作废留痕 |

| POST | /api/occupational-exam/finance/discount-perm/save | 发票重打:生成一张新记录(保留原发票号与金额),原发票自动作废留痕 |

| GET | /api/occupational-exam/finance/my-min-rate | 发票重打:生成一张新记录(保留原发票号与金额),原发票自动作废留痕 |

| GET | /api/occupational-exam/finance/daily-settle | 当前登录账号允许的最低折扣率 |

| POST | /api/occupational-exam/finance/daily-settle/close | 日结统计(某日收入、退费、支付方式分布) |

| GET | /api/occupational-exam/finance/monthly-report | 日结(对当日进行结账留痕,幂等覆盖) |

| GET | /api/occupational-exam/finance/registers | 月结统计(按日汇总 + 支付方式 + 合计) |

7.2.7 GuideController(15 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/guide/depts | 第14轮:智能导检(科室配置 / 入队出队 / 插队 / VIP 优先 / 医生呼叫下一位 / 未到检标记) 第15轮:报告领取签收台账 |

| POST | /api/occupational-exam/guide/dept | 导检科室列表 |

| POST | /api/occupational-exam/guide/dept/online | 新增/修改科室 |

| DELETE | /api/occupational-exam/guide/dept/{id} | 科室在线/离线切换 |

| GET | /api/occupational-exam/guide/queue | 删除科室 |

| POST | /api/occupational-exam/guide/enqueue | 队列看板:按科室分组返回候检/已呼叫/完成 |

| POST | /api/occupational-exam/guide/call-next | 入队(可从登记单直接入队;重复入队不重复插入) |

| POST | /api/occupational-exam/guide/jump | 医生呼叫下一位:取本科室排序最前的候检者,置为已呼叫 |

| POST | /api/occupational-exam/guide/vip | 插队(把某人提到本科室最前:priority 设为当前最大+1) |

| POST | /api/occupational-exam/guide/finish | VIP 标记 |

| POST | /api/occupational-exam/guide/mark | 完成检查(同步登记单状态推进) |

| DELETE | /api/occupational-exam/guide/queue/{id} | 标记未到检 / 暂停 |

| GET | /api/occupational-exam/guide/calls | 出队(从队列移除) |

| GET | /api/occupational-exam/guide/receives | 呼叫记录 |

| POST | /api/occupational-exam/guide/receive | 签收台账 |

7.2.8 InterpretController(10 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/interpret/knowledge | 职业病重点项目关键词(兜底:知识库未维护 occ_key 时按名称识别) |

| POST | /api/occupational-exam/interpret/knowledge | 知识库全部(供自动解读内部使用,不分页) |

| PUT | /api/occupational-exam/interpret/knowledge/{id} | 新增知识库条目 |

| DELETE | /api/occupational-exam/interpret/knowledge/{id} | 修改知识库条目 |

| POST | /api/occupational-exam/interpret/knowledge/{id}/toggle | 删除知识库条目(软约束:仅停用标记,物理删除需先停用) |

| GET | /api/occupational-exam/interpret/knowledge/export | 批量导入(覆盖式 upsert:按 tenant_id + item_code) |

| GET | /api/occupational-exam/interpret/knowledge/template | 导出(返回全量 JSON 数组,前端落文件) |

| GET | /api/occupational-exam/interpret/{reportId} | 生成 / 重新生成解读初稿。 遍历登记单下各检查项目,比对阈值判定异常等级,按规则落状态。 |

| GET | /api/occupational-exam/interpret/{reportId}/logs | 驳回重生成 |

| GET | /api/occupational-exam/interpret/status-counts | 解读操作日志(永久留痕) |

7.2.9 ItemRuleController(10 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/item-rule/rel | 第7轮:项目规则引擎(性别属性 / 项目互斥 / 项目联动) 第8轮:登记增强(登记单项目明细 / 弃项标记 / 复用历史订单项目) 数据落 peis_db:base_item_rel(规则)、biz_register_item(登记单项目明细) |

| POST | /api/occupational-exam/item-rule/rel | 规则列表:可按主项目过滤 |

| DELETE | /api/occupational-exam/item-rule/rel/{id} | 新增规则(mutex 互斥 / link 联动),双向一致:互斥与联动都视为对称关系 |

| GET | /api/occupational-exam/item-rule/items | 删除规则(连同对称那条一起删) |

| POST | /api/occupational-exam/item-rule/check | 可选项目(按性别过滤,返回性别属性) |

| GET | /api/occupational-exam/item-rule/register-items | 校验选中项目:性别不符 / 互斥冲突 / 联动建议缺项。 body: { gender: 1|2, itemIds: [..] } 返回: { genderBlocked:[], mutexConflicts:[{itemId,itemName,conflictId,conflictName}], linkSuggest:[{itemId,itemName,suggestId,suggestName}] } |

| POST | /api/occupational-exam/item-rule/register-items/generate | 查询某登记单的项目明细 |

| POST | /api/occupational-exam/item-rule/register-item/add | 按套餐生成登记单项目明细(重复调用不会重复插入) |

| POST | /api/occupational-exam/item-rule/register-item/abandon | 加项(含校验:性别不符、互斥冲突直接拒绝) |

| POST | /api/occupational-exam/item-rule/register-items/copy-history | 弃项标记 / 取消弃项 |

7.2.10 ModuleController(7 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/modules/mine | 按角色代码查可见模块(多角色就宽合并:任一角色 write 即 write) |

| GET | /api/occupational-exam/modules | 当前用户有权模块清单(前端 hasModule / canWrite 用)。 V2.5.0029:返回值带上 access_mode(write=可改 / read=只读),没有记录即「关闭」。 多个角色同时授权同一模块时按「就宽」原则合并:任一角色给 write 即 write,否则 read。 |

| PUT | /api/occupational-exam/modules/state | 全部模块(管理员 / 机构管理员:授权界面用) |

| POST | /api/occupational-exam/modules | 模块总开关(V2.5.0029):整站层面决定这个模块是否存在。 关掉的模块对所有角色都不可见 —— 与角色授权是「与」的关系,这里关了谁都看不到。 body: { "states": { "registers.create": 1, "finance.invoice": 0 } } |

| DELETE | /api/occupational-exam/modules/{key} | 新增/更新模块(管理员) |

| GET | /api/occupational-exam/modules/role/{roleId} | 删除模块(管理员) |

| POST | /api/occupational-exam/modules/role/{roleId} | 某角色已授权模块(管理员 / 机构管理员)。 V2.5.0029:返回 { key: "write" | "read" };列表里没有的模块即「关闭」。 |

7.2.11 ModuleLibController(7 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/modlib/modules | 写入时强制租户(非超管必须有租户) |

| POST | /api/occupational-exam/modlib/modules | 写入时强制租户(非超管必须有租户) |

| DELETE | /api/occupational-exam/modlib/modules/{id} | 写入时强制租户(非超管必须有租户) |

| GET | /api/occupational-exam/modlib/modules/{id}/items | 写入时强制租户(非超管必须有租户) |

| POST | /api/occupational-exam/modlib/modules/{id}/items | 写入时强制租户(非超管必须有租户) |

| GET | /api/occupational-exam/modlib/packages/{id}/modules | 写入时强制租户(非超管必须有租户) |

| POST | /api/occupational-exam/modlib/packages/{id}/modules | 写入时强制租户(非超管必须有租户) |

7.2.12 OccConfigController(5 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/config/public | 主库(hdc_platform)用于读工具箱统一版本号 |

| GET | /api/occupational-exam/config/mine | 主库(hdc_platform)用于读工具箱统一版本号 |

| POST | /api/occupational-exam/config/hospital-name | 主库(hdc_platform)用于读工具箱统一版本号 |

| GET | /api/occupational-exam/config/guide | 指南配置默认值(表无记录/表不可用时的兜底) |

| POST | /api/occupational-exam/config/guide | 读取体检指南动态配置(登录用户均可读,体检指南页展示用)。 唯一真源 = peis_db.sys_guide_config(按租户一行,管理员在「系统设置」修改)。 |

7.2.13 OccLabController(2 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/lab/{registerId} | 检验结果(设计方案 模块6):手工录入 + Excel/LIS 导入预留。 保存时按项目参考区间快照自动判定异常;source=manual/import/lis。 |

| POST | /api/occupational-exam/lab/{registerId} | 某登记单的检验项目 + 已录结果(应录=套餐内数值型项目) |

7.2.14 OccLoginBgController(4 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/config/login-bg | 登录页底图:管理员在「系统管理 → 登录页底图」上传一张图片,登录页全屏铺底展示。 存储:图片文件落在 {peis.file-dir}/loginbg/bg_{tenantId}.{ext}, 记录写在 peis_db.sys_login_bg(每个租户一条,重复上传覆盖)。 读取:/api/occupational-exam/config/login-bg 为免登录接口(登录页未登录也要能显示), 已在 WebConfig 白名单放行,返回图片二进制;未配置时返回 404,登录页回退渐变底色。 |

| POST | /api/occupational-exam/config/login-bg/upload | 免登录读取底图(登录页用);未配置返回 404 |

| DELETE | /api/occupational-exam/config/login-bg | 管理员上传底图(覆盖本机构原有底图) |

| GET | /api/occupational-exam/config/login-bg/info | 管理员删除底图(恢复默认渐变底色) |

7.2.15 OccMenuController(4 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/menus/tree | 模块显隐查询(V2.5.0029 页面模块授权) |

| GET | /api/occupational-exam/menus/mine | 当前用户可见的模块 key 集合(含总开关 enabled=1 过滤) |

| GET | /api/occupational-exam/menus/roles | 当前用户可见菜单(前端侧栏按此渲染) |

| GET | /api/occupational-exam/menus/role/{roleCode} | 保存角色菜单授权 |

7.2.16 OccNoticeController(3 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/notices | 生成通知书(结论签发后;RECHECK 类型建议先有复查类结论) |

| GET | /api/occupational-exam/notices/{id} | 生成通知书(结论签发后;RECHECK 类型建议先有复查类结论) |

| GET | /api/occupational-exam/notices/{id}/download | 生成通知书(结论签发后;RECHECK 类型建议先有复查类结论) |

7.2.17 OccTenantController(4 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/tenants | 租户新建管理员默认密码 |

| PUT | /api/occupational-exam/tenants/{id}/status | 建机构:同事务插租户 + 机构管理员账号 |

| POST | /api/occupational-exam/tenants/{id}/reset-password | 启用/停用(停用后该机构全部账号无法登录) |

| GET | /api/occupational-exam/tenants/{id} | 重置该机构某账号密码(平台超管代为重置) |

7.2.18 OccVersionController(2 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/version | 职业病库数据源(peis_db) |

| GET | /api/occupational-exam/version/log | 职业病库数据源(peis_db) |

7.2.19 OccupationalAuthController(3 项)

| 方法 | 路径 | 功能说明 |

| POST | /api/occupational-exam/auth/login | 登录 / 当前用户 |

| GET | /api/occupational-exam/auth/me | 取来访真实 IP(经 nginx 转发时取 X-Forwarded-For 首段) |

| POST | /api/occupational-exam/auth/password | 取来访真实 IP(经 nginx 转发时取 X-Forwarded-For 首段) |

7.2.20 OccupationalWorkerController(6 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/workers | 劳动者档案:身份证 SM4 加密 + SHA256 指纹去重 + 动态数据脱敏(data:unmask 权限可见明文) |

| POST | /api/occupational-exam/workers | 劳动者档案:身份证 SM4 加密 + SHA256 指纹去重 + 动态数据脱敏(data:unmask 权限可见明文) |

| GET | /api/occupational-exam/workers/{id} | 劳动者档案:身份证 SM4 加密 + SHA256 指纹去重 + 动态数据脱敏(data:unmask 权限可见明文) |

| PUT | /api/occupational-exam/workers/{id} | 劳动者档案:身份证 SM4 加密 + SHA256 指纹去重 + 动态数据脱敏(data:unmask 权限可见明文) |

| DELETE | /api/occupational-exam/workers/{id} | 修改档案:仅允许更新非身份字段(姓名/工种/接害工龄/住址/既往史),身份证与出生日期由身份证派生、不可改 |

| POST | /api/occupational-exam/workers/import | 动态脱敏:身份证(保留前3后4)/ 手机号(保留前3后4);有权限返回明文。 字段解密已由 Sm4TypeHandler→GmCrypto 门面在读库时统一完成;这里补充 SM3 摘要完整性校验。 |

7.2.21 OpenInterpretController(1 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/open/interpret | 固定免责声明(对外返回内容末尾必带,前端以红色展示) |

7.2.22 OperLogController(1 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/oper-logs | 操作日志查询(设计方案 模块1 系统管理:操作日志/登录日志) |

7.2.23 QualityController(13 项)

| 方法 | 路径 | 功能说明 |

| POST | /api/occupational-exam/quality/arrive | 第12轮:标本采集/送检/交接全流程 + 到检确认(防替检拍照) 第13轮:危急值阈值配置 + 检验结果自动判危急 + 告警处理台账 |

| GET | /api/occupational-exam/quality/arrive/{registerId} | 到检确认(可附带拍照路径,防替检) |

| GET | /api/occupational-exam/quality/samples | 到检状态查询(登记单列表附带) |

| POST | /api/occupational-exam/quality/sample/collect | 标本台账列表 |

| POST | /api/occupational-exam/quality/sample/send | 标本采集 |

| POST | /api/occupational-exam/quality/sample/receive | 标本送检 |

| POST | /api/occupational-exam/quality/sample/reject | 标本接收(检验科签收) |

| GET | /api/occupational-exam/quality/critical/rules | 标本拒收(必须填原因) |

| POST | /api/occupational-exam/quality/critical/rule | 阈值规则列表 |

| DELETE | /api/occupational-exam/quality/critical/rule/{id} | 新增/修改阈值规则 |

| GET | /api/occupational-exam/quality/critical/records | 删除阈值规则 |

| POST | /api/occupational-exam/quality/critical/eval | 告警台账 |

| POST | /api/occupational-exam/quality/critical/handle | 评估检验结果是否触发危急值(检验结果保存后调用)。 body: { registerId, itemId, value } —— value 为数值 命中阈值则写入 biz_critical_record(同项目未处理的不重复写入) |

7.2.24 RegisterController(11 项)

| 方法 | 路径 | 功能说明 |

| POST | /api/occupational-exam/registers | 体检登记单:创建/列表/详情/状态流转/加锁解锁 |

| GET | /api/occupational-exam/registers | 体检登记单:创建/列表/详情/状态流转/加锁解锁 |

| GET | /api/occupational-exam/registers/pending | 体检登记单:创建/列表/详情/状态流转/加锁解锁 |

| GET | /api/occupational-exam/registers/archived-search | 待录入名单(需求③):返回指定科室「已登记但尚未录入完成」的登记单。 仅排除已归档/已取消;对每个登记单,按套餐过滤出该科室的应检项目, 若该科室仍有未录入项(recorded < expected)则纳入列表,并附带劳动者姓名。 |

| PUT | /api/occupational-exam/registers/{id} | 登记单对应劳动者姓名(含匿名脱敏) |

| GET | /api/occupational-exam/registers/{id} | 编辑登记单:保存「体检登记」页编辑框里的修改(已签发/归档/取消的单据拒绝修改) |

| GET | /api/occupational-exam/registers/{id}/guide | 读取原始行(供完整性校验;列名取规范化字段清单) |

| POST | /api/occupational-exam/registers/{id}/transition | 体检指引单数据(供打印/批量打印):登记单 + 劳动者 + 单位 + 套餐 + 按科室分组的应检项目。 员工拿着这张单去各科室检查,科室医生在「已完成」栏打勾。 |

| POST | /api/occupational-exam/registers/batch | 体检指引单数据(供打印/批量打印):登记单 + 劳动者 + 单位 + 套餐 + 按科室分组的应检项目。 员工拿着这张单去各科室检查,科室医生在「已完成」栏打勾。 |

| POST | /api/occupational-exam/registers/{id}/lock | 团体预约批量登记(设计方案 模块4 P0): 传 employerId + packageId + examType + factorIds + workerIds[],逐个生成登记单。 已有未完结登记单的劳动者自动跳过。 |

| POST | /api/occupational-exam/registers/{id}/unlock | 团体预约批量登记(设计方案 模块4 P0): 传 employerId + packageId + examType + factorIds + workerIds[],逐个生成登记单。 已有未完结登记单的劳动者自动跳过。 |

7.2.25 ReportController(2 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/reports | 生成报告(要求登记单已签发) |

| GET | /api/occupational-exam/reports/{id}/download | 报告列表(可按登记单过滤) |

7.2.26 ReportTemplateController(7 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/report-template/placeholders | 第9轮:报告模板管理与多套模板适配 - 模板支持按业务类型(occupational 职业病 / health 普通体检 / common 通用兜底)切换 - 渲染时自动替换 ${占位符},供报告预览 / PDF 生成使用 |

| GET | /api/occupational-exam/report-template/list | 可用占位符说明 |

| GET | /api/occupational-exam/report-template/{id} | 模板列表 |

| POST | /api/occupational-exam/report-template/save | 模板列表 |

| POST | /api/occupational-exam/report-template/delete | 新增 / 修改模板 |

| GET | /api/occupational-exam/report-template/match | 删除(软删) |

| POST | /api/occupational-exam/report-template/render | 按登记单自动匹配模板: 优先取登记单业务类型对应的默认启用模板,其次同类型启用模板,再退到 common 默认模板。 |

7.2.27 ResultController(4 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/results/items/{registerId} | 科室检查结果录入:录入前必须持锁;保存后解锁。按科室隔离录入权限。 |

| POST | /api/occupational-exam/results/save/{registerId} | 取某登记单某项目的最新一条归档修订(revision 最大);无则返回 null |

| POST | /api/occupational-exam/results/amend/{registerId} | 批量保存某登记单的结果(要求先 lock) |

| GET | /api/occupational-exam/results/{registerId} | 归档后修订(需求⑤):已归档记录被修改时,原 biz_exam_result 记录不得删除/更改,必须保留备查; 本次修改仅新增一条「替换显示」的修订记录(biz_exam_result_amend)。 限制:仅 ARCHIVED 状态允许;按科室隔离写入(医生只能修订本科室项目);无需持锁。 请求体:{ "reason": "修订说明", "items": [ {itemId, resultText, resultValue, abnormal}, ... ] } |

7.2.28 StatController(4 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/stat/overview | 工作台统计 + 汇总报表(按状态/结论/单位/因素多维汇总,支持 CSV 导出) |

| GET | /api/occupational-exam/stat/summary | 工作台统计 + 汇总报表(按状态/结论/单位/因素多维汇总,支持 CSV 导出) |

| GET | /api/occupational-exam/stat/summary/export | 汇总报表:start/end(登记日期,含)、employerId、factorId 过滤。 返回 byStatus / byConclusion / byEmployer / byFactor 四个维度。 |

| GET | /api/occupational-exam/stat/followup | 汇总报表 CSV 导出(Excel 可直接打开,UTF-8 BOM) |

7.2.29 StdCatalogController(9 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/std/stats | 国家标准知识库接入层 —— 将 base_std_ 6 张标准表(职业病目录 / GBZ 188 监护规范) 与本系统业务档案打通。 <p><b>两类能力:</b> <ol> <li><b>查询</b>:法定病种目录、接害因素档案、检查规则与项目,供登记页 / 结论页 下拉与自动带出({@code /suggest-items})使用;</li> <li><b>一键导入</b>:把国标因素、检查项目、GBZ188 套餐灌进业务表 base_hazard_factor / base_exam_item / base_package(+base_package_item), 幂等可重复执行(已存在的跳过或覆盖重建,不会重复造数据)。</li> </ol> <p>标准数据 tenant_id=1(全体共享),导入时写入当前操作租户。 |

| GET | /api/occupational-exam/std/categories | 标准库数据量概览(页面头部展示) |

| GET | /api/occupational-exam/std/diseases | 12 大类职业病目录 |

| GET | /api/occupational-exam/std/hazards | 病种目录:可按大类、关键词检索 |

| GET | /api/occupational-exam/std/hazards/{code} | 接害因素档案:可按类别(粉尘/化学物/物理因素…)、关键词检索 |

| GET | /api/occupational-exam/std/hazards/{code}/rules | 因素详情:档案 + 全部检查规则 + 每条规则的项目 + 对应法定职业病 |

| GET | /api/occupational-exam/std/rules/{id}/items | 某因素的检查规则 |

| GET | /api/occupational-exam/std/hazards/{code}/diseases | 某规则下的必检/选检项目 |

| GET | /api/occupational-exam/std/suggest-items | 某因素对应的法定职业病 |

7.2.30 UserManageController(6 项)

| 方法 | 路径 | 功能说明 |

| GET | /api/occupational-exam/users | 业务角色白名单(防提权到 platform_admin) |

| POST | /api/occupational-exam/users | 业务角色白名单(防提权到 platform_admin) |

| PUT | /api/occupational-exam/users/{id}/dept | 业务角色白名单(防提权到 platform_admin) |

| DELETE | /api/occupational-exam/users/{id} | 变更 / 解除科室归属(deptId 为空表示从科室移除,不删除账号) |

| PUT | /api/occupational-exam/users/{id} | 删除医生账号(软删除,保留历史数据关联) |

| POST | /api/occupational-exam/users/{id}/reset-password | 修改姓名/角色/状态/科室 |

7.3 关键接口说明

登录接口 POST /api/occupational-exam/auth/login:入参用户名与密码,校验 BCrypt 哈希与失败锁定策略,成功返回 JWT 令牌与用户角色、菜单权限。

登记创建接口 POST /api/occupational-exam/registers:入参劳动者、体检类别、套餐与接害因素集合,服务端发号并生成应检项目,返回登记单。批量登记接口 POST /registers/batch 支持团体名单一次创建多张登记单并返回逐单结果。

状态流转接口 POST /registers/{id}/transition:入参目标状态,服务端校验状态机合法性并乐观锁提交。

报告生成接口 POST /api/occupational-exam/reports/generate/{registerId}:校验结论已签发后生成 PDF,返回报告记录与版本号;下载接口 GET /reports/{id}/download 输出文件流。

汇总导出接口 GET /api/occupational-exam/stat/summary/export:按维度参数聚合后输出 CSV 文件流(UTF-8 BOM)。

国密配置接口(GmConfigController):查询加密状态、保存开关与算法及密钥、密钥轮换;保存动作记录操作日志。

7.4 关键接口入参与出参

关键业务接口的入参、出参与处理要点如下(路径省略统一前缀 /api/occupational-exam)。

表 7-1 关键接口入参出参说明

| 接口 | 方法与路径 | 主要入参 | 主要出参 | 处理要点 |

| 登录 | POST /auth/login | username, password | token(JWT), 用户信息, 角色码, 菜单树 | 失败计数与锁定;密码 BCrypt 校验 |

| 登记单列表 | GET /registers | page, size, 状态/日期/关键字过滤 | 登记单分页列表(含状态、应检进度) | 强制租户过滤 |

| 创建登记单 | POST /registers | workerId, examType, packageId, factorIds, regDate | 登记单(含 TJ 编号与应检项目) | 序列发号;事务写入主表+关联表 |

| 批量登记 | POST /registers/batch | 单位、类别、日期、人员名单 | 逐单成功/失败明细 | 逐单校验;失败不阻断 |

| 状态流转 | POST /registers/{id}/transition | targetStatus | 成功/业务异常 | 状态机校验+乐观锁 |

| 领单/退单 | POST /registers/{id}/lock | /unlock | — | 成功/占用提示 | 行级软锁 lock_by/lock_time |

| 导检建议 | GET /registers/{id}/guide | — | 按科室排队的建议检查顺序 | 按应检项目所属科室聚合 |

| 保存科室结果 | POST /results | registerId, itemId, resultText/resultValue, abnormal | 保存结果 | 唯一约束防重;参考区间自动判定 |

| 待检队列 | GET /registers/pending | dept | 本科室待检/在检列表 | 按科室×状态过滤 |

| 保存结论 | POST /conclusion/{registerId} | conclusionType, summary, 复查建议 | 结论记录 | 与登记单一对一 |

| 提交/审核/签发 | POST /conclusion/{registerId}/submit | /audit | /sign | 意见/通过标志 | 任务状态更新 | 审核历史逐轮留痕;签发记录人与时间 |

| 审核配置 | GET/POST /conclusion/review-config | 启用二级复审、复审人 | 配置保存/读取 | 仅管理员 |

| 生成报告 | POST /reports/generate/{registerId} | — | 报告记录(REP 号、版本) | 校验已签发;iText 生成 PDF |

| 报告下载 | GET /reports/{id}/download | — | PDF 文件流 | 鉴权后输出 |

| 通知书生成 | POST /notices/{regId} | noticeType | 通知书记录(NTC 号、PDF 路径) | 按结论类型联动 |

| 附件上传 | POST /attaches/upload | bizNo, attachType, file | 附件记录 | jpg/png/pdf ≤10MB |

| 汇总统计 | GET /stat/summary | 维度(状态/结论/单位/因素), 日期区间 | 聚合结果集 | SQL 层聚合+租户过滤 |

| 汇总导出 | GET /stat/summary/export | 同上 | CSV 文件流(UTF-8 BOM) | 导出动作写日志 |

| 随访查询 | GET /stat/followup | type(复查/疑似/禁忌证) | 随访名单 | 联系方式按字段权限脱敏 |

| 建档 | POST /workers | 姓名, 身份证号, 单位, 工种, 接害信息 | 档案记录 | SHA-256 查重;SM4 可选加密 |

| 批量导入 | POST /workers/import | 名单数据 | 成功/失败明细 | 逐行校验 |

| 用户管理 | GET/POST/PUT/DELETE /users, /users/{id}/reset-password | 用户字段/新口令 | 用户记录 | 口令仅存 BCrypt 哈希 |

| 菜单授权 | GET /menus/mine, POST /menus/role | 角色 ID, 菜单勾选集 | 菜单树/授权结果 | 父子菜单联动校验 |

| 租户管理 | GET/POST /tenants, /tenants/{id}/status | /reset-password | 机构信息/状态/新口令 | 租户记录 | 仅平台超管 |

| 国密配置 | GET/POST /gm/config | enabled, algorithm, sm4Key, sm2KeyPair | 状态(指纹/版本)/保存结果 | 保存动作写日志;运行期生效 |

| 操作日志 | GET /operlogs | 操作人/模块/时间区间 | 日志分页列表 | 仅管理员 |

7.5 关键接口报文示例

以下为关键接口的请求/响应报文示例(JSON,节选核心字段):

登录 POST /auth/login

{

"request": {"username": "chief01", "password": "******"},

"response": {"code": 0, "message": "ok",

"data": {"token": "eyJhbGciOiJIUzI1NiJ9...", "realName": "钱医师",

"roles": ["chief", "doctor"], "tenantId": 1,

"menus": [{"id": 1, "name": "工作台", "path": "/dashboard"}, ...]}}}

创建登记单 POST /registers

{

"request": {"workerId": 1042, "examType": "ONJOB", "packageId": 2,

"factorIds": [2], "regDate": "2026-10-03"},

"response": {"code": 0, "data": {"id": 3312, "regNo": "TJ20261003-000112",

"status": "REGISTERED", "packageCode": "PKG0002",

"requiredItems": 5, "lockBy": null, "version": 0}}}

批量登记 POST /registers/batch

{

"request": {"employerId": 23, "examType": "ONJOB", "regDate": "2026-10-09",

"workers": [{"workerId": 1042, "packageId": 2}, ...]},

"response": {"code": 0, "data": {"created": 72, "failed": 2,

"failures": [{"workerId": 1088, "reason": "未建档"}]}}}

领单软锁 POST /registers/{id}/lock

{

"response": {"code": 0, "message": "领取成功"} |

{"code": 4012, "message": "登记单已被 [王医生] 领取"}}

保存科室结果 POST /results

{

"request": {"registerId": 3312, "itemId": 10, "dept": "电测听室",

"resultValue": 38, "unit": "dB"},

"response": {"code": 0, "data": {"abnormal": 2, "refHigh": 25,

"flag": "敏感项异常", "snapshot": "纯音听力(左)"}}}

保存主检结论 POST /conclusion/{registerId}

{

"request": {"conclusionType": "RECHECK",

"summary": "双耳高频听力下降,建议复查电测听",

"recheckItems": "纯音听力(双)"},

"response": {"code": 0, "data": {"id": 187, "state": "DRAFT"}}}

审核 POST /conclusion/{registerId}/audit

{

"request": {"pass": true, "comment": "与科室结果一致"},

"response": {"code": 0, "data": {"state": "PENDING_RE_REVIEW",

"auditRound": 1}}}

签发 POST /conclusion/{registerId}/sign

{

"response": {"code": 0, "data": {"signTime": "2026-10-02 16:41:08",

"signer": "王主检", "registerStatus": "SIGNED"}}}

生成报告 POST /reports/generate/{registerId}

{

"response": {"code": 0, "data": {"reportNo": "REP20261002-000034",

"version": 1, "pdfPath": "/files/occupational/REP…034.pdf"}}}

汇总统计 GET /stat/summary?dim=factor

{

"response": {"code": 0, "data": {"rows": [

{"factor": "噪声", "planned": 274, "checked": 261, "normal": 233,

"recheck": 25, "suspect": 2, "contraindication": 1, "passRate": 89.3}, ...]}}}

国密配置 POST /gm/config

{

"request": {"enabled": true, "algorithm": "SM4",

"gmKeySm4": "{"k2":"<64位十六进制>"}"},

"response": {"code": 0, "data": {"fingerprint": "3FA9…C21B",

"keyVersions": 3, "active": "k2"}}}

随访查询 GET /stat/followup?type=RECHECK

{

"response": {"code": 0, "data": [{"regNo": "TJ20261002-000098",

"workerName": "赵*", "employer": "惠达诚制造", "factor": "噪声",

"phone": "138****2211", "recheckItems": "纯音听力(双)"}]}}

本章小结:本章从认证、权限、存储、传输、审计、防篡改六个层面给出安全设计,并附认证时序、威胁对策矩阵与二十项安全基线,可直接用于安全验收。

第8章 系统安全设计

8.1 身份认证安全

用户口令以 BCrypt 哈希存储,数据库不保存任何明文口令;登录接口实施失败计数锁定(连续失败达到阈值后锁定账号一段时间),抵御暴力破解;登录成功签发 JWT 令牌(含用户标识、角色、租户标识与过期时间),后续请求统一由认证拦截器校验;令牌过期后须重新认证。全部登录事件(含失败)写入操作日志。

认证安全设计要点说明:口令哈希采用 BCrypt 自适应代价因子,单次校验耗时约百毫秒量级,天然抑制离线穷举;失败锁定以数据库字段持久化,重启服务不丢失计数;JWT 采用服务端密钥签名,令牌不落地敏感明文,载荷仅含标识与角色码;会话服务支持后续扩展令牌吊销能力。

8.2 权限访问安全

系统实施四级访问控制:菜单级(角色菜单授权驱动侧栏动态渲染,前端路由守卫拦截地址栏直输)、接口级(后端按角色与权限码二次鉴权,前端隐藏不等于放行)、数据级(业务查询强制追加租户过滤,跨租户访问拦截;平台超管凭跨租户标记全局管理)、字段级(sys_field_perm 按「角色×表×字段」配置 read/write/mask,敏感字段对无权角色自动脱敏)。权限模型如图 5-5 所示。

权限访问安全设计要点说明:四级权限中,菜单级解决「看得到什么」、接口级解决「调得动什么」、数据级解决「查得到谁的数据」、字段级解决「看得懂哪个字段」;四级独立配置、逐层收窄,任一层拒绝即拒绝。授权变更即时生效的机制为:授权保存在角色菜单关系表,前端每次进入系统拉取最新菜单树,后端每次请求实时校验,无需发布或重启。

8.3 数据存储安全(国密加密)

系统支持 SM2/SM3/SM4 国密算法可选加密:SM4 对姓名、身份证号、职业健康史、联系电话等敏感字段加密落盘(密文前缀 SM4V1:),读取时对授权用户透明解密;SM3 对敏感字段计算摘要存证,读取时校验完整性、监测篡改;SM2 对报告签发等关键数据非对称签名。加密能力可由管理员一键开关,关闭时系统直接明文读写、业务功能不受影响。密钥文件支持多版本与轮换,旧密文按密钥标识解密,密钥文件指纹登记于数据安全页面供核对。开关逻辑如图 5-6 所示。

存储安全设计要点说明:加密粒度选择「字段级」而非「库级」——库级加密(如透明加密)无法做到按字段授权解密与脱敏,而字段级加密配合类型处理器可实现「写入即加密、读取按授权解密、无权即掩码」的细粒度控制;密文前缀标识保证密钥轮换期间新旧密文共存可解;SM3 摘要列独立于密文列存储,即使密文被篡改也能被发现。

8.4 传输安全

生产部署支持 HTTPS(Nginx TLS 终结),前后端同源部署避免跨域攻击面;国密安全通道组件(GmSecureChannel)支持对敏感接口启用国密加密传输;会话令牌由服务端会话服务(OccSessionService)管理,支持会话校验与失效控制。

传输安全设计要点说明:生产环境强制 HTTPS,TLS 版本与加密套件按等保要求配置;同源部署消除跨域风险面,同时避免 CORS 带来的凭据暴露;国密安全通道为政采场景预留国密 TLS 升级路径。

8.5 日志审计安全

操作日志覆盖登录登出、单据增改与状态流转、基础数据变更、权限变更、报告生成与下载;敏感访问审计(SensitiveAuditLogger)单独记录敏感字段明文查看与数据导出行为。日志仅增不改不删、不可篡改,支持按模块、操作人、时间区间检索,为责任追溯与合规检查提供证据链。

审计安全设计要点说明:日志的「不可篡改」由三层保证——应用层不提供修改删除接口、数据库层以仅增权限约束运维操作、内容层记录操作明细与来源 IP 形成证据链;敏感访问审计与普通操作日志分离存储类别,便于合规检查时单独出证。

8.6 防篡改与防越权设计

● 越权防护:所有业务查询按租户强制过滤,详情接口校验记录归属,跨租户访问返回无权限并留痕;

● 数据篡改监测:SM3 摘要校验敏感字段完整性,异常标记即时暴露;

● 并发篡改防护:乐观锁版本号校验,拒绝旧版本数据覆盖;

● 注入防护:数据访问统一使用参数化查询(MyBatis 预编译),杜绝 SQL 注入;

● 输入校验:前后端双重校验,非法输入在入口拦截并友好提示;

● 功能授权:加密狗按模块维度控制功能开通,菜单隐藏与路由拦截双闸。

8.7 认证与鉴权时序

一次典型业务请求的认证鉴权时序如下:

1. 用户在登录页提交用户名与口令;

2. 认证接口查询用户并校验锁定状态(fail_count/lock_until),锁定中直接拒绝;

3. BCrypt 校验口令哈希,失败则累加失败计数(达阈值锁定)并返回错误;

4. 校验通过:签发 JWT(载荷含用户 ID、角色码、租户 tid、过期时间),返回菜单树与角色;

5. 前端保存令牌,后续请求携带 Authorization 头;

6. 认证拦截器对 /api/occupational-exam/** 统一拦截:验签、校验过期、注入身份上下文;

7. 业务控制器执行角色/权限码检查(前端隐藏菜单不等于后端放行);

8. 数据访问层经 TenantScope 自动追加租户条件;详情接口校验记录归属;

9. 字段权限在查询出口执行脱敏;敏感字段按加密开关解密或掩码输出;

10. 响应返回;关键写操作与敏感访问写入操作日志/敏感审计。

8.8 安全威胁与对策矩阵

表 8-1 安全威胁与对策矩阵

| 威胁场景 | 风险 | 系统对策 |

| 暴力破解登录 | 口令穷举 | 失败计数锁定 + BCrypt 慢哈希 + 登录日志 |

| 越权访问他人租户数据 | 水平/垂直越权 | JWT 携带 tid + TenantScope 强制过滤 + 详情归属校验 |

| 敏感信息泄露(库被拖/内部导出) | 身份证号等明文外泄 | SM4 字段加密 + 字段权限脱敏 + 明文查看审计 |

| 数据被篡改(内部或拖库后) | 体检结果/结论被改 | SM3 完整性摘要校验 + 操作日志不可改 + 乐观锁 |

| SQL 注入 | 恶意输入拼接 | MyBatis 参数化查询统一处理 |

| 未授权接口调用 | 绕过前端直调接口 | 认证拦截器全局拦截 + 角色权限码二次校验 |

| 报告伪造 | 冒签报告 | SM2 签名 + 签发人/时间留痕 + 报告版本化 |

| 功能滥用(未授权模块) | 越权启用功能 | 加密狗模块级授权(菜单隐藏+路由拦截双闸) |

| 抵赖(否认操作) | 操作后不承认 | 操作日志+敏感审计全程留痕、不可篡改 |

8.9 安全配置基线清单

系统部署与运行须满足以下安全基线(部署验收逐项核对):

● 口令策略:长度 ≥ 8,仅存 BCrypt 哈希,禁止明文回显;

● 登录锁定:连续失败 5 次锁定 15 分钟;

● JWT 有效期按机构策略配置,过期重新认证;

● 管理类接口仅限 admin 及以上角色;

● 敏感字段查询出口统一脱敏,掩码格式全局一致;

● 明文查看必须单次授权并写敏感审计;

● SM4 密钥文件权限收窄至服务运行账号;

● 密钥轮换记录版本与指纹,双人复核;

● 数据库账号最小权限(业务库专用账号,禁 DDL);

● 备份文件异地存放并限制访问;

● HTTPS 部署,TLS 证书按期更新;

● Nginx 仅开放必要路径,静态目录禁列目录;

● 上传文件类型白名单(jpg/png/pdf)与大小上限校验;

● 附件存储目录禁止执行权限;

● 操作日志、敏感审计仅增不改不删;

● 跨租户访问默认拒绝并留痕;

● 错误响应不暴露堆栈与内部路径;

● 依赖组件版本定期核查并升级安全补丁;

● 服务器仅开放必要端口(80/443/8080 内网);

● 定期恢复演练验证备份有效性。

8.10 十大核心安全防护机制逐项设计

除 SM2/SM3/SM4 国密算法应用外,系统还落地以下十项安全防护机制。每项机制按「机制原理—输入—处理逻辑—输出」统一格式逐项说明,全部对应系统实际实现(security、dongle、config 包源码),可作为安全验收的逐项依据。

8.10.1 独立授权验证服务器与软加密狗模拟 SDK

机制原理:系统采用「独立授权验证服务器 + 软加密狗」双层授权体系。软加密狗以 RSA-SHA256 签名的授权文件(license.dat)模拟插在服务器上的硬件加密狗:授权字段(机构标识、有效期、授权模块清单、最大在线终端数)拼接规范串后由发授权方私钥签名,程序内置公钥(dongle_pub.pem)对文件做 RSA-SHA256 验签,文件被篡改即验签失败;真硬件加密狗(深思精锐/飞天诚信/圣天诺等)经 RealDongleProvider 适配器骨架预留,配置 occ.dongle.provider=real 即可切换厂商 SDK,业务代码零改动。独立授权验证服务器在登录时经国密安全通道(GM1:SM2 双向身份鉴别 + SM4 加密链路)签发短期访问票据,服务器不可达时自动降级为本地会话,保证离线可用。

输入:登录请求(账号、口令、客户端 IP);授权文件 license.dat;授权验证服务器地址配置。

处理逻辑:

● ①登录门禁:账号密码校验之前先执行加密狗校验——未插狗/文件损坏/验签失败/授权过期分别抛 4801~4803 拒绝登录。

● ②验签:内置公钥对授权文件规范串做 RSA-SHA256 验签。

● ③客户端数量控制:登录成功后 registerSession 登记在线终端,达到授权上限抛 4804 拒绝新登录。

● ④模块授权:moduleForPath+isModuleEnabled 供菜单过滤与接口拦截——未授权模块菜单不渲染、接口直接 403。

● ⑤校验留痕:每次校验的成败、序列号、时间、账号、IP 写入 sys_dongle_log。

● ⑥降级策略:授权服务器不可达自动降级本地会话。

● 加密狗组件自身故障时放行(防护组件缺陷不得把全站关在门外),但「明确校验不通过」必须拦截。

输出:授权通过:正常进入系统、按授权清单渲染菜单、登记在线会话;授权失败:返回 4801~4804 错误码并拒绝,校验记录落 sys_dongle_log 供审计。

8.10.2 菜单权限与行级数据权限的多角色隔离

机制原理:权限模型为「菜单权限 + 行级数据权限」两级:菜单级解决「看得到什么」——菜单树按角色授权(sys_menu + 角色菜单关系表),前端侧栏按登录返回的菜单树动态渲染;行级解决「查得到谁的数据」——全部业务表带 tenant_id 租户列,数据访问层经 TenantScope 自动追加租户过滤条件,详情接口校验记录归属,跨租户访问一律拒绝。角色体系含超级管理员、机构管理员、主检医师、审核医师、科室医生、登记员、查看员等,角色间职责隔离:业务操作、质量判定(主检与审核不得同一人)、系统治理三权分立。

输入:登录身份(用户 ID、角色码、租户 ID,由 JWT 携带);请求的菜单/接口/数据行。

处理逻辑:

● ①登录成功后按角色查询菜单树返回前端,侧栏动态渲染,无授权菜单不下发。

● ②接口层 AuthInterceptor 校验 JWT 合法性并注入 uid/username/roles 上下文,控制器按角色码与权限码(如 data:unmask)二次校验。

● ③数据层 TenantScope 对 SQL 自动追加 tenant_id 等值条件,列表查询天然隔离。

● ④详情/编辑接口先查记录归属,租户不匹配返回越权错误。

● ⑤平台超管与机构管理员数据范围不同:超管仅机构治理,不读机构内体检业务明细。

输出:各角色只见其权属菜单与数据:登记员看不到审核操作,科室医生只见本科室任务,机构间数据完全隔离,越权请求被拦截并留痕。

8.10.3 后端越权访问检查与前端空壳化渲染

机制原理:系统遵循「前端仅是空壳、权限判定全部在后端」原则:前端构建产物(Vue 编译后的静态资源)不含任何业务规则与权限判定逻辑,菜单、按钮、数据均由后端接口下发后渲染,前端隐藏菜单不等于后端放行;报告 PDF、通知书等文书由后端服务端渲染生成,浏览器端无法通过 F12 修改前端数据伪造业务结果;全部写接口在后端逐请求校验身份、角色、权限码与数据归属,篡改前端内存状态或直接构造 API 调用均被后端拒绝。

输入:HTTP 请求(含或不含 Authorization 头);请求路径、方法、参数。

处理逻辑:

● ①认证拦截器对 /api/occupational-exam/** 全局拦截:无令牌/令牌过期/验签失败一律 401。

● ②后端按权限码校验(菜单可见性对应的 perm_code 在控制器再次校验),前端绕过无效。

● ③写操作(新增/修改/删除/审核/签发)在后端校验角色与记录归属后执行,越权返回 403 并记录。

● ④文书渲染(报告/通知书 PDF)在后端完成,前端仅展示与下载,页面元素篡改不影响服务端数据与文书。

● ⑤响应数据按字段权限过滤,未授权字段不下发到前端(而非前端隐藏)。

输出:任何绕过前端直接调用接口的请求均被后端拦截或按权限裁剪返回;前端篡改不产生任何业务效果;服务端渲染文书与数据库数据始终一致。

8.10.4 账号安全策略(密码哈希、复杂度、错误锁定、会话超时)

机制原理:账号安全四件套:①密码哈希——口令以 BCrypt 自适应代价哈希存储($2a$10$ 前缀),数据库不存明文,单次校验约百毫秒,天然抑制离线穷举与彩虹表;②密码复杂度——设置/重置密码强制至少 8 位,登录与重置接口双侧校验;③登录错误锁定——失败计数 fail_count 累加,连续 5 次错误锁定 10 分钟(lock_until),锁定期间登录直接拒绝并提示剩余时间,登录成功自动清零;④会话超时——登录签发一次性短期会话令牌(随机 256bit,库内仅存 SHA-256 摘要,防拖库重放),滑动有效期空闲 30 分钟自动销毁(再访问一律 401),并有绝对有效期上限兜底;管理员可强制下线任意在线会话。

输入:登录请求(用户名、口令);改密/重置请求(新口令);携带会话票据与 JWT 的业务请求。

处理逻辑:

● ①登录:先查锁定状态(lock_until 未到 → 拒绝并提示),BCrypt 比对口令,失败则 fail_count+1(满 5 次写 lock_until=now+10min 并清零计数),成功则清零计数与锁、签发 JWT 与一次性会话票据。

● ②改密:校验长度 ≥8 位后 BCrypt 哈希入库,并使旧会话失效。

● ③会话:每次请求校验票据存在性与最后活跃时间,空闲超 idle-minutes(默认 30)销毁,超过绝对有效期强制失效。

● 活跃请求刷新滑动窗口。

● ④独立授权验证服务器场景下,会话票据经 GM1 国密通道换取,服务器不可达降级本地签发。

输出:口令仅以哈希形态存在;暴力破解被 5 次/10 分钟锁定抑制;离开工位 30 分钟的终端自动失效;管理员可即时踢出可疑会话。

8.10.5 全链路不可篡改操作审计日志

机制原理:审计日志覆盖登录日志、操作日志、数据修改日志与敏感数据访问日志四类,全程留痕、仅增不改不删。敏感数据审计(SensitiveAuditLogger)额外做两件事:审计明细 detail 经 SM4 加密落盘(sec_audit_log.detail_cipher),防止审计库被直接阅读;采用 SHA-256 哈希链防篡改——chain_hash = SHA256(前一条 chain_hash ‖ 本条 detail_hash ‖ account ‖ action ‖ target),任意一行被删改,其后续全链校验立即失败,篡改行为可被证明。新增/修改/删除/查看敏感数据四类操作全部留痕,含操作人、时间、IP、对象与结果。

输入:业务写操作(谁、何时、对哪条数据、做了什么、原值/新值);敏感数据访问事件(查看明文、导出等)。

处理逻辑:

● ①操作发生时同步写操作日志(oper_log):账号、时间、IP、模块、动作、对象、明细。

● ②敏感事件写 sec_audit_log:detail 先 SM4 加密再落盘,计算哈希链 chain_hash 入库。

● ③日志表只提供写入与查询接口,无修改/删除 API,数据库账号按仅增权限约束。

● ④查询侧支持按时间/账号/模块检索,时间索引保障长期积累后的性能。

● ⑤校验侧可对哈希链逐条重算验证完整性。

输出:完整证据链:任何业务变更与敏感访问可追溯到人、时间、来源 IP;审计记录自身加密存储且被篡改即可证明(哈希链断裂);满足等保与个人信息保护合规检查出证要求。

8.10.6 HTTPS 传输加密

机制原理:系统生产部署强制 HTTPS:客户端到 Nginx 之间以 TLS 加密传输,Nginx 终结 TLS 后经内网回源到应用服务(127.0.0.1:8080),避免明文 HTTP 在公网链路上被窃听或中间人篡改;登录口令、身份证号等敏感字段即使被网络抓包也无法还原。同时应用与数据库、应用与授权验证服务器之间的关键链路分别以内网隔离与国密安全通道(GM1)保护。国密安全通道为政采场景预留国密 TLS(SM2 证书/TLCP 协议)升级路径。

输入:客户端发起的 HTTPS 请求;Nginx TLS 证书与私钥;授权服务器的 SM2 双向证书。

处理逻辑:

● ①浏览器经 TLS 与 Nginx 建立加密会话,证书校验通过后通信。

● ②Nginx 按路由规则将静态资源直接返回、将 /api/occupational-exam/ 反向代理至本机 8080,回源走内网回环。

● ③JWT 令牌、请求参数、响应数据全程密文传输。

● ④独立授权验证服务器通信经 GM1 通道:SM2 双向身份鉴别确认双方身份 + SM4 加密业务数据。

● ⑤HSTS/强制跳转策略将 HTTP 请求重定向至 HTTPS。

输出:全链路密文传输:链路抓包仅见密文;服务器身份可验证(防钓鱼);内外网分层隔离,公网仅暴露 443。

8.10.7 TDE 数据库透明加密

机制原理:存储加密采取「应用层字段级国密加密为主、数据库层透明加密(TDE)为辅」的双层设计:应用层对身份证号、口令等敏感列以 SM4 加密后入库(与业务逻辑解耦,密文带版本前缀支持轮换);数据库层 TDE 对数据文件、日志文件落盘时透明加密、读取时透明解密,防止磁盘/备份介质被盗或被直接挂载读取(防「拖库」最后防线);同时 SM4 敏感表每日定时自动备份(EncryptedBackupService,每日 02:30 整表导出 INSERT SQL,表内本身已是密文,导出即密文),备份文件与清单(manifest)一并落备份目录并限制访问权限。

输入:业务写请求中的敏感字段(明文入口仅存在于应用内存);MySQL 数据文件、redo/undo/binlog;每日备份任务触发信号。

处理逻辑:

● ①应用层:SM4TypeHandler 在写入时对标注字段自动 SM4 加密(SM4V1: 密文前缀+版本标识),读取时按密钥版本自动解密。

● ②数据库层:启用 TDE 后 InnoDB 表空间与 redo log 落盘自动加密(AES-256 或国产加密卡方案),对 SQL 与应用完全透明,无性能感知。

● ③备份层:定时任务整表导出密文 INSERT SQL + manifest(备份时间、表清单、行数、校验值),备份目录独立于数据目录并限制权限。

● ④恢复演练:定期以备份文件恢复到测试库验证可用性。

输出:数据库文件、日志、备份介质全部密文落盘:磁盘被盗或文件被拷走均无法直接读取;应用层敏感字段另有一层国密加密,双层独立、互为冗余。

8.10.8 敏感明文查看的单独权限控制

机制原理:敏感字段(身份证号、联系电话等)的明文查看是独立授权的能力,不随普通查询权限附带:仅具备 data:unmask 权限码(sys_menu.perm_code,经角色授权分配)的账号可查看完整明文,其余账号即使能打开页面也只能看到掩码;每次明文查看实时校验权限并写入敏感访问审计(谁、何时、查了谁、来自哪个 IP),实现「可见即审计、无权即掩码」。

输入:列表/详情查询请求;当前账号的角色-权限码关系;目标记录的敏感字段。

处理逻辑:

● ①DataMaskService.canUnmask 实时查询当前账号是否具备 data:unmask 权限码(角色授权关系表联合查询)。

● ②有权限:返回明文(或经国密解密后的明文),同步写敏感审计日志。

● ③无权限:maskWorkerRow 对身份证号、手机号执行掩码(保留前 3 后 4,中间以 * 填充)后返回,原始明文不出后端。

● ④掩码在服务端完成而非前端隐藏,F12 与直接调接口均拿不到明文。

● ⑤权限分配与回收由机构管理员在角色授权页操作,即时生效。

输出:无权限账号全链路(页面、接口、导出)只能取得掩码值;明文查看 100% 留痕可审计;权限回收后立即回到掩码态。

8.10.9 敏感数据脱敏展示

机制原理:脱敏在服务端响应出口统一执行(DataMaskService),规则按字段类型定义:身份证号保留前 3 后 4、手机号保留前 3 后 4、其余敏感文本按头尾保留中间打星;导出文件(CSV、报告 PDF)与页面列表遵循同一脱敏规则,导出动作同样经过 data:unmask 权限判定,防止「页面掩码、导出明文」的旁路泄露。脱敏输出与加密存储、字段权限三层配合:存储层密文(SM4)、出口层掩码(DataMaskService)、授权层明文(data:unmask + 审计)。

输入:查询结果集(含 idCardEnc、phone 等敏感列);导出请求(CSV/PDF)。

处理逻辑:

● ①响应组装阶段逐行调用 maskWorkerRow:身份证号 maskIdCard(前 3 后 4)、手机号 maskPhone(前 3 后 4)、通用字段 mask(v, head, tail)。

● ②掩码替换发生在后端 Map 组装阶段,明文不出服务端。

● ③导出链路复用同一掩码逻辑并叠加权限判定。

● ④报告 PDF 中身份证号默认掩码展示,明文仅在持 data:unmask 权限且留痕的场景输出。

输出:任何非授权场景下,页面、接口、导出、文书中敏感字段一律为掩码形态;即使页面被截屏、文件被转发,也不泄露完整个人信息。

8.10.10 SM3 业务记录完整性校验(防篡改)

机制原理:对敏感业务记录引入 SM3 密码杂凑完整性校验(Sm3IntegrityService):敏感字段写入时计算其 SM3 摘要存入同表的 gm_digest 摘要列(SM4 密文列与摘要列分离存储);读取时实时重算 SM3 并与存储摘要比对,不一致立即判定记录被篡改并告警阻断。SM3 为国密杂凑算法(GB/T 32905),输出 256 位摘要,抗碰撞性满足完整性校验要求;与审计日志哈希链(SHA-256)形成「业务数据 + 审计数据」双链完整性防护。

输入:敏感业务记录(密文字段值);写请求与读请求;历史 gm_digest 摘要值。

处理逻辑:

● ①写入:字段值经 SM4 加密得密文,密文(或字段规范序串)经 SM3 计算摘要,密文与摘要同事务写入业务表。

● ②读取:读出密文后实时重算 SM3,与 gm_digest 比对——一致则正常解密返回。

● 不一致判定篡改,记录告警事件并阻断该记录返回。

● ③密钥轮换/数据迁移后按摘要批量校验数据一致性。

● ④敏感审计日志另以哈希链防删改,两层独立。

输出:任何对数据库记录的直接修改(绕过应用改库、拖库后改数据、误操作)都会因 SM3 摘要不匹配被发现;数据完整性可证明、可定期体检,篡改可被检测与定位。

第9章 性能设计

9.1 并发性能指标

系统面向中等规模体检机构日常并发(百级在办登记单、数十名并发录入用户)设计:页面操作响应目标 2 秒内;列表查询分页返回(默认每页 10—50 条),杜绝全量数据一次性拉取;统计查询在 SQL 层完成聚合,避免应用层全表计算。

9.2 查询性能优化

● 分页查询统一由 MyBatis-Plus 分页插件执行物理分页;

● 热点查询建立复合索引(登记单状态+日期、操作日志时间等,见表 6-1);

● 列表查询仅取展示字段,详情按需查询;

● 连接池管理数据库连接,避免频繁建连开销。

9.3 批量导入处理机制

劳动者批量导入与团体批量登记在服务端逐行校验、逐行返回结果(成功/失败明细),单批数据量按机构规模配置;导入事务按批次提交,避免超长事务;失败行不阻断成功行入库,修正后可重导。

9.4 大数据量统计优化

汇总统计将聚合下推到 SQL(GROUP BY + 条件索引);CSV 导出采用流式写出,避免内存峰值;报告 PDF 生成与统计查询相互独立,不影响在线业务响应。

9.5 性能指标与容量规划

表 9-1 性能设计指标

| 指标项 | 设计指标 | 保障手段 |

| 登录响应 | ≤ 1.5 秒 | BCrypt 校验与 JWT 签发在毫秒级完成 |

| 列表分页查询 | ≤ 2 秒 | 物理分页 + 复合索引 |

| 登记单创建 | ≤ 1.5 秒 | 序列发号与事务写入 |

| 结果保存 | ≤ 1.5 秒 | 唯一约束校验 + 参考区间判定 |

| 报告 PDF 生成 | ≤ 5 秒 | 数据汇总与 iText 渲染 |

| 汇总统计(万级单据) | ≤ 3 秒 | SQL 聚合下推 + 条件索引 |

| CSV 导出(万级行) | ≤ 10 秒 | 流式写出 |

| 并发用户 | ≥ 100 在线 / 50 并发操作 | 连接池 + 无状态 JWT 水平扩展 |

| 在办登记单容量 | ≥ 50 万张/年 | 分表归档策略:已归档单据转入历史查询通道 |

| 批量导入 | ≥ 1000 人/批 | 分批事务 + 逐行校验 |

9.6 容量测算

表 9-2 存储容量测算

| 数据对象 | 规模假设 | 测算说明 | 容量估算 |

| 劳动者档案 | 10 万份 | 每份 <2KB(密文列) | < 200 MB |

| 体检登记单 | 20 万张/年 | 主表 + 因素关联 + 应检进度 | < 1 GB/年 |

| 检查/检验结果 | 每张单 10—30 条 | 20 万张 → 300—600 万行/年 | 2—4 GB/年(含索引) |

| 报告 PDF | 每份 100—300KB | 10 万份/年 | 10—30 GB/年(文件目录) |

| 操作日志 | 50 万行/年 | 含敏感审计 | < 500 MB/年 |

| 数据库总体 | 三年滚动 | 归档历史单据 | < 15 GB |

9.7 性能验收测试场景

表 9-3 性能验收测试场景

| 场景 | 方法 | 通过标准 |

| 登录并发 | 50 并发持续 5 分钟 | 成功率 100%,平均响应 ≤ 1.5s |

| 登记高频写入 | 模拟 30 用户连续创建登记单 | 编号无重号,平均响应 ≤ 1.5s |

| 列表分页 | 10 万级登记单下翻页查询 | 响应 ≤ 2s |

| 结果录入 | 20 医生并发保存结果 | 无死锁,无版本冲突误报 |

| 报告生成 | 批量触发 50 份 PDF | 全部成功,单份 ≤ 5s |

| 统计与导出 | 四维统计 + 万级 CSV 导出 | 统计 ≤ 3s,导出 ≤ 10s |

第10章 出错处理设计

10.1 异常分类

系统异常分为三类:业务异常(输入不合法、状态流转非法、唯一性冲突、资源不存在等预期内错误)、系统异常(数据库、文件 IO 等运行时错误)、鉴权异常(未登录、令牌过期、无权限、越权访问)。

10.2 业务异常处理

业务异常由统一业务异常类(BizException)承载、全局异常处理器(OccupationalExceptionHandler)统一转换为 { code, message } 响应,前端以消息提示呈现,不暴露堆栈细节;状态机越序、软锁冲突、乐观锁版本冲突等场景给出明确的可操作提示(如刷新后重试)。

10.3 数据库异常与事务回滚

多数据源场景下,本模块事务显式绑定业务事务管理器;跨表写入(登记单+关联表、报告+通知书等)在同一事务内完成,任一步失败整体回滚,杜绝半写状态;序列发号使用原子递增保证编号唯一;数据库连接异常由连接池自动恢复并记录日志。

10.4 前端异常提示

前端对接口非 0 响应统一弹出消息提示(成功/警告/错误分级);表单字段级校验在提交前拦截;文件上传对类型与大小前端预校验;会话过期统一跳转登录页。页面不出现未处理异常白屏,全局错误兜底提示。

10.5 错误码表

统一响应 code 节选如下(业务异常经全局异常处理器转换,前端按码值给出对应操作提示)。

表 10-1 错误码表

| code | 含义 | 处理建议 |

| 0 | 成功 | — |

| 4001 | 参数校验失败 | 按提示修正输入;前后端双重校验 |

| 4002 | 身份证号非法 | 检查格式与校验位 |

| 4003 | 重复建档 | 命中身份证摘要唯一索引,引导关联既有档案 |

| 4010 | 登记单不存在或已删除 | 确认单号 |

| 4011 | 状态流转非法 | 按状态机顺序操作;刷新查看最新状态 |

| 4012 | 登记单被占用 | 软锁持有人正在编辑,稍后重试 |

| 4013 | 版本冲突 | 数据已被他人修改,刷新后重试 |

| 4014 | 存在未完成的必检项目 | 补录后提交 |

| 4020 | 结论已存在 | 结论与登记单一对一 |

| 4021 | 结论未签发 | 先完成审核签发再生成报告 |

| 4022 | 审核职责冲突 | 初审/复审人与主检医师不得相同 |

| 4030 | 文件类型不支持 | 仅 jpg/png/pdf |

| 4031 | 文件超过大小限制 | 单文件 ≤ 10MB |

| 4041 | 账号或密码错误 | 注意失败锁定策略 |

| 4042 | 账号锁定中 | 等待锁定期满 |

| 4043 | 无权限 | 联系管理员授权 |

| 4044 | 跨租户访问被拒绝 | 数据归属校验未通过 |

| 5001 | 系统内部错误 | 联系运维,查看服务日志 |

| 5002 | 数据库操作失败 | 事务已回滚,重试操作 |

10.6 典型异常场景处理对照

表 10-2 典型异常场景处理对照表

| 异常场景 | 系统表现 | 处理方式 |

| 两人同时编辑同一登记单 | 后保存者收到版本冲突提示 | 刷新后基于最新数据修改再提交,先保存者修改不丢失 |

| 医生领单后离岗未退单 | 登记单被软锁占用 | 锁超时自动释放;管理员可强制释放并留痕 |

| 录入值超出参考区间但属个体差异 | 系统标记异常 | 保留系统判定,主检小结中说明临床解释 |

| 批量导入 500 行中 12 行失败 | 返回成功/失败明细 | 按失败原因修正后仅重导失败行 |

| 结论签发后发现某项结果录错 | 报告与结论需要更正 | 更正结果→重新出具结论→审核签发→重出报告(版本+1),全链路留痕 |

| 报告生成时文件目录不可写 | 生成失败报错 | 检查磁盘与权限后重试;数据库记录不产生半写 |

| 上传非 PDF/图片附件 | 前端预校验+后端白名单拦截 | 转换格式后重传 |

| 同一身份证重复导入 | SHA-256 唯一索引拦截 | 关联既有档案,补充本次接害信息 |

| 加密开启后部分历史数据明文 | 读取时按前缀识别 | 按维护任务批量加密回填,期间功能不受影响 |

| SM3 校验提示不一致 | 字段完整性告警 | 核查是否绕过系统直接改库,恢复后重算摘要 |

| 用户误停用自己的唯一管理员 | 机构失去管理入口 | 平台超管重置机构管理员账号 |

| 检验 LIS 适配器连通失败 | 适配器测试接口报错 | 检查适配器配置(地址/凭证),测试通过后恢复导入 |

| 统计页打开缓慢 | 数据量增长 | 缩小日期区间;归档历史单据走历史通道 |

| 导出 CSV 用文本工具打开乱码 | 编码显示问题 | 使用 Excel 直接打开(UTF-8 BOM 已内置) |

| 服务器重启后服务未自启 | 站点不可访问 | 按运维手册启动主服务,检查 8080 健康接口 |

10.7 前端输入校验规则清单

表 10-3 前端输入校验规则清单

| 输入项 | 校验规则 |

| 身份证号 | 18 位格式 + 校验位算法;自动解析出生日期与性别 |

| 口令 | 登录必填;修改/重置符合长度要求;不回显 |

| 手机号 | 11 位格式;列表脱敏展示 |

| 数值结果 | 数值范围与精度限制;超参考区间自动判异常 |

| 日期 | 登记日期不晚于当日;区间查询起≤止 |

| 文件上传 | 扩展名白名单 jpg/png/pdf;单文件 ≤ 10MB |

| 编码类字段 | 唯一性即时校验;特殊字符过滤 |

| 必选下拉 | 套餐/因素/类别等提交前非空校验 |

第11章 系统维护设计

11.1 数据备份机制

数据库每日定时全量备份(mysqldump),备份文件异地目录保存;报告、通知书与附件文件目录定时增量备份;SM4 密钥文件单独备份并限制访问权限。恢复操作纳入运维规程并定期演练。

11.2 系统参数可视化配置

机构名称、体检指南、登录页底图等系统参数由「系统设置」页面在线维护(管理员可编辑、医生只读);国密开关、算法与密钥由「数据安全」页面在线配置,运行期即时生效,无需重启服务;报告模板由「报告模板」页面配置。

11.3 日志留存管理

操作日志与敏感访问审计日志持久化存储,仅增不改不删;日志支持按时间检索与导出,留存周期按机构合规要求配置;日志表时间索引保障长期积累后的检索性能。

11.4 版本管理

系统内置版本接口(GET /api/occupational-exam/version)与「版本记录」页面,登记每次发布的功能变更;报告重出采用版本化管理(version 递增、历史留存),保证文书可追溯。

版本号管理机制:当前版本 V2.5.0030(版本库登记时间 2026-10-03 02:33:11)。版本号唯一真源为版本登记表 tool_versions(工具标识 occupational_exam),由平台按发布内容指纹自动递增,杜绝人工虚报;每次发版在版本更新记录表 sys_version_log 中逐条登记(版本号、更新内容、日期),「版本记录」页面直接展示该表内容。版本更新记录明细如下:

表 11-2 版本更新记录明细(摘自 sys_version_log)

| 版本号 | 更新内容 | 日期 |

| V2.5.0030 | 数据安全新增国密加密可选功能(SM2/SM3/SM4) | 2026-10-03 |

| V2.5.0029 | 菜单与角色授权改为按页面模块授权 | 2026-10-03 |

| V2.5.0028 | 全站列表统一改为点名称打开编辑框 | 2026-10-03 |

| V2.5.0027 | 体检登记改为点姓名打开编辑框 | 2026-10-03 |

| V2.5.0019 | 报告智能解读模块上线 | 2026-09-30 |

| V2.5.0018 | 医生管理迁入科室编辑栏 + 医生原笔迹手写签名模板 | 2026-09-30 |

| V2.5.0017 | 检查项目数据字典扩充(八大类 576 项) | 2026-09-30 |

| V2.5.0016 | 科室管理双击编辑栏 + 检查项目勾选分配 | 2026-09-29 |

| V2.5.0015 | 基础档案迁入系统设置 + 新增体检科 + 套餐编号 | 2026-09-29 |

| V2.5.0014 | 新增「体检模块库」基础框架 | 2026-09-29 |

| V2.5.0013 | 科室录入明确显示受检者对象 | 2026-09-29 |

| V2.5.0012 | 团体预约批量生成员工检查指引单 | 2026-09-29 |

| V2.5.0011 | 科室录入修复登记单不存在 | 2026-09-29 |

| V2.5.0010 | 个人档案新增年龄/住址/电话 | 2026-09-29 |

| V2.5.0009 | 体检指南支持后台配置 | 2026-09-28 |

| V2.5.0008 | 体检指南内容补充 | 2026-09-28 |

| V2.5.0007 | 新增体检指南页面 | 2026-09-28 |

| V2.5.0006 | 个人体检与单位员工分类 | 2026-09-28 |

| V2.5.0005 | 单位编辑新增银行信息 | 2026-09-28 |

| V2.5.0004 | 菜单名称调整 | 2026-09-28 |

| V2.5.0003 | 团体预约按单位过滤 | 2026-09-28 |

| V2.5.0002 | 团体预约页修复 | 2026-09-28 |

| V2.5.0001 | 导检与总检派单修复 | 2026-09-28 |

| V2.5.0000 | 总检多级审核、派单与匿名体检 | 2026-09-28 |

| V2.4.0000 | 第三方接口配置 | 2026-09-28 |

| V2.3.0000 | 界面重构:导航折叠与单页化 | 2026-09-28 |

| V2.2.0000 | 模块级权限基座 | 2026-09-28 |

| V2.1.0000 | 财务结算与报告模板:收费/退费/发票/日结月结 + 多套报告模板自动适配 | 2026-09-28 |

| V2.0.0000 | 重大扩充:体检业务全流程模块落地 | 2026-09-28 |

| V1.2.0005 | 新增版本记录页面 | 2026-09-28 |

| V1.2.0004 | 权限体系修正与安全加固 | 2026-09-28 |

| V1.2.0003 | 登录页与系统稳定性优化 | 2026-09-27 |

| V1.2.0002 | 国家标准知识库接入 | 2026-09-27 |

| V1.2.0001 | 业务模块补齐 | 2026-09-26 |

| V1.1.0000 | 基础版本上线 | 2026-09-26 |

11.5 发布与升级操作规程

● 升级前:备份业务库(mysqldump 全量)、备份当前运行 jar 与前端产物、备份密钥文件;

● 执行升级:替换部署包(先本地验证),执行增量 SQL 迁移脚本,重启服务并做健康检查(登录接口、核心列表接口);

● 升级后:回归核心链路(登记→录入→审核→报告),核对版本接口返回值与版本记录页登记内容一致;

● 回滚预案:升级失败立即回退备份包与备份库,密钥文件不动,保证数据可恢复。

11.6 日常运维清单

表 11-1 日常运维任务清单

| 周期 | 运维任务 | 要求 |

| 每日 | 检查服务健康(8080 健康接口、登录接口) | 异常告警即处置 |

| 每日 | 数据库全量备份执行与结果核对 | 备份失败当日补做 |

| 每周 | 文件目录(报告/附件)增量备份 | 抽查恢复可读 |

| 每周 | 操作日志抽查(异常登录、越权记录) | 发现异常上报 |

| 每月 | 备份恢复演练(抽样库恢复到临时实例) | 验证备份有效性 |

| 每月 | 磁盘空间与慢查询核查 | 容量低于 20% 扩容 |

| 每季 | 密钥指纹核对与权限复核(账号/角色/字段权限) | 冗余权限回收 |

| 每季 | 依赖组件安全通告核查 | 按需升级补丁 |

11.7 故障应急处理预案

表 11-2 故障应急处理预案

| 故障场景 | 应急措施 |

| 服务无响应/8080 不通 | 查看服务日志定位(数据库连接/端口占用);重启主服务;必要时回退最近备份包 |

| 数据库不可用 | 检查 MySQL 进程与磁盘空间;恢复备份库;恢复后核对序列表与单据完整性 |

| 报告 PDF 生成失败 | 检查文件目录空间与写权限;失败单据重试;不影响登记录入主流程 |

| 密钥文件异常 | 立即停止加密开关(明文模式保业务);从备份恢复密钥文件并核对指纹;恢复后重新开启 |

| 误操作数据 | 以操作日志定位误操作范围;从最近备份恢复相关数据;补记审计说明 |

| 前端页面异常 | 回退前端构建产物备份;静态资源缓存刷新 |

第12章 附录

附录A 界面原型图汇总

以下界面原型图与系统实际页面布局一致(示意数据),供界面说明与验收对照。

图 12-1 系统登录页界面原型

登录页左侧为系统形象区,右侧为账号密码登录表单;连续失败触发账号锁定策略。

图 12-2 工作台界面原型

工作台展示今日登记、检查中、待审核、本月已完成四项核心指标与在办单据列表,登记单状态实时跟踪。

图 12-3 体检登记页界面原型

登记页提供新建登记、团体批量登记入口与多条件检索;列表展示登记单号、套餐、状态与领单人。

图 12-4 科室结果录入页界面原型

左侧为科室待检队列,右侧为应检项目录入表格;数值型结果自动比对参考区间,异常项自动标红。

图 12-5 总检审核工作台界面原型

审核工作台列出待初审/待复审任务,展示主检小结,支持初审通过、退回修改、复审签发操作。

图 12-6 报告中心界面原型

报告中心按报告号/状态检索,支持预览、下载、批量导出;报告版本化管理。

图 12-7 汇总报表界面原型

汇总报表提供状态/结论/单位/危害因素四维度统计与合格率计算,支持 CSV 导出。

图 12-8 数据安全(国密配置)界面原型

数据安全页集中管理国密加密开关、SM4 密钥指纹、SM3/SM2 状态与敏感访问审计记录。

附录B 数据字典简表

系统数据表与字段全量结构见第 6.3 节,此处列示核心业务表速查。

表 12-1 数据表速查(全量表结构见 6.3)

| 表名 | 说明 | 字段数 |

| biz_adapter_config | 第三方接口适配器配置 | 14 |

| sys_attach | 附件(病历/委托资料等,挂登记单号) | 10 |

| base_dept | 科室(设计方案 模块2 基础档案) | 6 |

| base_dict | 字典(体检类别/结论类型/录入快捷短语等,设计方案 模块1 系统管理-字典) | 6 |

| biz_conclusion | Conclusion | 14 |

| biz_conclusion_audit | 总检多级审核流水:每级审核(提交/通过/打回/签发)留痕 | 10 |

| biz_conclusion_task | 总检派单任务池:已检完待总检的登记单 + 指派主检医师 | 12 |

| doctor_sign_template | 医生原笔迹手写签名模板 | 13 |

| biz_employer | Employer | 9 |

| base_exam_item | ExamItem | 16 |

| exam_item_knowledge | 检查项目解读知识库:参考上下限、异常分级阈值、自动解读文案、健康指导建议。

命中优先级:绝对值阈值(mild/mod/crit) > 百分比偏离(mild_pct/mod_pct) > 兜底规则。 | 30 |

| base_package | ExamPackage | 7 |

| biz_register | 体检登记单(核心单据):状态机 + 乐观锁 + 行级软锁 | 17 |

| exam_report_interpret | 报告智能解读主表(当前版本)。

状态机:NOT_GENERATED →(生成)→ AUTO_PENDING | PENDING_REVIEW

AUTO_PENDING / PENDING_REVIEW →(复核通过)→ REVIEWED

AUTO_PENDING / PENDING_REVIEW →(驳回)→ REJECTED →(重新生成)→ AUTO_PENDING | PENDING_REVIEW

REVIEWED →(报告归档)→ LOCKED(终态,禁止任何写入) | 24 |

| exam_report_interpret_log | 解读操作日志:初稿与终稿内容、生成/复核时间、操作医生、操作类型,永久留痕。

数据库层已加 BEFORE DELETE 触发器禁止删除,应用层同样不提供删除接口。 | 18 |

| biz_exam_result | ExamResult | 13 |

| biz_exam_result_amend | 科室检查结果「归档后修订」记录表。

业务规则(需求⑤):已归档的体检记录被修改时,原记录(biz_exam_result)不得删除或更改,

必须继续保存在数据库中以备查阅;本次修改只新增一条「替换显示」的修订记录。

同一 (register_id, item_id) 允许多次修订,版本号 revision 自增,display 取最新版本。

original_result_id 指向被修订的原始 biz_exam_result.id,用于溯源审计。 | 15 |

| base_hazard_factor | HazardFactor | 8 |

| biz_lab_result | 检验结果(设计方案 模块6:手工录入 + 导入预留,参考区间快照 + 异常自动判定) | 11 |

| biz_notice | 通知书(复查/转诊/调离) | 8 |

| sys_oper_log | OperLog | 10 |

| base_package_item | 套餐-项目关联(套餐精确过滤的依据) | 3 |

| biz_register_hazard | RegisterHazard | 3 |

| biz_report | 体检报告(签发后生成 PDF,重出报告 version+1 保留旧版) | 9 |

| biz_review_config | 多级审核级别配置:可按模块扩展(默认 CONCLUSION 总检,1/2/3 级) | 6 |

| seq_rule | 单据号序列(发号用 SELECT ... FOR UPDATE 行锁保证不重复) | 2 |

| base_std_disease | 法定职业病病种目录(2025 版 135 种,含开放性条款与限定范围)。 | 14 |

| base_std_disease_category | 职业病大类目录(国家卫健委 2025 版《职业病分类和目录》12 大类)。 | 11 |

| base_std_exam_item | 标准检查项目明细(GBZ 188 必检/选检),隶属 base_std_exam_rule。 | 10 |

| base_std_exam_rule | 职业健康检查规则(GBZ 188):因素 × 检查类别(岗前/在岗/离岗/应急)。

周期多为条件式表述,exam_cycle_months 可能为 NULL,完整原文见 remark。 | 13 |

| base_std_hazard | 接害因素标准档案(GBZ 188 职业健康监护技术规范)。

hazard_code 沿用标准条款号(如 6.1 / 7.1),导入业务表时直接作为 factor_code,保持双向可关联。 | 17 |

| base_std_hazard_disease | 危害因素 ↔ 法定职业病病种关联。 | 7 |

| sys_menu | 菜单(1=菜单 2=按钮) | 8 |

| sys_role | 角色 | 5 |

| sys_role_menu | 角色-菜单授权 | 3 |

| sys_tenant | 租户(体检机构) | 8 |

| sys_user | SysUser | 13 |

| biz_worker | Worker | 14 |

附录C 国密算法应用说明

SM4(分组密码,GB/T 32907):用于敏感字段加密存储。系统以 SM4-ECB 模式加密(固定初始向量用于字段级确定性加密,支持等值检索的密文索引场景),密文以 SM4V1: 前缀标识版本;密钥由密钥文件统一管理,支持多版本轮换。

SM3(密码杂凑,GB/T 32905):用于敏感字段完整性校验。写入时计算原文摘要存 gm_digest 列;读取时重算比对,不一致即标记完整性异常,实现防篡改监测。

SM2(椭圆曲线公钥密码,GB/T 32918):用于报告签发等关键场景的数字签名。私钥由密钥管理器保管,公钥可分发验证方核验签发来源与数据完整性。

开关策略:三种算法均可由管理员独立开关;加密关闭时类型处理器与响应处理直接透传,业务功能不受影响;加密开启后新写入数据即时加密,存量数据可由维护任务批量加密回填。

附录D 业务表单样例

体检登记单样例要素:登记单号(TJyyyyMMdd-nnnnnn)、姓名、性别、出生日期、身份证号(掩码)、用人单位、工种、接害工龄、体检类别、接害因素、套餐、登记日期、登记员。

表单要素说明(体检登记单):

表 12-2 体检登记单要素明细

| 序号 | 要素 | 说明/取值来源 |

| 1 | 登记单号(TJyyyyMMdd-nnnnnn) | TJyyyyMMdd-nnnnnn |

| 2 | 姓名 | — |

| 3 | 性别 | — |

| 4 | 出生日期 | — |

| 5 | 身份证号(掩码展示) | 掩码展示 |

| 6 | 用人单位 | — |

| 7 | 工种 | — |

| 8 | 接害工龄(年) | 年 |

| 9 | 体检类别(上岗前/在岗/离岗/应急) | 上岗前/在岗/离岗/应急 |

| 10 | 接害因素(多选) | 多选 |

| 11 | 体检套餐(PKG 编号) | PKG 编号 |

| 12 | 登记日期 | — |

| 13 | 登记员 | — |

| 14 | 状态 | — |

| 15 | 备注 | — |

表单要素说明(职业健康检查报告):

表 12-3 职业健康检查报告要素明细

| 序号 | 要素 | 说明/取值来源 |

| 1 | 报告编号(REP 序列) | REP 序列 |

| 2 | 报告版本号 | — |

| 3 | 劳动者基本信息 | — |

| 4 | 用人单位与工种 | — |

| 5 | 接害因素与接害工龄 | — |

| 6 | 体检类别 | — |

| 7 | 各科室检查结果(含项目名快照) | 含项目名快照 |

| 8 | 检验结果(数值/单位/参考区间快照) | 数值/单位/参考区间快照 |

| 9 | 异常项汇总 | — |

| 10 | 主检小结 | — |

| 11 | 结论类型(四类) | 四类 |

| 12 | 复查项目建议(如有) | 如有 |

| 13 | 主检医师签名 | — |

| 14 | 审核医师签名 | — |

| 15 | 签发时间 | — |

| 16 | 机构名称 | — |

表单要素说明(复查通知书):

表 12-4 复查通知书要素明细

| 序号 | 要素 | 说明/取值来源 |

| 1 | 通知书编号(NTC 序列) | NTC 序列 |

| 2 | 劳动者信息 | — |

| 3 | 体检登记单号 | — |

| 4 | 原体检结论 | — |

| 5 | 复查项目清单 | — |

| 6 | 复查期限要求 | — |

| 7 | 机构名称与联系方式 | — |

| 8 | 出具日期 | — |

附录E 随访与周期体检预警规则

表 12-4 随访与到期预警规则

| 环节 | 规则 |

| 复查名单提取 | 汇总报表按结论类型=复查筛选,输出劳动者、单位、因素、复查项目建议与联系方式(脱敏) |

| 复查通知书送达 | 结论签发即自动生成复查通知书 PDF,登记员下载后送达用人单位/劳动者 |

| 复检登记 | 复检按新登记单走全流程,档案与接害因素沿用,结果与原单可对照 |

| 周期体检到期预警 | 按「劳动者最近体检日期 + 接害因素检查周期(月)」滚动计算,输出即将到期(30 天内)与已到期名单 |

| 疑似职业病转诊 | 结论为疑似职业病时自动生成转诊建议书,提示职业病诊断机构鉴定流程 |

| 职业禁忌证调离 | 结论为职业禁忌证时自动生成调离通知书,提示用人单位调离相应作业岗位 |

| 危急值闭环 | 质控页登记危急值→通知医生→处理→确认闭环,未闭环持续警示 |

附录F GBZ 188 危害因素与必检项目对照表

系统种子数据按 GBZ 188-2014 初始化的因素-目标疾病-检查周期-依据条款-必检项目对照如下(机构可在国家标准库中扩展):

表 12-5 GBZ 188 因素与必检项目对照

| 危害因素 | 目标疾病 | 检查周期 | 依据条款 | 必检项目(种子配置) |

| 粉尘(矽尘等)F01 | 职业性尘肺病 | 12 个月 | GBZ188-2014 4.1 | 内科检查、外科检查、胸部X线(高千伏)、肺功能、血常规 |

| 噪声 F02 | 职业性噪声聋 | 12 个月 | GBZ188-2014 8.1 | 内科检查、电测听、纯音听力(左)、纯音听力(右)、血常规 |

| 苯 F03 | 职业性苯中毒 / 职业性苯中毒所致白血病 | 12 个月 | GBZ188-2014 5.1 | 内科检查、血常规、肝功能 |

| 铅 F04 | 职业性铅中毒 | 12 个月 | GBZ188-2014 5.2 | 内科检查、血常规、肝功能、尿铅(参考区间 0—0.07 mg/L) |

| 高温 F05 | 中暑 | 12 个月 | GBZ188-2014 9.1 | 内科检查为主,按规范结合心电图等项目配置 |

附录G 界面控件说明

第 12 章附录 A 与第 5 章各界面原型图中的主要控件与交互说明如下:

登录页控件:

● 账号输入框:必填,长度 2—50;

● 密码输入框:必填,遮盖显示;

● 登录按钮:提交认证,失败提示并累计失败次数;

● 锁定提示区:连续失败达阈值后展示剩余锁定时间。

工作台控件:

● 指标卡片×4:今日登记、检查中、待审核、本月已完成(实时聚合);

● 在办单据表:登记单号/姓名/类别/状态/当前科室/操作;

● 快捷入口:登记、录入、审核、报告。

体检登记页控件:

● 工具栏:新建登记、团体批量登记;

● 检索区:登记单号/姓名/身份证、体检类别、状态、日期区间;

● 登记单列表:单号、姓名、单位、工种、套餐、状态、领单人;行内操作:查看/编辑/流转。

科室录入页控件:

● 左侧待检队列:本科室按状态过滤,点击选中;

● 右侧录入表格:应检项目、结果输入(文本框/数值框)、参考区间、判定(自动);

● 操作按钮:保存、提交完成(校验必检项完整性)。

总检审核工作台控件:

● 任务列表:登记单号、姓名、结论类型、主检医师、审核环节、状态;

● 结论详情区:主检小结、异常项汇总、复查建议;

● 操作按钮:初审通过、退回修改(必填意见)、复审签发。

报告中心控件:

● 检索区:报告号/登记单号、状态、日期;

● 报告列表:报告号、登记单号、姓名、结论、版本、签发时间;

● 操作:预览(内嵌 PDF)、下载、重出(版本 +1 确认)。

汇总报表控件:

● 维度切换页签:状态/结论/单位/危害因素;

● 过滤区:日期区间、单位、因素;

● 统计表格:各维度人数分布与合格率;导出 CSV 按钮。

数据安全页控件:

● 加密开关:SM4 开启/关闭(保存即时生效);

● 密钥信息区:密钥文件、版本数、激活标识、指纹;

● SM3/SM2 状态区:校验开关、签名开关与密钥对状态;

● 敏感访问审计表:时间、操作人、操作、对象、结果。

附录I 角色-菜单可见性矩阵

按默认授权策略的角色-菜单可见性矩阵如下(1 可见,0 不可见;机构可按授权页自定义调整):

表 12-7 角色-菜单可见性矩阵

| 角色 | 工作台 | 劳动者档案 | 单位体检 | 体检指南 | 团体预约 | 体检登记 | 科室录入 | 主检结论 | 总检审核 | 报告中心 | 报告解读/知识库 | 通知书 | 附件管理 | 汇总报表 | 基础档案 | 国家标准/项目规则 | 质控/收费 | 用户/菜单授权 | 租户管理 | 操作日志/数据安全 | 系统设置 |

| 工作台 | 1 | 1 | 1 | 1 | 1 | | | | | | | | | | | | | | | | |

| 劳动者档案 | 1 | 1 | 1 | 1 | 1 | | | | | | | | | | | | | | | | |

| 单位体检 | 1 | 1 | 1 | 1 | 1 | | | | | | | | | | | | | | | | |

| 体检指南 | 1 | 1 | 1 | 1 | 1 | | | | | | | | | | | | | | | | |

| 团体预约 | 1 | 1 | 1 | 1 | 1 | | | | | | | | | | | | | | | | |

| 体检登记 | 1 | 1 | 1 | 1 | 1 | | | | | | | | | | | | | | | | |

| 科室录入 | 1 | 1 | 1 | 1 | 0 | | | | | | | | | | | | | | | | |

| 主检结论 | 1 | 1 | 1 | 0 | 0 | | | | | | | | | | | | | | | | |

| 总检审核 | 1 | 1 | 1 | 0 | 0 | | | | | | | | | | | | | | | | |

| 报告中心 | 1 | 1 | 1 | 0 | 0 | | | | | | | | | | | | | | | | |

| 报告解读/知识库 | 1 | 1 | 1 | 0 | 0 | | | | | | | | | | | | | | | | |

| 通知书 | 1 | 1 | 1 | 0 | 0 | | | | | | | | | | | | | | | | |

| 附件管理 | 1 | 1 | 1 | 1 | 1 | | | | | | | | | | | | | | | | |

| 汇总报表 | 1 | 1 | 1 | 0 | 0 | | | | | | | | | | | | | | | | |

| 基础档案 | 1 | 1 | 0 | 0 | 0 | | | | | | | | | | | | | | | | |

| 国家标准/项目规则 | 1 | 1 | 0 | 0 | 0 | | | | | | | | | | | | | | | | |

| 质控/收费 | 1 | 1 | 1 | 0 | 0 | | | | | | | | | | | | | | | | |

| 用户/菜单授权 | 1 | 1 | 0 | 0 | 0 | | | | | | | | | | | | | | | | |

| 租户管理 | 1 | 0 | 0 | 0 | 0 | | | | | | | | | | | | | | | | |

| 操作日志/数据安全 | 1 | 1 | 0 | 0 | 0 | | | | | | | | | | | | | | | | |

| 系统设置 | 1 | 1 | 0 | 0 | 0 | | | | | | | | | | | | | | | | |

附录K 报告 PDF 版式说明

个人职业健康检查报告 PDF 版面自上而下分为六个区:

表 12-9 报告 PDF 版面分区说明

| 分区 | 内容 | 数据来源 |

| 抬头区 | 机构名称(系统参数)、报告编号、报告版本 | sys 参数 / biz_report |

| 基本信息区 | 姓名、性别、年龄、身份证号(掩码)、单位、工种、接害因素、接害工龄、体检类别 | biz_worker / biz_register / biz_register_hazard |

| 检查结果区 | 各科室检查结果明细、检验结果(数值/单位/参考区间/异常标记) | biz_exam_result / biz_lab_result |

| 结论区 | 主检小结、结论类型、复查建议、职业禁忌证提示 | biz_conclusion |

| 签署区 | 主检医师签名(签名模板)、审核医师、签发日期 | doctor_sign_template / biz_conclusion |

| 页脚区 | 页码、机构联系方式 | 系统参数 |

附录L 职业健康专业名词说明

表 12-10 专业名词说明

| 名词 | 说明 |

| 职业禁忌证 | 劳动者从事特定职业病危害作业时所存在的、可能导致职业病发生或病情加重的医学禁忌情形 |

| 疑似职业病 | 检查发现与接触的职业病危害因素密切相关的健康损害,需提交职业病诊断机构进一步诊断 |

| 离岗时健康检查 | 劳动者脱离接害作业岗位时进行的职业健康检查 |

| 应急健康检查 | 发生急性职业病危害事故后对接触者进行的紧急健康检查 |

| 上岗前健康检查 | 拟从事接触职业病危害因素作业的新录用人员(含转岗)的岗前检查 |

| 在岗期间健康检查 | 对在岗接害人员按规范周期进行的定期健康检查 |

| 高频听力下降 | 噪声作业职业健康检查中的常见异常,纯音听力检查高频段听阈升高 |

| 接害工龄 | 劳动者接触职业病危害因素的累计工作年限 |

附录M 版本发布记录(摘自版本更新记录表)

以下为系统全部版本更新记录,与「版本记录」页面展示内容一致:

表 12-12 版本发布记录

| 版本号 | 日期 | 发布内容 |

| V2.5.0030 | 2026-10-03 | 数据安全新增国密加密可选功能(SM2/SM3/SM4) |

| V2.5.0029 | 2026-10-03 | 菜单与角色授权改为按页面模块授权 |

| V2.5.0028 | 2026-10-03 | 全站列表统一改为点名称打开编辑框 |

| V2.5.0027 | 2026-10-03 | 体检登记改为点姓名打开编辑框 |

| V2.5.0019 | 2026-09-30 | 报告智能解读模块上线 |

| V2.5.0018 | 2026-09-30 | 医生管理迁入科室编辑栏 + 医生原笔迹手写签名模板 |

| V2.5.0017 | 2026-09-30 | 检查项目数据字典扩充(八大类 576 项) |

| V2.5.0016 | 2026-09-29 | 科室管理双击编辑栏 + 检查项目勾选分配 |

| V2.5.0015 | 2026-09-29 | 基础档案迁入系统设置 + 新增体检科 + 套餐编号 |

| V2.5.0014 | 2026-09-29 | 新增「体检模块库」基础框架 |

| V2.5.0013 | 2026-09-29 | 科室录入明确显示受检者对象 |

| V2.5.0012 | 2026-09-29 | 团体预约批量生成员工检查指引单 |

| V2.5.0011 | 2026-09-29 | 科室录入修复登记单不存在 |

| V2.5.0010 | 2026-09-29 | 个人档案新增年龄/住址/电话 |

| V2.5.0009 | 2026-09-28 | 体检指南支持后台配置 |

| V2.5.0008 | 2026-09-28 | 体检指南内容补充 |

| V2.5.0007 | 2026-09-28 | 新增体检指南页面 |

| V2.5.0006 | 2026-09-28 | 个人体检与单位员工分类 |

| V2.5.0005 | 2026-09-28 | 单位编辑新增银行信息 |

| V2.5.0004 | 2026-09-28 | 菜单名称调整 |

| V2.5.0003 | 2026-09-28 | 团体预约按单位过滤 |

| V2.5.0002 | 2026-09-28 | 团体预约页修复 |

| V2.5.0001 | 2026-09-28 | 导检与总检派单修复 |

| V2.5.0000 | 2026-09-28 | 总检多级审核、派单与匿名体检 |

| V2.4.0000 | 2026-09-28 | 第三方接口配置 |

| V2.3.0000 | 2026-09-28 | 界面重构:导航折叠与单页化 |

| V2.2.0000 | 2026-09-28 | 模块级权限基座 |

| V2.1.0000 | 2026-09-28 | 财务结算与报告模板:收费/退费/发票/日结月结 + 多套报告模板自动适配 |

| V2.0.0000 | 2026-09-28 | 重大扩充:体检业务全流程模块落地 |

| V1.2.0005 | 2026-09-28 | 新增版本记录页面 |

| V1.2.0004 | 2026-09-28 | 权限体系修正与安全加固 |

| V1.2.0003 | 2026-09-27 | 登录页与系统稳定性优化 |

| V1.2.0002 | 2026-09-27 | 国家标准知识库接入 |

| V1.2.0001 | 2026-09-26 | 业务模块补齐 |

| V1.1.0000 | 2026-09-26 | 基础版本上线 |

附录N 交付与验收清单

表 12-13 交付与验收清单

| 验收类别 | 验收内容 | 通过标准 |

| 功能验收 | 按第 5 章十二模块逐项演示:建档、导入、登记、录入、审核、报告、统计、权限、日志、加密 | 全流程无阻断 |

| 性能验收 | 登录、列表、登记、报告生成响应时间按表 9-1 抽测 | 满足指标 |

| 安全验收 | 按 8.8 基线清单逐项核对(口令、锁定、脱敏、日志、密钥权限、上传白名单等 20 项) | 全部符合 |

| 数据验收 | 建表脚本执行成功;种子数据完整;租户隔离抽测(跨租户访问被拒) | 核对通过 |

| 报告验收 | 四类结论报告 PDF 与三类通知书版式要素按附录 D 核对 | 要素齐全 |

| 恢复验收 | 备份恢复演练:库恢复 + 文件恢复 + 登录验证 | 可恢复 |

职业健康检查报告样例要素:报告编号(REP 序列)、基本信息、用人单位与工种、接害因素与工龄、各科室检查结果与检验结果、异常项汇总、主检小结与结论类型、主检医师与审核医师签名、签发时间、版本号。

复查通知书样例要素:通知书编号(NTC 序列)、劳动者信息、体检结论、复查项目、复查期限、机构联系方式;转诊建议书与调离通知书要素类似,按结论类型区分处置要求。

版本更新记录(实时)

加载中…