# 数据模型详解 **本文档引用的文件** - [models.py](file://backend/app/models/models.py) - [finance.py](file://backend/app/models/finance.py) - [schemas.py](file://backend/app/schemas/schemas.py) - [database.py](file://backend/app/core/database.py) - [config.py](file://backend/app/core/config.py) - [init_db.py](file://backend/init_db.py) - [assessment_service.py](file://backend/app/services/assessment_service.py) - [salary_service.py](file://backend/app/services/salary_service.py) - [staff_service.py](file://backend/app/services/staff_service.py) - [indicator_service.py](file://backend/app/services/indicator_service.py) - [001_initial.py](file://backend/alembic/versions/001_initial.py) - [002_template.py](file://backend/alembic/versions/002_template.py) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构概览](#架构概览) 5. [详细组件分析](#详细组件分析) 6. [依赖分析](#依赖分析) 7. [性能考虑](#性能考虑) 8. [故障排除指南](#故障排除指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向医院绩效系统的核心数据模型,系统化阐述 Department、Staff、Assessment、AssessmentDetail、SalaryRecord 等关键实体的设计理念、字段定义、数据类型与约束条件,并深入解析模型间的关系映射、级联操作与数据完整性保障机制。同时,结合服务层业务逻辑,给出数据验证规则、业务规则实现、性能优化策略、模型扩展指南以及版本兼容与迁移策略,帮助开发者与运维人员高效理解与维护该数据模型。 ## 项目结构 后端采用 SQLAlchemy ORM + Alembic 迁移的架构,模型集中于 models 模块,配合 Pydantic 的数据模式(schemas)进行输入输出校验;数据库连接通过异步引擎与会话工厂实现;迁移脚本确保数据库结构演进的可控性。 ```mermaid graph TB subgraph "模型层" M1["models.py
核心业务模型"] M2["finance.py
财务核算模型"] end subgraph "数据模式层" S1["schemas.py
Pydantic模式"] end subgraph "基础设施层" C1["config.py
配置"] D1["database.py
数据库连接"] end subgraph "迁移层" V1["001_initial.py
初始版本"] V2["002_template.py
模板版本"] end subgraph "服务层" A1["assessment_service.py"] S2["salary_service.py"] ST1["staff_service.py"] I1["indicator_service.py"] end M1 --> S1 M2 --> S1 C1 --> D1 V1 --> M1 V2 --> M1 A1 --> M1 S2 --> M1 ST1 --> M1 I1 --> M1 ``` **图表来源** - [models.py](file://backend/app/models/models.py#L62-L230) - [finance.py](file://backend/app/models/finance.py#L45-L74) - [schemas.py](file://backend/app/schemas/schemas.py#L1-L743) - [database.py](file://backend/app/core/database.py#L9-L39) - [config.py](file://backend/app/core/config.py#L9-L47) - [001_initial.py](file://backend/alembic/versions/001_initial.py#L21-L183) - [002_template.py](file://backend/alembic/versions/002_template.py#L21-L96) **章节来源** - [models.py](file://backend/app/models/models.py#L1-L438) - [finance.py](file://backend/app/models/finance.py#L1-L79) - [schemas.py](file://backend/app/schemas/schemas.py#L1-L743) - [database.py](file://backend/app/core/database.py#L1-L39) - [config.py](file://backend/app/core/config.py#L1-L47) - [001_initial.py](file://backend/alembic/versions/001_initial.py#L1-L183) - [002_template.py](file://backend/alembic/versions/002_template.py#L1-L96) ## 核心组件 本节聚焦五个关键模型的字段定义、数据类型、约束条件与业务含义。 - Department(科室信息) - 字段与类型:自增主键、字符串名称与编码(唯一)、枚举类型、层级、排序、启用状态、描述、时间戳 - 约束:编码唯一;索引覆盖类型与父级 - 关系:自关联父子关系;一对多到 Staff - 业务意义:支撑组织架构与层级管理 - Staff(员工信息) - 字段与类型:唯一工号、姓名、所属科室外键、职位、职称、联系方式、基本工资、绩效系数、状态、入职日期、时间戳 - 约束:工号唯一;索引覆盖科室与状态 - 关系:多对一到 Department;一对多到 Assessment、SalaryRecord - 业务意义:员工档案与薪酬基础数据 - Assessment(考核记录) - 字段与类型:员工外键、考核年月、周期类型、总分、加权得分、状态、考核人/审核人外键、时间戳、备注 - 约束:复合索引覆盖员工、年月、状态;级联删除明细 - 关系:多对一到 Staff;一对多到 AssessmentDetail - 业务意义:记录单次考核的聚合结果与流转状态 - AssessmentDetail(考核明细) - 字段与类型:考核记录外键、指标外键、实际值、得分、佐证材料、备注、时间戳 - 约束:明细索引覆盖考核与指标 - 关系:多对一到 Assessment、Indicator - 业务意义:承载具体指标的得分与证据 - SalaryRecord(工资核算记录) - 字段与类型:员工外键、年月、基本工资、绩效得分、绩效奖金、扣款、补贴、应发工资、状态、备注、时间戳 - 约束:索引覆盖员工与年月 - 关系:多对一到 Staff - 业务意义:工资发放依据与统计入口 **章节来源** - [models.py](file://backend/app/models/models.py#L62-L230) - [schemas.py](file://backend/app/schemas/schemas.py#L64-L311) ## 架构概览 数据模型围绕“员工-科室-考核-工资”主线展开,通过外键与关系映射实现强一致的数据完整性;服务层负责业务规则与流程控制,如考核状态机、工资计算与生成、模板导入等。 ```mermaid classDiagram class Department { +int id +string name +string code +enum dept_type +int level +int sort_order +bool is_active +datetime created_at +datetime updated_at +children : Department[] +staff : Staff[] } class Staff { +int id +string employee_id +string name +int department_id +string position +string title +string phone +string email +float base_salary +float performance_ratio +enum status +datetime hire_date +datetime created_at +datetime updated_at +department : Department +assessments : Assessment[] +salary_records : SalaryRecord[] } class Assessment { +int id +int staff_id +int period_year +int period_month +string period_type +float total_score +float weighted_score +enum status +int assessor_id +int reviewer_id +datetime submit_time +datetime review_time +string remark +datetime created_at +datetime updated_at +staff : Staff +assessor : Staff +reviewer : Staff +details : AssessmentDetail[] } class AssessmentDetail { +int id +int assessment_id +int indicator_id +float actual_value +float score +string evidence +string remark +datetime created_at +datetime updated_at +assessment : Assessment +indicator : Indicator } class SalaryRecord { +int id +int staff_id +int period_year +int period_month +float base_salary +float performance_score +float performance_bonus +float deduction +float allowance +float total_salary +string status +string remark +datetime created_at +datetime updated_at +staff : Staff } Department "1" <-- "many" Staff : "外键" Staff "1" <-- "many" Assessment : "外键" Staff "1" <-- "many" SalaryRecord : "外键" Assessment "1" <-- "many" AssessmentDetail : "级联删除" ``` **图表来源** - [models.py](file://backend/app/models/models.py#L62-L230) ## 详细组件分析 ### Department(科室信息) - 设计要点 - 使用自关联实现层级树结构,支持多级科室组织 - 通过枚举限定科室类型,便于筛选与模板匹配 - 索引提升按类型与父子关系查询效率 - 业务规则 - 启用/停用控制科室参与统计与流程 - 层级与排序用于前端树形展示与权限控制 - 外键与关系 - Department.parent → Department.children(自关联) - Department.staff → Staff(一对多) **章节来源** - [models.py](file://backend/app/models/models.py#L62-L86) - [001_initial.py](file://backend/alembic/versions/001_initial.py#L22-L41) ### Staff(员工信息) - 设计要点 - 唯一工号确保跨系统识别一致性 - 绩效系数与基本工资构成工资基础 - 状态枚举支持在职、休假、离职、退休等生命周期 - 业务规则 - 仅在职员工参与考核与工资生成 - 基本工资与绩效系数影响最终绩效奖金 - 外键与关系 - Staff.department → Department - Staff.assessments → Assessment - Staff.salary_records → SalaryRecord **章节来源** - [models.py](file://backend/app/models/models.py#L88-L114) - [schemas.py](file://backend/app/schemas/schemas.py#L107-L149) - [init_db.py](file://backend/init_db.py#L42-L53) ### Assessment(考核记录) - 设计要点 - 年、月、周期类型组合唯一性避免重复 - 总分与加权得分分离,加权由明细权重累积 - 状态机驱动流程:草稿→提交→审核→确认/驳回 - 业务规则 - 仅草稿或驳回状态允许修改 - 提交后进入审核流程,审核通过方可确认 - 外键与关系 - Assessment.staff → Staff - Assessment.assessor/reviewer → Staff - Assessment.details → AssessmentDetail(级联删除) ```mermaid stateDiagram-v2 [*] --> 草稿 草稿 --> 已提交 : "提交" 已提交 --> 已审核 : "审核通过" 已提交 --> 已驳回 : "审核驳回" 已审核 --> 已确认 : "确认" 已确认 --> [*] 已驳回 --> 草稿 : "修改后重新提交" ``` **图表来源** - [models.py](file://backend/app/models/models.py#L149-L178) - [assessment_service.py](file://backend/app/services/assessment_service.py#L159-L205) **章节来源** - [models.py](file://backend/app/models/models.py#L149-L178) - [assessment_service.py](file://backend/app/services/assessment_service.py#L79-L262) ### AssessmentDetail(考核明细) - 设计要点 - 明细与指标绑定,支持不同指标的权重与计算 - 实际值与得分可独立记录,便于审计与复核 - 业务规则 - 加权得分来源于指标权重与得分乘积之和 - 外键与关系 - AssessmentDetail.assessment → Assessment - AssessmentDetail.indicator → Indicator **章节来源** - [models.py](file://backend/app/models/models.py#L181-L202) - [assessment_service.py](file://backend/app/services/assessment_service.py#L79-L108) ### SalaryRecord(工资核算记录) - 设计要点 - 应发工资 = 基本工资 + 绩效奖金 + 补贴 - 扣款 - 绩效奖金 = 绩效基数 × (绩效得分/100) × 绩效系数 - 年月唯一,避免重复发薪 - 业务规则 - 仅当考核处于“已确认”状态才可生成工资记录 - 工资记录状态默认“待处理”,支持后续调整 - 外键与关系 - SalaryRecord.staff → Staff ```mermaid flowchart TD Start(["开始"]) --> GetAssessment["获取已确认考核记录"] GetAssessment --> Exists{"是否存在?"} Exists --> |否| End(["结束"]) Exists --> |是| CalcBonus["计算绩效奖金"] CalcBonus --> SumTotal["计算应发工资"] SumTotal --> CreateRecord["创建工资记录"] CreateRecord --> End ``` **图表来源** - [models.py](file://backend/app/models/models.py#L205-L230) - [salary_service.py](file://backend/app/services/salary_service.py#L127-L190) **章节来源** - [models.py](file://backend/app/models/models.py#L205-L230) - [salary_service.py](file://backend/app/services/salary_service.py#L70-L199) ### 财务核算模型(DepartmentFinance) - 设计要点 - 收入/支出两类,按类别细分(检查费、检验费、床位费、材料费、人员支出等) - 金额非负约束,确保财务数据正确性 - 按科室与年月索引,支持财务统计 - 业务规则 - 金额必须≥0 - 与科室关联,支持按科室维度的收支结余分析 **章节来源** - [finance.py](file://backend/app/models/finance.py#L45-L74) ## 依赖分析 - 模型依赖 - Assessment 依赖 Staff、AssessmentDetail - AssessmentDetail 依赖 Assessment、Indicator - SalaryRecord 依赖 Staff - Department 依赖 Staff(自关联) - 服务层依赖 - AssessmentService 依赖 Assessment、AssessmentDetail、Indicator - SalaryService 依赖 Staff、Assessment、SalaryRecord - 其他服务(StaffService、IndicatorService)分别依赖对应模型 - 数据库与配置 - 异步引擎与会话工厂统一管理连接与事务 - Alembic 迁移脚本确保表结构演进 ```mermaid graph LR A["AssessmentService"] --> AM["Assessment"] A --> ADM["AssessmentDetail"] A --> IM["Indicator"] S["SalaryService"] --> SM["Staff"] S --> AS["Assessment"] S --> SRM["SalaryRecord"] ST["StaffService"] --> STM["Staff"] I["IndicatorService"] --> IM ``` **图表来源** - [assessment_service.py](file://backend/app/services/assessment_service.py#L79-L262) - [salary_service.py](file://backend/app/services/salary_service.py#L77-L199) - [staff_service.py](file://backend/app/services/staff_service.py#L16-L112) - [indicator_service.py](file://backend/app/services/indicator_service.py#L16-L197) **章节来源** - [assessment_service.py](file://backend/app/services/assessment_service.py#L1-L262) - [salary_service.py](file://backend/app/services/salary_service.py#L1-L199) - [staff_service.py](file://backend/app/services/staff_service.py#L1-L112) - [indicator_service.py](file://backend/app/services/indicator_service.py#L1-L197) ## 性能考虑 - 索引策略 - 员工:按部门与状态建立索引,加速筛选与分页 - 考核:按员工、年月、状态建立复合索引,支持快速定位与统计 - 工资:按员工与年月建立索引,提升查询效率 - 科室:按类型与父级建立索引,优化树形查询 - 查询优化 - 使用 selectinload 预加载关联对象,减少 N+1 查询 - 分页查询配合 COUNT 子查询,避免全表扫描 - 异步与连接池 - 异步引擎与连接池配置,提升并发吞吐 - 数据类型 - 使用 Numeric 精确存储金额与分数,避免浮点误差 **章节来源** - [models.py](file://backend/app/models/models.py#L82-L85) - [models.py](file://backend/app/models/models.py#L111-L114) - [models.py](file://backend/app/models/models.py#L174-L178) - [models.py](file://backend/app/models/models.py#L227-L230) - [config.py](file://backend/app/core/config.py#L18-L22) - [database.py](file://backend/app/core/database.py#L9-L20) ## 故障排除指南 - 常见问题 - 无法更新考核:仅草稿或驳回状态允许修改 - 无法生成工资:需先完成“已确认”的考核记录 - 重复工资:同一年月同员工只允许一条工资记录 - 财务异常:金额必须≥0,否则触发约束错误 - 排查步骤 - 检查 Assessment 状态与时间戳 - 核对 Staff 的基本工资与绩效系数 - 确认 SalaryRecord 的年月与员工唯一性 - 校验 DepartmentFinance 的金额与类别 - 日志与调试 - 开启数据库回滚与关闭,确保异常时数据一致性 - 使用分页与索引优化查询,避免超时 **章节来源** - [assessment_service.py](file://backend/app/services/assessment_service.py#L111-L156) - [salary_service.py](file://backend/app/services/salary_service.py#L127-L190) - [finance.py](file://backend/app/models/finance.py#L73-L74) - [database.py](file://backend/app/core/database.py#L28-L39) ## 结论 本数据模型以清晰的实体边界、严谨的外键关系与完善的索引策略为基础,结合服务层的状态机与计算逻辑,实现了从“员工-科室-考核-工资”的闭环管理。通过 Alembic 迁移与 Pydantic 模式,系统具备良好的可演进性与可维护性。建议在扩展新功能时遵循现有命名规范、索引策略与事务处理模式,确保数据一致性与性能表现。 ## 附录 ### 字段定义与约束对照表 - Department - 字段:id、name、code(唯一)、dept_type、parent_id、level、sort_order、is_active、description、created_at、updated_at - 约束:唯一索引(code),普通索引(dept_type、parent_id) - Staff - 字段:id、employee_id(唯一)、name、department_id、position、title、phone、email、base_salary、performance_ratio、status、hire_date、created_at、updated_at - 约束:唯一索引(employee_id),普通索引(department_id、status) - Assessment - 字段:id、staff_id、period_year、period_month、period_type、total_score、weighted_score、status、assessor_id、reviewer_id、submit_time、review_time、remark、created_at、updated_at - 约束:普通索引(staff_id、period_year、period_month、status),级联删除明细 - AssessmentDetail - 字段:id、assessment_id、indicator_id、actual_value、score、evidence、remark、created_at、updated_at - 约束:普通索引(assessment_id、indicator_id) - SalaryRecord - 字段:id、staff_id、period_year、period_month、base_salary、performance_score、performance_bonus、deduction、allowance、total_salary、status、remark、created_at、updated_at - 约束:普通索引(staff_id、period_year、period_month) - DepartmentFinance - 字段:id、department_id、period_year、period_month、finance_type、category、amount(≥0)、source、remark、created_at、updated_at - 约束:普通索引(department_id、period_year、period_month、finance_type、category),check(amount ≥ 0) **章节来源** - [models.py](file://backend/app/models/models.py#L62-L230) - [finance.py](file://backend/app/models/finance.py#L45-L74) ### 版本兼容与迁移策略 - 初始版本(001_initial.py) - 创建 departments、staff、indicators、assessments、assessment_details、salary_records、users 表 - 建立基础索引与外键约束 - 模板版本(002_template.py) - 新增 indicator_templates、template_indicators 表 - 为 indicators 表动态添加 BSC 维度、目标单位、考核方法、扣分标准、数据来源、适用科室类型、是否 veto 等列 - 迁移建议 - 新增字段采用条件判断(如字段存在性检查),避免重复执行报错 - 对历史数据进行补全(如适用科室类型 JSON 数组),确保业务可用 - 升级前备份数据库,升级后验证索引与约束生效 **章节来源** - [001_initial.py](file://backend/alembic/versions/001_initial.py#L21-L183) - [002_template.py](file://backend/alembic/versions/002_template.py#L21-L96)