提交文件
This commit is contained in:
384
.qoder/repowiki/zh/content/业务逻辑设计/业务规则验证.md
Normal file
384
.qoder/repowiki/zh/content/业务逻辑设计/业务规则验证.md
Normal file
@@ -0,0 +1,384 @@
|
||||
# 业务规则验证
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.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/api/v1/assessments.py](file://backend/app/api/v1/assessments.py)
|
||||
- [backend/app/api/v1/indicators.py](file://backend/app/api/v1/indicators.py)
|
||||
- [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py)
|
||||
- [backend/app/main.py](file://backend/app/main.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)
|
||||
- [AGENTS.md](file://AGENTS.md)
|
||||
- [docs/frontend.md](file://docs/frontend.md)
|
||||
- [frontend/DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件聚焦于医院绩效系统的“业务规则验证”能力,系统性梳理并解释以下方面:
|
||||
- 考核周期限制、重复数据检查、数据完整性校验与业务冲突处理
|
||||
- 规则引擎实现、动态规则配置与扩展机制
|
||||
- 异常数据处理策略、错误提示与用户反馈机制
|
||||
- 业务规则的自定义配置、规则测试与维护指南
|
||||
|
||||
系统采用 FastAPI + SQLAlchemy 的后端架构,结合 Pydantic 数据模式进行输入输出校验;数据库层面通过索引与约束保证数据一致性;API 层对业务状态流转进行严格控制;前端通过统一错误处理与消息提示提升用户体验。
|
||||
|
||||
## 项目结构
|
||||
后端采用分层架构:API 路由层负责请求接入与权限控制,服务层封装业务规则与状态机,模型层定义数据结构与约束,模式层定义输入输出结构。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "API 层"
|
||||
A1["/assessments<br/>考核管理"]
|
||||
A2["/indicators<br/>指标管理"]
|
||||
A3["/staff<br/>员工管理"]
|
||||
end
|
||||
subgraph "服务层"
|
||||
S1["AssessmentService<br/>考核服务"]
|
||||
S2["PerformancePlanService<br/>绩效计划服务"]
|
||||
S3["IndicatorService<br/>指标服务"]
|
||||
S4["StaffService<br/>员工服务"]
|
||||
end
|
||||
subgraph "模型层"
|
||||
M1["Assessment<br/>考核记录"]
|
||||
M2["AssessmentDetail<br/>考核明细"]
|
||||
M3["Indicator<br/>考核指标"]
|
||||
M4["Staff<br/>员工"]
|
||||
M5["PerformancePlan<br/>绩效计划"]
|
||||
end
|
||||
subgraph "模式层"
|
||||
P1["AssessmentCreate/Update/Response"]
|
||||
P2["IndicatorCreate/Update/Response"]
|
||||
P3["StaffCreate/Update/Response"]
|
||||
end
|
||||
A1 --> S1
|
||||
A2 --> S3
|
||||
A3 --> S4
|
||||
S1 --> M1
|
||||
S1 --> M2
|
||||
S1 --> M3
|
||||
S2 --> M5
|
||||
S3 --> M3
|
||||
S4 --> M4
|
||||
S1 --> P1
|
||||
S3 --> P2
|
||||
S4 --> P3
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [backend/app/api/v1/indicators.py](file://backend/app/api/v1/indicators.py#L1-L142)
|
||||
- [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L1-L124)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py#L1-L342)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L117-L203)
|
||||
- [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L194-L311)
|
||||
|
||||
章节来源
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [backend/app/api/v1/indicators.py](file://backend/app/api/v1/indicators.py#L1-L142)
|
||||
- [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L1-L124)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py#L1-L342)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L117-L203)
|
||||
- [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L194-L311)
|
||||
|
||||
## 核心组件
|
||||
- 考核服务(AssessmentService):实现考核记录的创建、更新、提交、审核、确认与批量创建;内置状态机与关键业务约束(如草稿/已提交/已审核/已确认状态流转限制、重复考核记录检查)。
|
||||
- 绩效计划服务(PerformancePlanService):实现计划的创建、提交、审批、激活与统计;支持 KPI 关联的增删改查。
|
||||
- 指标服务(IndicatorService):实现指标的 CRUD、模板导入与去重策略。
|
||||
- 员工服务(StaffService):实现员工的 CRUD、按科室检索与关键字搜索。
|
||||
- 数据模型(models.py):定义实体、枚举、索引与约束(如权重>0、唯一索引、外键关系)。
|
||||
- 数据模式(schemas.py):定义输入输出结构与 Pydantic 校验规则(范围、长度、枚举、必填等)。
|
||||
- API 路由(assessments.py、indicators.py、staff.py):暴露 REST 接口,集成权限依赖与错误处理。
|
||||
- 安全模块(security.py):JWT 解析、用户鉴权与角色权限控制。
|
||||
- 主程序(main.py):全局异常处理与日志记录。
|
||||
|
||||
章节来源
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L14-L263)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py#L15-L342)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L117-L203)
|
||||
- [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L194-L311)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [backend/app/api/v1/indicators.py](file://backend/app/api/v1/indicators.py#L1-L142)
|
||||
- [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L1-L124)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L55-L110)
|
||||
- [backend/app/main.py](file://backend/app/main.py#L58-L75)
|
||||
|
||||
## 架构总览
|
||||
系统通过 API 路由接收请求,经由安全中间件与权限依赖进行身份与角色校验,随后调用对应服务层执行业务规则与状态机控制,最终持久化到数据库并通过模式层进行序列化返回。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant FE as "前端"
|
||||
participant API as "API 路由"
|
||||
participant SEC as "安全模块"
|
||||
participant SVC as "服务层"
|
||||
participant DB as "数据库"
|
||||
FE->>API : "提交请求"
|
||||
API->>SEC : "解析JWT/校验权限"
|
||||
SEC-->>API : "返回当前用户"
|
||||
API->>SVC : "调用业务方法"
|
||||
SVC->>DB : "读写数据/执行约束"
|
||||
DB-->>SVC : "返回结果"
|
||||
SVC-->>API : "返回领域对象"
|
||||
API-->>FE : "标准化响应"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L55-L110)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L70-L108)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L149-L178)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 考核记录业务规则验证
|
||||
- 状态机与流转控制
|
||||
- 草稿(draft)→ 提交(submitted)→ 审核(reviewed/rejected)→ 确认(finalized)
|
||||
- 仅允许特定状态下的操作,防止逆向或越权变更
|
||||
- 重复数据检查
|
||||
- 批量创建时按“员工+年度+月份”组合检查是否存在重复记录
|
||||
- 总分与加权得分计算
|
||||
- 总分:明细得分求和
|
||||
- 加权得分:明细得分×指标权重求和
|
||||
- 明细完整性
|
||||
- 每条明细包含指标ID、实际值、得分、佐证材料、备注等字段
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 草稿
|
||||
草稿 --> 已提交 : "提交"
|
||||
已提交 --> 已审核 : "审核通过"
|
||||
已提交 --> 已驳回 : "审核不通过"
|
||||
已审核 --> 已确认 : "确认"
|
||||
已确认 --> [*]
|
||||
已驳回 --> [*]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L45-L51)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L158-L205)
|
||||
|
||||
章节来源
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L70-L108)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L208-L262)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L149-L178)
|
||||
|
||||
### 绩效计划业务规则验证
|
||||
- 计划状态机
|
||||
- 草稿(draft)→ 待审批(pending)→ 批准(approved)→ 执行中(active)→ 完成(completed)
|
||||
- 审批与版本
|
||||
- 审批通过/拒绝时记录审批人、审批时间与意见
|
||||
- 激活后标记为生效
|
||||
- KPI 关联管理
|
||||
- 支持增删改查 KPI 关联,包含目标值、权重、评分方法与参数
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["创建计划"]) --> Draft["保存为草稿"]
|
||||
Draft --> Pending["提交审批"]
|
||||
Pending --> Approved{"审批通过?"}
|
||||
Approved --> |是| Active["激活执行"]
|
||||
Approved --> |否| Rejected["标记为已驳回"]
|
||||
Active --> Completed["完成"]
|
||||
Rejected --> End(["结束"])
|
||||
Completed --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L270-L296)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py#L130-L182)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py#L195-L249)
|
||||
|
||||
章节来源
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py#L15-L342)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L270-L338)
|
||||
|
||||
### 指标与模板业务规则验证
|
||||
- 指标唯一性
|
||||
- 指标编码唯一,创建前需检查重复
|
||||
- 权重约束
|
||||
- 指标权重>0,数据库层通过 CheckConstraint 保证
|
||||
- 模板导入
|
||||
- 支持覆盖或跳过已存在指标,避免重复创建
|
||||
- 适用科室类型
|
||||
- 指标可标注适用科室类型集合(JSON 字符串),用于筛选与过滤
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Import["导入模板"] --> CheckCode["按编码检查是否已存在"]
|
||||
CheckCode --> Exists{"已存在?"}
|
||||
Exists --> |是且覆盖| Update["更新现有指标"]
|
||||
Exists --> |是且不覆盖| Skip["跳过该指标"]
|
||||
Exists --> |否| Create["创建新指标"]
|
||||
Update --> Done["提交事务"]
|
||||
Skip --> Done
|
||||
Create --> Done
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/api/v1/indicators.py](file://backend/app/api/v1/indicators.py#L128-L141)
|
||||
- [backend/app/services/indicator_service.py](file://backend/app/services/indicator_service.py#L106-L154)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L143-L146)
|
||||
|
||||
章节来源
|
||||
- [backend/app/api/v1/indicators.py](file://backend/app/api/v1/indicators.py#L71-L112)
|
||||
- [backend/app/services/indicator_service.py](file://backend/app/services/indicator_service.py#L67-L104)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L117-L146)
|
||||
|
||||
### 员工业务规则验证
|
||||
- 工号唯一性
|
||||
- 创建时检查工号是否已存在
|
||||
- 关键字搜索
|
||||
- 支持姓名或工号模糊匹配
|
||||
- 状态与部门过滤
|
||||
- 支持按部门与状态筛选
|
||||
|
||||
章节来源
|
||||
- [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L68-L108)
|
||||
- [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py#L69-L112)
|
||||
|
||||
### 数据模型与约束
|
||||
- 考核记录与明细
|
||||
- 考核记录:staff_id、period_year、period_month、status、assessor_id、reviewer_id 等
|
||||
- 明细:assessment_id、indicator_id、actual_value、score、evidence、remark
|
||||
- 索引:staff、period_year+month、status
|
||||
- 指标
|
||||
- code 唯一;weight>0;bs_dimension、target_unit、assessment_method、deduction_standard、data_source、applicable_dept_types、is_veto
|
||||
- 模板与关联
|
||||
- 模板:template_code 唯一;模板指标关联唯一约束(template_id, indicator_id)
|
||||
|
||||
章节来源
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L149-L203)
|
||||
- [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L87-L131)
|
||||
- [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py#L21-L63)
|
||||
|
||||
### 规则引擎与动态配置
|
||||
- 当前实现
|
||||
- 业务规则主要以内置服务方法与状态机形式实现,例如:状态流转限制、重复记录检查、权重>0 约束等
|
||||
- 动态规则配置建议
|
||||
- 可引入“规则配置表”,存储规则表达式(如 JSON/脚本片段),在服务层按配置动态执行
|
||||
- 对于“一票否决”等强约束,可在模型层增加布尔标志并在服务层强制执行
|
||||
- 扩展机制
|
||||
- 通过插件化或策略模式扩展不同科室类型的评分策略
|
||||
- 为 KPI 关联增加“评分参数(JSON)”字段,支持动态参数化评分
|
||||
|
||||
章节来源
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L133-L136)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L314-L338)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py#L195-L249)
|
||||
|
||||
### 异常数据处理与用户反馈
|
||||
- 后端异常处理
|
||||
- HTTP 异常与校验异常分别捕获并记录日志,保持接口稳定性
|
||||
- 前端错误处理
|
||||
- 统一使用 Element Plus 的消息与确认框,区分成功/警告/错误场景
|
||||
- 错误提示
|
||||
- 员工不存在、工号已存在、指标编码已存在、状态不允许等明确提示
|
||||
|
||||
章节来源
|
||||
- [backend/app/main.py](file://backend/app/main.py#L58-L75)
|
||||
- [AGENTS.md](file://AGENTS.md#L112-L134)
|
||||
- [docs/frontend.md](file://docs/frontend.md#L291-L325)
|
||||
|
||||
## 依赖分析
|
||||
- API 依赖安全模块进行用户鉴权与角色校验
|
||||
- 服务层依赖模型层进行数据读写与约束校验
|
||||
- 模式层为 API 与服务层提供输入输出结构与 Pydantic 校验
|
||||
- 数据库迁移脚本定义表结构、索引与约束
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
API_A["/assessments"] --> SEC["security.py"]
|
||||
API_I["/indicators"] --> SEC
|
||||
API_S["/staff"] --> SEC
|
||||
SEC --> SVC_A["AssessmentService"]
|
||||
SEC --> SVC_P["PerformancePlanService"]
|
||||
SEC --> SVC_I["IndicatorService"]
|
||||
SEC --> SVC_S["StaffService"]
|
||||
SVC_A --> MODELS["models.py"]
|
||||
SVC_P --> MODELS
|
||||
SVC_I --> MODELS
|
||||
SVC_S --> MODELS
|
||||
MODELS --> SCHEMAS["schemas.py"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [backend/app/api/v1/indicators.py](file://backend/app/api/v1/indicators.py#L1-L142)
|
||||
- [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L1-L124)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L55-L110)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py#L1-L342)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438)
|
||||
- [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L1-L743)
|
||||
|
||||
章节来源
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L55-L110)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py#L1-L342)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438)
|
||||
- [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L1-L743)
|
||||
|
||||
## 性能考虑
|
||||
- 查询优化
|
||||
- 使用 selectinload 预加载关联对象,减少 N+1 查询
|
||||
- 为高频查询字段建立索引(如 staff_id、period_year+month、status)
|
||||
- 分页与总数统计
|
||||
- 使用子查询统计总数,避免重复扫描
|
||||
- 并发与事务
|
||||
- 批量创建时使用 flush/commit 控制事务边界,确保一致性
|
||||
- 缓存与热点
|
||||
- 对常用指标与模板可引入缓存层,降低数据库压力
|
||||
|
||||
章节来源
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L28-L55)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py#L28-L59)
|
||||
- [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L110-L112)
|
||||
|
||||
## 故障排查指南
|
||||
- 后端健康检查
|
||||
- 访问 /health 确认服务可用
|
||||
- 日志定位
|
||||
- 查看后端日志目录中的 app_*.log 与 error_*.log
|
||||
- 常见问题
|
||||
- 404:检查路由前缀与接口路径
|
||||
- 500:查看后端异常堆栈与数据库约束冲突
|
||||
- CORS:确认前端代理与后端 CORS 配置一致
|
||||
- 前端调试
|
||||
- 使用浏览器开发者工具查看 Console 与 Network 标签,确认请求头与响应体
|
||||
|
||||
章节来源
|
||||
- [backend/app/main.py](file://backend/app/main.py#L54-L56)
|
||||
- [frontend/DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L1-L60)
|
||||
|
||||
## 结论
|
||||
系统在业务规则验证方面具备完善的层次化实现:API 层进行权限与输入校验,服务层执行状态机与关键约束,模型层通过索引与约束保障数据完整性。对于动态规则与扩展需求,建议引入规则配置表与参数化评分机制,以增强灵活性与可维护性。
|
||||
|
||||
## 附录
|
||||
- 自定义配置建议
|
||||
- 新增“规则配置表”,支持按科室类型/指标类型配置评分策略
|
||||
- 为 KPI 关联增加“评分参数(JSON)”字段,支持动态参数化
|
||||
- 规则测试
|
||||
- 单元测试覆盖状态机边界条件(草稿→提交→审核→确认)
|
||||
- 集成测试覆盖重复数据检查与约束触发场景
|
||||
- 维护指南
|
||||
- 通过 Alembic 迁移管理数据库结构演进
|
||||
- 保持 Pydantic 模式与数据库约束同步,避免运行时异常
|
||||
449
.qoder/repowiki/zh/content/业务逻辑设计/业务逻辑设计.md
Normal file
449
.qoder/repowiki/zh/content/业务逻辑设计/业务逻辑设计.md
Normal file
@@ -0,0 +1,449 @@
|
||||
# 业务逻辑设计
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [backend/app/main.py](file://backend/app/main.py)
|
||||
- [backend/app/core/config.py](file://backend/app/core/config.py)
|
||||
- [backend/app/core/database.py](file://backend/app/core/database.py)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.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/api/v1/__init__.py](file://backend/app/api/v1/__init__.py)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py)
|
||||
- [backend/app/api/v1/salary.py](file://backend/app/api/v1/salary.py)
|
||||
- [backend/app/api/v1/stats.py](file://backend/app/api/v1/stats.py)
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py)
|
||||
- [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py)
|
||||
- [backend/app/services/stats_service.py](file://backend/app/services/stats_service.py)
|
||||
- [backend/app/services/template_service.py](file://backend/app/services/template_service.py)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 引言
|
||||
|
||||
本文件为医院绩效系统的业务逻辑设计文档,旨在全面阐述系统的业务规则、流程控制、状态转换、权限控制、并发处理和事务管理等核心机制。通过对考核流程、工资计算算法、统计分析逻辑以及权限控制机制的深入解析,帮助开发者和运维人员准确理解系统的设计思路与实现细节,并为后续的功能扩展、性能优化和维护提供指导。
|
||||
|
||||
## 项目结构
|
||||
|
||||
后端采用 FastAPI + SQLAlchemy 2.0 的异步架构,遵循分层设计模式,主要分为以下层次:
|
||||
|
||||
- 应用入口层:负责应用实例创建、中间件配置、路由注册与异常处理
|
||||
- API 层:定义 REST 接口,处理请求参数校验与响应封装
|
||||
- 服务层:实现业务逻辑,协调数据访问与跨表操作
|
||||
- 数据模型层:定义数据库实体与关系映射
|
||||
- 核心配置层:提供数据库连接、安全认证、配置管理等基础设施
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "应用入口层"
|
||||
MAIN["main.py<br/>应用实例创建"]
|
||||
ROUTER_INIT["api/v1/__init__.py<br/>路由注册"]
|
||||
end
|
||||
subgraph "API 层"
|
||||
ASSESSMENTS_API["assessments.py<br/>考核接口"]
|
||||
SALARY_API["salary.py<br/>工资接口"]
|
||||
STATS_API["stats.py<br/>统计接口"]
|
||||
AUTH_API["auth.py<br/>认证接口"]
|
||||
end
|
||||
subgraph "服务层"
|
||||
ASSESSMENT_SERVICE["assessment_service.py<br/>考核服务"]
|
||||
SALARY_SERVICE["salary_service.py<br/>工资服务"]
|
||||
STATS_SERVICE["stats_service.py<br/>统计服务"]
|
||||
TEMPLATE_SERVICE["template_service.py<br/>模板服务"]
|
||||
PLAN_SERVICE["performance_plan_service.py<br/>计划服务"]
|
||||
end
|
||||
subgraph "数据模型层"
|
||||
MODELS["models.py<br/>数据模型"]
|
||||
SCHEMAS["schemas.py<br/>数据模式"]
|
||||
end
|
||||
subgraph "核心配置层"
|
||||
CONFIG["config.py<br/>系统配置"]
|
||||
DATABASE["database.py<br/>数据库连接"]
|
||||
SECURITY["security.py<br/>安全认证"]
|
||||
end
|
||||
MAIN --> ROUTER_INIT
|
||||
ROUTER_INIT --> ASSESSMENTS_API
|
||||
ROUTER_INIT --> SALARY_API
|
||||
ROUTER_INIT --> STATS_API
|
||||
ROUTER_INIT --> AUTH_API
|
||||
ASSESSMENTS_API --> ASSESSMENT_SERVICE
|
||||
SALARY_API --> SALARY_SERVICE
|
||||
STATS_API --> STATS_SERVICE
|
||||
ASSESSMENT_SERVICE --> MODELS
|
||||
SALARY_SERVICE --> MODELS
|
||||
STATS_SERVICE --> MODELS
|
||||
TEMPLATE_SERVICE --> MODELS
|
||||
PLAN_SERVICE --> MODELS
|
||||
MODELS --> DATABASE
|
||||
ASSESSMENTS_API --> SECURITY
|
||||
SALARY_API --> SECURITY
|
||||
STATS_API --> SECURITY
|
||||
AUTH_API --> SECURITY
|
||||
CONFIG --> DATABASE
|
||||
CONFIG --> SECURITY
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/main.py](file://backend/app/main.py#L15-L77)
|
||||
- [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py#L1-L17)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [backend/app/api/v1/salary.py](file://backend/app/api/v1/salary.py#L1-L156)
|
||||
- [backend/app/api/v1/stats.py](file://backend/app/api/v1/stats.py#L1-L242)
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L1-L74)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py#L1-L260)
|
||||
- [backend/app/services/stats_service.py](file://backend/app/services/stats_service.py#L1-L300)
|
||||
- [backend/app/services/template_service.py](file://backend/app/services/template_service.py#L1-L293)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py#L1-L342)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438)
|
||||
- [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L1-L743)
|
||||
- [backend/app/core/config.py](file://backend/app/core/config.py#L1-L47)
|
||||
- [backend/app/core/database.py](file://backend/app/core/database.py#L1-L39)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110)
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/main.py](file://backend/app/main.py#L15-L77)
|
||||
- [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py#L1-L17)
|
||||
|
||||
## 核心组件
|
||||
|
||||
本节概述系统的核心业务组件及其职责边界:
|
||||
|
||||
- 考核管理:支持个人与批量考核创建、状态流转(草稿→提交→审核→确认)、明细评分与加权计算
|
||||
- 工资核算:基于考核结果自动计算绩效奖金,支持单条与批量工资生成、确认与批量确认
|
||||
- 统计分析:提供 BSC 维度分析、科室与个人排名、趋势分析、指标完成度等多维统计
|
||||
- 权限控制:基于 JWT 的用户认证与授权,区分普通员工、管理员与经理权限
|
||||
- 模板管理:支持指标模板的创建、维护与关联,支撑不同科室类型的标准化考核
|
||||
- 绩效计划:支持医院级、科室级、个人级计划的生命周期管理与审批流程
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L14-L263)
|
||||
- [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py#L14-L260)
|
||||
- [backend/app/services/stats_service.py](file://backend/app/services/stats_service.py#L16-L300)
|
||||
- [backend/app/services/template_service.py](file://backend/app/services/template_service.py#L20-L293)
|
||||
- [backend/app/services/performance_plan_service.py](file://backend/app/services/performance_plan_service.py#L15-L342)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L55-L110)
|
||||
|
||||
## 架构概览
|
||||
|
||||
系统采用分层架构,API 层负责请求处理与响应封装,服务层承载业务规则,数据模型层抽象数据库实体,核心配置层提供基础设施能力。数据库连接采用异步 SQLAlchemy,确保高并发场景下的性能表现;安全认证基于 JWT,结合权限装饰器实现细粒度的访问控制。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
CLIENT["客户端"]
|
||||
API["API 层<br/>FastAPI 路由"]
|
||||
SERVICE["服务层<br/>业务逻辑"]
|
||||
MODEL["数据模型层<br/>SQLAlchemy ORM"]
|
||||
DB["数据库<br/>PostgreSQL"]
|
||||
SEC["安全认证<br/>JWT + 权限"]
|
||||
CLIENT --> API
|
||||
API --> SEC
|
||||
API --> SERVICE
|
||||
SERVICE --> MODEL
|
||||
MODEL --> DB
|
||||
SEC --> DB
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/main.py](file://backend/app/main.py#L19-L48)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L21-L53)
|
||||
- [backend/app/core/database.py](file://backend/app/core/database.py#L10-L20)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 考核流程设计
|
||||
|
||||
考核流程围绕 Assessment 与 AssessmentDetail 实体展开,支持从草稿到确认的完整闭环。服务层提供创建、更新、提交、审核、确认等操作,并严格控制状态转换合法性。
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 草稿
|
||||
草稿 --> 已提交 : "提交"
|
||||
已提交 --> 已审核 : "审核通过"
|
||||
已提交 --> 已驳回 : "审核驳回"
|
||||
已审核 --> 已确认 : "确认"
|
||||
已确认 --> [*]
|
||||
已驳回 --> [*]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L45-L52)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L158-L206)
|
||||
|
||||
关键实现要点:
|
||||
- 总分与加权得分计算:遍历明细项累加得分,并乘以对应指标权重得到加权得分
|
||||
- 状态校验:仅允许在特定状态下进行状态变更,防止非法状态转换
|
||||
- 批量创建:按科室批量生成考核记录,避免重复创建
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L70-L108)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L110-L156)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L208-L262)
|
||||
|
||||
### 工资计算算法
|
||||
|
||||
工资计算基于考核结果与员工基本信息,采用固定基数与绩效系数相结合的方式计算绩效奖金,并据此生成最终工资。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["开始"]) --> GetAssessment["获取已确认考核记录"]
|
||||
GetAssessment --> CheckExist{"是否存在?"}
|
||||
CheckExist --> |否| EndError["结束:无匹配记录"]
|
||||
CheckExist --> |是| CalcBonus["计算绩效奖金<br/>奖金 = 基数 × (加权得分/100) × 绩效系数"]
|
||||
CalcBonus --> CalcTotal["计算应发工资<br/>应发 = 基本工资 + 绩效奖金 + 补贴 - 扣款"]
|
||||
CalcTotal --> CreateRecord["创建工资记录"]
|
||||
CreateRecord --> EndSuccess["结束:生成成功"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py#L127-L190)
|
||||
- [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py#L70-L101)
|
||||
|
||||
关键实现要点:
|
||||
- 绩效基数为可配置常量,便于统一调整
|
||||
- 单次生成时检查是否已存在对应期次的工资记录,避免重复
|
||||
- 批量生成支持按科室筛选已确认的考核记录
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py#L17-L26)
|
||||
- [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py#L127-L190)
|
||||
- [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py#L192-L219)
|
||||
|
||||
### 统计分析逻辑
|
||||
|
||||
统计服务提供多维度的分析能力,包括 BSC 维度分析、科室与个人排名、趋势分析、指标完成度等。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class StatsService {
|
||||
+get_bsc_dimension_stats(db, department_id, period_year, period_month) Dict
|
||||
+get_department_stats(db, period_year, period_month) List
|
||||
+get_trend_stats(db, department_id, period_year, months) List
|
||||
+get_ranking_stats(db, period_year, period_month, limit) List
|
||||
+get_completion_stats(db, indicator_id, period_year, period_month) Dict
|
||||
}
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/services/stats_service.py](file://backend/app/services/stats_service.py#L16-L300)
|
||||
|
||||
关键实现要点:
|
||||
- BSC 维度分析:按平衡计分卡四个维度聚合得分与权重,计算平均分
|
||||
- 科室统计:按科室汇总员工数量、总分、平均分、最高/最低分
|
||||
- 趋势分析:支持跨月度的趋势统计,考虑跨年场景
|
||||
- 排名统计:支持个人与科室的加权得分排名
|
||||
- 指标完成度:计算指标平均得分与目标值的完成率
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/services/stats_service.py](file://backend/app/services/stats_service.py#L19-L72)
|
||||
- [backend/app/services/stats_service.py](file://backend/app/services/stats_service.py#L74-L146)
|
||||
- [backend/app/services/stats_service.py](file://backend/app/services/stats_service.py#L148-L199)
|
||||
- [backend/app/services/stats_service.py](file://backend/app/services/stats_service.py#L201-L244)
|
||||
- [backend/app/services/stats_service.py](file://backend/app/services/stats_service.py#L246-L299)
|
||||
|
||||
### 权限控制机制
|
||||
|
||||
系统采用基于 JWT 的认证与授权机制,结合 FastAPI 的依赖注入实现细粒度的权限控制。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as "客户端"
|
||||
participant AuthAPI as "认证接口"
|
||||
participant Security as "安全模块"
|
||||
participant DB as "数据库"
|
||||
Client->>AuthAPI : POST /api/v1/auth/login
|
||||
AuthAPI->>Security : 验证用户名与密码
|
||||
Security->>DB : 查询用户信息
|
||||
DB-->>Security : 用户记录
|
||||
Security-->>AuthAPI : 生成访问令牌
|
||||
AuthAPI-->>Client : 返回令牌
|
||||
Client->>ProtectedAPI : 请求受保护资源
|
||||
ProtectedAPI->>Security : 解析与验证令牌
|
||||
Security-->>ProtectedAPI : 当前用户信息
|
||||
ProtectedAPI-->>Client : 返回业务数据
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L37)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L55-L82)
|
||||
|
||||
关键实现要点:
|
||||
- 登录接口:校验用户名与密码,返回 JWT 令牌
|
||||
- 当前用户:从令牌解析用户 ID,查询数据库获取用户对象
|
||||
- 权限装饰器:提供获取激活用户、管理员与经理用户的依赖函数
|
||||
- 角色区分:普通员工、管理员、经理,不同操作需要不同权限级别
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L37)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L55-L110)
|
||||
|
||||
### 并发处理与事务管理
|
||||
|
||||
系统采用异步 SQLAlchemy 连接池与依赖注入的会话管理,确保事务的正确提交与回滚。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["请求进入"]) --> GetSession["获取异步会话"]
|
||||
GetSession --> ExecuteOps["执行数据库操作"]
|
||||
ExecuteOps --> CommitOrRollback{"操作成功?"}
|
||||
CommitOrRollback --> |是| Commit["提交事务"]
|
||||
CommitOrRollback --> |否| Rollback["回滚事务"]
|
||||
Commit --> CloseSession["关闭会话"]
|
||||
Rollback --> CloseSession
|
||||
CloseSession --> End(["请求结束"])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/core/database.py](file://backend/app/core/database.py#L28-L39)
|
||||
|
||||
关键实现要点:
|
||||
- 会话工厂:配置异步引擎与会话参数,开启自动提交与回滚
|
||||
- 依赖注入:在每个请求中创建独立会话,确保线程安全
|
||||
- 异常处理:捕获异常并执行回滚,防止脏数据
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/core/database.py](file://backend/app/core/database.py#L28-L39)
|
||||
|
||||
### 业务规则验证与状态转换
|
||||
|
||||
业务规则通过服务层的状态校验与数据约束共同实现,确保流程的合规性与数据一致性。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Entry(["业务操作入口"]) --> ValidateInput["校验输入参数"]
|
||||
ValidateInput --> CheckStatus["检查当前状态"]
|
||||
CheckStatus --> StatusOK{"状态允许?"}
|
||||
StatusOK --> |否| Reject["拒绝操作并返回错误"]
|
||||
StatusOK --> |是| ApplyRule["应用业务规则"]
|
||||
ApplyRule --> Persist["持久化数据"]
|
||||
Persist --> UpdateState["更新状态"]
|
||||
UpdateState --> Success["返回成功响应"]
|
||||
Reject --> End(["结束"])
|
||||
Success --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L117-L118)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L176-L177)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L198-L199)
|
||||
|
||||
关键实现要点:
|
||||
- 状态转换:仅在合法状态下允许下一步操作
|
||||
- 参数校验:对关键字段进行范围与格式校验
|
||||
- 数据一致性:通过事务保证多表写入的一致性
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L110-L156)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L158-L206)
|
||||
|
||||
### 扩展点与自定义配置
|
||||
|
||||
系统提供了丰富的扩展点与配置项,便于根据医院实际需求进行定制:
|
||||
|
||||
- 配置扩展:数据库连接池大小、JWT 过期时间、分页参数等
|
||||
- 工资算法扩展:通过调整绩效基数与系数实现不同的激励策略
|
||||
- 统计维度扩展:新增统计指标与分析维度
|
||||
- 权限扩展:新增角色与权限标识,配合前端菜单控制
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/core/config.py](file://backend/app/core/config.py#L12-L33)
|
||||
- [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py#L17-L18)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
系统各层之间的依赖关系清晰,API 层依赖服务层,服务层依赖数据模型层,核心配置层为底层基础设施。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
API_ASSESS["API: 考核接口"] --> SVC_ASSESS["服务: 考核服务"]
|
||||
API_SALARY["API: 工资接口"] --> SVC_SALARY["服务: 工资服务"]
|
||||
API_STATS["API: 统计接口"] --> SVC_STATS["服务: 统计服务"]
|
||||
API_AUTH["API: 认证接口"] --> SEC["安全模块"]
|
||||
SVC_ASSESS --> MODELS["数据模型"]
|
||||
SVC_SALARY --> MODELS
|
||||
SVC_STATS --> MODELS
|
||||
MODELS --> DB["数据库连接"]
|
||||
SEC --> DB
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [backend/app/api/v1/salary.py](file://backend/app/api/v1/salary.py#L1-L156)
|
||||
- [backend/app/api/v1/stats.py](file://backend/app/api/v1/stats.py#L1-L242)
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L1-L74)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py#L1-L260)
|
||||
- [backend/app/services/stats_service.py](file://backend/app/services/stats_service.py#L1-L300)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438)
|
||||
- [backend/app/core/database.py](file://backend/app/core/database.py#L1-L39)
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [backend/app/api/v1/salary.py](file://backend/app/api/v1/salary.py#L1-L156)
|
||||
- [backend/app/api/v1/stats.py](file://backend/app/api/v1/stats.py#L1-L242)
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L1-L74)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [backend/app/services/salary_service.py](file://backend/app/services/salary_service.py#L1-L260)
|
||||
- [backend/app/services/stats_service.py](file://backend/app/services/stats_service.py#L1-L300)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438)
|
||||
- [backend/app/core/database.py](file://backend/app/core/database.py#L1-L39)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
- 异步 I/O:采用 SQLAlchemy 2.0 异步引擎与会话,提升高并发场景下的吞吐量
|
||||
- 连接池配置:通过配置文件调整连接池大小与溢出数量,平衡内存与性能
|
||||
- 查询优化:服务层使用 selectinload 进行关联加载,减少 N+1 查询问题
|
||||
- 分页与索引:API 层支持分页,模型层为常用查询字段建立索引,提升查询效率
|
||||
- 缓存策略:建议在统计分析层引入 Redis 缓存热点数据,降低数据库压力
|
||||
|
||||
[本节为通用性能建议,不涉及具体文件分析]
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
常见问题与排查步骤:
|
||||
- 认证失败:检查用户名与密码是否正确,确认用户状态为激活
|
||||
- 权限不足:确认当前用户角色是否满足操作要求(管理员/经理)
|
||||
- 状态转换错误:检查当前记录状态是否允许进行下一步操作
|
||||
- 数据库异常:查看日志文件,确认连接池配置与事务提交/回滚是否正常
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L30-L34)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L94-L109)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L117-L118)
|
||||
- [backend/app/core/database.py](file://backend/app/core/database.py#L34-L36)
|
||||
|
||||
## 结论
|
||||
|
||||
本系统通过清晰的分层架构与严格的业务规则实现了医院绩效管理的全流程自动化,涵盖考核、工资、统计与权限控制等核心功能。服务层的状态机设计与事务管理确保了业务流程的合规性与数据一致性,异步数据库连接提升了系统在高并发场景下的稳定性。未来可在统计分析与缓存策略方面进一步优化,以满足更大规模的应用需求。
|
||||
|
||||
[本节为总结性内容,不涉及具体文件分析]
|
||||
|
||||
## 附录
|
||||
|
||||
- 数据模型概览:涵盖科室、员工、指标、考核、工资、计划、模板、菜单等核心实体
|
||||
- API 接口清单:提供各模块的 REST 接口说明与权限要求
|
||||
- 配置参数说明:数据库连接、JWT、分页等系统配置项
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L62-L438)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L20-L166)
|
||||
- [backend/app/api/v1/salary.py](file://backend/app/api/v1/salary.py#L20-L156)
|
||||
- [backend/app/api/v1/stats.py](file://backend/app/api/v1/stats.py#L17-L242)
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L74)
|
||||
- [backend/app/core/config.py](file://backend/app/core/config.py#L12-L33)
|
||||
349
.qoder/repowiki/zh/content/业务逻辑设计/工资计算算法.md
Normal file
349
.qoder/repowiki/zh/content/业务逻辑设计/工资计算算法.md
Normal file
@@ -0,0 +1,349 @@
|
||||
# 工资计算算法
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py)
|
||||
- [salary.py](file://backend/app/api/v1/salary.py)
|
||||
- [models.py](file://backend/app/models/models.py)
|
||||
- [schemas.py](file://backend/app/schemas/schemas.py)
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py)
|
||||
- [assessments.py](file://backend/app/api/v1/assessments.py)
|
||||
- [finance.py](file://backend/app/models/finance.py)
|
||||
- [database.md](file://docs/database.md)
|
||||
- [详细设计.md](file://docs/详细设计.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件面向医院绩效系统的工资计算算法,系统性阐述绩效奖金计算公式、工资构成要素与计算逻辑,解释基础工资、绩效系数、考核得分权重的计算方法,覆盖不同岗位类型的差异、特殊津贴与扣款处理,以及批量工资生成的算法实现、并发处理与数据一致性保障。同时提供计算规则的配置方式、扩展点与性能优化策略,帮助读者在理解现有实现的基础上进行定制与演进。
|
||||
|
||||
## 项目结构
|
||||
后端采用FastAPI + SQLAlchemy异步ORM,服务层负责业务逻辑,API层提供REST接口,模型层定义数据库表结构与关系,Schema层定义请求/响应数据结构。工资计算相关的核心文件如下:
|
||||
- 服务层:salary_service.py(工资计算与生成)、assessment_service.py(考核计算)
|
||||
- API层:salary.py(工资接口)、assessments.py(考核接口)
|
||||
- 模型层:models.py(实体与关系)、finance.py(财务核算模型)
|
||||
- Schema层:schemas.py(数据模式)
|
||||
- 文档:database.md(数据库设计)、详细设计.md(系统设计)
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "API层"
|
||||
A1["salary.py"]
|
||||
A2["assessments.py"]
|
||||
end
|
||||
subgraph "服务层"
|
||||
S1["salary_service.py"]
|
||||
S2["assessment_service.py"]
|
||||
end
|
||||
subgraph "模型层"
|
||||
M1["models.py"]
|
||||
M2["finance.py"]
|
||||
end
|
||||
subgraph "Schema层"
|
||||
SC["schemas.py"]
|
||||
end
|
||||
subgraph "文档"
|
||||
D1["database.md"]
|
||||
D2["详细设计.md"]
|
||||
end
|
||||
A1 --> S1
|
||||
A2 --> S2
|
||||
S1 --> M1
|
||||
S2 --> M1
|
||||
S1 --> SC
|
||||
S2 --> SC
|
||||
M1 --> D1
|
||||
D2 --> D1
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [salary.py](file://backend/app/api/v1/salary.py#L1-L156)
|
||||
- [assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L1-L260)
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [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.md](file://docs/database.md#L1-L216)
|
||||
- [详细设计.md](file://docs/详细设计.md#L1-L196)
|
||||
|
||||
章节来源
|
||||
- [salary.py](file://backend/app/api/v1/salary.py#L1-L156)
|
||||
- [assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L1-L260)
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [models.py](file://backend/app/models/models.py#L1-L438)
|
||||
- [schemas.py](file://backend/app/schemas/schemas.py#L1-L743)
|
||||
- [finance.py](file://backend/app/models/finance.py#L1-L79)
|
||||
- [database.md](file://docs/database.md#L1-L216)
|
||||
- [详细设计.md](file://docs/详细设计.md#L1-L196)
|
||||
|
||||
## 核心组件
|
||||
- 工资服务(SalaryService):提供工资记录查询、创建、更新、生成、批量生成、确认与批量确认等能力;核心计算函数为绩效奖金计算。
|
||||
- 考核服务(AssessmentService):提供考核记录的创建、更新、提交、审核、确认与批量创建等能力;核心计算为总分与加权得分。
|
||||
- 数据模型(models.py):定义员工、考核、工资记录等实体及其字段与关系。
|
||||
- 数据模式(schemas.py):定义API请求/响应的数据结构。
|
||||
- 财务模型(finance.py):定义科室财务收支记录,用于财务核算与对账。
|
||||
|
||||
章节来源
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L14-L260)
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py#L14-L263)
|
||||
- [models.py](file://backend/app/models/models.py#L88-L231)
|
||||
- [schemas.py](file://backend/app/schemas/schemas.py#L272-L311)
|
||||
- [finance.py](file://backend/app/models/finance.py#L45-L79)
|
||||
|
||||
## 架构总览
|
||||
工资计算遵循“先考核、后工资”的流程:考核服务计算加权得分,工资服务据此生成工资记录。系统通过API层暴露查询、生成、确认等接口,服务层封装业务规则,模型层承载数据与关系。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant API as "API层(salary.py)"
|
||||
participant SVC as "服务层(SalaryService)"
|
||||
participant ASVC as "服务层(AssessmentService)"
|
||||
participant DB as "数据库(models.py)"
|
||||
U->>API : "POST /salary/generate"
|
||||
API->>SVC : "generate_from_assessment(staff_id, year, month)"
|
||||
SVC->>DB : "查询员工信息(Staff)"
|
||||
SVC->>DB : "查询已确认考核(Assessment.status=FINALIZED)"
|
||||
SVC->>SVC : "calculate_performance_bonus(weighted_score, performance_ratio)"
|
||||
SVC->>DB : "插入SalaryRecord"
|
||||
SVC-->>API : "返回工资记录ID"
|
||||
API-->>U : "生成成功"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [salary.py](file://backend/app/api/v1/salary.py#L96-L110)
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L127-L190)
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py#L195-L205)
|
||||
- [models.py](file://backend/app/models/models.py#L88-L231)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 绩效奖金计算公式与工资构成
|
||||
- 绩效奖金计算
|
||||
- 公式:绩效奖金 = 绩效基数 × (绩效得分/100) × 绩效系数
|
||||
- 绩效基数:固定常量,可在服务层中配置与调整
|
||||
- 绩效得分:来自考核的加权得分
|
||||
- 绩效系数:来自员工表的performance_ratio
|
||||
- 工资构成要素
|
||||
- 基本工资:来自员工表base_salary
|
||||
- 绩效奖金:按上述公式计算
|
||||
- 补贴:允许在工资记录中单独维护
|
||||
- 扣款:允许在工资记录中单独维护
|
||||
- 应发工资:基本工资 + 绩效奖金 + 补贴 - 扣款
|
||||
- 状态流转
|
||||
- 工资记录默认状态为“待确认”,确认后进入“已确认”状态
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["开始"]) --> LoadStaff["加载员工信息"]
|
||||
LoadStaff --> LoadAssess["加载已确认考核"]
|
||||
LoadAssess --> CheckDup{"是否存在同周期工资记录?"}
|
||||
CheckDup --> |是| Abort["终止生成"]
|
||||
CheckDup --> |否| CalcBonus["计算绩效奖金<br/>= 基数 × (得分/100) × 系数"]
|
||||
CalcBonus --> ComputeTotal["计算应发工资<br/>= 基本工资 + 奖金 + 补贴 - 扣款"]
|
||||
ComputeTotal --> CreateRec["创建工资记录(状态: 待确认)"]
|
||||
CreateRec --> End(["结束"])
|
||||
Abort --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L127-L190)
|
||||
- [models.py](file://backend/app/models/models.py#L205-L231)
|
||||
|
||||
章节来源
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L17-L18)
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L71-L74)
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L173-L174)
|
||||
- [models.py](file://backend/app/models/models.py#L205-L231)
|
||||
|
||||
### 考核得分权重与加权计算
|
||||
- 总分:明细得分累加
|
||||
- 加权得分:明细得分 × 指标权重累加
|
||||
- 考核状态:草稿 → 提交 → 审核 → 确认(FINALIZED)
|
||||
- 生成工资时要求考核状态为“已确认”,避免未完成流程的误算
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["创建考核"] --> B["计算总分=sum(明细.score)"]
|
||||
B --> C["计算加权得分=Σ(明细.score × 指标权重)"]
|
||||
C --> D["提交/审核/确认"]
|
||||
D --> E{"状态=FINALIZED?"}
|
||||
E --> |是| F["可用于生成工资"]
|
||||
E --> |否| G["不可生成工资"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py#L71-L108)
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py#L195-L205)
|
||||
|
||||
章节来源
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py#L71-L108)
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py#L195-L205)
|
||||
|
||||
### 不同岗位类型的工资差异
|
||||
- 基础差异体现在两个字段:
|
||||
- 基本工资(base_salary):由员工信息决定
|
||||
- 绩效系数(performance_ratio):由员工信息决定
|
||||
- 系统未内置“岗位类型”字段,因此不同岗位的差异通过上述两字段配置体现。若需引入岗位类型,可在模型层新增字段并在服务层扩展计算逻辑。
|
||||
|
||||
章节来源
|
||||
- [models.py](file://backend/app/models/models.py#L88-L114)
|
||||
- [schemas.py](file://backend/app/schemas/schemas.py#L107-L118)
|
||||
|
||||
### 特殊津贴与扣款处理
|
||||
- 特殊津贴与扣款通过工资记录的allowance与deduction字段维护,支持在创建与更新时单独设置。
|
||||
- 应发工资为基本工资、绩效奖金、补贴与扣款的组合,计算逻辑在服务层统一处理。
|
||||
|
||||
章节来源
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L77-L124)
|
||||
- [models.py](file://backend/app/models/models.py#L205-L231)
|
||||
- [schemas.py](file://backend/app/schemas/schemas.py#L274-L311)
|
||||
|
||||
### 批量工资生成与并发处理
|
||||
- 单次生成:根据员工ID与周期生成单条工资记录
|
||||
- 科室批量生成:遍历该科室已确认考核的员工,逐条生成工资记录
|
||||
- 并发与一致性:
|
||||
- 生成前检查是否存在同周期工资记录,避免重复
|
||||
- 使用数据库事务与flush/refresh确保写入一致性
|
||||
- 批量生成时逐条生成,避免跨事务的复杂锁竞争
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant API as "API层(salary.py)"
|
||||
participant SVC as "服务层(SalaryService)"
|
||||
participant DB as "数据库(models.py)"
|
||||
API->>SVC : "batch_generate_for_department(dept_id, year, month)"
|
||||
SVC->>DB : "查询该科室已确认考核的员工"
|
||||
loop 遍历每个员工
|
||||
SVC->>SVC : "generate_from_assessment(staff_id, year, month)"
|
||||
SVC->>DB : "检查同周期是否存在工资记录"
|
||||
alt 存在则跳过
|
||||
SVC-->>SVC : "跳过"
|
||||
else 不存在则生成
|
||||
SVC->>DB : "插入SalaryRecord"
|
||||
end
|
||||
end
|
||||
SVC-->>API : "返回生成的记录列表"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [salary.py](file://backend/app/api/v1/salary.py#L113-L129)
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L193-L219)
|
||||
|
||||
章节来源
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L193-L219)
|
||||
- [salary.py](file://backend/app/api/v1/salary.py#L113-L129)
|
||||
|
||||
### 数据一致性与状态管理
|
||||
- 工资记录状态:pending(待确认)→ confirmed(已确认)
|
||||
- 考核记录状态:draft → submitted → reviewed → finalized
|
||||
- 生成工资时仅接受finalized状态的考核,确保数据一致性
|
||||
- 批量确认接口支持按周期与科室范围批量更新状态
|
||||
|
||||
章节来源
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L222-L259)
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py#L158-L205)
|
||||
|
||||
### 计算规则配置与扩展点
|
||||
- 绩效基数:可通过修改服务层常量进行配置
|
||||
- 绩效系数:通过员工信息维护
|
||||
- 加权计算方法:在考核服务中实现,可扩展为更复杂的权重聚合
|
||||
- 工资构成扩展:可在Schema与模型中增加新的字段,并在服务层扩展计算逻辑
|
||||
|
||||
章节来源
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L17-L18)
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py#L71-L108)
|
||||
- [schemas.py](file://backend/app/schemas/schemas.py#L274-L311)
|
||||
- [models.py](file://backend/app/models/models.py#L205-L231)
|
||||
|
||||
## 依赖关系分析
|
||||
- API层依赖服务层;服务层依赖模型层;Schema层为API与服务层之间的数据契约
|
||||
- 工资服务依赖员工与考核数据;考核服务依赖指标与明细数据
|
||||
- 数据库索引覆盖查询与统计场景,有助于提升查询性能
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
API_S["salary.py"] --> SVC_S["salary_service.py"]
|
||||
API_A["assessments.py"] --> SVC_A["assessment_service.py"]
|
||||
SVC_S --> MODELS["models.py"]
|
||||
SVC_A --> MODELS
|
||||
MODELS --> DB["数据库"]
|
||||
SCHEMAS["schemas.py"] --> API_S
|
||||
SCHEMAS --> API_A
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [salary.py](file://backend/app/api/v1/salary.py#L1-L156)
|
||||
- [assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L1-L260)
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [models.py](file://backend/app/models/models.py#L1-L438)
|
||||
- [schemas.py](file://backend/app/schemas/schemas.py#L1-L743)
|
||||
|
||||
章节来源
|
||||
- [salary.py](file://backend/app/api/v1/salary.py#L1-L156)
|
||||
- [assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L1-L260)
|
||||
- [assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [models.py](file://backend/app/models/models.py#L1-L438)
|
||||
- [schemas.py](file://backend/app/schemas/schemas.py#L1-L743)
|
||||
|
||||
## 性能考量
|
||||
- 查询与分页:服务层提供分页查询,避免一次性加载大量数据
|
||||
- 关联加载:使用selectinload按需加载关联对象,减少N+1查询
|
||||
- 索引优化:数据库表对常用查询字段建立索引,如工资记录的员工ID与周期组合索引
|
||||
- 批量操作:批量生成与批量确认接口减少多次往返,提升吞吐
|
||||
- 异步IO:基于SQLAlchemy异步会话,适合高并发场景
|
||||
|
||||
章节来源
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L21-L58)
|
||||
- [models.py](file://backend/app/models/models.py#L227-L231)
|
||||
- [database.md](file://docs/database.md#L197-L216)
|
||||
|
||||
## 故障排查指南
|
||||
- 无法生成工资
|
||||
- 检查是否存在同周期的工资记录
|
||||
- 检查考核是否已确认(FINALIZED)
|
||||
- 检查员工是否存在
|
||||
- 无法更新工资
|
||||
- 仅待确认状态可更新
|
||||
- 无法确认工资
|
||||
- 仅待确认状态可确认
|
||||
- 批量生成异常
|
||||
- 检查是否存在未确认的考核
|
||||
- 检查数据库连接与事务
|
||||
|
||||
章节来源
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L133-L164)
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L104-L124)
|
||||
- [salary_service.py](file://backend/app/services/salary_service.py#L222-L231)
|
||||
|
||||
## 结论
|
||||
本系统以“考核得分×绩效系数×基数”的核心公式实现绩效奖金计算,通过严格的流程控制与状态管理确保数据一致性。工资构成清晰、扩展灵活,支持按科室批量生成与批量确认,满足医院绩效工资核算的实际需求。未来可在模型层引入岗位类型、扩展加权计算方法与增加更多补贴/扣款项,进一步提升系统的适应性与可配置性。
|
||||
|
||||
## 附录
|
||||
- 数据库表结构概览与索引
|
||||
- 员工表:包含基本工资与绩效系数
|
||||
- 考核表:包含总分与加权得分
|
||||
- 工资记录表:包含基本工资、绩效得分、绩效奖金、补贴、扣款与应发工资
|
||||
- 系统设计文档要点
|
||||
- 多维度考核、评分方法(区间法、扣分法等)
|
||||
- 绩效结果应用(与绩效工资挂钩)
|
||||
|
||||
章节来源
|
||||
- [database.md](file://docs/database.md#L97-L136)
|
||||
- [database.md](file://docs/database.md#L197-L216)
|
||||
- [详细设计.md](file://docs/详细设计.md#L328-L381)
|
||||
357
.qoder/repowiki/zh/content/业务逻辑设计/权限控制机制.md
Normal file
357
.qoder/repowiki/zh/content/业务逻辑设计/权限控制机制.md
Normal file
@@ -0,0 +1,357 @@
|
||||
# 权限控制机制
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py)
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.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/api/v1/staff.py](file://backend/app/api/v1/staff.py)
|
||||
- [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py)
|
||||
- [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py)
|
||||
- [backend/app/services/menu_service.py](file://backend/app/services/menu_service.py)
|
||||
- [backend/app/core/config.py](file://backend/app/core/config.py)
|
||||
- [backend/app/main.py](file://backend/app/main.py)
|
||||
- [backend/app/core/logging_config.py](file://backend/app/core/logging_config.py)
|
||||
- [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件系统化阐述医院绩效系统的权限控制机制,重点覆盖基于角色的访问控制(RBAC)实现、菜单权限与数据权限设计、JWT令牌验证、用户角色分配与权限继承机制。文档同时给出不同角色(管理员、科室负责人、普通员工)的权限范围与操作限制,解释后端中间件式权限校验、动态权限检查与安全审计日志策略,并提供权限配置的扩展方式、权限矩阵与安全最佳实践。
|
||||
|
||||
## 项目结构
|
||||
后端采用 FastAPI + SQLAlchemy 异步 ORM 的分层架构,权限控制相关代码主要集中在以下模块:
|
||||
- 安全与认证:core/security.py、api/v1/auth.py、core/config.py
|
||||
- 数据模型:models/models.py(含用户、菜单等)
|
||||
- 前端路由守卫:frontend/src/router/index.js(令牌拦截)
|
||||
- 日志与审计:core/logging_config.py
|
||||
- API 路由聚合:api/v1/__init__.py
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "后端"
|
||||
A["main.py<br/>应用入口与CORS"]
|
||||
B["api/v1/__init__.py<br/>路由聚合"]
|
||||
C["core/security.py<br/>JWT与权限依赖"]
|
||||
D["api/v1/auth.py<br/>登录/注册/当前用户"]
|
||||
E["models/models.py<br/>User/Menu等模型"]
|
||||
F["core/config.py<br/>JWT配置"]
|
||||
G["core/logging_config.py<br/>日志与审计"]
|
||||
end
|
||||
subgraph "前端"
|
||||
H["frontend/src/router/index.js<br/>路由守卫"]
|
||||
end
|
||||
H --> A
|
||||
A --> B
|
||||
B --> D
|
||||
D --> C
|
||||
C --> E
|
||||
C --> F
|
||||
A --> G
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/main.py](file://backend/app/main.py#L15-L77)
|
||||
- [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py#L1-L17)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110)
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L1-L74)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261)
|
||||
- [backend/app/core/config.py](file://backend/app/core/config.py#L23-L26)
|
||||
- [backend/app/core/logging_config.py](file://backend/app/core/logging_config.py#L1-L65)
|
||||
|
||||
章节来源
|
||||
- [backend/app/main.py](file://backend/app/main.py#L15-L77)
|
||||
- [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py#L1-L17)
|
||||
|
||||
## 核心组件
|
||||
- JWT 与令牌管理:负责令牌签发、解码、过期控制与用户解析。
|
||||
- 权限依赖注入:提供“当前用户”、“当前有效用户”、“管理员”、“管理员或经理”的依赖函数,作为路由装饰器实现中间件式权限控制。
|
||||
- 用户模型与角色:User 模型包含 role 字段,支持 admin、manager、staff 角色。
|
||||
- 菜单模型与权限标识:Menu 模型包含 permission 字段,用于前端按钮级权限标识。
|
||||
- 员工与菜单 API:通过依赖注入实现不同角色的访问控制。
|
||||
|
||||
章节来源
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L34-L110)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L347-L373)
|
||||
- [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L68-L109)
|
||||
- [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L98-L150)
|
||||
|
||||
## 架构总览
|
||||
后端通过 FastAPI 的依赖注入系统,在每个路由上声明所需的权限依赖,实现“中间件式”的权限控制。前端通过路由守卫拦截未登录访问,后端通过 OAuth2 Bearer 令牌进行鉴权。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant FE as "前端"
|
||||
participant API as "FastAPI路由"
|
||||
participant SEC as "security依赖"
|
||||
participant DB as "数据库"
|
||||
participant MOD as "模型(User)"
|
||||
FE->>API : "携带Authorization : Bearer token"
|
||||
API->>SEC : "依赖注入 : get_current_user()"
|
||||
SEC->>SEC : "decode_token()"
|
||||
SEC->>DB : "按ID查询用户"
|
||||
DB-->>SEC : "返回User"
|
||||
SEC->>MOD : "校验is_active"
|
||||
MOD-->>API : "返回当前用户"
|
||||
API-->>FE : "执行业务逻辑/返回数据"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L55-L91)
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L37)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### JWT 与令牌验证
|
||||
- 令牌签发:使用 HS256 算法,包含 exp 与 sub(用户ID),默认有效期 8 小时。
|
||||
- 令牌解码:验证签名与过期时间,失败则抛出凭据无效异常。
|
||||
- 用户解析:从载荷提取 sub(用户ID),查询数据库获取用户实体并校验 is_active。
|
||||
- 依赖链路:OAuth2PasswordBearer 提供 tokenUrl,get_current_user 解析用户,get_current_active_user 进一步校验状态。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["进入受保护路由"]) --> GetToken["从Authorization头获取Bearer token"]
|
||||
GetToken --> Decode["decode_token() 验证签名与过期"]
|
||||
Decode --> Valid{"解码成功?"}
|
||||
Valid --> |否| Raise401["抛出401未授权"]
|
||||
Valid --> |是| LoadUser["按ID查询User"]
|
||||
LoadUser --> Active{"is_active=true?"}
|
||||
Active --> |否| Raise403["抛出403禁止访问"]
|
||||
Active --> |是| ReturnUser["返回当前用户"]
|
||||
Raise401 --> End(["结束"])
|
||||
Raise403 --> End
|
||||
ReturnUser --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L34-L91)
|
||||
- [backend/app/core/config.py](file://backend/app/core/config.py#L23-L26)
|
||||
|
||||
章节来源
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L34-L91)
|
||||
- [backend/app/core/config.py](file://backend/app/core/config.py#L23-L26)
|
||||
|
||||
### RBAC 角色与权限继承
|
||||
- 角色定义:User.role 支持 admin(管理员)、manager(经理)、staff(普通员工)。
|
||||
- 权限依赖:
|
||||
- get_current_active_user:校验用户激活状态。
|
||||
- get_current_manager_user:要求 admin 或 manager。
|
||||
- get_current_admin_user:要求 admin。
|
||||
- 路由装饰示例:
|
||||
- 员工管理:创建/更新/删除需管理员或经理权限。
|
||||
- 菜单管理:创建/更新/删除需管理员或经理权限;初始化默认菜单需管理员权限。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class User {
|
||||
+int id
|
||||
+string username
|
||||
+string role
|
||||
+bool is_active
|
||||
}
|
||||
class SecurityDeps {
|
||||
+get_current_user(token) User
|
||||
+get_current_active_user(user) User
|
||||
+get_current_manager_user(user) User
|
||||
+get_current_admin_user(user) User
|
||||
}
|
||||
class StaffAPI {
|
||||
+create_staff() Response
|
||||
+update_staff() Response
|
||||
+delete_staff() Response
|
||||
}
|
||||
class MenuAPI {
|
||||
+create_menu() Response
|
||||
+update_menu() Response
|
||||
+delete_menu() Response
|
||||
+init_default_menus() Response
|
||||
}
|
||||
StaffAPI --> SecurityDeps : "依赖manager/admin"
|
||||
MenuAPI --> SecurityDeps : "依赖manager/admin"
|
||||
SecurityDeps --> User : "返回当前用户"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L85-L110)
|
||||
- [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L68-L109)
|
||||
- [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L98-L150)
|
||||
|
||||
章节来源
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L85-L110)
|
||||
- [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L68-L109)
|
||||
- [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L98-L150)
|
||||
|
||||
### 菜单权限与前端集成
|
||||
- 菜单模型:Menu 包含 permission 字段,用于前端按钮级权限标识。
|
||||
- 菜单服务:提供树形结构、列表查询、默认初始化等能力。
|
||||
- 前端路由守卫:未登录访问会被重定向至登录页,确保前端侧最小暴露面。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant FE as "前端"
|
||||
participant API as "菜单API"
|
||||
participant SVC as "MenuService"
|
||||
participant DB as "数据库"
|
||||
FE->>API : "GET /menus/tree?visible_only=true"
|
||||
API->>SVC : "get_tree(visible_only)"
|
||||
SVC->>DB : "查询可见且启用的菜单树"
|
||||
DB-->>SVC : "返回菜单树"
|
||||
SVC-->>API : "返回树形结构"
|
||||
API-->>FE : "渲染菜单树/按钮权限"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L17-L29)
|
||||
- [backend/app/services/menu_service.py](file://backend/app/services/menu_service.py#L16-L29)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L347-L373)
|
||||
|
||||
章节来源
|
||||
- [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L17-L29)
|
||||
- [backend/app/services/menu_service.py](file://backend/app/services/menu_service.py#L16-L29)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L347-L373)
|
||||
|
||||
### 数据权限与业务边界
|
||||
- 员工管理:仅管理员或经理可增删改;查询列表对所有有效用户开放。
|
||||
- 菜单管理:对菜单树与列表查询不强制管理员权限,但对写操作(创建/更新/删除/初始化)要求管理员或经理。
|
||||
- 建议扩展:可在服务层增加“数据域过滤”,例如按用户关联的 staff_id 或 department_id 限制查询范围,避免越权访问。
|
||||
|
||||
章节来源
|
||||
- [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L20-L49)
|
||||
- [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L68-L109)
|
||||
- [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L32-L65)
|
||||
- [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L98-L150)
|
||||
|
||||
### 认证流程与注册
|
||||
- 登录:用户名+密码校验,账户激活状态校验,成功后签发访问令牌。
|
||||
- 注册:校验用户名唯一性,生成密码哈希,创建用户并返回结果。
|
||||
- 当前用户:通过 /api/v1/auth/me 获取当前用户信息。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant FE as "前端"
|
||||
participant AUTH as "Auth路由"
|
||||
participant SEC as "security"
|
||||
participant DB as "数据库"
|
||||
FE->>AUTH : "POST /auth/login"
|
||||
AUTH->>DB : "按用户名查询用户"
|
||||
DB-->>AUTH : "返回User"
|
||||
AUTH->>SEC : "verify_password()"
|
||||
SEC-->>AUTH : "校验通过"
|
||||
AUTH->>SEC : "create_access_token(user.id)"
|
||||
SEC-->>AUTH : "返回access_token"
|
||||
AUTH-->>FE : "{access_token, token_type}"
|
||||
FE->>AUTH : "GET /auth/me"
|
||||
AUTH->>SEC : "get_current_active_user"
|
||||
SEC->>DB : "查询当前用户"
|
||||
DB-->>SEC : "返回User"
|
||||
SEC-->>AUTH : "返回当前用户"
|
||||
AUTH-->>FE : "用户信息"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L73)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L24-L43)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L55-L91)
|
||||
|
||||
章节来源
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L73)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L24-L43)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L55-L91)
|
||||
|
||||
### 安全审计与日志
|
||||
- 日志配置:按天轮转 app_error 日志,区分控制台与文件输出等级。
|
||||
- 异常处理:全局 HTTP 与验证异常记录到日志,便于审计与追踪。
|
||||
- 建议:在权限决策点(如 get_current_manager_user)增加审计日志,记录用户ID、操作、IP、时间与结果。
|
||||
|
||||
章节来源
|
||||
- [backend/app/core/logging_config.py](file://backend/app/core/logging_config.py#L1-L65)
|
||||
- [backend/app/main.py](file://backend/app/main.py#L58-L74)
|
||||
|
||||
## 依赖关系分析
|
||||
- 路由聚合:api/v1/__init__.py 将各模块路由统一挂载到主应用。
|
||||
- 中间件:main.py 配置 CORS,确保前后端跨域通信。
|
||||
- 安全依赖:security.py 的依赖函数被各业务路由复用,形成统一的权限控制入口。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
INIT["api/v1/__init__.py"] --> AUTH["api/v1/auth.py"]
|
||||
INIT --> STAFF["api/v1/staff.py"]
|
||||
INIT --> MENUS["api/v1/menus.py"]
|
||||
MAIN["main.py"] --> INIT
|
||||
AUTH --> SEC["core/security.py"]
|
||||
STAFF --> SEC
|
||||
MENUS --> SEC
|
||||
SEC --> CFG["core/config.py"]
|
||||
SEC --> MODELS["models/models.py"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py#L1-L17)
|
||||
- [backend/app/main.py](file://backend/app/main.py#L41-L51)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110)
|
||||
- [backend/app/core/config.py](file://backend/app/core/config.py#L23-L26)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261)
|
||||
|
||||
章节来源
|
||||
- [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py#L1-L17)
|
||||
- [backend/app/main.py](file://backend/app/main.py#L41-L51)
|
||||
|
||||
## 性能考虑
|
||||
- 令牌解码与用户查询:建议在网关或中间件层缓存近期活跃用户的轻量信息,减少数据库查询压力。
|
||||
- 分页与索引:员工与菜单查询使用分页与索引,避免大结果集扫描。
|
||||
- CORS 与异常处理:合理配置允许的源与方法,减少预检请求开销。
|
||||
|
||||
## 故障排查指南
|
||||
- 401 未授权:检查 Authorization 头是否携带 Bearer token,确认 token 未过期。
|
||||
- 403 禁止访问:确认用户角色满足 get_current_manager_user 或 get_current_admin_user 要求。
|
||||
- 登录失败:检查用户名/密码与账户激活状态。
|
||||
- 跨域问题:确认 CORS_ORIGINS 配置与前端访问地址一致。
|
||||
|
||||
章节来源
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L55-L110)
|
||||
- [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L37)
|
||||
- [backend/app/core/config.py](file://backend/app/core/config.py#L28-L29)
|
||||
|
||||
## 结论
|
||||
该系统采用简洁明确的 RBAC 模式:以角色驱动的依赖注入实现中间件式权限控制,结合 JWT 令牌与用户激活状态校验,满足后台管理场景下的安全需求。菜单模型的 permission 字段为前端按钮级权限提供了基础。建议后续在服务层引入数据域过滤与权限审计日志,进一步强化数据权限与合规性。
|
||||
|
||||
## 附录
|
||||
|
||||
### 角色权限矩阵(摘要)
|
||||
- 管理员(admin)
|
||||
- 员工管理:创建/更新/删除
|
||||
- 菜单管理:创建/更新/删除/初始化
|
||||
- 科室负责人(manager)
|
||||
- 员工管理:创建/更新/删除
|
||||
- 菜单管理:创建/更新/删除(不含初始化)
|
||||
- 普通员工(staff)
|
||||
- 员工管理:仅查询列表与详情
|
||||
- 菜单管理:查询菜单树/列表(写操作受限)
|
||||
|
||||
章节来源
|
||||
- [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L68-L109)
|
||||
- [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L98-L150)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L85-L110)
|
||||
|
||||
### 安全最佳实践
|
||||
- 强制使用 HTTPS 传输,避免令牌在传输中泄露。
|
||||
- 生产环境更换 SECRET_KEY,定期轮换。
|
||||
- 严格限制 CORS 源,避免跨站风险。
|
||||
- 对高敏感操作(如删除)增加二次确认与审计日志。
|
||||
- 在服务层增加数据域过滤,防止越权读取。
|
||||
408
.qoder/repowiki/zh/content/业务逻辑设计/统计分析逻辑.md
Normal file
408
.qoder/repowiki/zh/content/业务逻辑设计/统计分析逻辑.md
Normal file
@@ -0,0 +1,408 @@
|
||||
# 统计分析逻辑
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py)
|
||||
- [stats.py](file://backend/app/api/v1/stats.py)
|
||||
- [models.py](file://backend/app/models/models.py)
|
||||
- [finance.py](file://backend/app/models/finance.py)
|
||||
- [schemas.py](file://backend/app/schemas/schemas.py)
|
||||
- [finance.py](file://backend/app/api/v1/finance.py)
|
||||
- [stats.js](file://frontend/src/api/stats.js)
|
||||
- [Dashboard.vue](file://frontend/src/views/Dashboard.vue)
|
||||
- [Reports.vue](file://frontend/src/views/reports/Reports.vue)
|
||||
- [详细设计.md](file://docs/详细设计.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件面向医院绩效系统的统计分析逻辑,围绕平衡计分卡(BSC)四个维度(财务、客户、内部流程、学习与成长)展开,系统性阐述:
|
||||
- 维度统计与加权平均的实现
|
||||
- 科室绩效排名、趋势分析、同比/环比计算
|
||||
- 多维度数据聚合、图表数据生成与前端展示
|
||||
- 统计口径定义、数据准确性保障与性能优化策略
|
||||
- 统计结果的展示逻辑、导出能力现状与扩展建议、自定义报表配置思路
|
||||
|
||||
## 项目结构
|
||||
后端采用 FastAPI + SQLAlchemy 异步 ORM,统计分析位于服务层与 API 层,前端通过 ECharts 进行可视化展示。数据库模型涵盖指标、考核、员工、科室、财务等核心实体。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "后端"
|
||||
API["API 路由<br/>/stats/*"]
|
||||
SVC["统计服务<br/>StatsService"]
|
||||
MODELS["数据模型<br/>Assessment/Detail/Indicator/Department/Staff"]
|
||||
FINANCE_MODEL["财务模型<br/>DepartmentFinance"]
|
||||
end
|
||||
subgraph "前端"
|
||||
FE_API["前端统计接口封装<br/>stats.js"]
|
||||
DASHBOARD["仪表盘视图<br/>Dashboard.vue"]
|
||||
REPORTS["报表视图<br/>Reports.vue"]
|
||||
end
|
||||
FE_API --> API
|
||||
API --> SVC
|
||||
SVC --> MODELS
|
||||
SVC --> FINANCE_MODEL
|
||||
DASHBOARD --> FE_API
|
||||
REPORTS --> FE_API
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [stats.py](file://backend/app/api/v1/stats.py#L1-L242)
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L1-L300)
|
||||
- [models.py](file://backend/app/models/models.py#L117-L203)
|
||||
- [finance.py](file://backend/app/models/finance.py#L45-L74)
|
||||
- [stats.js](file://frontend/src/api/stats.js#L1-L43)
|
||||
- [Dashboard.vue](file://frontend/src/views/Dashboard.vue#L225-L819)
|
||||
- [Reports.vue](file://frontend/src/views/reports/Reports.vue#L183-L245)
|
||||
|
||||
**章节来源**
|
||||
- [stats.py](file://backend/app/api/v1/stats.py#L1-L242)
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L1-L300)
|
||||
- [models.py](file://backend/app/models/models.py#L117-L203)
|
||||
- [finance.py](file://backend/app/models/finance.py#L45-L74)
|
||||
- [stats.js](file://frontend/src/api/stats.js#L1-L43)
|
||||
- [Dashboard.vue](file://frontend/src/views/Dashboard.vue#L225-L819)
|
||||
- [Reports.vue](file://frontend/src/views/reports/Reports.vue#L183-L245)
|
||||
|
||||
## 核心组件
|
||||
- 统计服务层(StatsService):提供 BSC 维度统计、科室统计、趋势分析、排名、指标完成度等核心统计方法。
|
||||
- API 层(/stats):暴露统计接口,负责参数解析、默认值处理、响应包装。
|
||||
- 数据模型:Assessment/AssessmentDetail/Indicator/Department/Staff/Finance 相关表,支撑统计口径与聚合。
|
||||
- 前端接口封装与可视化:stats.js 封装请求,Dashboard.vue 与 Reports.vue 使用 ECharts 渲染图表。
|
||||
|
||||
**章节来源**
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L16-L300)
|
||||
- [stats.py](file://backend/app/api/v1/stats.py#L14-L242)
|
||||
- [models.py](file://backend/app/models/models.py#L117-L203)
|
||||
- [finance.py](file://backend/app/models/finance.py#L45-L74)
|
||||
- [stats.js](file://frontend/src/api/stats.js#L1-L43)
|
||||
- [Dashboard.vue](file://frontend/src/views/Dashboard.vue#L225-L819)
|
||||
- [Reports.vue](file://frontend/src/views/reports/Reports.vue#L183-L245)
|
||||
|
||||
## 架构总览
|
||||
统计分析的调用链路如下:
|
||||
- 前端通过 stats.js 请求 /stats/* 接口
|
||||
- API 层解析参数并调用 StatsService
|
||||
- StatsService 基于 SQLAlchemy 异步查询,按统计口径进行聚合
|
||||
- 返回标准化 JSON 结果,前端渲染图表与表格
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant FE as "前端(stats.js)"
|
||||
participant API as "API 路由(stats.py)"
|
||||
participant SVC as "统计服务(StatsService)"
|
||||
participant DB as "数据库(ORM)"
|
||||
FE->>API : GET /stats/department?year&month
|
||||
API->>SVC : get_department_stats(year, month)
|
||||
SVC->>DB : 查询Assessment/AssessmentDetail/Staff/Department
|
||||
DB-->>SVC : 聚合结果
|
||||
SVC-->>API : 列表(含科室均分/排名等)
|
||||
API-->>FE : JSON 响应
|
||||
FE->>FE : ECharts 渲染图表
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [stats.js](file://frontend/src/api/stats.js#L1-L43)
|
||||
- [stats.py](file://backend/app/api/v1/stats.py#L36-L49)
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L75-L146)
|
||||
|
||||
**章节来源**
|
||||
- [stats.js](file://frontend/src/api/stats.js#L1-L43)
|
||||
- [stats.py](file://backend/app/api/v1/stats.py#L36-L49)
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L75-L146)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### BSC 四维度统计(财务、客户、内部流程、学习与成长)
|
||||
- 统计口径
|
||||
- 维度得分 = Σ(指标得分 × 指标权重) / Σ(指标权重)
|
||||
- 指标得分来自 AssessmentDetail.score,权重来自 Indicator.weight
|
||||
- 仅统计状态为“已确认”的考核记录
|
||||
- 查询条件
|
||||
- 可按年、月、科室过滤
|
||||
- 返回字段
|
||||
- 各维度的总分、权重、指标数量、平均分(总分/权重)
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["进入 get_bsc_dimension_stats"]) --> BuildCond["构建查询条件<br/>状态=FINALIZED<br/>可选: 年/月/科室"]
|
||||
BuildCond --> JoinTables["连接表: Indicator → AssessmentDetail → Assessment"]
|
||||
JoinTables --> GroupByDim["按 bs_dimension 分组"]
|
||||
GroupByDim --> Calc["计算: 总分=Σ(score*weight)<br/>权重=Σ(weight)<br/>指标数=count(*)"]
|
||||
Calc --> Avg["平均分=总分/权重"]
|
||||
Avg --> Return["返回维度统计+周期"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L19-L72)
|
||||
- [models.py](file://backend/app/models/models.py#L117-L146)
|
||||
|
||||
**章节来源**
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L19-L72)
|
||||
- [models.py](file://backend/app/models/models.py#L117-L146)
|
||||
|
||||
### 科室绩效统计与排名
|
||||
- 统计口径
|
||||
- 按科室汇总:员工数、总分、平均分、最高分、最低分、员工列表
|
||||
- 平均分 = 总分 / 员工数
|
||||
- 结果按平均分降序排列
|
||||
- 排名口径
|
||||
- 员工维度:按加权得分降序取前 N
|
||||
- 科室维度:按科室平均分降序取前 N
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
S1["查询 FINALIZED 考核记录"] --> Join["连接 Staff/Assessment/Department"]
|
||||
Join --> Group["按 Department 聚合"]
|
||||
Group --> Sum["累计: 员工数/总分/最高分/最低分"]
|
||||
Sum --> Avg["平均分=总分/员工数"]
|
||||
Avg --> Sort["按平均分降序"]
|
||||
Sort --> Limit["可选: 截取前N"]
|
||||
Limit --> Out["返回科室统计列表"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L75-L146)
|
||||
|
||||
**章节来源**
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L75-L146)
|
||||
|
||||
### 趋势分析(月度)
|
||||
- 统计口径
|
||||
- 以月为粒度,计算当月平均总分、平均加权分、记录数
|
||||
- 可按年份与最近 N 个月过滤
|
||||
- 跨年处理:若起始月小于 1,则跨年累加
|
||||
- 返回字段
|
||||
- 月份、平均得分、平均加权得分、记录数
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
T0["输入: 年份/月份数/科室ID"] --> T1["构造条件: FINALIZED"]
|
||||
T1 --> T2{"是否指定年份?"}
|
||||
T2 -- 是 --> T3["计算起始月=当前月-N+1"]
|
||||
T3 --> T4{"起始月<1?"}
|
||||
T4 -- 是 --> T5["拼接跨年条件"]
|
||||
T4 -- 否 --> T6["拼接同年内条件"]
|
||||
T2 -- 否 --> T7["使用当前年份"]
|
||||
T5 --> T8["连接 Staff/Assessment"]
|
||||
T6 --> T8
|
||||
T7 --> T8
|
||||
T8 --> T9["按月分组, 计算平均值与计数"]
|
||||
T9 --> T10["返回趋势数据"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L148-L199)
|
||||
|
||||
**章节来源**
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L148-L199)
|
||||
|
||||
### 指标完成度统计
|
||||
- 统计口径
|
||||
- 计算指标平均得分、最大/最小得分、完成率 = min(平均得分/目标值×100, 100)
|
||||
- 可按年、月、指标过滤
|
||||
- 返回字段
|
||||
- 指标ID/名称/编码、目标值、最高分、平均分、完成率、样本数
|
||||
|
||||
**章节来源**
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L246-L299)
|
||||
|
||||
### 财务相关统计(收支趋势)
|
||||
- 当前实现
|
||||
- /stats/finance-trend 为演示接口,返回模拟数据
|
||||
- 建议实现
|
||||
- 使用 DepartmentFinance 表按月统计收入/支出/结余
|
||||
- 与财务模型一致的类别枚举(收入/支出类别)
|
||||
- 与趋势分析一致的“最近 N 月”参数
|
||||
|
||||
**章节来源**
|
||||
- [stats.py](file://backend/app/api/v1/stats.py#L156-L183)
|
||||
- [finance.py](file://backend/app/models/finance.py#L45-L74)
|
||||
|
||||
### 统计结果展示与图表生成
|
||||
- Dashboard.vue
|
||||
- 初始化 ECharts 实例,加载趋势、饼图、科室排名、财务趋势、仪表盘等数据
|
||||
- 趋势图:双轴(得分/奖金),折线+面积
|
||||
- 仪表盘:床位使用率、药占比、材料占比、患者满意度(模拟数据)
|
||||
- Reports.vue
|
||||
- 科室柱状图(平均分)+折线(奖金总额)
|
||||
- 支持筛选与刷新
|
||||
|
||||
**章节来源**
|
||||
- [Dashboard.vue](file://frontend/src/views/Dashboard.vue#L423-L819)
|
||||
- [Reports.vue](file://frontend/src/views/reports/Reports.vue#L183-L245)
|
||||
|
||||
## 依赖关系分析
|
||||
- 统计服务依赖数据模型与枚举(Assessment/AssessmentDetail/Indicator/Department/Staff/BSCDimension/AssessmentStatus)
|
||||
- API 层依赖统计服务与安全中间件(用户鉴权)
|
||||
- 前端依赖 stats.js 封装的接口,调用 /stats/* 并渲染图表
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
STATS_API["/stats/*"] --> STATS_SVC["StatsService"]
|
||||
STATS_SVC --> MODELS_M["Assessment/Detail/Indicator/Department/Staff"]
|
||||
STATS_SVC --> MODELS_F["DepartmentFinance"]
|
||||
FE_STATS["stats.js"] --> STATS_API
|
||||
DASH["Dashboard.vue"] --> FE_STATS
|
||||
REPORTS["Reports.vue"] --> FE_STATS
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [stats.py](file://backend/app/api/v1/stats.py#L14-L242)
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L10-L13)
|
||||
- [models.py](file://backend/app/models/models.py#L117-L203)
|
||||
- [finance.py](file://backend/app/models/finance.py#L45-L74)
|
||||
- [stats.js](file://frontend/src/api/stats.js#L1-L43)
|
||||
|
||||
**章节来源**
|
||||
- [stats.py](file://backend/app/api/v1/stats.py#L14-L242)
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L10-L13)
|
||||
- [models.py](file://backend/app/models/models.py#L117-L203)
|
||||
- [finance.py](file://backend/app/models/finance.py#L45-L74)
|
||||
- [stats.js](file://frontend/src/api/stats.js#L1-L43)
|
||||
|
||||
## 性能考虑
|
||||
- 查询优化
|
||||
- 使用 group_by 与聚合函数一次性计算,避免多次往返
|
||||
- 为常用过滤字段(状态、年、月、科室)建立索引(模型中已有索引)
|
||||
- 异步 I/O
|
||||
- 使用 SQLAlchemy AsyncSession,降低阻塞
|
||||
- 缓存策略
|
||||
- 对热点报表(如趋势、排名)可引入 Redis 缓存,设置合理过期时间
|
||||
- 分页与限制
|
||||
- 排名接口限制返回条数(默认 10),避免大数据集传输
|
||||
- 前端渲染
|
||||
- ECharts 按需初始化,窗口 resize 时重绘,避免重复实例化
|
||||
|
||||
**章节来源**
|
||||
- [models.py](file://backend/app/models/models.py#L174-L178)
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L202-L244)
|
||||
- [Dashboard.vue](file://frontend/src/views/Dashboard.vue#L441-L447)
|
||||
|
||||
## 故障排查指南
|
||||
- 接口返回空数据
|
||||
- 检查考核状态是否为 FINALIZED
|
||||
- 确认年/月/科室参数是否正确
|
||||
- 确认数据是否已归档到对应周期
|
||||
- 趋势数据异常
|
||||
- 跨年月份计算是否正确(起始月<1 的分支)
|
||||
- 是否存在缺失月份导致平均值异常
|
||||
- 图表不显示
|
||||
- 确认 ECharts 实例已初始化且容器尺寸有效
|
||||
- 检查数据结构与图表配置项是否匹配
|
||||
- 财务趋势为空
|
||||
- 当前 /stats/finance-trend 为演示接口,需对接 DepartmentFinance 表真实数据
|
||||
|
||||
**章节来源**
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L148-L199)
|
||||
- [Dashboard.vue](file://frontend/src/views/Dashboard.vue#L423-L447)
|
||||
- [stats.py](file://backend/app/api/v1/stats.py#L156-L183)
|
||||
|
||||
## 结论
|
||||
本系统以 BSC 四维度为核心,结合指标权重与加权平均,实现了维度得分、科室统计、趋势分析与排名等关键统计能力。通过异步查询与前端可视化,形成了从数据到洞察的完整闭环。财务趋势与关键指标仪表盘目前为演示实现,建议尽快对接 DepartmentFinance 表,以提供真实财务数据支持。
|
||||
|
||||
## 附录
|
||||
|
||||
### 统计口径与算法一览
|
||||
- BSC 维度统计
|
||||
- 维度得分 = Σ(得分×权重)/Σ(权重)
|
||||
- 仅统计 FINALIZED 考核
|
||||
- 科室统计
|
||||
- 员工数、总分、平均分、最高/最低分
|
||||
- 平均分=总分/员工数
|
||||
- 趋势分析
|
||||
- 月度平均总分、平均加权分、记录数
|
||||
- 跨年处理:起始月<1 时拼接跨年条件
|
||||
- 指标完成度
|
||||
- 完成率=min(平均得分/目标值×100, 100)
|
||||
- 排名
|
||||
- 员工:按加权得分降序取前 N
|
||||
- 科室:按平均分降序取前 N
|
||||
|
||||
**章节来源**
|
||||
- [stats_service.py](file://backend/app/services/stats_service.py#L19-L299)
|
||||
|
||||
### 数据模型与统计关系
|
||||
```mermaid
|
||||
erDiagram
|
||||
INDICATOR {
|
||||
int id PK
|
||||
string name
|
||||
string code
|
||||
enum bs_dimension
|
||||
numeric weight
|
||||
numeric max_score
|
||||
numeric target_value
|
||||
}
|
||||
ASSESSMENT {
|
||||
int id PK
|
||||
int staff_id FK
|
||||
int period_year
|
||||
int period_month
|
||||
numeric total_score
|
||||
numeric weighted_score
|
||||
enum status
|
||||
}
|
||||
ASSESSMENT_DETAIL {
|
||||
int id PK
|
||||
int assessment_id FK
|
||||
int indicator_id FK
|
||||
numeric actual_value
|
||||
numeric score
|
||||
}
|
||||
STAFF {
|
||||
int id PK
|
||||
int department_id FK
|
||||
string employee_id
|
||||
string name
|
||||
}
|
||||
DEPARTMENT {
|
||||
int id PK
|
||||
string name
|
||||
string code
|
||||
enum dept_type
|
||||
}
|
||||
INDICATOR ||--o{ ASSESSMENT_DETAIL : "包含"
|
||||
ASSESSMENT_DETAIL ||--|| ASSESSMENT : "属于"
|
||||
ASSESSMENT ||--|| STAFF : "由员工产生"
|
||||
STAFF ||--|| DEPARTMENT : "属于"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [models.py](file://backend/app/models/models.py#L117-L203)
|
||||
|
||||
### 导出与自定义报表配置
|
||||
- 导出能力现状
|
||||
- 后端未提供报表导出接口
|
||||
- 前端未实现 Excel/PDF 导出
|
||||
- 建议
|
||||
- 新增 /stats/export 接口,支持按参数导出 CSV/Excel
|
||||
- 前端增加导出按钮,调用后端接口并下载文件
|
||||
- 自定义报表配置:允许用户保存筛选条件与图表布局,后续可扩展为“仪表盘模板”
|
||||
|
||||
**章节来源**
|
||||
- [stats.py](file://backend/app/api/v1/stats.py#L1-L242)
|
||||
- [Dashboard.vue](file://frontend/src/views/Dashboard.vue#L225-L819)
|
||||
|
||||
### 与系统设计文档的对应关系
|
||||
- 设计目标与原则
|
||||
- 战略导向、分类分层、定量与定性结合、可操作性、持续改进
|
||||
- 报表与分析中心
|
||||
- 标准报表、自定义仪表盘、多维分析、趋势预测、数据导出
|
||||
- 实施路线图
|
||||
- 分阶段推进,逐步覆盖全院并深化应用
|
||||
|
||||
**章节来源**
|
||||
- [详细设计.md](file://docs/详细设计.md#L1-L196)
|
||||
384
.qoder/repowiki/zh/content/业务逻辑设计/考核流程设计.md
Normal file
384
.qoder/repowiki/zh/content/业务逻辑设计/考核流程设计.md
Normal file
@@ -0,0 +1,384 @@
|
||||
# 考核流程设计
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py)
|
||||
- [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.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/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js)
|
||||
- [docs/详细设计.md](file://docs/详细设计.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 引言
|
||||
本文件面向医院绩效系统的“考核流程设计”,围绕考核状态流转机制(草稿→提交→审核→确认)进行系统化说明,涵盖业务规则、权限控制、数据验证、流程实现、批量创建与并发处理、异常处理与事务管理策略,以及流程控制的扩展点与自定义配置选项。文档同时提供前后端交互与数据库结构映射,帮助开发者与运维人员快速理解与实施。
|
||||
|
||||
## 项目结构
|
||||
后端采用FastAPI + SQLAlchemy异步ORM,按领域模块划分:API路由、服务层、数据模型、Schema定义、安全认证与配置。前端采用Vue 3 + Element Plus,提供考核列表、状态操作与批量创建能力。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "前端"
|
||||
FE_List["Assessments.vue<br/>考核列表与操作"]
|
||||
FE_API["assessment.js<br/>HTTP客户端封装"]
|
||||
end
|
||||
subgraph "后端"
|
||||
API["assessments.py<br/>API路由"]
|
||||
SVC["assessment_service.py<br/>服务层"]
|
||||
SCHEMA["schemas.py<br/>数据模式"]
|
||||
SEC["security.py<br/>权限与认证"]
|
||||
MODEL["models.py<br/>数据模型"]
|
||||
DB[("数据库")]
|
||||
end
|
||||
FE_List --> FE_API
|
||||
FE_API --> API
|
||||
API --> SVC
|
||||
SVC --> MODEL
|
||||
SVC --> SCHEMA
|
||||
API --> SEC
|
||||
SVC --> DB
|
||||
MODEL --> DB
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L200)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L1-L50)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L1-L743)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438)
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L149-L203)
|
||||
- [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L194-L271)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L85-L110)
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L200)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L1-L50)
|
||||
|
||||
## 核心组件
|
||||
- 数据模型层:定义考核记录、明细、员工、科室、指标等实体及其关系与索引。
|
||||
- 服务层:封装业务逻辑,包括创建、更新、提交、审核、确认、批量创建等。
|
||||
- API层:暴露REST接口,绑定权限装饰器,返回标准化响应。
|
||||
- Schema层:定义请求/响应数据结构与枚举类型,确保前后端契约一致。
|
||||
- 安全层:基于JWT的认证与授权,区分普通员工、管理员与经理权限。
|
||||
- 前端视图与API封装:提供考核列表、状态操作按钮与批量创建弹窗。
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L149-L203)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L14-L263)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L17-L166)
|
||||
- [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L194-L271)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L85-L110)
|
||||
|
||||
## 架构总览
|
||||
系统采用分层架构:前端负责交互与调用,后端API路由接收请求,服务层执行业务规则,数据模型映射到数据库,安全中间件进行权限校验。状态流转由服务层严格控制,API层仅暴露受控的端点。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant FE as "前端"
|
||||
participant API as "API路由"
|
||||
participant SEC as "安全中间件"
|
||||
participant SVC as "服务层"
|
||||
participant DB as "数据库"
|
||||
FE->>API : "提交/审核/确认请求"
|
||||
API->>SEC : "校验JWT与角色"
|
||||
SEC-->>API : "通过/拒绝"
|
||||
API->>SVC : "调用业务方法"
|
||||
SVC->>DB : "读写数据"
|
||||
DB-->>SVC : "返回结果"
|
||||
SVC-->>API : "业务结果"
|
||||
API-->>FE : "标准化响应"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L1-L50)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L105-L145)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L85-L110)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L158-L205)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 考核状态与业务规则
|
||||
- 状态枚举:草稿(draft)、已提交(submitted)、已审核(reviewed)、已确认(finalized)、已驳回(rejected)。
|
||||
- 状态流转:
|
||||
- 草稿 → 已提交:仅草稿或已驳回状态允许提交。
|
||||
- 已提交 → 已审核/已驳回:审核人根据审批结果切换状态。
|
||||
- 已审核 → 已确认:仅已审核状态允许确认。
|
||||
- 权限控制:
|
||||
- 提交:当前活跃用户即可。
|
||||
- 审核/确认:管理员或经理角色。
|
||||
- 数据验证:
|
||||
- 提交前:校验状态必须为草稿。
|
||||
- 审核:校验状态必须为已提交。
|
||||
- 确认:校验状态必须为已审核。
|
||||
- 更新:仅允许草稿或已驳回状态修改明细与备注。
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 草稿
|
||||
草稿 --> 已提交 : "提交"
|
||||
已提交 --> 已审核 : "审核通过"
|
||||
已提交 --> 已驳回 : "审核驳回"
|
||||
已审核 --> 已确认 : "确认"
|
||||
已确认 --> [*]
|
||||
已驳回 --> 草稿 : "重新编辑"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L45-L51)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L158-L205)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L105-L145)
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L45-L51)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L158-L205)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L105-L145)
|
||||
|
||||
### 考核创建与更新流程
|
||||
- 创建:
|
||||
- 计算总分与加权得分(加权=Σ(指标得分×指标权重))。
|
||||
- 写入主表与明细表,刷新实体。
|
||||
- 更新:
|
||||
- 仅草稿或已驳回状态允许更新。
|
||||
- 删除旧明细,重建新明细并重新计算总分与加权得分。
|
||||
- 可选更新备注。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["进入创建/更新"]) --> CheckStatus["检查状态是否允许"]
|
||||
CheckStatus --> |不允许| Error["返回错误"]
|
||||
CheckStatus --> |允许| BuildDetails["构建明细列表"]
|
||||
BuildDetails --> CalcScore["计算总分与加权得分"]
|
||||
CalcScore --> Persist["持久化主表与明细"]
|
||||
Persist --> Refresh["刷新实体"]
|
||||
Refresh --> Done(["完成"])
|
||||
Error --> Done
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L71-L156)
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L71-L156)
|
||||
|
||||
### 考核提交、审核与确认流程
|
||||
- 提交:
|
||||
- 校验状态为草稿,设置提交时间,状态变更为已提交。
|
||||
- 审核:
|
||||
- 校验状态为已提交,记录审核人与时间;通过则变更为已审核,否则变更为已驳回。
|
||||
- 确认:
|
||||
- 校验状态为已审核,状态变更为已确认。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant API as "API"
|
||||
participant SVC as "服务层"
|
||||
participant DB as "数据库"
|
||||
U->>API : "POST /assessments/{id}/submit"
|
||||
API->>SVC : "submit(id)"
|
||||
SVC->>DB : "读取并校验状态"
|
||||
DB-->>SVC : "返回记录"
|
||||
SVC->>DB : "更新状态=已提交, 写入提交时间"
|
||||
DB-->>SVC : "提交成功"
|
||||
SVC-->>API : "返回结果"
|
||||
API-->>U : "提交成功"
|
||||
U->>API : "POST /assessments/{id}/review?approved={bool}&remark={text}"
|
||||
API->>SVC : "review(id, reviewer_id, approved, remark)"
|
||||
SVC->>DB : "读取并校验状态"
|
||||
DB-->>SVC : "返回记录"
|
||||
SVC->>DB : "更新状态=已审核/已驳回, 写入审核人与时间"
|
||||
DB-->>SVC : "审核完成"
|
||||
SVC-->>API : "返回结果"
|
||||
API-->>U : "审核通过/已驳回"
|
||||
U->>API : "POST /assessments/{id}/finalize"
|
||||
API->>SVC : "finalize(id)"
|
||||
SVC->>DB : "读取并校验状态"
|
||||
DB-->>SVC : "返回记录"
|
||||
SVC->>DB : "更新状态=已确认"
|
||||
DB-->>SVC : "确认完成"
|
||||
SVC-->>API : "返回结果"
|
||||
API-->>U : "确认成功"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L105-L145)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L158-L205)
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L105-L145)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L158-L205)
|
||||
|
||||
### 批量创建考核流程与并发处理
|
||||
- 批量创建:
|
||||
- 获取指定科室当月在职员工列表。
|
||||
- 检查是否存在同周期重复记录,避免重复创建。
|
||||
- 为每位员工创建空明细(默认得分0),并持久化。
|
||||
- 并发处理:
|
||||
- 使用数据库事务保证创建完整性。
|
||||
- 建议在高并发场景下增加唯一性约束与去重检查,避免重复创建。
|
||||
- 可引入队列或批处理策略,分批创建以降低锁竞争。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
S(["开始批量创建"]) --> FetchStaff["查询在职员工"]
|
||||
FetchStaff --> Loop{"遍历员工"}
|
||||
Loop --> |存在| Skip["跳过已存在记录"]
|
||||
Loop --> |不存在| CreateAssess["创建考核记录(0分)"]
|
||||
CreateAssess --> CreateDetails["为每个指标创建明细(0分)"]
|
||||
CreateDetails --> Next["下一个员工"]
|
||||
Skip --> Next
|
||||
Next --> |完成| Flush["批量刷新持久化"]
|
||||
Flush --> E(["结束"])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L208-L262)
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L208-L262)
|
||||
|
||||
### 权限控制与安全策略
|
||||
- 当前用户:从JWT载荷解析用户ID,查询用户信息并校验是否激活。
|
||||
- 管理员:要求角色为admin。
|
||||
- 经理/管理员:要求角色为admin或manager。
|
||||
- API端点:
|
||||
- 提交/更新:当前活跃用户。
|
||||
- 审核/确认:管理员或经理。
|
||||
- 建议扩展:支持“谁可以审核/确认”配置化,结合用户与角色、科室层级、指标类型等策略。
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L55-L110)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L105-L145)
|
||||
|
||||
### 数据验证与事务管理
|
||||
- 数据验证:
|
||||
- 状态前置校验:提交/审核/确认均严格校验当前状态。
|
||||
- 更新校验:仅允许草稿或已驳回状态修改明细。
|
||||
- 前端校验:列表页根据状态显示对应操作按钮。
|
||||
- 事务管理:
|
||||
- 服务层使用flush/refresh保证一致性。
|
||||
- 建议在关键流程(批量创建、跨表更新)使用显式事务包裹,失败回滚。
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L111-L205)
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L55-L64)
|
||||
|
||||
### 前后端交互与扩展点
|
||||
- 前端:
|
||||
- 列表页支持按科室、周期、状态筛选,分页加载。
|
||||
- 操作按钮按状态动态显示(提交、审核、确认)。
|
||||
- 批量创建弹窗支持选择科室、周期与指标集合。
|
||||
- 扩展点:
|
||||
- 自定义评分方法:在指标模板与方案中扩展评分参数。
|
||||
- 流程定制:支持按科室类型/岗位类型配置不同的审批链路。
|
||||
- 结果应用:扩展到绩效工资、晋升、评优等联动模块。
|
||||
|
||||
**章节来源**
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L200)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L1-L50)
|
||||
- [docs/详细设计.md](file://docs/详细设计.md#L57-L121)
|
||||
|
||||
## 依赖关系分析
|
||||
- API层依赖安全中间件与服务层。
|
||||
- 服务层依赖数据模型与Schema。
|
||||
- 数据模型依赖数据库引擎与索引。
|
||||
- 前端依赖API封装与Element Plus组件库。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
FE["Assessments.vue"] --> APIJS["assessment.js"]
|
||||
APIJS --> API["assessments.py"]
|
||||
API --> SEC["security.py"]
|
||||
API --> SVC["assessment_service.py"]
|
||||
SVC --> MODEL["models.py"]
|
||||
SVC --> SCHEMA["schemas.py"]
|
||||
MODEL --> DB[("数据库")]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L200)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L1-L50)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
- [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L1-L263)
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438)
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L149-L203)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L14-L263)
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L1-L166)
|
||||
|
||||
## 性能考虑
|
||||
- 查询优化:
|
||||
- 为常用过滤字段(员工ID、周期、状态)建立索引。
|
||||
- 使用selectinload减少N+1查询。
|
||||
- 写入优化:
|
||||
- 批量插入明细,减少往返次数。
|
||||
- flush/refresh时机合理控制,避免过度刷新。
|
||||
- 并发与锁:
|
||||
- 批量创建时注意唯一性检查与去重,避免重复写入。
|
||||
- 高并发场景建议引入队列或分批策略。
|
||||
|
||||
[本节为通用指导,无需特定文件引用]
|
||||
|
||||
## 故障排除指南
|
||||
- 常见问题:
|
||||
- 状态不允许:检查当前状态是否满足提交/审核/确认前置条件。
|
||||
- 权限不足:确认当前用户角色是否为管理员或经理。
|
||||
- 重复创建:批量创建时检查同周期是否已存在记录。
|
||||
- 排查步骤:
|
||||
- 查看API响应码与消息。
|
||||
- 核对服务层状态校验逻辑。
|
||||
- 检查数据库索引与唯一约束。
|
||||
- 建议:
|
||||
- 增加更详细的错误码与国际化提示。
|
||||
- 在服务层捕获异常并记录上下文日志。
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/api/v1/assessments.py](file://backend/app/api/v1/assessments.py#L105-L145)
|
||||
- [backend/app/services/assessment_service.py](file://backend/app/services/assessment_service.py#L158-L205)
|
||||
|
||||
## 结论
|
||||
本设计以清晰的状态机为核心,结合严格的权限控制与数据验证,实现了从创建到确认的完整考核流程。服务层承担业务规则,API层提供受控接口,前端提供直观的操作体验。通过索引优化、事务管理与并发控制,系统具备良好的可扩展性与稳定性。后续可在流程定制、评分方法与结果应用等方面进一步增强。
|
||||
|
||||
[本节为总结,无需特定文件引用]
|
||||
|
||||
## 附录
|
||||
|
||||
### 数据模型与索引映射
|
||||
- 考核记录表:staff_id、period_year+period_month、status等索引。
|
||||
- 考核明细表:assessment_id、indicator_id索引。
|
||||
- 员工表:department_id、status索引。
|
||||
- 指标表:indicator_type权重约束。
|
||||
|
||||
**章节来源**
|
||||
- [backend/app/models/models.py](file://backend/app/models/models.py#L149-L203)
|
||||
- [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L87-L131)
|
||||
|
||||
### 数据库迁移与扩展
|
||||
- 初始版本:创建科室、员工、指标、考核、明细、工资、用户等核心表。
|
||||
- 模板扩展:新增指标模板与模板指标关联表,并向指标表补充BSC维度等字段。
|
||||
|
||||
**章节来源**
|
||||
- [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L21-L183)
|
||||
- [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py#L21-L96)
|
||||
Reference in New Issue
Block a user