Files
hospital_performance/.qoder/repowiki/zh/content/后端开发指南/服务层开发/工资服务.md
2026-02-28 15:16:15 +08:00

16 KiB
Raw Blame History

工资服务

**本文引用的文件** - [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py) - [backend/app/api/v1/salary.py](file://backend/app/api/v1/salary.py) - [backend/app/models/models.py](file://backend/app/models/models.py) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py) - [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py) - [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py) - [backend/app/core/database.py](file://backend/app/core/database.py) - [backend/app/core/config.py](file://backend/app/core/config.py) - [backend/init_db.py](file://backend/init_db.py)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 组件详解
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件面向“工资服务”的开发与维护,围绕 SalaryService 类的实现架构展开,系统性阐述以下内容:

  • 绩效奖金计算算法:基础工资、绩效系数、考核等级对应的奖金计算逻辑
  • 工资记录的数据结构、字段含义与业务规则
  • 批量生成工资记录的机制:按月度、季度或年度的计算流程
  • 与考核服务、员工服务的集成关系与数据一致性保障
  • 异常处理、事务管理与性能优化策略
  • 实际计算示例与边界条件处理

项目结构

后端采用分层架构API 层负责路由与鉴权Service 层封装业务逻辑Model 层定义数据模型Schema 层定义输入输出结构。工资服务位于 Service 层,与考核服务、员工服务协作,最终落库到 SalaryRecord。

graph TB
API["API 路由<br/>salary.py"] --> SVC["服务层<br/>salary_service.py"]
SVC --> MODEL["模型层<br/>models.py 中的 SalaryRecord/Assessment/Staff"]
SVC --> SCHEMA["Schema 定义<br/>schemas.py"]
SVC --> ASSESS_SVC["考核服务<br/>assessment_service.py"]
SVC --> STAFF_SVC["员工服务<br/>staff_service.py"]
SVC --> DB["数据库连接<br/>database.py"]
DB --> CONF["配置<br/>config.py"]

图表来源

章节来源

核心组件

  • 工资服务SalaryService提供查询、创建、更新、生成、确认、批量生成与批量确认等能力核心算法集中在绩效奖金计算与总工资汇总。
  • 工资记录模型SalaryRecord持久化存储工资条目包含基础工资、绩效得分、绩效奖金、扣款、补贴、应发工资、状态等字段。
  • 考核服务AssessmentService提供考核的创建、提交、审核、确认等流程为工资生成提供“已确认”的考核数据。
  • 员工服务StaffService提供员工信息查询与维护为工资生成提供基础工资与绩效系数。
  • API 路由salary.py对外暴露查询、生成、确认、批量生成与批量确认等接口并进行权限校验。

章节来源

架构总览

工资服务的调用链路如下:前端请求经 API 路由进入,由 SalaryService 执行业务逻辑;若需要从考核生成,则联动 AssessmentService 与 StaffService最终写入数据库并返回结果。

sequenceDiagram
participant FE as "前端"
participant API as "API 路由<br/>salary.py"
participant SVC as "服务层<br/>salary_service.py"
participant ASSESS as "考核服务<br/>assessment_service.py"
participant STAFF as "员工服务<br/>staff_service.py"
participant DB as "数据库"
FE->>API : "POST /salary/generate"
API->>SVC : "generate_from_assessment(staff_id, year, month)"
SVC->>DB : "查询员工信息"
DB-->>SVC : "Staff"
SVC->>DB : "查询已确认考核"
DB-->>SVC : "Assessment(finalized)"
SVC->>SVC : "calculate_performance_bonus()"
SVC->>DB : "插入 SalaryRecord"
DB-->>SVC : "返回新记录"
SVC-->>API : "返回记录ID"
API-->>FE : "生成成功"

图表来源

组件详解

工资记录数据模型与字段语义

  • 表名salary_records
  • 字段与含义(节选):
    • staff_id员工ID
    • period_year / period_month所属周期年/月)
    • base_salary基本工资
    • performance_score绩效得分
    • performance_bonus绩效奖金
    • allowance补贴
    • deduction扣款
    • total_salary应发工资base_salary + performance_bonus + allowance - deduction
    • status状态默认 pending支持 confirmed
    • remark备注
    • created_at / updated_at创建与更新时间

业务规则:

  • 总工资由服务层在创建/更新时计算并入库
  • 状态仅允许在“pending”状态下进行更新与确认
  • 生成工资记录前需确保同一员工当月无重复记录

章节来源

绩效奖金计算算法

  • 奖金基数PERFORMANCE_BASE静态常量
  • 计算公式:奖金 = 奖金基数 × (绩效得分/100) × 员工绩效系数
  • 输入来源:
    • 绩效得分:来自已确认的 Assessment.weighted_score
    • 绩效系数:来自 Staff.performance_ratio
  • 输出performance_bonus用于后续总工资计算
flowchart TD
Start(["开始"]) --> LoadAssess["加载已确认考核<br/>Assessment.finalized"]
LoadAssess --> LoadStaff["加载员工信息<br/>Staff.performance_ratio"]
LoadStaff --> CalcBonus["计算奖金<br/>奖金 = 奖金基数 × 得分/100 × 系数"]
CalcBonus --> SumTotal["汇总总工资<br/>总工资 = 基本工资 + 奖金 + 补贴 - 扣款"]
SumTotal --> Persist["持久化 SalaryRecord"]
Persist --> End(["结束"])

