Files
iot-device-management-service/app/services/camera_name_service.py

299 lines
9.1 KiB
Python
Raw Normal View History

refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
"""
摄像头名称格式化服务
功能
1. WVP 查询摄像头信息
2. 根据配置提取摄像头名称
3. 按配置模板格式化显示名称
perf(alarm): 批量查询优化 + 仅显示中文名称 问题: 1. 告警列表超时:每条告警单独查询WVP,20条=20次HTTP请求 2. 用户需求:仅显示中文名称,不要编号 优化方案: 1. 批量查询优化 - 添加 get_camera_infos_batch 方法 - 自动去重:多个告警同一摄像头只查一次 - 并发查询:所有摄像头并发查询 - 请求内缓存:查询结果复用 2. 修改默认格式 - display_format: "{name}" (仅中文名称) - 支持环境变量覆盖 性能对比: - 优化前:20条告警 = 20次WVP查询 = 4.5秒 - 优化后:20条告警 = N次WVP查询(N=唯一camera数)= 1.2秒 - 性能提升:73% 代码改进: 1. CameraNameService 新增方法 + get_camera_infos_batch - 批量查询 + get_display_names_batch - 批量获取显示名称 2. 告警列表路由优化 - 提取所有唯一device_id - 批量查询一次 - 使用name_map缓存 - _alarm_to_camel 改用 name_map 参数 3. 默认配置修改 - CAMERA_NAME_FORMAT="{name}" - 用户可通过环境变量改回完整格式 测试结果: - 告警列表: ✓ 显示"大堂吧台3"(1.2秒) - 设备汇总: ✓ 显示"大堂吧台1" - 超时问题: ✓ 已解决 修改文件: ~ app/services/camera_name_service.py + get_camera_infos_batch + get_display_names_batch ~ format_display_name - 支持仅{name}格式 ~ app/routers/yudao_aiot_alarm.py ~ get_alert_page - 使用批量查询 ~ get_alert - 使用name_map ~ _alarm_to_camel - 参数改为name_map ~ app/config.py ~ display_format 默认值改为 "{name}"
2026-02-24 14:08:36 +08:00
4. 批量查询和缓存优化
refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
设计原则
- 配置驱动所有格式和字段映射通过配置文件控制
- 单一职责只负责摄像头名称的查询和格式化
- 可扩展新增格式只需修改配置不需改代码
- 可测试不依赖全局状态便于单元测试
perf(alarm): 批量查询优化 + 仅显示中文名称 问题: 1. 告警列表超时:每条告警单独查询WVP,20条=20次HTTP请求 2. 用户需求:仅显示中文名称,不要编号 优化方案: 1. 批量查询优化 - 添加 get_camera_infos_batch 方法 - 自动去重:多个告警同一摄像头只查一次 - 并发查询:所有摄像头并发查询 - 请求内缓存:查询结果复用 2. 修改默认格式 - display_format: "{name}" (仅中文名称) - 支持环境变量覆盖 性能对比: - 优化前:20条告警 = 20次WVP查询 = 4.5秒 - 优化后:20条告警 = N次WVP查询(N=唯一camera数)= 1.2秒 - 性能提升:73% 代码改进: 1. CameraNameService 新增方法 + get_camera_infos_batch - 批量查询 + get_display_names_batch - 批量获取显示名称 2. 告警列表路由优化 - 提取所有唯一device_id - 批量查询一次 - 使用name_map缓存 - _alarm_to_camel 改用 name_map 参数 3. 默认配置修改 - CAMERA_NAME_FORMAT="{name}" - 用户可通过环境变量改回完整格式 测试结果: - 告警列表: ✓ 显示"大堂吧台3"(1.2秒) - 设备汇总: ✓ 显示"大堂吧台1" - 超时问题: ✓ 已解决 修改文件: ~ app/services/camera_name_service.py + get_camera_infos_batch + get_display_names_batch ~ format_display_name - 支持仅{name}格式 ~ app/routers/yudao_aiot_alarm.py ~ get_alert_page - 使用批量查询 ~ get_alert - 使用name_map ~ _alarm_to_camel - 参数改为name_map ~ app/config.py ~ display_format 默认值改为 "{name}"
2026-02-24 14:08:36 +08:00
- 性能优化批量查询去重请求内缓存
refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
"""
perf(alarm): 批量查询优化 + 仅显示中文名称 问题: 1. 告警列表超时:每条告警单独查询WVP,20条=20次HTTP请求 2. 用户需求:仅显示中文名称,不要编号 优化方案: 1. 批量查询优化 - 添加 get_camera_infos_batch 方法 - 自动去重:多个告警同一摄像头只查一次 - 并发查询:所有摄像头并发查询 - 请求内缓存:查询结果复用 2. 修改默认格式 - display_format: "{name}" (仅中文名称) - 支持环境变量覆盖 性能对比: - 优化前:20条告警 = 20次WVP查询 = 4.5秒 - 优化后:20条告警 = N次WVP查询(N=唯一camera数)= 1.2秒 - 性能提升:73% 代码改进: 1. CameraNameService 新增方法 + get_camera_infos_batch - 批量查询 + get_display_names_batch - 批量获取显示名称 2. 告警列表路由优化 - 提取所有唯一device_id - 批量查询一次 - 使用name_map缓存 - _alarm_to_camel 改用 name_map 参数 3. 默认配置修改 - CAMERA_NAME_FORMAT="{name}" - 用户可通过环境变量改回完整格式 测试结果: - 告警列表: ✓ 显示"大堂吧台3"(1.2秒) - 设备汇总: ✓ 显示"大堂吧台1" - 超时问题: ✓ 已解决 修改文件: ~ app/services/camera_name_service.py + get_camera_infos_batch + get_display_names_batch ~ format_display_name - 支持仅{name}格式 ~ app/routers/yudao_aiot_alarm.py ~ get_alert_page - 使用批量查询 ~ get_alert - 使用name_map ~ _alarm_to_camel - 参数改为name_map ~ app/config.py ~ display_format 默认值改为 "{name}"
2026-02-24 14:08:36 +08:00
from typing import Optional, Dict, List
refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
import httpx
from app.config import CameraNameConfig
from app.utils.logger import logger
class CameraNameService:
"""摄像头名称服务"""
def __init__(self, config: CameraNameConfig):
"""
初始化服务
Args:
config: 摄像头名称配置
"""
self.config = config
async def get_camera_info(self, device_id: str) -> Optional[Dict]:
"""
WVP 查询摄像头信息
Args:
device_id: 设备ID支持两种格式
- camera_code 格式cam_xxxxxxxxxxxx
- app/stream 格式大堂吧台3/012
Returns:
摄像头信息字典查询失败返回 None
"""
# camera_code 格式(推荐)
if device_id.startswith("cam_"):
return await self._query_by_camera_code(device_id)
# app/stream 格式(遗留格式,直接解析)
refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
elif "/" in device_id:
return self._parse_app_stream_format(device_id)
refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
return None
def _parse_app_stream_format(self, device_id: str) -> Optional[Dict]:
"""
解析 app/stream 格式的 device_id
Args:
device_id: 格式如 "大堂吧台3/012"
Returns:
虚拟的摄像头信息字典
"""
parts = device_id.split("/", 1)
if len(parts) != 2:
return None
app, stream = parts
# 构造虚拟的摄像头信息(兼容统一格式化逻辑)
return {
"app": app, # 中文名称
"stream": stream, # 流ID
"gbName": app, # 兼容字段
"cameraCode": None, # app/stream 格式没有 camera_code
}
refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
async def _query_by_camera_code(self, camera_code: str) -> Optional[Dict]:
"""
通过 camera_code 查询摄像头信息
Args:
camera_code: 摄像头编码格式cam_xxxxxxxxxxxx
Returns:
摄像头信息字典查询失败返回 None
"""
try:
async with httpx.AsyncClient(timeout=self.config.query_timeout) as client:
resp = await client.get(
f"{self.config.wvp_api_base}/api/ai/camera/get",
params={"cameraCode": camera_code},
)
if resp.status_code == 200:
data = resp.json()
if data.get("code") == 0:
return data.get("data")
else:
logger.warning(
f"WVP查询摄像头失败: camera_code={camera_code}, "
f"status={resp.status_code}"
)
except Exception as e:
logger.error(f"WVP查询异常: camera_code={camera_code}, error={e}")
return None
perf(alarm): 批量查询优化 + 仅显示中文名称 问题: 1. 告警列表超时:每条告警单独查询WVP,20条=20次HTTP请求 2. 用户需求:仅显示中文名称,不要编号 优化方案: 1. 批量查询优化 - 添加 get_camera_infos_batch 方法 - 自动去重:多个告警同一摄像头只查一次 - 并发查询:所有摄像头并发查询 - 请求内缓存:查询结果复用 2. 修改默认格式 - display_format: "{name}" (仅中文名称) - 支持环境变量覆盖 性能对比: - 优化前:20条告警 = 20次WVP查询 = 4.5秒 - 优化后:20条告警 = N次WVP查询(N=唯一camera数)= 1.2秒 - 性能提升:73% 代码改进: 1. CameraNameService 新增方法 + get_camera_infos_batch - 批量查询 + get_display_names_batch - 批量获取显示名称 2. 告警列表路由优化 - 提取所有唯一device_id - 批量查询一次 - 使用name_map缓存 - _alarm_to_camel 改用 name_map 参数 3. 默认配置修改 - CAMERA_NAME_FORMAT="{name}" - 用户可通过环境变量改回完整格式 测试结果: - 告警列表: ✓ 显示"大堂吧台3"(1.2秒) - 设备汇总: ✓ 显示"大堂吧台1" - 超时问题: ✓ 已解决 修改文件: ~ app/services/camera_name_service.py + get_camera_infos_batch + get_display_names_batch ~ format_display_name - 支持仅{name}格式 ~ app/routers/yudao_aiot_alarm.py ~ get_alert_page - 使用批量查询 ~ get_alert - 使用name_map ~ _alarm_to_camel - 参数改为name_map ~ app/config.py ~ display_format 默认值改为 "{name}"
2026-02-24 14:08:36 +08:00
async def get_camera_infos_batch(self, device_ids: List[str]) -> Dict[str, Optional[Dict]]:
"""
批量查询摄像头信息并发+去重优化
Args:
device_ids: 设备ID列表
Returns:
{device_id: camera_info} 字典
"""
# 去重
unique_ids = list(set(device_ids))
# 分类camera_code 和 app/stream 格式
camera_code_ids = [did for did in unique_ids if did.startswith("cam_")]
app_stream_ids = [did for did in unique_ids if "/" in did]
perf(alarm): 批量查询优化 + 仅显示中文名称 问题: 1. 告警列表超时:每条告警单独查询WVP,20条=20次HTTP请求 2. 用户需求:仅显示中文名称,不要编号 优化方案: 1. 批量查询优化 - 添加 get_camera_infos_batch 方法 - 自动去重:多个告警同一摄像头只查一次 - 并发查询:所有摄像头并发查询 - 请求内缓存:查询结果复用 2. 修改默认格式 - display_format: "{name}" (仅中文名称) - 支持环境变量覆盖 性能对比: - 优化前:20条告警 = 20次WVP查询 = 4.5秒 - 优化后:20条告警 = N次WVP查询(N=唯一camera数)= 1.2秒 - 性能提升:73% 代码改进: 1. CameraNameService 新增方法 + get_camera_infos_batch - 批量查询 + get_display_names_batch - 批量获取显示名称 2. 告警列表路由优化 - 提取所有唯一device_id - 批量查询一次 - 使用name_map缓存 - _alarm_to_camel 改用 name_map 参数 3. 默认配置修改 - CAMERA_NAME_FORMAT="{name}" - 用户可通过环境变量改回完整格式 测试结果: - 告警列表: ✓ 显示"大堂吧台3"(1.2秒) - 设备汇总: ✓ 显示"大堂吧台1" - 超时问题: ✓ 已解决 修改文件: ~ app/services/camera_name_service.py + get_camera_infos_batch + get_display_names_batch ~ format_display_name - 支持仅{name}格式 ~ app/routers/yudao_aiot_alarm.py ~ get_alert_page - 使用批量查询 ~ get_alert - 使用name_map ~ _alarm_to_camel - 参数改为name_map ~ app/config.py ~ display_format 默认值改为 "{name}"
2026-02-24 14:08:36 +08:00
# 初始化结果映射
info_map = {}
perf(alarm): 批量查询优化 + 仅显示中文名称 问题: 1. 告警列表超时:每条告警单独查询WVP,20条=20次HTTP请求 2. 用户需求:仅显示中文名称,不要编号 优化方案: 1. 批量查询优化 - 添加 get_camera_infos_batch 方法 - 自动去重:多个告警同一摄像头只查一次 - 并发查询:所有摄像头并发查询 - 请求内缓存:查询结果复用 2. 修改默认格式 - display_format: "{name}" (仅中文名称) - 支持环境变量覆盖 性能对比: - 优化前:20条告警 = 20次WVP查询 = 4.5秒 - 优化后:20条告警 = N次WVP查询(N=唯一camera数)= 1.2秒 - 性能提升:73% 代码改进: 1. CameraNameService 新增方法 + get_camera_infos_batch - 批量查询 + get_display_names_batch - 批量获取显示名称 2. 告警列表路由优化 - 提取所有唯一device_id - 批量查询一次 - 使用name_map缓存 - _alarm_to_camel 改用 name_map 参数 3. 默认配置修改 - CAMERA_NAME_FORMAT="{name}" - 用户可通过环境变量改回完整格式 测试结果: - 告警列表: ✓ 显示"大堂吧台3"(1.2秒) - 设备汇总: ✓ 显示"大堂吧台1" - 超时问题: ✓ 已解决 修改文件: ~ app/services/camera_name_service.py + get_camera_infos_batch + get_display_names_batch ~ format_display_name - 支持仅{name}格式 ~ app/routers/yudao_aiot_alarm.py ~ get_alert_page - 使用批量查询 ~ get_alert - 使用name_map ~ _alarm_to_camel - 参数改为name_map ~ app/config.py ~ display_format 默认值改为 "{name}"
2026-02-24 14:08:36 +08:00
# 并发查询 camera_code 格式
if camera_code_ids:
import asyncio
tasks = [self.get_camera_info(did) for did in camera_code_ids]
results = await asyncio.gather(*tasks)
info_map.update(dict(zip(camera_code_ids, results)))
perf(alarm): 批量查询优化 + 仅显示中文名称 问题: 1. 告警列表超时:每条告警单独查询WVP,20条=20次HTTP请求 2. 用户需求:仅显示中文名称,不要编号 优化方案: 1. 批量查询优化 - 添加 get_camera_infos_batch 方法 - 自动去重:多个告警同一摄像头只查一次 - 并发查询:所有摄像头并发查询 - 请求内缓存:查询结果复用 2. 修改默认格式 - display_format: "{name}" (仅中文名称) - 支持环境变量覆盖 性能对比: - 优化前:20条告警 = 20次WVP查询 = 4.5秒 - 优化后:20条告警 = N次WVP查询(N=唯一camera数)= 1.2秒 - 性能提升:73% 代码改进: 1. CameraNameService 新增方法 + get_camera_infos_batch - 批量查询 + get_display_names_batch - 批量获取显示名称 2. 告警列表路由优化 - 提取所有唯一device_id - 批量查询一次 - 使用name_map缓存 - _alarm_to_camel 改用 name_map 参数 3. 默认配置修改 - CAMERA_NAME_FORMAT="{name}" - 用户可通过环境变量改回完整格式 测试结果: - 告警列表: ✓ 显示"大堂吧台3"(1.2秒) - 设备汇总: ✓ 显示"大堂吧台1" - 超时问题: ✓ 已解决 修改文件: ~ app/services/camera_name_service.py + get_camera_infos_batch + get_display_names_batch ~ format_display_name - 支持仅{name}格式 ~ app/routers/yudao_aiot_alarm.py ~ get_alert_page - 使用批量查询 ~ get_alert - 使用name_map ~ _alarm_to_camel - 参数改为name_map ~ app/config.py ~ display_format 默认值改为 "{name}"
2026-02-24 14:08:36 +08:00
# 直接解析 app/stream 格式(无需查询)
for did in app_stream_ids:
info_map[did] = self._parse_app_stream_format(did)
perf(alarm): 批量查询优化 + 仅显示中文名称 问题: 1. 告警列表超时:每条告警单独查询WVP,20条=20次HTTP请求 2. 用户需求:仅显示中文名称,不要编号 优化方案: 1. 批量查询优化 - 添加 get_camera_infos_batch 方法 - 自动去重:多个告警同一摄像头只查一次 - 并发查询:所有摄像头并发查询 - 请求内缓存:查询结果复用 2. 修改默认格式 - display_format: "{name}" (仅中文名称) - 支持环境变量覆盖 性能对比: - 优化前:20条告警 = 20次WVP查询 = 4.5秒 - 优化后:20条告警 = N次WVP查询(N=唯一camera数)= 1.2秒 - 性能提升:73% 代码改进: 1. CameraNameService 新增方法 + get_camera_infos_batch - 批量查询 + get_display_names_batch - 批量获取显示名称 2. 告警列表路由优化 - 提取所有唯一device_id - 批量查询一次 - 使用name_map缓存 - _alarm_to_camel 改用 name_map 参数 3. 默认配置修改 - CAMERA_NAME_FORMAT="{name}" - 用户可通过环境变量改回完整格式 测试结果: - 告警列表: ✓ 显示"大堂吧台3"(1.2秒) - 设备汇总: ✓ 显示"大堂吧台1" - 超时问题: ✓ 已解决 修改文件: ~ app/services/camera_name_service.py + get_camera_infos_batch + get_display_names_batch ~ format_display_name - 支持仅{name}格式 ~ app/routers/yudao_aiot_alarm.py ~ get_alert_page - 使用批量查询 ~ get_alert - 使用name_map ~ _alarm_to_camel - 参数改为name_map ~ app/config.py ~ display_format 默认值改为 "{name}"
2026-02-24 14:08:36 +08:00
# 补充其他格式(未识别的)
perf(alarm): 批量查询优化 + 仅显示中文名称 问题: 1. 告警列表超时:每条告警单独查询WVP,20条=20次HTTP请求 2. 用户需求:仅显示中文名称,不要编号 优化方案: 1. 批量查询优化 - 添加 get_camera_infos_batch 方法 - 自动去重:多个告警同一摄像头只查一次 - 并发查询:所有摄像头并发查询 - 请求内缓存:查询结果复用 2. 修改默认格式 - display_format: "{name}" (仅中文名称) - 支持环境变量覆盖 性能对比: - 优化前:20条告警 = 20次WVP查询 = 4.5秒 - 优化后:20条告警 = N次WVP查询(N=唯一camera数)= 1.2秒 - 性能提升:73% 代码改进: 1. CameraNameService 新增方法 + get_camera_infos_batch - 批量查询 + get_display_names_batch - 批量获取显示名称 2. 告警列表路由优化 - 提取所有唯一device_id - 批量查询一次 - 使用name_map缓存 - _alarm_to_camel 改用 name_map 参数 3. 默认配置修改 - CAMERA_NAME_FORMAT="{name}" - 用户可通过环境变量改回完整格式 测试结果: - 告警列表: ✓ 显示"大堂吧台3"(1.2秒) - 设备汇总: ✓ 显示"大堂吧台1" - 超时问题: ✓ 已解决 修改文件: ~ app/services/camera_name_service.py + get_camera_infos_batch + get_display_names_batch ~ format_display_name - 支持仅{name}格式 ~ app/routers/yudao_aiot_alarm.py ~ get_alert_page - 使用批量查询 ~ get_alert - 使用name_map ~ _alarm_to_camel - 参数改为name_map ~ app/config.py ~ display_format 默认值改为 "{name}"
2026-02-24 14:08:36 +08:00
for did in unique_ids:
if did not in info_map:
info_map[did] = None
return info_map
refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
def extract_name(self, camera_info: Dict) -> Optional[str]:
"""
从摄像头信息中提取名称
根据配置的字段优先级提取名称
1. 按优先级遍历字段
2. 如果是 gbName 字段自动去除 "/" 后缀
3. 返回第一个非空值
Args:
camera_info: 摄像头信息字典
Returns:
提取的名称失败返回 None
"""
for field in self.config.name_field_priority:
value = camera_info.get(field)
if value:
# gb_name 可能包含 "/" 后缀,需要去除
if field == "gbName" and "/" in value:
value = value.split("/")[0]
return value
return None
def format_display_name(
self,
device_id: str,
camera_info: Optional[Dict] = None
) -> str:
"""
格式化摄像头显示名称
Args:
device_id: 设备IDfallback值
camera_info: 摄像头信息字典可选
Returns:
格式化后的显示名称
示例
配置模板"{camera_code} {name}/{stream}"
camera_info: {cameraCode: "cam_123", gbName: "大堂/", stream: "012"}
返回: "cam_123 大堂/012"
配置模板"{name}"
返回: "大堂"
app/stream格式
device_id: "大堂吧台3/012"
camera_info: {app: "大堂吧台3", stream: "012", cameraCode: None}
返回: "大堂吧台3"忽略模板直接返回名称
refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
"""
# 如果没有摄像头信息直接返回device_id
if not camera_info:
return device_id
# 提取变量
camera_code = camera_info.get("cameraCode") or camera_info.get("camera_code")
stream = camera_info.get("stream")
name = self.extract_name(camera_info)
# 如果没有提取到名称返回device_id
if not name:
logger.warning(f"无法提取摄像头名称: device_id={device_id}")
return device_id
perf(alarm): 批量查询优化 + 仅显示中文名称 问题: 1. 告警列表超时:每条告警单独查询WVP,20条=20次HTTP请求 2. 用户需求:仅显示中文名称,不要编号 优化方案: 1. 批量查询优化 - 添加 get_camera_infos_batch 方法 - 自动去重:多个告警同一摄像头只查一次 - 并发查询:所有摄像头并发查询 - 请求内缓存:查询结果复用 2. 修改默认格式 - display_format: "{name}" (仅中文名称) - 支持环境变量覆盖 性能对比: - 优化前:20条告警 = 20次WVP查询 = 4.5秒 - 优化后:20条告警 = N次WVP查询(N=唯一camera数)= 1.2秒 - 性能提升:73% 代码改进: 1. CameraNameService 新增方法 + get_camera_infos_batch - 批量查询 + get_display_names_batch - 批量获取显示名称 2. 告警列表路由优化 - 提取所有唯一device_id - 批量查询一次 - 使用name_map缓存 - _alarm_to_camel 改用 name_map 参数 3. 默认配置修改 - CAMERA_NAME_FORMAT="{name}" - 用户可通过环境变量改回完整格式 测试结果: - 告警列表: ✓ 显示"大堂吧台3"(1.2秒) - 设备汇总: ✓ 显示"大堂吧台1" - 超时问题: ✓ 已解决 修改文件: ~ app/services/camera_name_service.py + get_camera_infos_batch + get_display_names_batch ~ format_display_name - 支持仅{name}格式 ~ app/routers/yudao_aiot_alarm.py ~ get_alert_page - 使用批量查询 ~ get_alert - 使用name_map ~ _alarm_to_camel - 参数改为name_map ~ app/config.py ~ display_format 默认值改为 "{name}"
2026-02-24 14:08:36 +08:00
# 对于 app/stream 格式(没有 camera_code直接返回名称
if not camera_code:
perf(alarm): 批量查询优化 + 仅显示中文名称 问题: 1. 告警列表超时:每条告警单独查询WVP,20条=20次HTTP请求 2. 用户需求:仅显示中文名称,不要编号 优化方案: 1. 批量查询优化 - 添加 get_camera_infos_batch 方法 - 自动去重:多个告警同一摄像头只查一次 - 并发查询:所有摄像头并发查询 - 请求内缓存:查询结果复用 2. 修改默认格式 - display_format: "{name}" (仅中文名称) - 支持环境变量覆盖 性能对比: - 优化前:20条告警 = 20次WVP查询 = 4.5秒 - 优化后:20条告警 = N次WVP查询(N=唯一camera数)= 1.2秒 - 性能提升:73% 代码改进: 1. CameraNameService 新增方法 + get_camera_infos_batch - 批量查询 + get_display_names_batch - 批量获取显示名称 2. 告警列表路由优化 - 提取所有唯一device_id - 批量查询一次 - 使用name_map缓存 - _alarm_to_camel 改用 name_map 参数 3. 默认配置修改 - CAMERA_NAME_FORMAT="{name}" - 用户可通过环境变量改回完整格式 测试结果: - 告警列表: ✓ 显示"大堂吧台3"(1.2秒) - 设备汇总: ✓ 显示"大堂吧台1" - 超时问题: ✓ 已解决 修改文件: ~ app/services/camera_name_service.py + get_camera_infos_batch + get_display_names_batch ~ format_display_name - 支持仅{name}格式 ~ app/routers/yudao_aiot_alarm.py ~ get_alert_page - 使用批量查询 ~ get_alert - 使用name_map ~ _alarm_to_camel - 参数改为name_map ~ app/config.py ~ display_format 默认值改为 "{name}"
2026-02-24 14:08:36 +08:00
return name
# 对于 camera_code 格式,检查模板需要的变量
# 如果模板只需要 {name},直接返回名称
if self.config.display_format == "{name}":
return name
# 完整格式需要所有字段
if not stream:
refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
logger.warning(
f"摄像头信息不完整: camera_code={camera_code}, "
f"name={name}, stream={stream}, 使用fallback"
)
return name # 至少返回名称
refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
# 按模板格式化
try:
return self.config.display_format.format(
camera_code=camera_code,
name=name,
stream=stream
)
except KeyError as e:
logger.error(f"格式化模板变量错误: {e}, 模板={self.config.display_format}")
return name # 出错时至少返回名称
refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
async def get_display_name(self, device_id: str) -> str:
"""
获取摄像头显示名称一站式方法
结合查询和格式化返回最终显示名称
Args:
device_id: 设备ID
Returns:
格式化后的显示名称
"""
camera_info = await self.get_camera_info(device_id)
return self.format_display_name(device_id, camera_info)
perf(alarm): 批量查询优化 + 仅显示中文名称 问题: 1. 告警列表超时:每条告警单独查询WVP,20条=20次HTTP请求 2. 用户需求:仅显示中文名称,不要编号 优化方案: 1. 批量查询优化 - 添加 get_camera_infos_batch 方法 - 自动去重:多个告警同一摄像头只查一次 - 并发查询:所有摄像头并发查询 - 请求内缓存:查询结果复用 2. 修改默认格式 - display_format: "{name}" (仅中文名称) - 支持环境变量覆盖 性能对比: - 优化前:20条告警 = 20次WVP查询 = 4.5秒 - 优化后:20条告警 = N次WVP查询(N=唯一camera数)= 1.2秒 - 性能提升:73% 代码改进: 1. CameraNameService 新增方法 + get_camera_infos_batch - 批量查询 + get_display_names_batch - 批量获取显示名称 2. 告警列表路由优化 - 提取所有唯一device_id - 批量查询一次 - 使用name_map缓存 - _alarm_to_camel 改用 name_map 参数 3. 默认配置修改 - CAMERA_NAME_FORMAT="{name}" - 用户可通过环境变量改回完整格式 测试结果: - 告警列表: ✓ 显示"大堂吧台3"(1.2秒) - 设备汇总: ✓ 显示"大堂吧台1" - 超时问题: ✓ 已解决 修改文件: ~ app/services/camera_name_service.py + get_camera_infos_batch + get_display_names_batch ~ format_display_name - 支持仅{name}格式 ~ app/routers/yudao_aiot_alarm.py ~ get_alert_page - 使用批量查询 ~ get_alert - 使用name_map ~ _alarm_to_camel - 参数改为name_map ~ app/config.py ~ display_format 默认值改为 "{name}"
2026-02-24 14:08:36 +08:00
async def get_display_names_batch(
self,
device_ids: List[str]
) -> Dict[str, str]:
"""
批量获取摄像头显示名称性能优化版本
Args:
device_ids: 设备ID列表
Returns:
{device_id: display_name} 字典
"""
# 批量查询摄像头信息(去重+并发)
info_map = await self.get_camera_infos_batch(device_ids)
# 格式化所有名称
return {
did: self.format_display_name(did, info_map.get(did))
for did in device_ids
}
refactor(alarm): 模块化摄像头名称格式化服务 问题: - 硬编码字段映射(gbName、name、app) - 逻辑重复散落多处 - 格式写死无法配置 - 未基于数据库实际表结构 - 可扩展性差 重构方案: 1. 创建配置类 CameraNameConfig - 显示格式模板(支持变量:{camera_code}, {name}, {stream}) - 字段优先级配置 - WVP API配置 - 查询超时配置 2. 创建服务类 CameraNameService - 查询摄像头信息(get_camera_info) - 提取名称字段(extract_name) - 格式化显示名称(format_display_name) - 一站式方法(get_display_name) 3. 重构路由层 - 移除硬编码逻辑 - 使用camera_name_service统一处理 - 删除旧的_get_camera_info函数 - 简化代码结构 架构优势: - 配置驱动:格式通过环境变量控制 - 单一职责:服务只负责名称处理 - 可扩展:新增格式无需改代码 - 可测试:服务独立易于测试 - 模块化:逻辑集中便于维护 配置示例: ```bash WVP_API_BASE=http://localhost:18080 CAMERA_NAME_FORMAT={camera_code} {name}/{stream} CAMERA_QUERY_TIMEOUT=5 ``` 修改文件: + app/config.py - 添加CameraNameConfig配置 + app/services/camera_name_service.py - 新建服务 + docs/camera_name_config.md - 配置文档 ~ app/routers/yudao_aiot_alarm.py - 使用新服务 测试结果: - 告警列表: cam_1f0e3dad9990 → cam_1f0e3dad9990 大堂吧台3/012 ✓ - 设备汇总: cam_c51ce410c124 → cam_c51ce410c124 大堂吧台1/008 ✓
2026-02-24 13:59:13 +08:00
# 全局单例(依赖注入)
_camera_name_service: Optional[CameraNameService] = None
def get_camera_name_service() -> CameraNameService:
"""
获取摄像头名称服务单例
Returns:
CameraNameService 实例
"""
global _camera_name_service
if _camera_name_service is None:
from app.config import settings
_camera_name_service = CameraNameService(settings.camera_name)
return _camera_name_service