"""Events API — 事件档案列表,三维筛选。""" import logging from datetime import datetime, timezone from fastapi import APIRouter, Depends, Query from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.database import get_db from app.middleware.auth import require_auth from app.models.event import Event, EventStatus, DOMAINS from app.models.user import User logger = logging.getLogger(__name__) router = APIRouter(prefix="/events", tags=["events"]) @router.get("") async def list_events( status: str | None = Query(None, description="按状态筛选"), domain: str | None = Query(None, description="按领域筛选"), search: str = Query("", description="按标题模糊搜索"), _user: User = Depends(require_auth), db: AsyncSession = Depends(get_db), ): """事件卡片列表,支持三维筛选。""" stmt = select(Event).order_by(Event.occurred_date.desc()) valid_statuses = {s.value for s in EventStatus} if status and status in valid_statuses: stmt = stmt.where(Event.status == status) if domain and domain in DOMAINS: stmt = stmt.where(Event.domain == domain) if search: stmt = stmt.where(Event.title.ilike(f"%{search}%")) result = await db.execute(stmt) events = result.scalars().all() now = datetime.now(timezone.utc) data = [] for ev in events: overdue_days = 0 if ev.next_review and ev.next_review < now: overdue_days = (now - ev.next_review).days data.append({ "id": ev.id, "title": ev.title, "level": ev.level.value, "domain": ev.domain, "status": ev.status.value, "occurred_date": ev.occurred_date.isoformat(), "last_reviewed": ev.last_reviewed.isoformat() if ev.last_reviewed else None, "no_new_info_count": ev.no_new_info_count, "next_review": ev.next_review.isoformat() if ev.next_review else None, "overdue_days": overdue_days, "created_at": ev.created_at.isoformat() if ev.created_at else None, "updated_at": ev.updated_at.isoformat() if ev.updated_at else None, }) return {"events": data}