import os from pydantic import BaseModel, Field from typing import Optional, List, Dict, Any from datetime import datetime class AlertCreate(BaseModel): camera_id: str = Field(..., description="摄像头标识") roi_id: Optional[str] = Field(None, description="ROI区域标识") bind_id: Optional[str] = Field(None, description="绑定ID") device_id: Optional[str] = Field(None, description="边缘设备ID") alert_type: str = Field(..., description="告警类型") algorithm: Optional[str] = Field(None, description="算法名称") confidence: Optional[int] = Field(None, ge=0, le=100, description="置信度") duration_minutes: Optional[int] = Field(None, ge=0, description="离岗时长(分钟)") trigger_time: datetime = Field(..., description="触发时间") message: Optional[str] = Field(None, description="告警消息") bbox: Optional[str] = Field(None, description="检测框坐标") class AlertResponse(BaseModel): id: int alert_no: str camera_id: str roi_id: Optional[str] bind_id: Optional[str] device_id: Optional[str] alert_type: str algorithm: Optional[str] confidence: Optional[int] duration_minutes: Optional[int] trigger_time: Optional[str] message: Optional[str] snapshot_url: Optional[str] bbox: Optional[Any] = None status: str level: Optional[str] handle_remark: Optional[str] handled_by: Optional[str] handled_at: Optional[str] work_order_id: Optional[int] ai_analysis: Optional[dict] created_at: Optional[str] updated_at: Optional[str] class Config: from_attributes = True class AlertListResponse(BaseModel): alerts: List[AlertResponse] total: int page: int page_size: int class AlertHandleRequest(BaseModel): status: str = Field(..., description="处理状态: confirmed/ignored/resolved") remark: Optional[str] = Field(None, description="处理备注") class AlertStatisticsResponse(BaseModel): total: int pending: int confirmed: int ignored: int resolved: int dispatched: int = 0 by_type: dict by_level: Optional[dict] = None # ==================== 设备相关 ==================== class DeviceResponse(BaseModel): id: int device_id: str device_name: Optional[str] status: str last_heartbeat: Optional[str] uptime_seconds: Optional[int] frames_processed: Optional[int] alerts_generated: Optional[int] extra_info: Optional[Dict[str, Any]] created_at: Optional[str] updated_at: Optional[str] class Config: from_attributes = True class DeviceListResponse(BaseModel): devices: List[DeviceResponse] total: int page: int page_size: int class DeviceStatisticsResponse(BaseModel): total: int online: int offline: int error: int # ==================== 健康检查 ==================== class HealthResponse(BaseModel): status: str database: str mqtt: Optional[str] = None websocket_connections: Optional[int] = None