18 KiB
数据模型详解
**本文档引用的文件** - [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)目录
简介
本文件面向医院绩效系统的核心数据模型,系统化阐述 Department、Staff、Assessment、AssessmentDetail、SalaryRecord 等关键实体的设计理念、字段定义、数据类型与约束条件,并深入解析模型间的关系映射、级联操作与数据完整性保障机制。同时,结合服务层业务逻辑,给出数据验证规则、业务规则实现、性能优化策略、模型扩展指南以及版本兼容与迁移策略,帮助开发者与运维人员高效理解与维护该数据模型。
项目结构
后端采用 SQLAlchemy ORM + Alembic 迁移的架构,模型集中于 models 模块,配合 Pydantic 的数据模式(schemas)进行输入输出校验;数据库连接通过异步引擎与会话工厂实现;迁移脚本确保数据库结构演进的可控性。
graph TB
subgraph "模型层"
M1["models.py<br/>核心业务模型"]
M2["finance.py<br/>财务核算模型"]
end
subgraph "数据模式层"
S1["schemas.py<br/>Pydantic模式"]
end
subgraph "基础设施层"
C1["config.py<br/>配置"]
D1["database.py<br/>数据库连接"]
end
subgraph "迁移层"
V1["001_initial.py<br/>初始版本"]
V2["002_template.py<br/>模板版本"]
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
图表来源
章节来源
核心组件
本节聚焦五个关键模型的字段定义、数据类型、约束条件与业务含义。
-
Department(科室信息)
- 字段与类型:自增主键、字符串名称与编码(唯一)、枚举类型、层级、排序、启用状态、描述、时间戳
- 约束:编码唯一;索引覆盖类型与父级
- 关系:自关联父子关系;一对多到 Staff
- 业务意义:支撑组织架构与层级管理
-
Staff(员工信息)
- 字段与类型:唯一工号、姓名、所属科室外键、职位、职称、联系方式、基本工资、绩效系数、状态、入职日期、时间戳
- 约束:工号唯一;索引覆盖科室与状态
- 关系:多对一到 Department;一对多到 Assessment、SalaryRecord
- 业务意义:员工档案与薪酬基础数据
-
Assessment(考核记录)
- 字段与类型:员工外键、考核年月、周期类型、总分、加权得分、状态、考核人/审核人外键、时间戳、备注
- 约束:复合索引覆盖员工、年月、状态;级联删除明细
- 关系:多对一到 Staff;一对多到 AssessmentDetail
- 业务意义:记录单次考核的聚合结果与流转状态
-
AssessmentDetail(考核明细)
- 字段与类型:考核记录外键、指标外键、实际值、得分、佐证材料、备注、时间戳
- 约束:明细索引覆盖考核与指标
- 关系:多对一到 Assessment、Indicator
- 业务意义:承载具体指标的得分与证据
-
SalaryRecord(工资核算记录)
- 字段与类型:员工外键、年月、基本工资、绩效得分、绩效奖金、扣款、补贴、应发工资、状态、备注、时间戳
- 约束:索引覆盖员工与年月
- 关系:多对一到 Staff
- 业务意义:工资发放依据与统计入口
章节来源
架构概览
数据模型围绕“员工-科室-考核-工资”主线展开,通过外键与关系映射实现强一致的数据完整性;服务层负责业务规则与流程控制,如考核状态机、工资计算与生成、模板导入等。
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 : "级联删除"
图表来源
详细组件分析
Department(科室信息)
- 设计要点
- 使用自关联实现层级树结构,支持多级科室组织
- 通过枚举限定科室类型,便于筛选与模板匹配
- 索引提升按类型与父子关系查询效率
- 业务规则
- 启用/停用控制科室参与统计与流程
- 层级与排序用于前端树形展示与权限控制
- 外键与关系
- Department.parent → Department.children(自关联)
- Department.staff → Staff(一对多)
章节来源
Staff(员工信息)
- 设计要点
- 唯一工号确保跨系统识别一致性
- 绩效系数与基本工资构成工资基础
- 状态枚举支持在职、休假、离职、退休等生命周期
- 业务规则
- 仅在职员工参与考核与工资生成
- 基本工资与绩效系数影响最终绩效奖金
- 外键与关系
- Staff.department → Department
- Staff.assessments → Assessment
- Staff.salary_records → SalaryRecord
章节来源
Assessment(考核记录)
- 设计要点
- 年、月、周期类型组合唯一性避免重复
- 总分与加权得分分离,加权由明细权重累积
- 状态机驱动流程:草稿→提交→审核→确认/驳回
- 业务规则
- 仅草稿或驳回状态允许修改
- 提交后进入审核流程,审核通过方可确认
- 外键与关系
- Assessment.staff → Staff
- Assessment.assessor/reviewer → Staff
- Assessment.details → AssessmentDetail(级联删除)
stateDiagram-v2
[*] --> 草稿
草稿 --> 已提交 : "提交"
已提交 --> 已审核 : "审核通过"
已提交 --> 已驳回 : "审核驳回"
已审核 --> 已确认 : "确认"
已确认 --> [*]
已驳回 --> 草稿 : "修改后重新提交"
图表来源
章节来源
AssessmentDetail(考核明细)
- 设计要点
- 明细与指标绑定,支持不同指标的权重与计算
- 实际值与得分可独立记录,便于审计与复核
- 业务规则
- 加权得分来源于指标权重与得分乘积之和
- 外键与关系
- AssessmentDetail.assessment → Assessment
- AssessmentDetail.indicator → Indicator
章节来源
SalaryRecord(工资核算记录)
- 设计要点
- 应发工资 = 基本工资 + 绩效奖金 + 补贴 - 扣款
- 绩效奖金 = 绩效基数 × (绩效得分/100) × 绩效系数
- 年月唯一,避免重复发薪
- 业务规则
- 仅当考核处于“已确认”状态才可生成工资记录
- 工资记录状态默认“待处理”,支持后续调整
- 外键与关系
- SalaryRecord.staff → Staff
flowchart TD
Start(["开始"]) --> GetAssessment["获取已确认考核记录"]
GetAssessment --> Exists{"是否存在?"}
Exists --> |否| End(["结束"])
Exists --> |是| CalcBonus["计算绩效奖金"]
CalcBonus --> SumTotal["计算应发工资"]
SumTotal --> CreateRecord["创建工资记录"]
CreateRecord --> End
图表来源
章节来源
财务核算模型(DepartmentFinance)
- 设计要点
- 收入/支出两类,按类别细分(检查费、检验费、床位费、材料费、人员支出等)
- 金额非负约束,确保财务数据正确性
- 按科室与年月索引,支持财务统计
- 业务规则
- 金额必须≥0
- 与科室关联,支持按科室维度的收支结余分析
章节来源
依赖分析
- 模型依赖
- Assessment 依赖 Staff、AssessmentDetail
- AssessmentDetail 依赖 Assessment、Indicator
- SalaryRecord 依赖 Staff
- Department 依赖 Staff(自关联)
- 服务层依赖
- AssessmentService 依赖 Assessment、AssessmentDetail、Indicator
- SalaryService 依赖 Staff、Assessment、SalaryRecord
- 其他服务(StaffService、IndicatorService)分别依赖对应模型
- 数据库与配置
- 异步引擎与会话工厂统一管理连接与事务
- Alembic 迁移脚本确保表结构演进
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
图表来源
章节来源
性能考虑
- 索引策略
- 员工:按部门与状态建立索引,加速筛选与分页
- 考核:按员工、年月、状态建立复合索引,支持快速定位与统计
- 工资:按员工与年月建立索引,提升查询效率
- 科室:按类型与父级建立索引,优化树形查询
- 查询优化
- 使用 selectinload 预加载关联对象,减少 N+1 查询
- 分页查询配合 COUNT 子查询,避免全表扫描
- 异步与连接池
- 异步引擎与连接池配置,提升并发吞吐
- 数据类型
- 使用 Numeric 精确存储金额与分数,避免浮点误差
章节来源
故障排除指南
- 常见问题
- 无法更新考核:仅草稿或驳回状态允许修改
- 无法生成工资:需先完成“已确认”的考核记录
- 重复工资:同一年月同员工只允许一条工资记录
- 财务异常:金额必须≥0,否则触发约束错误
- 排查步骤
- 检查 Assessment 状态与时间戳
- 核对 Staff 的基本工资与绩效系数
- 确认 SalaryRecord 的年月与员工唯一性
- 校验 DepartmentFinance 的金额与类别
- 日志与调试
- 开启数据库回滚与关闭,确保异常时数据一致性
- 使用分页与索引优化查询,避免超时
章节来源
结论
本数据模型以清晰的实体边界、严谨的外键关系与完善的索引策略为基础,结合服务层的状态机与计算逻辑,实现了从“员工-科室-考核-工资”的闭环管理。通过 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)
章节来源
版本兼容与迁移策略
- 初始版本(001_initial.py)
- 创建 departments、staff、indicators、assessments、assessment_details、salary_records、users 表
- 建立基础索引与外键约束
- 模板版本(002_template.py)
- 新增 indicator_templates、template_indicators 表
- 为 indicators 表动态添加 BSC 维度、目标单位、考核方法、扣分标准、数据来源、适用科室类型、是否 veto 等列
- 迁移建议
- 新增字段采用条件判断(如字段存在性检查),避免重复执行报错
- 对历史数据进行补全(如适用科室类型 JSON 数组),确保业务可用
- 升级前备份数据库,升级后验证索引与约束生效
章节来源