admin_stats_router.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. """
  2. 管理员数据统计API路由
  3. 提供用户统计、业务统计、模型统计和仪表盘等API端点
  4. """
  5. from typing import Optional
  6. from datetime import date
  7. from fastapi import APIRouter, Depends, HTTPException, status, Query
  8. from sqlalchemy.orm import Session
  9. from app.database import get_db
  10. from app.schemas.admin_stats_schema import (
  11. UserOverviewResponse, UserGrowthItem,
  12. BusinessOverviewResponse, BusinessTrendItem,
  13. ModelRankingItem,
  14. DashboardMetricsResponse
  15. )
  16. from app.services.admin_stats_service import AdminStatsService
  17. from app.dependencies.admin_auth import get_current_admin
  18. from app.models.admin import AdminUser
  19. router = APIRouter(prefix="/api/admin/stats", tags=["数据统计"])
  20. # ==================== 用户统计接口 ====================
  21. @router.get("/users/overview", response_model=UserOverviewResponse)
  22. async def get_user_overview(
  23. start_date: Optional[date] = Query(None, description="开始日期"),
  24. end_date: Optional[date] = Query(None, description="结束日期"),
  25. current_admin: AdminUser = Depends(get_current_admin),
  26. db: Session = Depends(get_db)
  27. ):
  28. """获取用户统计概览"""
  29. service = AdminStatsService(db)
  30. try:
  31. return await service.get_user_overview(start_date, end_date)
  32. except Exception:
  33. raise HTTPException(
  34. status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
  35. detail={"code": "DATABASE_ERROR", "message": "查询失败"}
  36. )
  37. @router.get("/users/growth-trend", response_model=list[UserGrowthItem])
  38. async def get_user_growth_trend(
  39. start_date: date = Query(..., description="开始日期"),
  40. end_date: date = Query(..., description="结束日期"),
  41. current_admin: AdminUser = Depends(get_current_admin),
  42. db: Session = Depends(get_db)
  43. ):
  44. """获取用户增长趋势"""
  45. service = AdminStatsService(db)
  46. try:
  47. return await service.get_user_growth_trend(start_date, end_date)
  48. except Exception:
  49. raise HTTPException(
  50. status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
  51. detail={"code": "DATABASE_ERROR", "message": "查询失败"}
  52. )
  53. # ==================== 业务统计接口 ====================
  54. @router.get("/business/overview", response_model=BusinessOverviewResponse)
  55. async def get_business_overview(
  56. start_date: Optional[date] = Query(None, description="开始日期"),
  57. end_date: Optional[date] = Query(None, description="结束日期"),
  58. current_admin: AdminUser = Depends(get_current_admin),
  59. db: Session = Depends(get_db)
  60. ):
  61. """获取业务统计概览"""
  62. service = AdminStatsService(db)
  63. try:
  64. return await service.get_business_overview(start_date, end_date)
  65. except Exception:
  66. raise HTTPException(
  67. status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
  68. detail={"code": "DATABASE_ERROR", "message": "查询失败"}
  69. )
  70. @router.get("/business/trend", response_model=list[BusinessTrendItem])
  71. async def get_business_trend(
  72. start_date: date = Query(..., description="开始日期"),
  73. end_date: date = Query(..., description="结束日期"),
  74. current_admin: AdminUser = Depends(get_current_admin),
  75. db: Session = Depends(get_db)
  76. ):
  77. """获取业务趋势"""
  78. service = AdminStatsService(db)
  79. try:
  80. return await service.get_business_trend(start_date, end_date)
  81. except Exception:
  82. raise HTTPException(
  83. status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
  84. detail={"code": "DATABASE_ERROR", "message": "查询失败"}
  85. )
  86. # ==================== 模型统计接口 ====================
  87. @router.get("/models/usage-ranking", response_model=list[ModelRankingItem])
  88. async def get_model_usage_ranking(
  89. start_date: Optional[date] = Query(None, description="开始日期"),
  90. end_date: Optional[date] = Query(None, description="结束日期"),
  91. top_n: int = Query(10, ge=1, le=100, description="返回Top N个模型"),
  92. current_admin: AdminUser = Depends(get_current_admin),
  93. db: Session = Depends(get_db)
  94. ):
  95. """获取模型使用排行"""
  96. service = AdminStatsService(db)
  97. try:
  98. return await service.get_model_usage_ranking(start_date, end_date, top_n)
  99. except Exception:
  100. raise HTTPException(
  101. status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
  102. detail={"code": "DATABASE_ERROR", "message": "查询失败"}
  103. )
  104. # ==================== 仪表盘接口 ====================
  105. @router.get("/dashboard", response_model=DashboardMetricsResponse)
  106. async def get_dashboard_metrics(
  107. current_admin: AdminUser = Depends(get_current_admin),
  108. db: Session = Depends(get_db)
  109. ):
  110. """获取仪表盘核心指标"""
  111. service = AdminStatsService(db)
  112. try:
  113. return await service.get_dashboard_metrics()
  114. except Exception:
  115. raise HTTPException(
  116. status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
  117. detail={"code": "DATABASE_ERROR", "message": "查询失败"}
  118. )