""" 控制台 API """ from fastapi import APIRouter, Depends, Query from sqlalchemy.orm import Session from typing import List from datetime import date, timedelta from app.models.base import get_db from app.schemas.dashboard import DashboardStats, CoreStats, DailyUsageItem, MonthlyUsageItem from app.services.token_service import TokenService, get_token_service from app.services.virtual_user_service import VirtualUserService, get_virtual_user_service from app.models.virtual_user import VirtualUser, UserStatus from app.models.interaction import InteractionRecord, InteractionType, InteractionStatus from app.models.token_usage import TokenUsage from sqlalchemy import func, and_ router = APIRouter() @router.get("", response_model=DashboardStats) def get_dashboard_stats( db: Session = Depends(get_db), token_service: TokenService = Depends(get_token_service), user_service: VirtualUserService = Depends(get_virtual_user_service) ): """获取控制台统计数据""" # 核心指标统计 today = date.today() yesterday = today - timedelta(days=1) # 用户统计 total_users = db.query(VirtualUser).count() active_users = db.query(VirtualUser).filter(VirtualUser.status == UserStatus.ACTIVE).count() disabled_users = total_users - active_users # 今日互动统计 today_interactions = db.query(InteractionRecord).filter( and_( func.date(InteractionRecord.execution_time) == today, InteractionRecord.status == InteractionStatus.SUCCESS ) ).all() today_comments = sum(1 for i in today_interactions if i.interaction_type == InteractionType.COMMENT) today_replies = sum(1 for i in today_interactions if i.interaction_type == InteractionType.REPLY) today_likes = sum(1 for i in today_interactions if i.interaction_type == InteractionType.LIKE) today_favorites = sum(1 for i in today_interactions if i.interaction_type == InteractionType.FAVORITE) today_shares = sum(1 for i in today_interactions if i.interaction_type == InteractionType.SHARE) # 昨日互动统计 yesterday_interactions = db.query(InteractionRecord).filter( and_( func.date(InteractionRecord.execution_time) == yesterday, InteractionRecord.status == InteractionStatus.SUCCESS ) ).all() yesterday_comments = sum(1 for i in yesterday_interactions if i.interaction_type == InteractionType.COMMENT) yesterday_replies = sum(1 for i in yesterday_interactions if i.interaction_type == InteractionType.REPLY) # Token 统计 today_tokens = token_service.get_today_usage() month_tokens = token_service.get_month_usage() remaining_tokens = token_service.get_remaining_tokens() core_stats = CoreStats( total_users=total_users, active_users=active_users, disabled_users=disabled_users, today_comments=today_comments, today_replies=today_replies, today_likes=today_likes, today_favorites=today_favorites, today_shares=today_shares, yesterday_comments=yesterday_comments, yesterday_replies=yesterday_replies, month_tokens=month_tokens, today_tokens=today_tokens, remaining_tokens=remaining_tokens ) # 每日 Token 使用(近 30 天) daily_usages = token_service.get_daily_usages(days=30) daily_items = [DailyUsageItem(date=u["date"], tokens=u["tokens"], comments=0, replies=0) for u in daily_usages] # 每月 Token 使用(近 12 个月) monthly_usages = token_service.get_monthly_usages(months=12) monthly_items = [MonthlyUsageItem(month=u["month"], tokens=u["tokens"]) for u in monthly_usages] # 最近互动记录 recent_interactions = db.query(InteractionRecord).order_by( InteractionRecord.execution_time.desc() ).limit(10).all() return DashboardStats( core_stats=core_stats, daily_token_usages=daily_items, monthly_token_usages=monthly_items, recent_interactions=[ { "id": r.id, "virtual_user_id": r.virtual_user_id, "interaction_type": r.interaction_type.value, "status": r.status.value, "execution_time": r.execution_time } for r in recent_interactions ] ) @router.get("/token/stats") def get_token_stats( db: Session = Depends(get_db), token_service: TokenService = Depends(get_token_service) ): """获取 Token 统计""" today_used = token_service.get_today_usage() today_limit = 10000 # TODO: 从系统配置读取 return { "today_used": today_used, "today_limit": today_limit, "today_remaining": max(0, today_limit - today_used), "usage_percentage": round((today_used / today_limit) * 100, 2) if today_limit > 0 else 0 } @router.get("/token/daily", response_model=List[DailyUsageItem]) def get_daily_token_usage( days: int = Query(30, ge=1, le=90, description="天数"), db: Session = Depends(get_db), token_service: TokenService = Depends(get_token_service) ): """获取每日 Token 使用""" usages = token_service.get_daily_usages(days=days) return [DailyUsageItem(date=u["date"], tokens=u["tokens"], comments=0, replies=0) for u in usages] @router.get("/token/monthly", response_model=List[MonthlyUsageItem]) def get_monthly_token_usage( months: int = Query(12, ge=1, le=24, description="月数"), db: Session = Depends(get_db), token_service: TokenService = Depends(get_token_service) ): """获取每月 Token 使用""" usages = token_service.get_monthly_usages(months=months) return [MonthlyUsageItem(month=u["month"], tokens=u["tokens"]) for u in usages]