213 lines
7.2 KiB
Python
213 lines
7.2 KiB
Python
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
|
||
]
|
||
} |