from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from sqlalchemy import or_ from typing import List, Optional from datetime import datetime, timezone from ..database import get_db from ..models import TaskLog from ..schemas import TaskLogBase, TaskLogResponse from .auth import get_current_admin router = APIRouter(prefix="/api/admin/task-logs", tags=["admin"]) MODULES = { "scheduled_refresh_search_cache": "🔍 搜索缓存", "scheduled_fetch_trends": "🔥 热点趋势", "scheduled_collect": "📡 内容采集", "scheduled_generate": "🤖 内容创作", "scheduled_optimize": "🔍 合规审查", "scheduled_optimize_sources": "📡 信息源优化", "scheduled_metrics_sync": "📊 指标同步", } @router.get("", response_model=List[TaskLogResponse]) def list_task_logs( db: Session = Depends(get_db), admin_user=Depends(get_current_admin), module_id: Optional[str] = None, status: Optional[str] = None, date: Optional[str] = None, limit: int = 50, ): query = db.query(TaskLog) if module_id: query = query.filter(TaskLog.module_id == module_id) if status: query = query.filter(TaskLog.status == status) if date: try: dt = datetime.strptime(date, "%Y-%m-%d").replace(tzinfo=timezone.utc) next_day = datetime(dt.year, dt.month, dt.day + 1, tzinfo=timezone.utc) query = query.filter(TaskLog.started_at >= dt, TaskLog.started_at < next_day) except ValueError: pass logs = query.order_by(TaskLog.started_at.desc()).limit(limit).all() return [TaskLogResponse.model_validate(l) for l in logs] @router.get("/modules") def list_modules(db: Session = Depends(get_db), admin_user=Depends(get_current_admin)): today = datetime.now(timezone.utc).date().isoformat() result = [] for mid, name in MODULES.items(): latest = db.query(TaskLog).filter(TaskLog.module_id == mid).order_by(TaskLog.started_at.desc()).first() total = db.query(TaskLog).filter(TaskLog.module_id == mid).count() success = db.query(TaskLog).filter(TaskLog.module_id == mid, TaskLog.status == "success").count() failed = db.query(TaskLog).filter(TaskLog.module_id == mid, TaskLog.status == "failed").count() running = db.query(TaskLog).filter(TaskLog.module_id == mid, TaskLog.status == "running").count() result.append({ "module_id": mid, "name": name, "last_run": latest.started_at.isoformat() if latest and latest.started_at else None, "last_status": latest.status if latest else None, "last_message": latest.message if latest else None, "total_runs": total, "success_runs": success, "failed_runs": failed, "running": running, }) return result @router.get("/{log_id}", response_model=TaskLogResponse) def get_task_log(log_id: int, db: Session = Depends(get_db), admin_user=Depends(get_current_admin)): log = db.query(TaskLog).filter(TaskLog.id == log_id).first() if not log: raise HTTPException(status_code=404, detail="记录不存在") return log @router.post("", response_model=TaskLogResponse) def create_task_log(log_data: TaskLogBase, db: Session = Depends(get_db), admin_user=Depends(get_current_admin)): log = TaskLog(**log_data.model_dump()) db.add(log) db.commit() db.refresh(log) return log @router.put("/{log_id}", response_model=TaskLogResponse) def update_task_log(log_id: int, log_update: TaskLogBase, db: Session = Depends(get_db), admin_user=Depends(get_current_admin)): log = db.query(TaskLog).filter(TaskLog.id == log_id).first() if not log: raise HTTPException(status_code=404, detail="记录不存在") data = log_update.model_dump(exclude_unset=True) for field, value in data.items(): setattr(log, field, value) db.commit() db.refresh(log) return log @router.delete("/{log_id}") def delete_task_log(log_id: int, db: Session = Depends(get_db), admin_user=Depends(get_current_admin)): log = db.query(TaskLog).filter(TaskLog.id == log_id).first() if not log: raise HTTPException(status_code=404, detail="记录不存在") db.delete(log) db.commit() return {"message": "删除成功"}