Files
hospital_performance/.qoder/repowiki/zh/content/数据模型详解/核心数据模型/工资核算模型.md
2026-02-28 15:16:15 +08:00

18 KiB
Raw Blame History

工资核算模型

**本文引用的文件** - [backend/app/models/models.py](file://backend/app/models/models.py) - [backend/app/models/finance.py](file://backend/app/models/finance.py) - [backend/app/api/v1/salary.py](file://backend/app/api/v1/salary.py) - [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py) - [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py) - [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py) - [frontend/src/views/salary/Salary.vue](file://frontend/src/views/salary/Salary.vue) - [frontend/src/api/salary.js](file://frontend/src/api/salary.js) - [docs/database.md](file://docs/database.md) - [docs/详细设计文档.md](file://docs/详细设计文档.md)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构概览
  5. 详细组件分析
  6. 依赖分析
  7. 性能考虑
  8. 故障排除指南
  9. 结论
  10. 附录

简介

本文档深入解析医院绩效系统中的工资核算模型重点围绕SalaryRecord模型的设计理念、实现细节以及与考核系统的集成关系。文档涵盖以下关键内容

  • 基本工资、绩效得分、绩效奖金、扣款补贴的计算逻辑
  • 工资核算的时间周期与状态管理(待处理、已确认)
  • 应发工资的计算公式与字段约束
  • 绩效奖金与绩效得分的关系、扣款与补贴的设置规则
  • 与员工的多对一关系、历史记录的版本控制
  • 批量核算的性能优化策略
  • 工资计算示例、异常处理机制与数据准确性验证方法

项目结构

后端采用FastAPI + SQLAlchemy异步ORM架构工资核算功能位于以下模块

  • 模型层定义SalaryRecord、Staff、Assessment等实体及其关系
  • 服务层:实现工资计算、生成、确认、批量处理等业务逻辑
  • API层提供REST接口支持按考核生成工资、批量生成与确认
  • 前端:提供工资记录查询、编辑、确认等界面
graph TB
subgraph "前端"
FE_View["Salary.vue<br/>视图组件"]
FE_API["salary.js<br/>API封装"]
end
subgraph "后端"
API["salary.py<br/>API路由"]
Service["salary_service.py<br/>服务层"]
Model["models.py<br/>数据模型"]
Schema["schemas.py<br/>数据模式"]
DB["数据库<br/>salary_records表"]
end
FE_View --> FE_API
FE_API --> API
API --> Service
Service --> Model
Model --> DB
Schema --> API

图表来源

章节来源

核心组件

  • SalaryRecord模型存储工资核算结果包含基本工资、绩效得分、绩效奖金、扣款、补贴、应发工资与状态
  • Staff模型员工基本信息与绩效系数用于绩效奖金计算
  • Assessment模型考核记录提供加权得分作为绩效奖金依据
  • SalaryService服务实现工资计算、生成、确认、批量处理等核心逻辑
  • API路由提供查询、创建、更新、按考核生成、批量生成与确认等接口

章节来源

架构概览

工资核算从考核结果出发,通过服务层计算绩效奖金并生成工资记录;前端提供查询与确认操作,后端通过权限控制确保只有管理员或经理可以进行关键操作。

sequenceDiagram
participant Client as "客户端"
participant API as "salary.py"
participant Service as "salary_service.py"
participant DB as "数据库"
Client->>API : POST /salary/generate?staff_id&period_year&period_month
API->>Service : generate_from_assessment(staff_id, year, month)
Service->>DB : 查询员工信息(Staff)
Service->>DB : 查询已确认考核(Assessment.status='finalized')
Service->>Service : calculate_performance_bonus(weighted_score, performance_ratio)
Service->>DB : 插入SalaryRecord(状态=pending)
DB-->>Service : 返回新记录
Service-->>API : 返回记录ID
API-->>Client : {code,message,data : id}

图表来源

章节来源

详细组件分析

SalaryRecord模型设计

  • 字段定义
    • 基本工资base_salary数值型精度10位小数2位
    • 绩效得分performance_score数值型精度5位小数2位
    • 绩效奖金performance_bonus数值型精度10位小数2位
    • 扣款deduction数值型精度10位小数2位
    • 补贴allowance数值型精度10位小数2位
    • 应发工资total_salary数值型精度10位小数2位
    • 状态status默认"pending"
    • 时间周期period_year、period_month
    • 外键staff_id关联员工表
  • 约束与索引
    • 外键约束staff_id -> staff.id
    • 索引staff_id、(period_year, period_month)
  • 关系
    • 与Staff为多对一关系支持反向访问salary_records
classDiagram
class Staff {
+int id
+string employee_id
+string name
+int department_id
+string position
+string title
+float base_salary
+float performance_ratio
+string status
+datetime hire_date
+datetime created_at
+datetime updated_at
+Assessment[] assessments
+SalaryRecord[] salary_records
}
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 "1" o-- "*" SalaryRecord : "多对一"

图表来源

章节来源

计算逻辑与公式

  • 绩效奖金计算
    • 公式:绩效奖金 = 绩效基数 × (绩效得分/100) × 绩效系数
    • 绩效基数:固定常量,服务层中定义
    • 绩效系数来自员工表的performance_ratio
  • 应发工资计算
    • 公式:应发工资 = 基本工资 + 绩效奖金 + 补贴 - 扣款
    • 该公式在创建与更新工资记录时均会重新计算并持久化
flowchart TD
Start(["开始"]) --> LoadStaff["加载员工信息<br/>获取base_salary, performance_ratio"]
LoadStaff --> LoadAssessment["加载已确认考核<br/>获取weighted_score"]
LoadAssessment --> CheckExisting{"是否存在同周期工资记录?"}
CheckExisting --> |是| ReturnNone["返回空不重复生成"]
CheckExisting --> |否| CalcBonus["计算绩效奖金<br/>bonus = 基数 × (score/100) × ratio"]
CalcBonus --> CalcTotal["计算应发工资<br/>total = base + bonus + allowance - deduction"]
CalcTotal --> CreateRecord["创建SalaryRecord<br/>状态=pending"]
CreateRecord --> End(["结束"])
ReturnNone --> End

图表来源

章节来源

时间周期与状态管理

  • 时间周期
    • 由period_year与period_month共同构成用于唯一标识某员工的某月工资记录
    • 数据库层面在salary_records上建立了复合索引(idx_salary_period),提升查询效率
  • 状态管理
    • 待处理pending默认状态
    • 已确认confirmed管理员/经理确认后变更)
    • 已发放paid当前服务层未实现但模型预留字段
  • 状态变更流程
    • 单条确认调用确认接口仅当状态为pending时允许变更
    • 批量确认按年月筛选pending状态记录可选择按科室过滤
