fix(alarm): 修复告警列表和汇总显示 camera_code 问题
问题: - 告警列表和汇总页面显示 camera_code(例如 cam_1f0e3dad9990)而不是中文摄像头名称 - _get_camera_info 函数过早检查 token 导致查询失败 修复: 1. 移除 camera_code 查询路径中不必要的 token 检查 - /api/ai/camera/get 已加入白名单,不需要认证 - 仅对 app/stream 格式保留 token 检查 2. 修复告警列表页面摄像头名称显示 - 将 _alarm_to_camel 改为 async 函数 - 添加摄像头名称查询逻辑(三级 fallback) - 使用 asyncio.gather 并发查询提升性能 3. 添加调试日志 - 记录摄像头查询请求和响应 - 便于排查问题 测试结果: - 告警汇总: cam_1f0e3dad9990 → "大堂吧台3" ✓ - 告警列表: cam_1f0e3dad9990 → "大堂吧台3" ✓ 相关文件: - app/routers/yudao_aiot_alarm.py
This commit is contained in:
@@ -29,7 +29,7 @@ from app.utils.logger import logger
|
||||
router = APIRouter(prefix="/admin-api/aiot/alarm", tags=["AIoT-告警"])
|
||||
|
||||
|
||||
def _alarm_to_camel(alarm_dict: dict) -> dict:
|
||||
async def _alarm_to_camel(alarm_dict: dict, current_user: dict = None) -> dict:
|
||||
"""将 alarm_event 字典转换为前端 camelCase 格式(兼容前端旧字段名)"""
|
||||
# snapshot_url: 根据存储方式转为可访问 URL
|
||||
storage = get_oss_storage()
|
||||
@@ -61,6 +61,27 @@ def _alarm_to_camel(alarm_dict: dict) -> dict:
|
||||
|
||||
alarm_id = alarm_dict.get("alarm_id")
|
||||
|
||||
# 查询摄像头名称(三级 fallback 策略)
|
||||
device_id = alarm_dict.get("device_id")
|
||||
device_name = device_id # 默认使用 device_id
|
||||
|
||||
if current_user and device_id:
|
||||
try:
|
||||
camera_info = await _get_camera_info(device_id, current_user)
|
||||
if camera_info:
|
||||
# 1. 优先使用 gb_name(去除 "/" 后缀)
|
||||
gb_name = camera_info.get("gbName") or camera_info.get("gb_name")
|
||||
if gb_name:
|
||||
device_name = gb_name.split("/")[0]
|
||||
# 2. 其次使用 name 字段
|
||||
elif camera_info.get("name"):
|
||||
device_name = camera_info.get("name")
|
||||
# 3. 最后才使用 app 字段
|
||||
elif camera_info.get("app"):
|
||||
device_name = camera_info.get("app")
|
||||
except Exception as e:
|
||||
logger.warning(f"告警列表查询摄像头信息失败: device_id={device_id}, error={e}")
|
||||
|
||||
return {
|
||||
# 新字段(三表结构)
|
||||
"alarmId": alarm_id,
|
||||
@@ -68,7 +89,7 @@ def _alarm_to_camel(alarm_dict: dict) -> dict:
|
||||
"alarmTypeName": _get_alarm_type_name(alarm_dict.get("alarm_type")),
|
||||
"algorithmCode": alarm_dict.get("algorithm_code"),
|
||||
"deviceId": alarm_dict.get("device_id"),
|
||||
"deviceName": alarm_dict.get("device_id"),
|
||||
"deviceName": device_name,
|
||||
"sceneId": alarm_dict.get("scene_id"),
|
||||
"eventTime": alarm_dict.get("event_time"),
|
||||
"firstFrameTime": alarm_dict.get("first_frame_time"),
|
||||
@@ -140,7 +161,8 @@ async def get_alert_page(
|
||||
page_size=pageSize,
|
||||
)
|
||||
|
||||
alarm_list = [_alarm_to_camel(a.to_dict()) for a in alarms]
|
||||
# 并发查询所有告警的摄像头名称
|
||||
alarm_list = await asyncio.gather(*[_alarm_to_camel(a.to_dict(), current_user) for a in alarms])
|
||||
|
||||
return YudaoResponse.page(
|
||||
list_data=alarm_list,
|
||||
@@ -165,7 +187,7 @@ async def get_alert(
|
||||
if not alarm_dict:
|
||||
raise HTTPException(status_code=404, detail="告警不存在")
|
||||
|
||||
return YudaoResponse.success(_alarm_to_camel(alarm_dict))
|
||||
return YudaoResponse.success(await _alarm_to_camel(alarm_dict, current_user))
|
||||
|
||||
|
||||
@router.put("/alert/handle")
|
||||
@@ -359,13 +381,6 @@ 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:
|
||||
@@ -375,8 +390,10 @@ async def _get_camera_info(device_id: str, current_user: dict) -> Optional[dict]
|
||||
f"{WVP_API_BASE}/api/ai/camera/get",
|
||||
params={"cameraCode": device_id},
|
||||
)
|
||||
logger.info(f"查询摄像头: device_id={device_id}, status={resp.status_code}")
|
||||
if resp.status_code == 200:
|
||||
data = resp.json()
|
||||
logger.info(f"WVP 响应: {data}")
|
||||
if data.get("code") == 0:
|
||||
return data.get("data")
|
||||
except Exception as e:
|
||||
@@ -384,6 +401,13 @@ async def _get_camera_info(device_id: str, current_user: dict) -> Optional[dict]
|
||||
|
||||
# 如果是 app/stream 格式
|
||||
elif "/" in device_id:
|
||||
# 获取 token(app/stream 查询需要认证)
|
||||
token = current_user.get("access_token") or current_user.get("token")
|
||||
if not token:
|
||||
logger.warning(f"查询 app/stream 失败: 缺少 token, device_id={device_id}")
|
||||
return None
|
||||
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
parts = device_id.split("/", 1)
|
||||
if len(parts) == 2:
|
||||
app, stream = parts
|
||||
|
||||
Reference in New Issue
Block a user