18 KiB
18 KiB
核心数据模型
**本文档引用的文件** - [models.py](file://backend/app/models/models.py) - [finance.py](file://backend/app/models/finance.py) - [database.py](file://backend/app/core/database.py) - [init_db.py](file://backend/app/core/init_db.py) - [schemas.py](file://backend/app/schemas/schemas.py) - [staff_service.py](file://backend/app/services/staff_service.py) - [assessment_service.py](file://backend/app/services/assessment_service.py) - [salary_service.py](file://backend/app/services/salary_service.py) - [database.md](file://docs/database.md)目录
简介
本文件详细阐述医院绩效系统的核心数据模型设计,重点涵盖Department(科室)、Staff(员工)、Assessment(考核记录)、AssessmentDetail(考核明细)、SalaryRecord(工资核算记录)等核心业务模型。文档从设计理念、实现细节、字段定义、数据类型、约束条件、业务规则、模型关联关系、索引设计、性能优化策略等多个维度进行全面解析,并提供使用示例和最佳实践指导。
项目结构
该系统采用分层架构,核心模型位于 backend/app/models/ 目录,数据库连接通过 backend/app/core/database.py 管理,初始化逻辑在 backend/app/core/init_db.py 中实现。数据验证通过 Pydantic 模式在 backend/app/schemas/schemas.py 中定义,服务层负责业务逻辑处理。
graph TB
subgraph "模型层"
M1[models.py<br/>核心业务模型]
M2[finance.py<br/>财务核算模型]
end
subgraph "核心配置"
C1[database.py<br/>数据库连接]
C2[init_db.py<br/>数据库初始化]
end
subgraph "数据验证"
S1[schemas.py<br/>Pydantic模式]
end
subgraph "服务层"
SV1[staff_service.py]
SV2[assessment_service.py]
SV3[salary_service.py]
end
M1 --> C1
M2 --> C1
C2 --> M1
S1 --> SV1
S1 --> SV2
S1 --> SV3
SV1 --> M1
SV2 --> M1
SV3 --> M1
图表来源
章节来源
核心组件
本节概述五个核心业务模型的设计理念和实现要点:
Department(科室)
- 设计理念:支持多层级组织架构,通过自关联实现父子关系
- 关键特性:科室类型枚举、层级管理、排序机制、激活状态控制
- 外键关系:自关联 parent_id 指向自身,children 反向关系
- 索引设计:按科室类型和父级ID建立索引
Staff(员工)
- 设计理念:员工与科室的一对多关系,支持多种状态管理
- 关键特性:工号唯一性、基本工资和绩效系数、状态枚举
- 外键关系:department_id 指向 Department,一对多关系
- 索引设计:按科室ID和状态建立复合索引
Assessment(考核记录)
- 设计理念:支持多周期、多状态的考核流程管理
- 关键特性:总分和加权得分计算、多角色参与(考核人、审核人)
- 外键关系:staff_id 指向 Staff,assessor_id 和 reviewer_id 自关联
- 索引设计:按员工ID、考核周期、状态建立复合索引
AssessmentDetail(考核明细)
- 设计理念:一对一关联 Assessment,支持多指标明细记录
- 关键特性:实际值和得分记录、佐证材料管理
- 外键关系:assessment_id 和 indicator_id 的双向关联
- 索引设计:按考核记录ID和指标ID建立索引
SalaryRecord(工资核算记录)
- 设计理念:基于考核结果的自动化工资核算
- 关键特性:基本工资、绩效奖金、扣款、补贴的统一管理
- 外键关系:staff_id 指向 Staff
- 索引设计:按员工ID和考核周期建立复合索引
章节来源
架构概览
系统采用分层架构,核心数据模型通过 SQLAlchemy ORM 映射到数据库表,配合 Pydantic 模式进行数据验证,服务层封装业务逻辑。
classDiagram
class Department {
+int id
+string name
+string code
+DeptType dept_type
+int parent_id
+int level
+int sort_order
+bool is_active
+string description
+datetime created_at
+datetime updated_at
+children : List[Department]
+staff : List[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
+StaffStatus status
+datetime hire_date
+datetime created_at
+datetime updated_at
+department : Department
+assessments : List[Assessment]
+salary_records : List[SalaryRecord]
}
class Assessment {
+int id
+int staff_id
+int period_year
+int period_month
+string period_type
+float total_score
+float weighted_score
+AssessmentStatus 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 : List[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" <-- "N" Staff : "一对多"
Staff "1" <-- "N" Assessment : "一对多"
Assessment "1" <-- "N" AssessmentDetail : "一对多"
Staff "1" <-- "N" SalaryRecord : "一对多"
Assessment "N" --> "1" Staff : "多对一"
AssessmentDetail "N" --> "1" Assessment : "多对一"
AssessmentDetail "N" --> "1" Indicator : "多对一"
SalaryRecord "N" --> "1" Staff : "多对一"
图表来源
详细组件分析
Department(科室)模型
字段定义与数据类型
- id: 主键,整数类型,自动递增
- name: 科室名称,字符串类型,最大长度100,必填
- code: 科室编码,字符串类型,最大长度20,唯一且必填
- dept_type: 科室类型枚举,支持临床、医技、医辅、行政、后勤等类型
- parent_id: 上级科室ID,整数类型,自关联外键
- level: 层级,整数类型,默认1,范围1-5
- sort_order: 排序,整数类型,默认0
- is_active: 是否启用,布尔类型,默认True
- description: 描述信息,文本类型
- created_at/updated_at: 时间戳,自动维护
约束条件与业务规则
- 唯一性约束:code 字段唯一
- 枚举约束:dept_type 必须属于预定义类型集合
- 自关联约束:parent_id 引用自身主键
- 层级限制:level 范围1-5
关联关系
- 一对多:Department → Staff(children)
- 自关联:parent_id → Department(parent)
索引设计
- idx_dept_type:按科室类型查询优化
- idx_dept_parent:按父级科室查询优化
章节来源
Staff(员工)模型
字段定义与数据类型
- id: 主键,整数类型,自动递增
- employee_id: 工号,字符串类型,最大长度20,唯一且必填
- name: 姓名,字符串类型,最大长度50,必填
- department_id: 所属科室ID,整数类型,外键约束
- position: 职位,字符串类型,最大长度50,必填
- title: 职称,字符串类型,最大长度50
- phone/email: 联系方式,字符串类型
- base_salary: 基本工资,数值类型,精度10,2,默认0
- performance_ratio: 绩效系数,数值类型,精度5,2,默认1.0,范围0-5
- status: 员工状态枚举,默认active
- hire_date: 入职日期,日期时间类型
- created_at/updated_at: 时间戳
约束条件与业务规则
- 唯一性约束:employee_id 唯一
- 数值范围约束:performance_ratio 范围0-5
- 外键约束:department_id 引用 Department.id
- 状态枚举:仅允许预定义状态值
关联关系
- 多对一:Staff → Department(department)
- 一对多:Department → Staff(staff)
- 一对多:Staff → Assessment(assessments)
- 一对多:Staff → SalaryRecord(salary_records)
索引设计
- idx_staff_dept:按科室ID查询优化
- idx_staff_status:按状态查询优化
章节来源
Assessment(考核记录)模型
字段定义与数据类型
- id: 主键,整数类型,自动递增
- staff_id: 员工ID,整数类型,外键约束
- period_year: 考核年度,整数类型,必填
- period_month: 考核月份,整数类型,必填
- period_type: 考核周期类型,字符串类型,默认monthly
- total_score: 总分,数值类型,精度5,2,默认0
- weighted_score: 加权得分,数值类型,精度5,2,默认0
- status: 考核状态枚举,默认draft
- assessor_id/reviewer_id: 考核人/审核人ID,整数类型,自关联外键
- submit_time/review_time: 提交/审核时间,日期时间类型
- remark: 备注,文本类型
- created_at/updated_at: 时间戳
约束条件与业务规则
- 外键约束:staff_id 引用 Staff.id
- 自关联约束:assessor_id/reviewer_id 引用 Staff.id
- 状态枚举:支持草稿、提交、审核、确认、驳回等状态
- 计算规则:total_score 为明细得分之和,weighted_score 为按指标权重加权
关联关系
- 多对一:Assessment → Staff(staff)
- 多对一:Assessment → Staff(assessor)
- 多对一:Assessment → Staff(reviewer)
- 一对多:Assessment → AssessmentDetail(details)
- 级联删除:details 支持级联删除
索引设计
- idx_assessment_staff:按员工ID查询优化
- idx_assessment_period:按考核周期查询优化
- idx_assessment_status:按状态查询优化
章节来源
AssessmentDetail(考核明细)模型
字段定义与数据类型
- id: 主键,整数类型,自动递增
- assessment_id: 考核记录ID,整数类型,外键约束
- indicator_id: 指标ID,整数类型,外键约束
- actual_value: 实际值,数值类型,精度10,2
- score: 得分,数值类型,精度5,2,默认0
- evidence: 佐证材料,文本类型
- remark: 备注,文本类型
- created_at/updated_at: 时间戳
约束条件与业务规则
- 外键约束:assessment_id 引用 Assessment.id,indicator_id 引用 Indicator.id
- 计算规则:Assessment.total_score = Σ(AssessmentDetail.score)
关联关系
- 多对一:AssessmentDetail → Assessment(assessment)
- 多对一:AssessmentDetail → Indicator(indicator)
索引设计
- idx_detail_assessment:按考核记录ID查询优化
- idx_detail_indicator:按指标ID查询优化
章节来源
SalaryRecord(工资核算记录)模型
字段定义与数据类型
- id: 主键,整数类型,自动递增
- staff_id: 员工ID,整数类型,外键约束
- period_year: 年度,整数类型,必填
- period_month: 月份,整数类型,必填
- base_salary: 基本工资,数值类型,精度10,2,默认0
- performance_score: 绩效得分,数值类型,精度5,2,默认0
- performance_bonus: 绩效奖金,数值类型,精度10,2,默认0
- deduction: 扣款,数值类型,精度10,2,默认0
- allowance: 补贴,数值类型,精度10,2,默认0
- total_salary: 应发工资,数值类型,精度10,2,默认0
- status: 状态,默认pending
- remark: 备注,文本类型
- created_at/updated_at: 时间戳
约束条件与业务规则
- 外键约束:staff_id 引用 Staff.id
- 计算规则:total_salary = base_salary + performance_bonus + allowance - deduction
- 状态管理:支持pending、confirmed、paid等状态
关联关系
- 多对一:SalaryRecord → Staff(staff)
索引设计
- idx_salary_staff:按员工ID查询优化
- idx_salary_period:按考核周期查询优化
章节来源
数据验证规则
系统采用 Pydantic 模式进行数据验证,确保输入数据的完整性和正确性:
员工数据验证
- employee_id: 长度不超过20字符,必填
- base_salary: 非负数,最小值0
- performance_ratio: 范围0-5
- name/position/title: 长度限制和必填约束
考核数据验证
- period_year: 范围2020-2100
- period_month: 范围1-12
- score: 非负数,最小值0
工资数据验证
- 所有金额字段:非负数约束
- 计算字段:自动计算,不允许直接修改
章节来源
依赖分析
系统模型间存在清晰的依赖关系,遵循数据库规范化原则:
graph TD
A[Department] --> B[Staff]
B --> C[Assessment]
C --> D[AssessmentDetail]
B --> E[SalaryRecord]
C -.-> F[Indicator]
G[Assessment] -.自关联.-> B
H[AssessmentDetail] -.多对一.-> F
subgraph "索引优化"
I[idx_dept_type]
J[idx_staff_dept]
K[idx_assessment_staff]
L[idx_detail_assessment]
M[idx_salary_staff]
end
A -.-> I
B -.-> J
C -.-> K
D -.-> L
E -.-> M
图表来源
外键约束与级联操作
- Assessment → AssessmentDetail: 级联删除(delete-orphan)
- Department → Staff: 一对多关系
- Staff → Assessment: 一对多关系
- Staff → SalaryRecord: 一对多关系
性能优化策略
查询优化
- 使用复合索引优化常用查询条件
- 通过 selectinload 减少 N+1 查询问题
- 分页查询避免大数据集加载
数据库连接
- 异步数据库连接提高并发性能
- 连接池管理优化资源使用
章节来源
性能考虑
索引策略
- 单列索引:按枚举类型、状态、激活状态快速过滤
- 复合索引:按员工ID+状态、考核周期、科室ID+状态等组合查询优化
查询优化
- 使用 selectinload 预加载关联数据
- 分页查询限制结果集大小
- 条件查询精确匹配减少扫描范围
缓存策略
- 频繁访问的枚举类型缓存
- 常用查询结果短期缓存
故障排除指南
常见问题与解决方案
数据重复错误
- 症状:插入重复的工号或科室编码
- 解决:检查唯一性约束,使用去重逻辑
外键约束错误
- 症状:插入不存在的员工或科室ID
- 解决:先创建关联实体,再创建子实体
数据验证失败
- 症状:字段超出范围或格式不正确
- 解决:检查 Pydantic 模式的验证规则
性能问题
- 症状:查询响应缓慢
- 解决:检查索引使用情况,优化查询条件
章节来源
结论
本核心数据模型设计充分体现了医院绩效管理的业务需求,通过清晰的实体关系、严格的约束条件、完善的索引策略和合理的性能优化,为系统的稳定运行提供了坚实基础。模型间的层次化设计支持复杂的组织架构,灵活的状态管理适应不同的业务流程,而完善的验证机制确保了数据质量。
附录
模型使用示例
创建员工
# 通过服务层创建员工
staff = await StaffService.create(db, staff_data)
创建考核记录
# 通过服务层创建考核
assessment = await AssessmentService.create(db, assessment_data)
生成工资记录
# 基于考核结果生成工资
salary_record = await SalaryService.generate_from_assessment(db, staff_id, year, month)
最佳实践
- 数据完整性:始终使用 Pydantic 模式进行数据验证
- 事务管理:在复杂操作中使用数据库事务保证一致性
- 索引优化:根据查询模式合理创建索引
- 错误处理:完善异常处理和回滚机制
- 性能监控:定期分析慢查询日志优化性能
章节来源