300 lines
10 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
2025-08-05 11:57:14 +08:00
from typing import List, Optional, Dict, Any
2025-08-02 12:38:52 +08:00
from datetime import datetime
from core.database import get_db
from models.event import Event
router = APIRouter()
2025-08-05 11:57:14 +08:00
@router.post("/", summary="创建事件")
2025-08-02 12:38:52 +08:00
async def create_event(
2025-08-05 11:57:14 +08:00
event_data: Dict[str, Any],
2025-08-02 12:38:52 +08:00
db: Session = Depends(get_db)
):
"""创建新的事件"""
2025-08-05 11:57:14 +08:00
db_event = Event(**event_data)
2025-08-02 12:38:52 +08:00
db.add(db_event)
db.commit()
db.refresh(db_event)
2025-08-05 11:57:14 +08:00
return {
"id": db_event.id,
"event_type": db_event.event_type,
"device_id": db_event.device_id,
"algorithm_id": db_event.algorithm_id,
"severity": db_event.severity,
"status": db_event.status,
"is_alert": db_event.is_alert,
"description": db_event.description,
"image_path": db_event.image_path,
"video_path": db_event.video_path,
"confidence": db_event.confidence,
"bbox": db_event.bbox,
"resolution_notes": db_event.resolution_notes,
"resolved_at": db_event.resolved_at,
"created_at": db_event.created_at,
"updated_at": db_event.updated_at
}
2025-08-02 12:38:52 +08:00
2025-08-05 11:57:14 +08:00
@router.get("/", summary="获取事件列表")
2025-08-02 12:38:52 +08:00
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()
2025-08-05 11:57:14 +08:00
event_list = []
for event in events:
event_list.append({
"id": event.id,
"event_type": event.event_type,
"device_id": event.device_id,
"algorithm_id": event.algorithm_id,
"severity": event.severity,
"status": event.status,
"is_alert": event.is_alert,
"description": event.description,
"image_path": event.image_path,
"video_path": event.video_path,
"confidence": event.confidence,
"bbox": event.bbox,
"resolution_notes": event.resolution_notes,
"resolved_at": event.resolved_at,
"created_at": event.created_at,
"updated_at": event.updated_at
})
return {
"events": event_list,
"total": total,
"page": skip // limit + 1,
"size": limit
}
2025-08-02 12:38:52 +08:00
2025-08-05 11:57:14 +08:00
@router.get("/{event_id}", summary="获取事件详情")
2025-08-02 12:38:52 +08:00
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="事件不存在")
2025-08-05 11:57:14 +08:00
return {
"id": event.id,
"event_type": event.event_type,
"device_id": event.device_id,
"algorithm_id": event.algorithm_id,
"severity": event.severity,
"status": event.status,
"is_alert": event.is_alert,
"description": event.description,
"image_path": event.image_path,
"video_path": event.video_path,
"confidence": event.confidence,
"bbox": event.bbox,
"resolution_notes": event.resolution_notes,
"resolved_at": event.resolved_at,
"created_at": event.created_at,
"updated_at": event.updated_at
}
2025-08-02 12:38:52 +08:00
2025-08-05 11:57:14 +08:00
@router.put("/{event_id}", summary="更新事件")
2025-08-02 12:38:52 +08:00
async def update_event(
event_id: int,
2025-08-05 11:57:14 +08:00
event_data: Dict[str, Any],
2025-08-02 12:38:52 +08:00
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="事件不存在")
2025-08-05 11:57:14 +08:00
for field, value in event_data.items():
if hasattr(db_event, field):
setattr(db_event, field, value)
2025-08-02 12:38:52 +08:00
db.commit()
db.refresh(db_event)
2025-08-05 11:57:14 +08:00
return {
"id": db_event.id,
"event_type": db_event.event_type,
"device_id": db_event.device_id,
"algorithm_id": db_event.algorithm_id,
"severity": db_event.severity,
"status": db_event.status,
"is_alert": db_event.is_alert,
"description": db_event.description,
"image_path": db_event.image_path,
"video_path": db_event.video_path,
"confidence": db_event.confidence,
"bbox": db_event.bbox,
"resolution_notes": db_event.resolution_notes,
"resolved_at": db_event.resolved_at,
"created_at": db_event.created_at,
"updated_at": db_event.updated_at
}
2025-08-02 12:38:52 +08:00
@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": "事件删除成功"}
2025-08-05 11:57:14 +08:00
@router.patch("/{event_id}/status", summary="更新事件状态")
2025-08-02 12:38:52 +08:00
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)
2025-08-05 11:57:14 +08:00
return {
"id": event.id,
"event_type": event.event_type,
"device_id": event.device_id,
"algorithm_id": event.algorithm_id,
"severity": event.severity,
"status": event.status,
"is_alert": event.is_alert,
"description": event.description,
"image_path": event.image_path,
"video_path": event.video_path,
"confidence": event.confidence,
"bbox": event.bbox,
"resolution_notes": event.resolution_notes,
"resolved_at": event.resolved_at,
"created_at": event.created_at,
"updated_at": event.updated_at
}
2025-08-02 12:38:52 +08:00
@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
]
}