17 KiB
17 KiB
统计分析服务
**本文引用的文件** - [backend/app/services/stats_service.py](file://backend/app/services/stats_service.py) - [backend/app/api/v1/stats.py](file://backend/app/api/v1/stats.py) - [backend/app/models/models.py](file://backend/app/models/models.py) - [backend/app/core/database.py](file://backend/app/core/database.py) - [backend/app/core/config.py](file://backend/app/core/config.py) - [backend/app/main.py](file://backend/app/main.py) - [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py) - [docs/详细设计.md](file://docs/详细设计.md)目录
简介
本文件面向“统计分析服务”的开发与使用,围绕 StatsService 类的实现原理展开,系统阐述多维度统计分析、数据聚合与报表生成能力,重点覆盖以下主题:
- BSC(平衡计分卡)维度分析:财务、客户、内部流程、学习与成长四个维度的指标计算与聚合
- 科室绩效统计:按科室汇总、平均分、最高/最低分、人员列表与排序
- 趋势分析:按月度的时间序列趋势(平均分、加权分)
- 排名统计:按加权分的绩效排名
- 指标完成度:指标平均分、最大/最小分、完成率
- 数据库交互模式、查询优化与潜在缓存策略
- 统计结果的数据格式化、图表数据准备与 API 接口设计
- 具体统计场景示例与性能考虑
项目结构
后端采用 FastAPI + SQLAlchemy 2.x 异步 ORM 的架构,统计分析服务位于服务层,API 层负责请求参数解析与响应封装,模型层定义数据结构与枚举,数据库层提供异步连接与会话管理。
graph TB
subgraph "应用层"
API["API 路由<br/>stats.py"]
SVC["服务层<br/>stats_service.py"]
end
subgraph "模型层"
MODELS["数据模型与枚举<br/>models.py"]
end
subgraph "基础设施"
CFG["配置<br/>config.py"]
DB["数据库连接<br/>database.py"]
MAIN["应用入口<br/>main.py"]
end
API --> SVC
SVC --> MODELS
API --> DB
SVC --> DB
DB --> CFG
MAIN --> API
图表来源
- backend/app/api/v1/stats.py
- backend/app/services/stats_service.py
- backend/app/models/models.py
- backend/app/core/database.py
- backend/app/core/config.py
- backend/app/main.py
章节来源
- backend/app/api/v1/stats.py
- backend/app/services/stats_service.py
- backend/app/models/models.py
- backend/app/core/database.py
- backend/app/core/config.py
- backend/app/main.py
核心组件
- StatsService:提供 BSC 维度统计、科室统计、趋势分析、排名、指标完成度等统计方法
- API 路由 stats.py:定义 /stats 前缀下的统计接口,负责参数校验、默认值处理与统一响应包装
- 数据模型与枚举:包含 BSC 维度、评估状态、科室类型、指标类型等,支撑统计逻辑
- 数据库与配置:异步连接、会话工厂、数据库 URL 与池参数
章节来源
架构总览
统计分析服务遵循“API → 服务 → 模型/数据库”的分层架构。API 层负责输入参数与响应格式标准化;服务层执行复杂聚合与计算;模型层提供数据结构与枚举;数据库层提供异步连接与事务管理。
sequenceDiagram
participant Client as "客户端"
participant API as "API(stats.py)"
participant Svc as "StatsService"
participant DB as "AsyncSession"
participant Model as "ORM模型"
Client->>API : GET /api/v1/stats/bsc-dimension
API->>API : 参数校验与默认值处理
API->>Svc : 调用 get_bsc_dimension_stats(...)
Svc->>DB : 异步查询SQLAlchemy select + func
DB->>Model : 映射到 Assessment/AssessmentDetail/Indicator/Department/Staff
Svc-->>API : 返回聚合结果
API-->>Client : 统一响应 {code,message,data}
图表来源
详细组件分析
StatsService 类与方法族
- get_bsc_dimension_stats:按 BSC 四维度聚合得分、权重与指标数量,计算平均分
- get_department_stats:按科室汇总人员、总分、平均分、最高/最低分与人员列表,并整体排序
- get_trend_stats:按月度聚合平均分与加权分,支持跨年范围与科室过滤
- get_ranking_stats:按加权分排名前 N 的员工
- get_completion_stats:按指标统计平均分、最大/最小分、完成率与样本数
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
}
class Assessment {
+int id
+int staff_id
+int period_year
+int period_month
+float total_score
+float weighted_score
+AssessmentStatus status
}
class AssessmentDetail {
+int id
+int assessment_id
+int indicator_id
+float actual_value
+float score
}
class Indicator {
+int id
+string name
+string code
+IndicatorType indicator_type
+BSCDimension bs_dimension
+float weight
+float max_score
+float target_value
}
class Department {
+int id
+string name
+string code
+DeptType dept_type
}
class Staff {
+int id
+string employee_id
+string name
+int department_id
}
StatsService --> Assessment : "查询"
StatsService --> AssessmentDetail : "连接"
StatsService --> Indicator : "按维度聚合"
StatsService --> Department : "科室汇总"
StatsService --> Staff : "关联人员"
图表来源
章节来源
BSC 维度分析(get_bsc_dimension_stats)
- 输入:可选科室 ID、年、月
- 过滤:仅统计已确认的考核记录
- 聚合:按 BSC 维度分组,计算总分(加权)、总权重、指标数量与平均分
- 输出:包含各维度的得分、权重、指标数与平均分,以及统计周期
flowchart TD
Start(["进入 get_bsc_dimension_stats"]) --> BuildCond["构建查询条件<br/>状态=FINALIZED(+年+月+科室)"]
BuildCond --> ExecSel["执行聚合查询<br/>按维度分组(sum(score*weight), sum(weight), count)"]
ExecSel --> Iterate["遍历结果<br/>填充维度字典"]
Iterate --> CalcAvg["计算平均分=总分/总权重"]
CalcAvg --> Ret["返回 {dimensions, period}"]
图表来源
章节来源
科室绩效统计(get_department_stats)
- 输入:年、月
- 过滤:仅统计已确认的考核记录
- 聚合:按科室汇总人员数、总分、平均分、最高/最低分,并收集人员得分列表
- 排序:按平均分降序
flowchart TD
S(["进入 get_department_stats"]) --> Q["查询关联数据<br/>Staff→Assessment→Department"]
Q --> Group["按科室分组聚合<br/>计数/求和/记录人员列表"]
Group --> Compute["计算平均分=总分/人数"]
Compute --> Sort["按平均分降序排序"]
Sort --> R(["返回科室统计列表"])
图表来源
章节来源
趋势分析(get_trend_stats)
- 输入:可选科室 ID、年(为空则使用当前年)、月份数(默认 6)
- 范围:若未指定年份,按当前年份与最近 N 个月推导起止月份,支持跨年
- 聚合:按月度 group by,计算平均分与加权分、样本数
flowchart TD
Enter(["进入 get_trend_stats"]) --> YearCheck{"是否指定年份?"}
YearCheck -- 否 --> SetCur["设置为当前年份"]
YearCheck -- 是 --> KeepYear["使用传入年份"]
SetCur --> Range["计算起始月=当前月-N+1<br/>处理跨年"]
KeepYear --> Range
Range --> Cond["构造月份范围条件"]
Cond --> Join["连接 Staff 并过滤 FINALIZED"]
Join --> GroupBy["按月分组聚合"]
GroupBy --> Out(["返回月度趋势列表"])
图表来源
章节来源
排名统计(get_ranking_stats)
- 输入:年、月、限制条数
- 过滤:仅统计已确认的考核记录
- 排序:按加权分降序,返回前 N 条并标注排名
sequenceDiagram
participant API as "API"
participant Svc as "StatsService"
participant DB as "AsyncSession"
API->>Svc : get_ranking_stats(year, month, limit)
Svc->>DB : select Staff/Assessment/Department
DB-->>Svc : 结果集
Svc-->>API : 按加权分降序,标注 rank
API-->>API : 统一响应
图表来源
章节来源
指标完成度(get_completion_stats)
- 输入:可选指标 ID、年、月
- 过滤:仅统计已确认的考核记录
- 聚合:按指标 group by,计算平均分、最大/最小分、样本数与完成率(平均分/目标值)
flowchart TD
In(["进入 get_completion_stats"]) --> Cond["构造条件<br/>FINALIZED(+年+月+指标ID?)"]
Cond --> Sel["select 指标字段 + avg/max/min/count"]
Sel --> Group["group by 指标"]
Group --> Rate["完成率=avg/max(target_value)"]
Rate --> Ret(["返回指标完成度列表"])
图表来源
章节来源
API 接口设计与数据格式
- 统一响应结构:包含 code、message、data 字段
- 参数校验与默认值:
- 年/月未传时,趋势与周期统计接口会使用当前年/月
- 排名与周期统计支持 limit 控制返回数量
- 接口一览:
- GET /stats/bsc-dimension:BSC 维度分析
- GET /stats/department:科室绩效统计
- GET /stats/trend:趋势分析(月度)
- GET /stats/department-ranking:科室绩效排名(前 N)
- GET /stats/ranking:个人绩效排名(前 N)
- GET /stats/completion:指标完成度
- GET /stats/period:周期统计(含汇总)
- GET /stats/alerts、/stats/kpi-gauges、/stats/finance-trend:预留接口(当前返回模拟数据)
sequenceDiagram
participant Client as "客户端"
participant Router as "FastAPI 路由"
participant Handler as "stats.py 处理函数"
participant Svc as "StatsService"
participant DB as "AsyncSession"
Client->>Router : GET /api/v1/stats/bsc-dimension?year&month&dept_id
Router->>Handler : 参数解析与默认值
Handler->>Svc : 调用对应统计方法
Svc->>DB : 异步查询
DB-->>Svc : 结果
Svc-->>Handler : 聚合结果
Handler-->>Client : {code,message,data}
图表来源
章节来源
数据模型与枚举(支撑统计)
- BSCDimension:financial、customer、internal_process、learning_growth
- AssessmentStatus:FINALIZED 等
- DeptType、IndicatorType 等枚举用于过滤与分类
- 关键实体:Assessment、AssessmentDetail、Indicator、Department、Staff
classDiagram
class BSCDimension {
<<enum>>
+FINANCIAL
+CUSTOMER
+INTERNAL_PROCESS
+LEARNING_GROWTH
}
class AssessmentStatus {
<<enum>>
+FINALIZED
}
class DeptType {
<<enum>>
+CLINICAL_SURGICAL
+...
}
class IndicatorType {
<<enum>>
+QUALITY
+QUANTITY
+EFFICIENCY
+SERVICE
+COST
}
图表来源
章节来源
依赖分析
- 统计服务依赖 SQLAlchemy 异步会话与 ORM 模型,通过 select + func 实现聚合
- API 层依赖服务层与数据库会话注入
- 配置层提供数据库连接参数与池大小,影响并发与吞吐
graph LR
API["api/v1/stats.py"] --> SVC["services/stats_service.py"]
SVC --> MODELS["models/models.py"]
API --> DB["core/database.py"]
SVC --> DB
DB --> CFG["core/config.py"]
图表来源
- backend/app/api/v1/stats.py
- backend/app/services/stats_service.py
- backend/app/models/models.py
- backend/app/core/database.py
- backend/app/core/config.py
章节来源
- backend/app/api/v1/stats.py
- backend/app/services/stats_service.py
- backend/app/core/database.py
- backend/app/core/config.py
性能考量
- 查询优化
- 使用 group by 与聚合函数(sum、avg、count)减少应用侧循环计算
- 通过索引字段过滤(Assessment.status、Assessment.period_year/month、Assessment.staff_id)降低扫描范围
- 趋势分析中按月分组,避免大结果集内存占用
- 数据库连接与并发
- 异步连接与会话工厂支持高并发;数据库池参数可在配置中调优
- 缓存策略(建议)
- 对高频但不频繁变化的统计结果(如 BSC 维度、指标完成度)引入短期缓存(如 Redis)
- 按参数组合生成缓存键(年、月、科室、指标等)
- 响应格式化
- 将数值统一为浮点并限制精度,便于前端图表渲染
- 提供图表友好的数组结构(时间序列、排名列表)
[本节为通用性能指导,不直接分析具体文件]
故障排查指南
- 常见问题
- 参数缺失:年/月未传导致默认值逻辑异常,检查 API 层默认值处理
- 权限与认证:确保请求携带有效 Token
- 数据缺失:仅统计已确认的考核记录,若无数据请检查 Assessment.status
- 日志与异常
- 应用层已注册全局异常处理器,便于定位错误
- 建议在服务层增加关键步骤的日志输出(如查询条件、聚合结果规模)
章节来源
结论
统计分析服务以 StatsService 为核心,围绕 BSC 四维度、科室统计、趋势分析、排名与指标完成度构建了完整的多维统计能力。通过 SQLAlchemy 异步 ORM 与合理的查询策略,实现了高效的数据聚合与报表生成。建议在生产环境中引入缓存与更细粒度的索引优化,并持续完善财务、预警与仪表盘等预留接口的实际数据来源。
[本节为总结性内容,不直接分析具体文件]
附录
统计场景示例
- BSC 维度分析:按月查看财务、客户、内部流程、学习与成长四个维度的加权得分与平均分
- 科室绩效:按月汇总各科室平均分、最高/最低分与人员列表,用于科室排名与改进
- 趋势分析:查看近 6 个月的平均分与加权分变化,识别波动与改善趋势
- 排名统计:查看个人绩效排名前 10 的员工及其所在科室
- 指标完成度:查看各指标的平均分、完成率与样本数,辅助指标优化
[本节为概念性场景说明,不直接分析具体文件]
与系统设计文档的对应关系
- 系统设计强调“多维度考核”“科学量化”“流程自动化”“报表与分析中心”,统计分析服务正对应“报表与分析中心”的实现。
章节来源