from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from typing import List, Optional, Dict, Any from datetime import datetime, timedelta from core.database import get_db from models.device import Device from models.algorithm import Algorithm from models.event import Event router = APIRouter() @router.get("/kpi", summary="获取主要KPI指标") async def get_dashboard_kpi(db: Session = Depends(get_db)): """获取仪表板主要KPI指标""" try: # 设备统计 total_devices = db.query(Device).count() online_devices = db.query(Device).filter(Device.status == "online").count() # 算法统计 total_algorithms = db.query(Algorithm).count() active_algorithms = db.query(Algorithm).filter(Algorithm.is_enabled == True).count() # 事件统计 total_events = db.query(Event).count() today = datetime.now().date() today_events = db.query(Event).filter( Event.created_at >= today ).count() # 告警事件统计 alert_events = db.query(Event).filter(Event.is_alert == True).count() resolved_events = db.query(Event).filter(Event.status == "resolved").count() return { "total_devices": total_devices, "online_devices": online_devices, "total_algorithms": total_algorithms, "active_algorithms": active_algorithms, "total_events": total_events, "today_events": today_events, "alert_events": alert_events, "resolved_events": resolved_events } except Exception as e: raise HTTPException(status_code=500, detail=f"获取KPI数据失败: {str(e)}") @router.get("/alarm-trend", summary="获取告警趋势统计") async def get_alarm_trend(db: Session = Depends(get_db)): """获取告警趋势统计数据 - 最近5个月的P0-P3警告统计""" try: # 获取最近5个月的数据 current_date = datetime.now() months = [] p0_warnings = [] p1_warnings = [] p2_warnings = [] p3_warnings = [] for i in range(5): # 计算月份 month_date = current_date - timedelta(days=30 * i) month_str = month_date.strftime("%Y-%m") months.append(month_str) # 模拟各级别警告数据 p0_count = 15 + (i * 3) % 25 # 15-40之间的随机数据 p1_count = 25 + (i * 2) % 35 # 25-60之间的随机数据 p2_count = 35 + (i * 4) % 45 # 35-80之间的随机数据 p3_count = 45 + (i * 3) % 55 # 45-100之间的随机数据 p0_warnings.append(p0_count) p1_warnings.append(p1_count) p2_warnings.append(p2_count) p3_warnings.append(p3_count) # 反转数组,让时间从早到晚 months.reverse() p0_warnings.reverse() p1_warnings.reverse() p2_warnings.reverse() p3_warnings.reverse() return { "months": months, "p0_warnings": p0_warnings, "p1_warnings": p1_warnings, "p2_warnings": p2_warnings, "p3_warnings": p3_warnings } except Exception as e: raise HTTPException(status_code=500, detail=f"获取告警趋势数据失败: {str(e)}") @router.get("/camera-stats", summary="获取摄像头统计") async def get_camera_stats(db: Session = Depends(get_db)): """获取摄像头统计数据""" try: # 设备统计 total_cameras = db.query(Device).filter(Device.device_type == "camera").count() online_cameras = db.query(Device).filter( Device.device_type == "camera", Device.status == "online" ).count() offline_cameras = total_cameras - online_cameras # TODO: 实现按位置统计 # 当前返回模拟数据 by_location = [ {"location": "港口区", "total": 45, "online": 42}, {"location": "码头区", "total": 38, "online": 35}, {"location": "办公区", "total": 23, "online": 21} ] return { "total_cameras": total_cameras, "online_cameras": online_cameras, "offline_cameras": offline_cameras, "by_location": by_location } except Exception as e: raise HTTPException(status_code=500, detail=f"获取摄像头统计数据失败: {str(e)}") @router.get("/algorithm-stats", summary="获取算法统计") async def get_algorithm_stats(db: Session = Depends(get_db)): """获取算法统计数据""" try: total_algorithms = db.query(Algorithm).count() active_algorithms = db.query(Algorithm).filter(Algorithm.is_enabled == True).count() # TODO: 实现按类型统计 # 当前返回模拟数据 by_type = [ {"type": "目标检测", "count": 3, "accuracy": 95.2}, {"type": "行为识别", "count": 2, "accuracy": 88.7}, {"type": "越界检测", "count": 3, "accuracy": 92.1} ] return { "total_algorithms": total_algorithms, "active_algorithms": active_algorithms, "by_type": by_type } except Exception as e: raise HTTPException(status_code=500, detail=f"获取算法统计数据失败: {str(e)}") @router.get("/event-hotspots", summary="获取事件热点统计") async def get_event_hotspots(db: Session = Depends(get_db)): """获取事件热点统计数据""" try: # TODO: 实现真实的事件热点统计 # 当前返回模拟数据 hotspots = [ { "location": "港口A区", "event_count": 45, "severity": "high", "coordinates": {"lat": 31.2304, "lng": 121.4737} }, { "location": "码头B区", "event_count": 32, "severity": "medium", "coordinates": {"lat": 31.2404, "lng": 121.4837} }, { "location": "办公区C区", "event_count": 18, "severity": "low", "coordinates": {"lat": 31.2204, "lng": 121.4637} } ] return { "hotspots": hotspots } except Exception as e: raise HTTPException(status_code=500, detail=f"获取事件热点数据失败: {str(e)}")