feat: 两步卡片状态机 + 安保工单对接 + 先到先得结单
- 新增 work_order_client.py:SHA256签名的工单API客户端(创建/自动结单) - 企微卡片改为两步交互:确认接单→[已处理完成/标记误报]→终态 - 告警通知后自动创建工单,orderId存入alarm_event_ext - 边缘端resolve支持先到先得:终态不可被覆盖 - 边缘端resolve后异步触发工单自动结单+卡片终态更新 - 新增WorkOrderConfig配置项 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -17,12 +17,13 @@ from typing import Dict, List
|
||||
|
||||
from app.models import (
|
||||
get_session,
|
||||
AlarmEvent, AlarmLlmAnalysis,
|
||||
AlarmEvent, AlarmLlmAnalysis, AlarmEventExt,
|
||||
CameraAreaBinding, AreaPersonBinding, NotifyArea,
|
||||
)
|
||||
from app.config import settings
|
||||
from app.services.vlm_service import get_vlm_service
|
||||
from app.services.wechat_service import get_wechat_service
|
||||
from app.services.wechat_service import get_wechat_service, ALARM_TYPE_NAMES, ALARM_LEVEL_NAMES
|
||||
from app.services.work_order_client import get_work_order_client
|
||||
from app.utils.logger import logger
|
||||
from app.utils.timezone import beijing_now
|
||||
|
||||
@@ -142,6 +143,21 @@ async def process_alarm_notification(alarm_data: Dict):
|
||||
else:
|
||||
logger.warning(f"个人卡片发送失败: {alarm_id}")
|
||||
|
||||
# ---- 4. 创建安保工单 ----
|
||||
wo_client = get_work_order_client()
|
||||
if wo_client.enabled:
|
||||
type_name = ALARM_TYPE_NAMES.get(alarm_type, alarm_type)
|
||||
level_name = ALARM_LEVEL_NAMES.get(alarm_level, "一般")
|
||||
wo_title = f"【{level_name}】{type_name}告警 - {area_name}"
|
||||
order_id = await wo_client.create_order(
|
||||
title=wo_title,
|
||||
area_id=area_name,
|
||||
alarm_id=alarm_id,
|
||||
alarm_type=alarm_type,
|
||||
)
|
||||
if order_id:
|
||||
_save_order_id(alarm_id, order_id)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"告警通知处理失败: {alarm_id}, error={e}", exc_info=True)
|
||||
|
||||
@@ -255,3 +271,22 @@ def _get_notify_persons(camera_id: str, alarm_level: int) -> tuple:
|
||||
return ("未知区域", [])
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def _save_order_id(alarm_id: str, order_id: str):
|
||||
"""将工单ID保存到 alarm_event_ext(ext_type=WORK_ORDER)"""
|
||||
db = get_session()
|
||||
try:
|
||||
ext = AlarmEventExt(
|
||||
alarm_id=alarm_id,
|
||||
ext_type="WORK_ORDER",
|
||||
ext_data={"order_id": order_id},
|
||||
)
|
||||
db.add(ext)
|
||||
db.commit()
|
||||
logger.info(f"工单ID已关联: alarm={alarm_id}, order={order_id}")
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
logger.error(f"保存工单ID失败: {e}")
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
Reference in New Issue
Block a user