"""后台管理接口:任务/Agent/日志/手动管控。""" from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Request from app.constants import TaskStatus from app.models.schemas import AgentInfo, LogEntry, TaskInfo from app.repository.log_repo import LogRepo from app.services.agent_service import AgentService from app.services.task_service import TaskService router = APIRouter() def get_task_service(request: Request) -> TaskService: return TaskService(request.app.state.redis) def get_agent_service(request: Request) -> AgentService: return AgentService(request.app.state.redis) def get_log_repo(request: Request) -> LogRepo: return LogRepo(request.app.state.redis) # ---------- 任务管理 ---------- @router.get("/tasks", response_model=list[TaskInfo], summary="任务列表") async def list_tasks( status: Optional[TaskStatus] = None, limit: int = 100, svc: TaskService = Depends(get_task_service), ): return await svc.list(status=status, limit=limit) @router.get("/tasks/{request_id}", response_model=TaskInfo, summary="任务详情") async def task_detail(request_id: str, svc: TaskService = Depends(get_task_service)): task = await svc.get(request_id) if not task: raise HTTPException(status_code=404, detail="task not found") return task @router.post("/tasks/{request_id}/cancel", summary="取消任务") async def admin_cancel(request_id: str, svc: TaskService = Depends(get_task_service)): if not await svc.cancel(request_id): raise HTTPException(status_code=400, detail="cannot cancel task") return {"ok": True} @router.post("/tasks/{request_id}/reset", summary="重置任务状态") async def admin_reset(request_id: str, svc: TaskService = Depends(get_task_service)): if not await svc.reset(request_id): raise HTTPException(status_code=400, detail="cannot reset task") return {"ok": True} # ---------- Agent 管理 ---------- @router.get("/agents", response_model=list[AgentInfo], summary="Agent 列表") async def list_agents(svc: AgentService = Depends(get_agent_service)): return await svc.all() @router.post("/agents/{agent_id}/offline", summary="下线 Agent") async def agent_offline(agent_id: str, svc: AgentService = Depends(get_agent_service)): if not await svc.take_offline(agent_id): raise HTTPException(status_code=404, detail="agent not found") return {"ok": True} # ---------- 日志审计 ---------- @router.get("/logs", response_model=list[LogEntry], summary="日志审计") async def logs( limit: int = 200, request_id: Optional[str] = None, agent_id: Optional[str] = None, repo: LogRepo = Depends(get_log_repo), ): return await repo.list(limit=limit, request_id=request_id, agent_id=agent_id) # ---------- 概览 ---------- @router.get("/overview", summary="概览统计") async def overview( task_svc: TaskService = Depends(get_task_service), agent_svc: AgentService = Depends(get_agent_service), ): tasks = await task_svc.list(limit=1000) agents = await agent_svc.all() from collections import Counter status_count = Counter(t.status.value for t in tasks) return { "task_total": len(tasks), "task_pending": status_count.get(TaskStatus.PENDING.value, 0), "task_running": status_count.get(TaskStatus.RUNNING.value, 0), "task_success": status_count.get(TaskStatus.SUCCESS.value, 0), "task_failed": status_count.get(TaskStatus.FAILED.value, 0), "agent_total": len(agents), "agent_online": sum(1 for a in agents if a.status.value == "online"), "agent_offline": sum(1 for a in agents if a.status.value == "offline"), }