Files
rssKeeper/backend/routers/dashboard.py
T

79 lines
2.3 KiB
Python
Raw Normal View History

"""仪表盘统计 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
]
}