"""仪表盘统计 API""" from fastapi import APIRouter, Depends from sqlalchemy.orm import Session from sqlalchemy import func, text from database import get_db from health_checker import get_overall_stats, get_feed_health router = APIRouter(prefix="/dashboard", tags=["dashboard"]) @router.get("/stats") def dashboard_stats(db: Session = Depends(get_db)): """仪表盘统计数据""" return get_overall_stats(db) @router.get("/health") def dashboard_health( skip: int = 0, limit: int = 100, db: Session = Depends(get_db), ): """RSS 源健康度列表""" all_health = get_feed_health(db) total = len(all_health) # 按健康状态排序:异常在前 status_order = {"unhealthy": 0, "warning": 1, "unknown": 2, "healthy": 3} all_health.sort(key=lambda x: status_order.get(x["health_status"], 2)) items = all_health[skip:skip + limit] return {"total": total, "items": items} @router.get("/articles-daily") def articles_daily(days: int = 30, db: Session = Depends(get_db)): """按发布日期统计文章数量""" from models import Article sql = text(""" SELECT DATE(published_at) as date, COUNT(*) as count FROM articles WHERE published_at IS NOT NULL AND published_at >= DATE('now', '-' || :days || ' days') GROUP BY DATE(published_at) ORDER BY date DESC """) rows = db.execute(sql, {"days": days}).fetchall() return { "days": days, "data": [{"date": str(r[0]), "count": r[1]} for r in rows], } @router.get("/recent-activity") def recent_activity(limit: int = 20, db: Session = Depends(get_db)): """最近的抓取活动""" from models import FetchLog, Feed from sqlalchemy import desc logs = db.query(FetchLog, Feed.title.label("feed_title")).join(Feed).order_by( desc(FetchLog.created_at) ).limit(limit).all() return { "items": [ { "id": log.id, "feed_id": log.feed_id, "feed_title": feed_title or "", "status": log.status, "articles_fetched": log.articles_fetched, "response_time_ms": log.response_time_ms, "error_message": log.error_message, "created_at": log.created_at.isoformat(), } for log, feed_title in logs ] }