""" 管理员数据统计API路由 提供用户统计、业务统计、模型统计和仪表盘等API端点 """ from typing import Optional from datetime import date from fastapi import APIRouter, Depends, HTTPException, status, Query from sqlalchemy.orm import Session from app.database import get_db from app.schemas.admin_stats_schema import ( UserOverviewResponse, UserGrowthItem, BusinessOverviewResponse, BusinessTrendItem, ModelRankingItem, DashboardMetricsResponse ) from app.services.admin_stats_service import AdminStatsService from app.dependencies.admin_auth import get_current_admin from app.models.admin import AdminUser router = APIRouter(prefix="/api/admin/stats", tags=["数据统计"]) # ==================== 用户统计接口 ==================== @router.get("/users/overview", response_model=UserOverviewResponse) async def get_user_overview( start_date: Optional[date] = Query(None, description="开始日期"), end_date: Optional[date] = Query(None, description="结束日期"), current_admin: AdminUser = Depends(get_current_admin), db: Session = Depends(get_db) ): """获取用户统计概览""" service = AdminStatsService(db) try: return await service.get_user_overview(start_date, end_date) except Exception: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail={"code": "DATABASE_ERROR", "message": "查询失败"} ) @router.get("/users/growth-trend", response_model=list[UserGrowthItem]) async def get_user_growth_trend( start_date: date = Query(..., description="开始日期"), end_date: date = Query(..., description="结束日期"), current_admin: AdminUser = Depends(get_current_admin), db: Session = Depends(get_db) ): """获取用户增长趋势""" service = AdminStatsService(db) try: return await service.get_user_growth_trend(start_date, end_date) except Exception: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail={"code": "DATABASE_ERROR", "message": "查询失败"} ) # ==================== 业务统计接口 ==================== @router.get("/business/overview", response_model=BusinessOverviewResponse) async def get_business_overview( start_date: Optional[date] = Query(None, description="开始日期"), end_date: Optional[date] = Query(None, description="结束日期"), current_admin: AdminUser = Depends(get_current_admin), db: Session = Depends(get_db) ): """获取业务统计概览""" service = AdminStatsService(db) try: return await service.get_business_overview(start_date, end_date) except Exception: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail={"code": "DATABASE_ERROR", "message": "查询失败"} ) @router.get("/business/trend", response_model=list[BusinessTrendItem]) async def get_business_trend( start_date: date = Query(..., description="开始日期"), end_date: date = Query(..., description="结束日期"), current_admin: AdminUser = Depends(get_current_admin), db: Session = Depends(get_db) ): """获取业务趋势""" service = AdminStatsService(db) try: return await service.get_business_trend(start_date, end_date) except Exception: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail={"code": "DATABASE_ERROR", "message": "查询失败"} ) # ==================== 模型统计接口 ==================== @router.get("/models/usage-ranking", response_model=list[ModelRankingItem]) async def get_model_usage_ranking( start_date: Optional[date] = Query(None, description="开始日期"), end_date: Optional[date] = Query(None, description="结束日期"), top_n: int = Query(10, ge=1, le=100, description="返回Top N个模型"), current_admin: AdminUser = Depends(get_current_admin), db: Session = Depends(get_db) ): """获取模型使用排行""" service = AdminStatsService(db) try: return await service.get_model_usage_ranking(start_date, end_date, top_n) except Exception: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail={"code": "DATABASE_ERROR", "message": "查询失败"} ) # ==================== 仪表盘接口 ==================== @router.get("/dashboard", response_model=DashboardMetricsResponse) async def get_dashboard_metrics( current_admin: AdminUser = Depends(get_current_admin), db: Session = Depends(get_db) ): """获取仪表盘核心指标""" service = AdminStatsService(db) try: return await service.get_dashboard_metrics() except Exception: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail={"code": "DATABASE_ERROR", "message": "查询失败"} )