""" 统计报表 API """ from typing import Optional from datetime import datetime from fastapi import APIRouter, Depends, Query from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.core.security import get_current_active_user from app.models.models import User from app.services.stats_service import StatsService router = APIRouter(prefix="/stats", tags=["统计报表"]) @router.get("/bsc-dimension", summary="BSC 维度分析") async def get_bsc_dimension_stats( department_id: Optional[int] = Query(None, description="科室 ID"), period_year: int = Query(..., description="年度"), period_month: int = Query(..., description="月份"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取 BSC 四个维度的统计分析""" result = await StatsService.get_bsc_dimension_stats( db, department_id, period_year, period_month ) return { "code": 200, "message": "success", "data": result } @router.get("/department", summary="科室绩效统计") async def get_department_stats( period_year: int = Query(..., description="年度"), period_month: int = Query(..., description="月份"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取各科室绩效统计""" result = await StatsService.get_department_stats(db, period_year, period_month) return { "code": 200, "message": "success", "data": result } @router.get("/trend", summary="趋势分析") async def get_trend_stats( department_id: Optional[int] = Query(None, description="科室 ID"), period_year: Optional[int] = Query(None, description="年度"), months: Optional[int] = Query(6, ge=1, le=24, description="最近几个月"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取绩效趋势分析(月度)""" # 如果没有指定年份,使用当前年份 if not period_year: period_year = datetime.now().year result = await StatsService.get_trend_stats(db, department_id, period_year, months) return { "code": 200, "message": "success", "data": result } @router.get("/alerts", summary="预警数据") async def get_alerts( limit: Optional[int] = Query(10, ge=1, le=100, description="返回数量"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取预警数据(考核到期、工资未发等)""" # TODO: 从数据库实际查询预警数据 # 目前返回模拟数据用于演示 return { "code": 200, "message": "success", "data": { "lowScoreStaff": [], # 低分员工 "incompleteDepartments": [], # 未完成考核科室 "anomalyData": [] # 异常数据 } } @router.get("/period", summary="周期统计") async def get_period_stats( period_year: Optional[int] = Query(None, description="年度"), period_month: Optional[int] = Query(None, description="月份"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取周期统计数据""" # 如果没有指定年月,使用当前年月 if not period_year: period_year = datetime.now().year if not period_month: period_month = datetime.now().month # 获取该周期的考核统计 result = await StatsService.get_department_stats(db, period_year, period_month) # 计算汇总数据 total_departments = len(result) total_staff = sum(dept.get('staff_count', 0) for dept in result) avg_score = sum(dept.get('avg_score', 0) for dept in result) / total_departments if total_departments > 0 else 0 return { "code": 200, "message": "success", "data": { "period": f"{period_year}年{period_month}月", "total_departments": total_departments, "total_staff": total_staff, "avg_score": round(avg_score, 2), "departments": result } } @router.get("/kpi-gauges", summary="关键指标仪表盘") async def get_kpi_gauges( period_year: Optional[int] = Query(None, description="年度"), period_month: Optional[int] = Query(None, description="月份"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取关键指标仪表盘数据""" # 如果没有指定年月,使用当前年月 if not period_year: period_year = datetime.now().year if not period_month: period_month = datetime.now().month # TODO: 从数据库实际计算这些指标 # 目前返回模拟数据用于演示 return { "code": 200, "message": "success", "data": { "bed_usage_rate": 85.5, # 床位使用率 (%) "drug_ratio": 32.8, # 药占比 (%) "material_ratio": 18.5, # 材料占比 (%) "satisfaction_rate": 92.3 # 患者满意度 (%) } } @router.get("/finance-trend", summary="收支趋势") async def get_finance_trend( months: Optional[int] = Query(6, ge=1, le=24, description="最近几个月"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取收支趋势数据""" # TODO: 从数据库实际查询收支数据 # 目前返回模拟数据用于演示 from datetime import datetime current_month = datetime.now().month data = [] for i in range(months, 0, -1): month = current_month - i + 1 if month < 1: month += 12 data.append({ "period": f"{month}月", "income": 1000000 + (months - i) * 50000, "expense": 800000 + (months - i) * 30000, "profit": 200000 + (months - i) * 20000 }) return { "code": 200, "message": "success", "data": data } @router.get("/department-ranking", summary="科室绩效排名") async def get_department_ranking( period_year: Optional[int] = Query(None, description="年度"), period_month: Optional[int] = Query(None, description="月份"), limit: Optional[int] = Query(10, ge=1, le=100, description="返回数量"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取科室绩效排名""" # 如果没有指定年月,使用当前年月 if not period_year: period_year = datetime.now().year if not period_month: period_month = datetime.now().month result = await StatsService.get_department_stats(db, period_year, period_month) # 返回前 limit 个 return { "code": 200, "message": "success", "data": result[:limit] if limit else result } @router.get("/ranking", summary="绩效排名") async def get_ranking_stats( period_year: int = Query(..., description="年度"), period_month: int = Query(..., description="月份"), limit: int = Query(10, ge=1, le=100, description="返回数量"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取绩效排名前 N 名""" result = await StatsService.get_ranking_stats(db, period_year, period_month, limit) return { "code": 200, "message": "success", "data": result } @router.get("/completion", summary="指标完成度") async def get_completion_stats( indicator_id: Optional[int] = Query(None, description="指标 ID"), period_year: int = Query(..., description="年度"), period_month: int = Query(..., description="月份"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取指标完成度统计""" result = await StatsService.get_completion_stats(db, indicator_id, period_year, period_month) return { "code": 200, "message": "success", "data": result }