图表来源

章节来源

工资记录生成与批量处理机制

  • 单条生成generate_from_assessment
    • 校验员工存在
    • 查询当期“已确认”的 Assessment
    • 检查是否存在重复工资记录
    • 计算奖金与总工资
    • 插入 SalaryRecord状态 pending
  • 批量生成batch_generate_for_department
    • 基于部门与周期,查询所有“已确认”的 Assessment
    • 对每个评估逐条调用单条生成
  • 批量确认batch_confirm
    • 按年/月筛选 pending 状态的记录
    • 可选按部门过滤
    • 将状态置为 confirmed 并返回确认数量
sequenceDiagram
participant API as "API 路由"
participant SVC as "SalaryService"
participant DB as "数据库"
API->>SVC : "batch_generate_for_department(dept_id, year, month)"
SVC->>DB : "查询已确认考核(按部门+周期)"
DB-->>SVC : "Assessments 列表"
loop 遍历每个 Assessment
SVC->>SVC : "generate_from_assessment()"
SVC->>DB : "插入 SalaryRecord"
end
SVC-->>API : "返回生成的记录列表"

图表来源

章节来源

与考核服务、员工服务的集成关系

  • 与考核服务AssessmentService
    • 生成工资记录的前提是存在“已确认”的 Assessment
    • 通过 Assessment.status == "finalized" 进行筛选
  • 与员工服务StaffService
    • 读取员工的基础工资与绩效系数
    • 作为奖金计算的输入参数
  • 数据一致性:
    • 生成前检查重复记录,避免重复发薪
    • 仅对 pending 状态的记录允许更新与确认

章节来源

API 接口与权限控制

  • 查询列表与详情:普通用户可访问
  • 创建、更新、单条生成、确认:需要管理员或经理权限
  • 批量生成、批量确认:需要管理员或经理权限
  • 返回格式遵循统一响应结构code/message/data

章节来源

依赖关系分析

  • SalaryService 依赖:
    • SQLAlchemy 异步会话AsyncSession
    • 模型SalaryRecord、Staff、Assessment
    • SchemaSalaryRecordCreate、SalaryRecordUpdate
    • 服务AssessmentService、StaffService
  • 外部依赖:
    • 数据库连接与事务管理database.py
    • 应用配置config.py
classDiagram
class SalaryService {
+get_list(...)
+get_by_id(...)
+create(...)
+update(...)
+calculate_performance_bonus(...)
+generate_from_assessment(...)
+batch_generate_for_department(...)
+confirm(...)
+batch_confirm(...)
}
class AssessmentService {
+get_by_id(...)
+finalize(...)
}
class StaffService {
+get_by_id(...)
}
class SalaryRecord
class Staff
class Assessment
SalaryService --> AssessmentService : "查询已确认考核"
SalaryService --> StaffService : "读取员工信息"
SalaryService --> SalaryRecord : "创建/更新"
SalaryService --> Staff : "读取基础工资/系数"
SalaryService --> Assessment : "读取加权得分"

图表来源

章节来源

性能考量

  • 数据库连接池与并发:
    • 配置文件提供数据库连接池大小与溢出参数,建议结合业务峰值合理设置
  • 查询优化:
    • SalaryRecord 与 Assessment 均具备按 staff_id、period、status 的索引,有利于分页与筛选
    • 批量生成时建议按部门分批处理,避免一次性加载过多记录
  • 事务与回滚:
    • 数据库会话在异常时自动回滚,确保数据一致性
  • I/O 与序列化:
    • API 层对响应进行统一包装,注意避免在高频接口中进行大量对象转换

章节来源

故障排查指南

  • 无法生成工资记录
    • 检查是否存在“已确认”的 Assessment
    • 检查是否已存在同员工/同周期的工资记录
    • 检查员工是否存在且基础工资/绩效系数有效
  • 更新失败
    • 仅允许对状态为“pending”的记录进行更新
  • 确认失败
    • 仅允许对状态为“pending”的记录进行确认
  • 批量生成/确认
    • 确认年/月参数正确
    • 如指定部门确认部门ID有效
  • 数据库异常
    • 查看会话依赖的回滚逻辑是否触发
    • 检查连接池配置与数据库可用性

章节来源

结论

SalaryService 提供了完整的工资核算闭环:从“已确认”的考核数据出发,结合员工基础信息,计算绩效奖金并生成工资记录;支持单条与批量生成、单条与批量确认,并通过严格的权限控制与状态约束保障业务正确性。配合合理的数据库索引与连接池配置,可在高并发场景下保持稳定与高效。

附录

实际计算示例与边界条件

  • 示例场景
    • 员工基础工资10000绩效系数1.2
    • 考核加权得分90
    • 奖金基数3000
    • 计算过程:奖金 = 3000 × (90/100) × 1.2;总工资 = 基础工资 + 奖金 + 补贴 - 扣款
  • 边界条件
    • 绩效得分/系数为 0奖金为 0
    • 补贴/扣款为负:不合法,应在输入层约束
    • 已存在同周期记录:拒绝重复生成
    • 非“已确认”考核:拒绝生成
    • 非“pending”状态拒绝更新/确认

章节来源