提交文件
This commit is contained in:
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)
|
||||
Reference in New Issue
Block a user