20 KiB
20 KiB
服务层开发
**本文档引用的文件** - [assessment_service.py](file://backend/app/services/assessment_service.py) - [salary_service.py](file://backend/app/services/salary_service.py) - [stats_service.py](file://backend/app/services/stats_service.py) - [department_service.py](file://backend/app/services/department_service.py) - [staff_service.py](file://backend/app/services/staff_service.py) - [indicator_service.py](file://backend/app/services/indicator_service.py) - [finance_service.py](file://backend/app/services/finance_service.py) - [performance_plan_service.py](file://backend/app/services/performance_plan_service.py) - [template_service.py](file://backend/app/services/template_service.py) - [menu_service.py](file://backend/app/services/menu_service.py) - [database.py](file://backend/app/core/database.py) - [config.py](file://backend/app/core/config.py) - [models.py](file://backend/app/models/models.py) - [assessments.py](file://backend/app/api/v1/assessments.py) - [salary.py](file://backend/app/api/v1/salary.py) - [stats.py](file://backend/app/api/v1/stats.py) - [departments.py](file://backend/app/api/v1/departments.py) - [staff.py](file://backend/app/api/v1/staff.py) - [indicators.py](file://backend/app/api/v1/indicators.py)目录
简介
本指南面向医院绩效系统服务层开发,系统化阐述服务层架构设计、依赖注入模式、业务逻辑封装与协作机制。文档覆盖考核服务、工资服务、统计服务、部门服务、员工服务、指标服务、财务服务、绩效计划服务、模板服务与菜单服务等核心模块,提供方法实现模式、参数校验、返回值处理、事务管理、异常处理与日志记录规范,并给出单元测试编写方法与Mock对象使用建议,以及性能优化与并发处理策略。
项目结构
后端采用分层架构,服务层位于API层与数据访问层之间,负责业务规则封装与跨实体协调。核心目录与文件关系如下:
graph TB
subgraph "API 层"
A1["/api/v1/assessments.py"]
A2["/api/v1/salary.py"]
A3["/api/v1/stats.py"]
A4["/api/v1/departments.py"]
A5["/api/v1/staff.py"]
A6["/api/v1/indicators.py"]
end
subgraph "服务层"
S1["assessment_service.py"]
S2["salary_service.py"]
S3["stats_service.py"]
S4["department_service.py"]
S5["staff_service.py"]
S6["indicator_service.py"]
S7["finance_service.py"]
S8["performance_plan_service.py"]
S9["template_service.py"]
S10["menu_service.py"]
end
subgraph "核心配置"
C1["core/config.py"]
C2["core/database.py"]
C3["models/models.py"]
end
A1 --> S1
A2 --> S2
A3 --> S3
A4 --> S4
A5 --> S5
A6 --> S6
S1 --> C2
S2 --> C2
S3 --> C2
S4 --> C2
S5 --> C2
S6 --> C2
S7 --> C2
S8 --> C2
S9 --> C2
S10 --> C2
S1 --> C3
S2 --> C3
S3 --> C3
S4 --> C3
S5 --> C3
S6 --> C3
S7 --> C3
S8 --> C3
S9 --> C3
S10 --> C3
C1 --> C2
图表来源
- assessments.py
- salary.py
- stats.py
- departments.py
- staff.py
- indicators.py
- assessment_service.py
- salary_service.py
- stats_service.py
- department_service.py
- staff_service.py
- indicator_service.py
- finance_service.py
- performance_plan_service.py
- template_service.py
- menu_service.py
- database.py
- config.py
- models.py
章节来源
核心组件
服务层由10个核心服务组成,分别对应业务领域:
- 考核服务:AssessmentService(创建、更新、提交、审核、确认、批量创建)
- 工资服务:SalaryService(计算绩效奖金、生成工资、批量生成、确认、批量确认)
- 统计服务:StatsService(BSC维度分析、科室统计、趋势分析、排名、完成度)
- 部门服务:DepartmentService(列表、树形结构、增删改查)
- 员工服务:StaffService(列表、详情、增删改查、按科室查询)
- 指标服务:IndicatorService(列表、模板导入、模板列表)
- 财务服务:FinanceService(收支明细、收支汇总、分类统计、增删改查)
- 绩效计划服务:PerformancePlanService(计划生命周期管理、树形结构、统计)
- 模板服务:TemplateService(模板增删改查、指标关联、标签映射)
- 菜单服务:MenuService(菜单树、列表、增删改查、默认菜单初始化)
每个服务均采用静态方法设计,便于在FastAPI依赖注入中直接调用,保持无状态与线程安全。
章节来源
- assessment_service.py
- salary_service.py
- stats_service.py
- department_service.py
- staff_service.py
- indicator_service.py
- finance_service.py
- performance_plan_service.py
- template_service.py
- menu_service.py
架构概览
服务层通过依赖注入从API层接收AsyncSession与当前用户上下文,执行业务逻辑并返回标准化响应。事务管理由数据库会话自动处理,异常通过HTTP异常抛出,日志通过应用日志框架记录。
sequenceDiagram
participant Client as "客户端"
participant API as "API路由"
participant Service as "服务层"
participant DB as "数据库会话"
participant Model as "ORM模型"
Client->>API : "HTTP请求"
API->>Service : "调用服务方法(AsyncSession, 参数)"
Service->>DB : "执行SQL查询/更新"
DB->>Model : "映射到ORM模型"
Model-->>DB : "返回结果"
DB-->>Service : "提交/回滚事务"
Service-->>API : "业务结果"
API-->>Client : "标准化响应"
图表来源
详细组件分析
考核服务 AssessmentService
- 功能职责
- 列表查询:支持多条件过滤、分页、总数统计
- 详情查询:加载员工、部门、明细与指标
- 创建:计算总分与加权得分,批量写入明细
- 更新:仅草稿或被拒状态下允许修改;重建明细并重算分数
- 提交/审核/确认:状态机流转,记录操作人与时间戳
- 批量创建:按科室与指标集合批量生成考核记录
- 实现模式
- 使用selectinload预加载关联,减少N+1查询
- flush/refresh确保持久化与读取一致性
- 状态前置校验,防止非法状态变更
- 参数验证与返回值
- API层进行输入参数校验与权限控制
- 服务层返回实体或None,由API层抛出HTTP异常
- 事务管理
- 单次调用内统一commit/rollback,保证原子性
- 并发处理
- 批量创建时先查询是否存在,避免重复创建
- 建议在API层增加幂等键与锁机制
flowchart TD
Start(["开始"]) --> CheckState["检查状态是否允许更新"]
CheckState --> |不允许| ReturnNone["返回None"]
CheckState --> |允许| DeleteOld["删除旧明细"]
DeleteOld --> Recalc["遍历新明细计算总分与加权分"]
Recalc --> Save["保存更新后的实体"]
Save --> Refresh["刷新实体"]
Refresh --> End(["结束"])
ReturnNone --> End
图表来源
章节来源
工资服务 SalaryService
- 功能职责
- 列表查询:支持按员工、科室、周期、状态过滤
- 详情查询:加载员工与部门信息
- 绩效奖金计算:奖金 = 基数 × (得分/100) × 绩效系数
- 创建/更新:计算总工资,仅待确认状态下允许更新
- 生成:从已确认考核生成工资记录
- 批量生成:按科室批量生成
- 确认/批量确认:变更状态并持久化
- 实现模式
- 通过员工信息读取基础工资与绩效系数
- 生成时检查重复,避免重复发薪
- 使用flush/refresh确保状态一致
- 参数验证与返回值
- API层校验周期与权限
- 服务层返回实体或None,API层处理错误
- 事务管理
- 单次操作内commit/rollback
- 性能优化
- 批量生成时一次查询所有已确认考核,减少往返
sequenceDiagram
participant API as "API"
participant SS as "SalaryService"
participant DB as "数据库"
API->>SS : "generate_from_assessment(staff_id, year, month)"
SS->>DB : "查询员工信息"
DB-->>SS : "员工信息"
SS->>DB : "查询已确认考核"
DB-->>SS : "考核记录"
SS->>SS : "计算绩效奖金"
SS->>DB : "创建工资记录"
DB-->>SS : "返回记录"
SS-->>API : "工资记录"
图表来源
章节来源
统计服务 StatsService
- 功能职责
- BSC维度统计:按维度汇总得分、权重与指标数量
- 科室统计:按科室汇总人数、总分、平均分、最高/最低分
- 趋势分析:月度趋势(支持跨年)
- 排名:员工与科室排名
- 完成度:指标平均分、目标完成率
- 实现模式
- 使用SQL聚合函数与分组,避免Python侧聚合
- 条件动态拼接,支持多维过滤
- 性能优化
- 合理使用索引与分页
- 趋势分析中对跨年场景进行区间合并
flowchart TD
Start(["开始"]) --> BuildCond["构建查询条件"]
BuildCond --> ExecQuery["执行聚合查询"]
ExecQuery --> GroupBy["按维度/科室/月份分组"]
GroupBy --> CalcAvg["计算平均分与完成率"]
CalcAvg --> Format["格式化输出"]
Format --> End(["结束"])
图表来源
章节来源
部门服务 DepartmentService
- 功能职责
- 列表查询:按类型与启用状态过滤
- 树形结构:手动构建父子关系,避免懒加载问题
- 增删改查:层级计算、唯一性校验
- 实现模式
- 手动构建树形结构,确保序列化稳定
- 删除前检查子节点,防止破坏层级
- 错误处理
- 不存在或有子节点时返回False/None,由API层抛错
章节来源
员工服务 StaffService
- 功能职责
- 列表查询:支持关键字搜索(姓名/工号)
- 详情查询:加载部门信息
- 增删改查:唯一性校验(工号)
- 按科室查询:返回在职员工
- 实现模式
- 使用ilike进行模糊匹配
- selectinload预加载部门
章节来源
指标服务 IndicatorService
- 功能职责
- 列表查询:按类型、维度、启用状态过滤
- 模板导入:支持覆盖策略
- 模板列表:内置模板集合
- 实现模式
- JSON字段存储适用科室类型数组
- 导入时检查编码唯一性
章节来源
财务服务 FinanceService
- 功能职责
- 收入/支出明细查询与汇总
- 收支结余计算
- 按类别统计收入/支出
- 增删改查财务记录
- 科室汇总:全院科室财务汇总
- 实现模式
- 类别标签映射,增强可读性
- 使用coalesce处理空值
章节来源
绩效计划服务 PerformancePlanService
- 功能职责
- 计划生命周期:草稿→待审批→批准→执行中→完成/取消
- 树形结构:支持层级关系
- 统计:按状态统计数量
- 指标关联:增删改查
- 实现模式
- 状态机严格控制流转
- 树形构建使用字典映射
章节来源
模板服务 TemplateService
- 功能职责
- 模板增删改查与指标关联
- 指标排序与去重
- 标签映射:类型与维度标签
- 实现模式
- 排序字段自动生成
- 关联唯一约束避免重复
章节来源
菜单服务 MenuService
- 功能职责
- 菜单树形结构与列表查询
- 增删改查与默认菜单初始化
- 实现模式
- 递归转字典,支持前端渲染
- 初始化时检查是否已有数据
章节来源
依赖分析
服务层依赖关系清晰,API层通过依赖注入获取AsyncSession与当前用户,服务层仅依赖数据库会话与模型定义,耦合度低、内聚性强。
graph TB
API_A["/api/v1/assessments.py"] --> SVC_A["AssessmentService"]
API_S["/api/v1/salary.py"] --> SVC_S["SalaryService"]
API_T["/api/v1/stats.py"] --> SVC_T["StatsService"]
API_D["/api/v1/departments.py"] --> SVC_D["DepartmentService"]
API_ST["/api/v1/staff.py"] --> SVC_ST["StaffService"]
API_I["/api/v1/indicators.py"] --> SVC_I["IndicatorService"]
SVC_A --> DB["get_db() AsyncSession"]
SVC_S --> DB
SVC_T --> DB
SVC_D --> DB
SVC_ST --> DB
SVC_I --> DB
SVC_A --> MODELS["models.py ORM"]
SVC_S --> MODELS
SVC_T --> MODELS
SVC_D --> MODELS
SVC_ST --> MODELS
SVC_I --> MODELS
图表来源
- assessments.py
- salary.py
- stats.py
- departments.py
- staff.py
- indicators.py
- assessment_service.py
- salary_service.py
- stats_service.py
- department_service.py
- staff_service.py
- indicator_service.py
- database.py
- models.py
章节来源
性能考虑
- 查询优化
- 使用selectinload预加载关联,避免N+1查询
- 合理使用索引(如staff、assessment、salary等表的复合索引)
- 分页参数限制,避免超大结果集
- 事务与并发
- 服务层单次调用内commit/rollback,保证一致性
- 批量操作使用flush减少往返
- 对重复创建场景增加存在性检查
- 缓存与降级
- 对只读统计结果可引入Redis缓存
- 对高频查询结果进行分页与限流
- 日志与监控
- 记录慢查询与异常堆栈
- 结合数据库慢查询日志定位瓶颈
故障排除指南
- 常见异常
- 未找到实体:返回None,API层抛出404
- 状态不允许:返回None,API层抛出400
- 唯一性冲突:编码重复导致创建失败,API层抛出400
- 事务回滚
- 数据库会话在异常时自动回滚,确保数据一致性
- 日志记录
- 应用日志与错误日志分离,便于排查
- 记录关键业务事件(创建、更新、状态变更)
章节来源
结论
服务层通过清晰的职责划分、严格的参数校验与状态机控制、完善的事务与异常处理,有效支撑了医院绩效系统的业务闭环。建议在后续迭代中进一步完善单元测试覆盖率、引入缓存与监控告警,并持续优化查询性能与并发处理能力。
附录
服务方法实现模式清单
- 列表查询:支持多条件过滤、分页、总数统计
- 详情查询:加载关联实体,返回完整信息
- 创建/更新:参数校验、业务计算、flush/refresh
- 删除:前置检查(如子节点、状态)
- 批量操作:批量查询、循环处理、一次性commit
参数验证与返回值处理
- API层负责输入参数校验与权限控制
- 服务层返回实体或None,由API层统一抛出HTTP异常
- 响应体遵循统一结构(code/message/data/total/page/page_size)
事务管理与异常处理
- 服务层单次调用内commit/rollback
- 数据库异常自动回滚并抛出
- 建议在API层捕获并记录异常日志
日志记录规范
- 记录关键业务事件与异常堆栈
- 区分应用日志与错误日志
- 包含请求ID、用户ID、操作时间
单元测试编写方法与Mock对象使用
- Mock数据库会话:使用unittest.mock.patch替换get_db依赖
- Mock服务方法:对复杂业务逻辑进行隔离测试
- 测试用例覆盖正常路径、边界条件与异常分支
- 使用pytest与factory_boy生成测试数据
性能优化与并发处理
- 查询优化:预加载、索引、分页
- 事务优化:批量flush、减少往返
- 并发控制:幂等键、锁机制、重试策略
- 监控与告警:慢查询、错误率、吞吐量