提交文件

This commit is contained in:
2026-02-28 15:16:15 +08:00
parent 1a4e50e0a4
commit 44f250f58e
159 changed files with 61268 additions and 0 deletions

View 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)