213 lines
7.2 KiB
Python
Raw Normal View History

2025-08-02 12:38:52 +08:00
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
]
}