stateDiagram-v2
[*] --> 待处理
待处理 --> 已确认 : "确认工资"
已确认 --> 已发放 : "发放工资"
已发放 --> [*]

图表来源

章节来源

与员工的多对一关系与历史版本控制

  • 多对一关系
    • SalaryRecord.staff_id -> Staff.id每个工资记录对应唯一员工
    • Staff.salary_records反向关系支持按员工查询其历史工资记录
  • 历史版本控制
    • 当前版本未实现SalaryRecord的版本号字段如需版本控制可在模型中增加version字段并在更新时递增
    • 绩效计划的版本控制已在其他模型中实现PerformancePlan.version可借鉴其模式

章节来源

批量核算的性能优化

  • 批量生成
    • 服务层先查询指定科室下所有已确认的考核记录,再逐条生成工资记录
    • 建议在大规模数据场景下:
      • 使用分批处理(分页查询考核记录)
      • 异步并发插入(注意数据库连接池与事务边界)
      • 增加数据库索引覆盖查询条件
  • 批量确认
    • 通过SQL查询一次性筛选出待确认记录减少多次往返
    • 支持按科室过滤,缩小确认范围

章节来源

扣款与补贴的设置规则

  • 扣款与补贴均为数值型字段,支持在创建或更新时设置
  • 服务层在创建与更新时均会重新计算应发工资total_salary = base_salary + performance_bonus + allowance - deduction
  • 建议在业务层增加校验规则:
    • 扣款与补贴必须非负
    • 应发工资计算后可进行合理性校验(如不得为负)

