from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from typing import List, Optional from datetime import datetime from core.database import get_db from models.event import Event from schemas.event import ( EventCreate, EventUpdate, EventResponse, EventListResponse ) router = APIRouter() @router.post("/", response_model=EventResponse, summary="创建事件") async def create_event( event: EventCreate, db: Session = Depends(get_db) ): """创建新的事件""" db_event = Event(**event.dict()) db.add(db_event) db.commit() db.refresh(db_event) return db_event @router.get("/", response_model=EventListResponse, summary="获取事件列表") async def get_events( skip: int = Query(0, ge=0, description="跳过记录数"), limit: int = Query(10, ge=1, le=100, description="返回记录数"), event_type: Optional[str] = Query(None, description="事件类型"), device_id: Optional[int] = Query(None, description="设备ID"), algorithm_id: Optional[int] = Query(None, description="算法ID"), severity: Optional[str] = Query(None, description="严重程度"), status: Optional[str] = Query(None, description="事件状态"), is_alert: Optional[bool] = Query(None, description="是否告警"), start_time: Optional[str] = Query(None, description="开始时间"), end_time: Optional[str] = Query(None, description="结束时间"), db: Session = Depends(get_db) ): """获取事件列表,支持分页和筛选""" query = db.query(Event) if event_type: query = query.filter(Event.event_type == event_type) if device_id: query = query.filter(Event.device_id == device_id) if algorithm_id: query = query.filter(Event.algorithm_id == algorithm_id) if severity: query = query.filter(Event.severity == severity) if status: query = query.filter(Event.status == status) if is_alert is not None: query = query.filter(Event.is_alert == is_alert) if start_time: try: start_dt = datetime.fromisoformat(start_time.replace('Z', '+00:00')) query = query.filter(Event.created_at >= start_dt) except ValueError: pass if end_time: try: end_dt = datetime.fromisoformat(end_time.replace('Z', '+00:00')) query = query.filter(Event.created_at <= end_dt) except ValueError: pass # 按创建时间倒序排列 query = query.order_by(Event.created_at.desc()) total = query.count() events = query.offset(skip).limit(limit).all() return EventListResponse( events=events, total=total, page=skip // limit + 1, size=limit ) @router.get("/{event_id}", response_model=EventResponse, summary="获取事件详情") async def get_event( event_id: int, db: Session = Depends(get_db) ): """根据ID获取事件详情""" event = db.query(Event).filter(Event.id == event_id).first() if not event: raise HTTPException(status_code=404, detail="事件不存在") return event @router.put("/{event_id}", response_model=EventResponse, summary="更新事件") async def update_event( event_id: int, event: EventUpdate, db: Session = Depends(get_db) ): """更新事件信息""" db_event = db.query(Event).filter(Event.id == event_id).first() if not db_event: raise HTTPException(status_code=404, detail="事件不存在") update_data = event.dict(exclude_unset=True) for field, value in update_data.items(): setattr(db_event, field, value) db.commit() db.refresh(db_event) return db_event @router.delete("/{event_id}", summary="删除事件") async def delete_event( event_id: int, db: Session = Depends(get_db) ): """删除事件""" event = db.query(Event).filter(Event.id == event_id).first() if not event: raise HTTPException(status_code=404, detail="事件不存在") db.delete(event) db.commit() return {"message": "事件删除成功"} @router.patch("/{event_id}/status", response_model=EventResponse, summary="更新事件状态") async def update_event_status( event_id: int, status: str = Query(..., description="新状态"), resolution_notes: Optional[str] = Query(None, description="处理备注"), db: Session = Depends(get_db) ): """更新事件状态""" event = db.query(Event).filter(Event.id == event_id).first() if not event: raise HTTPException(status_code=404, detail="事件不存在") event.status = status if resolution_notes: event.resolution_notes = resolution_notes # 如果状态为resolved,设置解决时间 if status == "resolved": event.resolved_at = datetime.utcnow() db.commit() db.refresh(event) return event @router.get("/types/list", summary="获取事件类型列表") async def get_event_types(): """获取所有事件类型""" return { "types": [ {"value": "person_detection", "label": "人员检测"}, {"value": "vehicle_detection", "label": "车辆检测"}, {"value": "intrusion", "label": "入侵检测"}, {"value": "face_recognition", "label": "人脸识别"}, {"value": "license_plate", "label": "车牌识别"}, {"value": "object_detection", "label": "物体检测"}, {"value": "behavior_analysis", "label": "行为分析"}, {"value": "other", "label": "其他"} ] } @router.get("/stats/summary", summary="获取事件统计摘要") async def get_event_stats_summary(db: Session = Depends(get_db)): """获取事件统计摘要""" total = db.query(Event).count() pending = db.query(Event).filter(Event.status == "pending").count() processing = db.query(Event).filter(Event.status == "processing").count() resolved = db.query(Event).filter(Event.status == "resolved").count() ignored = db.query(Event).filter(Event.status == "ignored").count() alerts = db.query(Event).filter(Event.is_alert == True).count() # 按严重程度统计 critical = db.query(Event).filter(Event.severity == "critical").count() high = db.query(Event).filter(Event.severity == "high").count() medium = db.query(Event).filter(Event.severity == "medium").count() low = db.query(Event).filter(Event.severity == "low").count() return { "total": total, "pending": pending, "processing": processing, "resolved": resolved, "ignored": ignored, "alerts": alerts, "severity": { "critical": critical, "high": high, "medium": medium, "low": low } } @router.get("/stats/by-type", summary="按类型统计事件") async def get_event_stats_by_type(db: Session = Depends(get_db)): """按事件类型统计""" from sqlalchemy import func stats = db.query( Event.event_type, func.count(Event.id).label('count') ).group_by(Event.event_type).all() return { "stats": [ {"type": stat.event_type, "count": stat.count} for stat in stats ] }