# 数据模型详解
**本文档引用的文件**
- [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)