章节来源

绩效奖金与绩效得分的关系

  • 绩效奖金 = 绩效基数 × (绩效得分/100) × 绩效系数
  • 绩效得分来自Assessment.weighted_score状态必须为"finalized"
  • 绩效系数来自Staff.performance_ratio不同岗位/级别可设置不同系数

章节来源

API与前端交互

  • API接口
    • 列表查询:支持按员工、科室、年份、月份、状态筛选
    • 详情查询:返回带员工与科室名称的完整信息
    • 创建/更新:仅允许在待处理状态下更新
    • 按考核生成:基于已确认考核自动生成工资记录
    • 批量生成/确认:支持按科室批量生成与批量确认
  • 前端展示
    • 列表显示基本工资、绩效得分、绩效奖金、补贴、扣款、应发工资等字段
    • 提供编辑弹窗,支持更新扣款、补贴、备注等

章节来源

依赖分析

  • 模型依赖
    • SalaryRecord依赖Staff外键
    • Assessment与SalaryRecord通过staff_id间接关联
  • 服务层依赖
    • 依赖Staff、Assessment模型进行数据查询与计算
    • 依赖Pydantic模式进行请求/响应数据校验
  • API层依赖
    • 依赖Security中间件进行权限控制管理员/经理)
    • 依赖数据库会话进行异步操作
graph LR
SalaryRecord["SalaryRecord模型"] --> Staff["Staff模型"]
SalaryService["SalaryService"] --> SalaryRecord
SalaryService --> Staff
SalaryService --> Assessment["Assessment模型"]
API["salary.py"] --> SalaryService
API --> Schema["schemas.py"]

图表来源

章节来源

性能考虑

  • 查询优化
    • salary_records表已建立索引staff_id、(period_year, period_month)
    • API层使用selectinload预加载关联对象避免N+1查询
  • 批量处理
    • 批量生成与确认采用SQL查询一次性筛选减少循环调用
    • 建议在高并发场景下增加数据库连接池配置与事务隔离级别
  • 数据类型
    • 使用Numeric类型保证金额精度避免浮点误差累积

[本节为通用性能建议,无需特定文件来源]

故障排除指南

  • 无法生成工资
    • 检查是否存在已确认的考核记录且状态为"finalized"
    • 检查是否已存在同周期的工资记录(防止重复生成)
  • 无法确认工资
    • 确认记录状态必须为"pending"
    • 检查权限:仅管理员或经理可执行确认操作
  • 数据不一致
    • 更新扣款/补贴后需重新计算应发工资
    • 核对数据库索引是否生效,避免查询性能问题

章节来源

结论

SalaryRecord模型通过清晰的字段设计与严格的计算逻辑实现了从考核到工资的自动化流转。服务层提供了完善的生成、确认与批量处理能力并通过索引与预加载优化了查询性能。未来可在版本控制、状态扩展如已发放与更细粒度的扣款/补贴规则方面进一步增强。

[本节为总结性内容,无需特定文件来源]

附录

工资计算示例

  • 输入
    • 员工:基本工资=10000绩效系数=1.2
    • 考核:加权得分=95
    • 扣款=0补贴=500
  • 计算过程
    • 绩效奖金 = 固定基数 × (95/100) × 1.2
    • 应发工资 = 10000 + 绩效奖金 + 500 - 0
  • 输出
    • 工资记录状态=pending等待确认

章节来源

数据准确性验证方法

  • 金额精度使用Numeric类型避免浮点误差
  • 业务规则:在服务层增加校验(扣款/补贴非负、应发工资合理)
  • 索引验证确认salary_records索引生效提升查询性能
  • 测试覆盖:编写单元测试验证计算逻辑与状态变更流程

章节来源