From 0d27e98d097148b7b1be6189e89f7170e84db255 Mon Sep 17 00:00:00 2001 From: 16337 <1633794139@qq.com> Date: Tue, 24 Feb 2026 14:49:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(alarm):=20=E7=BB=9F=E4=B8=80=E4=BD=BF?= =?UTF-8?q?=E7=94=A8stream=E7=BC=96=E5=8F=B7=E4=BD=9C=E4=B8=BA=E6=91=84?= =?UTF-8?q?=E5=83=8F=E5=A4=B4ID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 设备汇总和告警列表统一使用stream(012、008等)作为cameraId - 支持camera_code格式:从WVP API查询获取stream - 支持app/stream格式:直接解析提取stream部分 - 优化批量查询性能,使用camera_info_map减少重复查询 --- app/routers/yudao_aiot_alarm.py | 71 ++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 18 deletions(-) diff --git a/app/routers/yudao_aiot_alarm.py b/app/routers/yudao_aiot_alarm.py index fe77bc5..59b3fc7 100644 --- a/app/routers/yudao_aiot_alarm.py +++ b/app/routers/yudao_aiot_alarm.py @@ -28,12 +28,13 @@ from app.utils.logger import logger router = APIRouter(prefix="/admin-api/aiot/alarm", tags=["AIoT-告警"]) -async def _alarm_to_camel(alarm_dict: dict, name_map: dict = None) -> dict: +async def _alarm_to_camel(alarm_dict: dict, camera_info_map: dict = None, camera_service=None) -> dict: """将 alarm_event 字典转换为前端 camelCase 格式(兼容前端旧字段名) Args: alarm_dict: 告警字典 - name_map: 摄像头名称映射 {device_id: display_name},可选 + camera_info_map: 摄像头信息映射 {device_id: camera_info},可选 + camera_service: 摄像头服务实例,可选 """ # snapshot_url: 根据存储方式转为可访问 URL storage = get_oss_storage() @@ -64,13 +65,29 @@ async def _alarm_to_camel(alarm_dict: dict, name_map: dict = None) -> dict: duration_minutes = round(duration_ms / 60000, 1) if duration_ms else None alarm_id = alarm_dict.get("alarm_id") - - # 获取摄像头显示名称(从缓存映射中获取) device_id = alarm_dict.get("device_id") - device_name = device_id # 默认使用 device_id - if name_map and device_id in name_map: - device_name = name_map[device_id] + # 获取摄像头信息 + camera_info = None + if camera_info_map and device_id in camera_info_map: + camera_info = camera_info_map[device_id] + + # 获取摄像头名称 + device_name = device_id # 默认值 + if camera_service and camera_info: + device_name = camera_service.format_display_name(device_id, camera_info) + + # 提取摄像头ID(统一使用stream作为编号) + camera_id = device_id # 默认值 + if camera_info: + stream = camera_info.get("stream") + if stream: + camera_id = stream + elif device_id and "/" in device_id: + # app/stream 格式,直接解析 + parts = device_id.split("/", 1) + if len(parts) == 2: + camera_id = parts[1] return { # 新字段(三表结构) @@ -102,8 +119,9 @@ async def _alarm_to_camel(alarm_dict: dict, name_map: dict = None) -> dict: # 兼容前端旧字段名 "id": alarm_id, "alertNo": alarm_id, - "cameraId": alarm_dict.get("device_id"), # 保持原始ID(用于查询) - "cameraName": device_name, # 显示用的中文名称 + "deviceId": device_id, # 原始ID(用于查询) + "cameraId": camera_id, # 摄像头ID(stream编号) + "cameraName": device_name, # 摄像头名称 "alertType": alarm_dict.get("alarm_type"), "alertTypeName": _get_alarm_type_name(alarm_dict.get("alarm_type")), "confidence": confidence_pct, @@ -155,12 +173,12 @@ async def get_alert_page( # 提取所有唯一的 device_id device_ids = list(set(a.device_id for a in alarms if a.device_id)) - # 批量查询摄像头名称(去重+并发优化) + # 批量查询摄像头信息(去重+并发优化) camera_service = get_camera_name_service() - name_map = await camera_service.get_display_names_batch(device_ids) + camera_info_map = await camera_service.get_camera_infos_batch(device_ids) - # 转换为 camelCase 格式(使用缓存的名称映射) - alarm_list = [await _alarm_to_camel(a.to_dict(), name_map) for a in alarms] + # 转换为 camelCase 格式(使用摄像头信息映射) + alarm_list = [await _alarm_to_camel(a.to_dict(), camera_info_map, camera_service) for a in alarms] return YudaoResponse.page( list_data=alarm_list, @@ -274,12 +292,29 @@ async def get_device_summary_page( compat_list = [] for item in result.get("list", []): device_id = item.get("deviceId") - # 使用配置化服务获取显示名称 - device_name = await camera_service.get_display_name(device_id) - item["cameraId"] = device_id - item["cameraName"] = device_name - item["deviceName"] = device_name + # 批量查询摄像头信息 + camera_info = await camera_service.get_camera_info(device_id) + + # 提取摄像头名称 + device_name = camera_service.format_display_name(device_id, camera_info) + + # 提取摄像头ID(统一使用stream作为编号) + camera_id = device_id # 默认值 + if camera_info: + stream = camera_info.get("stream") + if stream: + camera_id = stream + elif "/" in device_id: + # app/stream 格式,直接解析 + parts = device_id.split("/", 1) + if len(parts) == 2: + camera_id = parts[1] + + item["deviceId"] = device_id # 原始ID(用于查询) + item["cameraId"] = camera_id # 摄像头ID(stream编号) + item["cameraName"] = device_name # 摄像头名称 + item["deviceName"] = device_name # 摄像头名称(兼容) item["pendingCount"] = item.get("unhandledCount") item["lastAlertTime"] = item.get("lastEventTime") item["lastAlertType"] = item.get("lastAlarmType")