diff --git a/app/services/notify_dispatch.py b/app/services/notify_dispatch.py index 2366cc6..78a3706 100644 --- a/app/services/notify_dispatch.py +++ b/app/services/notify_dispatch.py @@ -4,17 +4,15 @@ 告警创建后的异步处理流水线: 1. VLM 复核截图 → 写入 alarm_llm_analysis 2. 查表获取通知人员 (camera → area → person) -3. 推送企微通知: - - 群聊:image + news + @text 组合消息 - - 个人:button_interaction 模板卡片 +3. 创建 IoT 工单 → 告警状态改为 CONFIRMED +企微通知由 IoT 工单回调驱动,不在此处发送。 全程异步执行,不阻塞告警接收主流程。 -VLM 或企微不可用时自动降级,不影响系统运行。 +VLM 不可用时自动降级,不影响系统运行。 """ import os -from datetime import datetime -from typing import Dict, List +from typing import Dict from app.models import ( get_session, @@ -23,7 +21,7 @@ from app.models import ( ) from app.config import settings from app.services.vlm_service import get_vlm_service -from app.services.wechat_service import get_wechat_service, ALARM_TYPE_NAMES, ALARM_LEVEL_NAMES +from app.services.wechat_service import ALARM_TYPE_NAMES from app.services.camera_name_service import get_camera_name_service from app.services.work_order_client import get_work_order_client from app.utils.logger import logger @@ -110,46 +108,10 @@ async def process_alarm_notification(alarm_data: Dict): logger.info(f"演示模式: 使用测试用户 {test_uids}") if not persons: - logger.warning(f"未找到通知人员: camera={device_id}, 跳过企微推送") - return + logger.warning(f"未找到通知人员: camera={device_id}, 跳过工单创建") - # ========== 3. 推送企微通知 ========== - wechat_service = get_wechat_service() - if not wechat_service.enabled: - logger.info(f"企微未启用,跳过通知: {alarm_id}") - return - - # 通知显示时间:只显示 MM-DD HH:MM(不含年份和秒) - if isinstance(event_time, datetime): - event_time_str = event_time.strftime("%m-%d %H:%M") - else: - # 字符串格式 "2026-03-19 10:54:24" → "03-19 10:54" - s = str(event_time or "") - event_time_str = s[5:16] if len(s) >= 16 else s - - user_ids = [p["wechat_uid"] for p in persons] - group_chat_id = settings.wechat.group_chat_id - - # ---- 3a. 群聊组合消息 ---- - if group_chat_id: - await wechat_service.send_group_alarm_combo( - chat_id=group_chat_id, - alarm_id=alarm_id, - alarm_type=alarm_type, - area_name=area_name, - camera_name=camera_name, - description=description or f"{area_name} 检测到告警", - event_time=event_time_str, - alarm_level=alarm_level, - snapshot_url=presigned_snapshot_url, - mention_user_ids=user_ids, - ) - else: - logger.debug("未配置群聊ID,跳过群聊推送") - - # ---- 3b. 创建工单(优先于卡片发送) ---- + # ========== 3. 创建工单 ========== wo_client = get_work_order_client() - order_created = False if wo_client.enabled: wo_area_id = _get_alarm_area_id(alarm_id) or area_id_int if wo_area_id: @@ -172,28 +134,11 @@ async def process_alarm_notification(alarm_data: Dict): ) if order_id: _save_order_id(alarm_id, order_id) - order_created = True - logger.info(f"工单已创建,等待IoT回调发卡片: alarm={alarm_id}, order={order_id}") + _set_alarm_confirmed(alarm_id) + logger.info(f"工单已创建,告警已确认: alarm={alarm_id}, order={order_id}") else: logger.warning(f"告警无 area_id,跳过工单创建: {alarm_id}") - # ---- 3c. 个人卡片(仅在工单未创建时降级发送) ---- - if not order_created: - sent = await wechat_service.send_alarm_card( - user_ids=user_ids, - alarm_id=alarm_id, - alarm_type=alarm_type, - area_name=area_name, - camera_name=camera_name, - description=description, - event_time=event_time_str, - alarm_level=alarm_level, - ) - if sent: - logger.info(f"降级直发卡片完成: {alarm_id}") - else: - logger.warning(f"降级直发卡片失败: {alarm_id}") - except Exception as e: logger.error(f"告警通知处理失败: {alarm_id}, error={e}", exc_info=True) @@ -435,3 +380,20 @@ def _save_order_id(alarm_id: str, order_id: str): logger.error(f"保存工单ID失败: {e}") finally: db.close() + + +def _set_alarm_confirmed(alarm_id: str): + """工单创建后,将告警状态改为处理中""" + db = get_session() + try: + alarm = db.query(AlarmEvent).filter(AlarmEvent.alarm_id == alarm_id).first() + if alarm and alarm.alarm_status == "NEW": + alarm.alarm_status = "CONFIRMED" + alarm.handle_status = "HANDLING" + alarm.handle_remark = "已创建工单" + db.commit() + except Exception as e: + db.rollback() + logger.error(f"更新告警状态失败: {e}") + finally: + db.close()