diff --git a/.gitignore b/.gitignore index 9e959cd..64b3966 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,10 @@ Thumbs.db # PyInstaller *.manifest *.spec + +# Diagnostic documents and scripts - DO NOT COMMIT +*诊断*.md +*分析*.md +*报告*.md +*修复*.py +*patch*.py diff --git a/app/routers/yudao_aiot_alarm.py b/app/routers/yudao_aiot_alarm.py index f8a46b9..bc344df 100644 --- a/app/routers/yudao_aiot_alarm.py +++ b/app/routers/yudao_aiot_alarm.py @@ -17,6 +17,7 @@ from typing import Optional from datetime import datetime import httpx import asyncio +import os from app.yudao_compat import YudaoResponse, get_current_user from app.services.alarm_event_service import get_alarm_event_service, AlarmEventService @@ -243,11 +244,23 @@ async def get_device_summary_page( """获取设备告警汇总(分页)""" result = service.get_device_summary(page=pageNo, page_size=pageSize) - # 添加前端兼容字段别名 + # 添加前端兼容字段别名,并查询摄像头名称 compat_list = [] for item in result.get("list", []): - item["cameraId"] = item.get("deviceId") - item["cameraName"] = item.get("deviceName") + device_id = item.get("deviceId") + device_name = device_id # 默认使用 device_id + + # 尝试从 WVP 查询摄像头名称 + try: + camera_info = await _get_camera_info(device_id, current_user) + if camera_info: + device_name = camera_info.get("app") or camera_info.get("name") or device_id + except Exception as e: + logger.warning(f"查询摄像头信息失败: device_id={device_id}, error={e}") + + item["cameraId"] = device_id + item["cameraName"] = device_name + item["deviceName"] = device_name # 更新 deviceName 为实际名称 item["pendingCount"] = item.get("unhandledCount") item["lastAlertTime"] = item.get("lastEventTime") item["lastAlertType"] = item.get("lastAlarmType") @@ -329,6 +342,63 @@ async def edge_alarm_resolve( # ==================== 辅助函数 ==================== OPS_ALARM_URL = "http://192.168.0.104:48080/admin-api/ops/alarm/receive" +WVP_API_BASE = os.getenv("WVP_API_BASE", "http://localhost:18080") + + +async def _get_camera_info(device_id: str, current_user: dict) -> Optional[dict]: + """ + 从 WVP 查询摄像头信息 + 支持 camera_code 和 app/stream 两种格式 + """ + # 获取 token + token = current_user.get("access_token") or current_user.get("token") + if not token: + return None + + headers = {"Authorization": f"Bearer {token}"} + + # 如果是 camera_code 格式(cam_xxxxxxxxxxxx) + if device_id.startswith("cam_"): + try: + async with httpx.AsyncClient(timeout=5) as client: + # 调用 WVP 查询单个摄像头的 API + resp = await client.get( + f"{WVP_API_BASE}/admin-api/aiot/device/camera/get", + params={"cameraCode": device_id}, + headers=headers + ) + if resp.status_code == 200: + data = resp.json() + if data.get("code") == 0: + return data.get("data") + except Exception as e: + logger.warning(f"查询 camera_code 失败: {device_id}, error={e}") + + # 如果是 app/stream 格式 + elif "/" in device_id: + parts = device_id.split("/", 1) + if len(parts) == 2: + app, stream = parts + try: + async with httpx.AsyncClient(timeout=5) as client: + # 查询摄像头列表,筛选 app 和 stream + resp = await client.get( + f"{WVP_API_BASE}/admin-api/aiot/device/camera/list", + params={"page": 1, "count": 1, "query": stream}, + headers=headers + ) + if resp.status_code == 200: + data = resp.json() + if data.get("code") == 0: + camera_list = data.get("data", {}).get("list", []) + # 找到匹配的摄像头 + for camera in camera_list: + if camera.get("app") == app and camera.get("stream") == stream: + return camera + except Exception as e: + logger.warning(f"查询 app/stream 失败: {device_id}, error={e}") + + return None async def _notify_ops_platform(data: dict):