from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from pydantic import BaseModel from app.core.database import get_db from app.core.deps import get_current_user from app.models.report import ReportTemplate, ReportTask from app.models.user import User router = APIRouter(prefix="/reports", tags=["报表管理"]) class TemplateCreate(BaseModel): name: str report_type: str description: str | None = None fields: list[dict] filters: dict | None = None aggregation: str = "sum" time_granularity: str = "hour" class TaskCreate(BaseModel): template_id: int name: str | None = None schedule: str | None = None recipients: list[str] | None = None export_format: str = "xlsx" @router.get("/templates") async def list_templates(db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user)): result = await db.execute(select(ReportTemplate).order_by(ReportTemplate.id)) return [{ "id": t.id, "name": t.name, "report_type": t.report_type, "description": t.description, "fields": t.fields, "is_system": t.is_system, "aggregation": t.aggregation, "time_granularity": t.time_granularity, } for t in result.scalars().all()] @router.post("/templates") async def create_template(data: TemplateCreate, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user)): template = ReportTemplate(**data.model_dump(), created_by=user.id) db.add(template) await db.flush() return {"id": template.id, "name": template.name} @router.get("/tasks") async def list_tasks(db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user)): result = await db.execute(select(ReportTask).order_by(ReportTask.id.desc())) return [{ "id": t.id, "template_id": t.template_id, "name": t.name, "schedule": t.schedule, "status": t.status, "export_format": t.export_format, "file_path": t.file_path, "last_run": str(t.last_run) if t.last_run else None, } for t in result.scalars().all()] @router.post("/tasks") async def create_task(data: TaskCreate, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user)): task = ReportTask(**data.model_dump(), created_by=user.id) db.add(task) await db.flush() return {"id": task.id} @router.post("/tasks/{task_id}/run") async def run_task(task_id: int, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user)): result = await db.execute(select(ReportTask).where(ReportTask.id == task_id)) task = result.scalar_one_or_none() if not task: raise HTTPException(status_code=404, detail="任务不存在") task.status = "running" # TODO: trigger Celery task return {"message": "报表生成中", "task_id": task.id}