diff --git a/app/main.py b/app/main.py index b6844a2..ef5e3bf 100644 --- a/app/main.py +++ b/app/main.py @@ -65,10 +65,10 @@ async def lifespan(app: FastAPI): agent = get_agent_dispatcher() agent.init(settings.agent) - # 初始化工单客户端 - from app.services.work_order_client import get_work_order_client - wo_client = get_work_order_client() - wo_client.init(settings.work_order) + # 初始化工单客户端(暂未上线,待本地测试通过后启用) + # from app.services.work_order_client import get_work_order_client + # wo_client = get_work_order_client() + # wo_client.init(settings.work_order) logger.info("AI 告警平台启动完成") diff --git a/app/routers/edge_compat.py b/app/routers/edge_compat.py index 97574f9..9743684 100644 --- a/app/routers/edge_compat.py +++ b/app/routers/edge_compat.py @@ -89,50 +89,49 @@ async def edge_alarm_resolve( if not success: return YudaoResponse.error(404, "告警不存在") - # 如果之前不是终态(边缘端先到),触发自动结单 + 卡片更新 + # 如果之前不是终态(边缘端先到),触发卡片更新 if not was_terminal: - asyncio.create_task(_resolve_work_order_and_card(resolve.alarm_id, resolve.resolve_type)) + asyncio.create_task(_resolve_card_update(resolve.alarm_id, resolve.resolve_type)) return YudaoResponse.success(True) -async def _resolve_work_order_and_card(alarm_id: str, resolve_type: str): - """边缘端 resolve 后异步处理:更新卡片 + 自动结单""" +async def _resolve_card_update(alarm_id: str, resolve_type: str): + """边缘端 resolve 后异步处理:更新卡片(工单暂未上线)""" try: - from app.services.work_order_client import get_work_order_client from app.services.wechat_service import get_wechat_service - from app.models import get_session, AlarmEventExt - # 1. 自动结单 - wo_client = get_work_order_client() - if wo_client.enabled: - db = get_session() - try: - ext = db.query(AlarmEventExt).filter( - AlarmEventExt.alarm_id == alarm_id, - AlarmEventExt.ext_type == "WORK_ORDER", - ).first() - order_id = ext.ext_data.get("order_id", "") if ext and ext.ext_data else "" - finally: - db.close() + # 工单自动结单(暂未上线) + # from app.services.work_order_client import get_work_order_client + # from app.models import get_session, AlarmEventExt + # wo_client = get_work_order_client() + # if wo_client.enabled: + # db = get_session() + # try: + # ext = db.query(AlarmEventExt).filter( + # AlarmEventExt.alarm_id == alarm_id, + # AlarmEventExt.ext_type == "WORK_ORDER", + # ).first() + # order_id = ext.ext_data.get("order_id", "") if ext and ext.ext_data else "" + # finally: + # db.close() + # if order_id: + # remark_map = { + # "person_returned": "人员回岗自动关闭", + # "non_work_time": "非工作时间自动关闭", + # "intrusion_cleared": "入侵消失自动关闭", + # } + # remark = remark_map.get(resolve_type, f"边缘端自动结单: {resolve_type}") + # await wo_client.auto_complete_order(order_id, remark) - if order_id: - remark_map = { - "person_returned": "人员回岗自动关闭", - "non_work_time": "非工作时间自动关闭", - "intrusion_cleared": "入侵消失自动关闭", - } - remark = remark_map.get(resolve_type, f"边缘端自动结单: {resolve_type}") - await wo_client.auto_complete_order(order_id, remark) - - # 2. 更新企微卡片到终态(如果有 response_code) + # 更新企微卡片到终态(如果有 response_code) wechat = get_wechat_service() if wechat.enabled: response_code = wechat.get_response_code(alarm_id) if response_code: await wechat.update_alarm_card_terminal( response_code=response_code, - user_ids=[], # 空列表时企微更新所有已收到卡片的用户 + user_ids=[], alarm_id=alarm_id, action="auto_resolve", ) diff --git a/app/routers/wechat_callback.py b/app/routers/wechat_callback.py index b5c482b..55cf8a6 100644 --- a/app/routers/wechat_callback.py +++ b/app/routers/wechat_callback.py @@ -105,7 +105,7 @@ async def _process_card_button_click(msg: dict): """ try: from app.services.wechat_service import get_wechat_service - from app.services.work_order_client import get_work_order_client + # from app.services.work_order_client import get_work_order_client # 工单暂未上线 user_id = msg.get("FromUserName", "") event_key = msg.get("EventKey", "") @@ -136,7 +136,7 @@ async def _process_card_button_click(msg: dict): return wechat = get_wechat_service() - wo_client = get_work_order_client() + # wo_client = get_work_order_client() # 工单暂未上线 service = get_alarm_event_service() # ---- 第一步:确认接单 ---- @@ -181,10 +181,10 @@ async def _process_card_button_click(msg: dict): operator_name=user_id, ) - # 自动结单 - order_id = _get_order_id_for_alarm(alarm_id) - if order_id: - await wo_client.auto_complete_order(order_id, f"误报忽略 by {user_id}") + # 自动结单(工单暂未上线) + # order_id = _get_order_id_for_alarm(alarm_id) + # if order_id: + # await wo_client.auto_complete_order(order_id, f"误报忽略 by {user_id}") # ---- 第二步:已处理完成 ---- elif action == "complete": @@ -207,10 +207,10 @@ async def _process_card_button_click(msg: dict): operator_name=user_id, ) - # 自动结单 - order_id = _get_order_id_for_alarm(alarm_id) - if order_id: - await wo_client.auto_complete_order(order_id, f"已处理 by {user_id}") + # 自动结单(工单暂未上线) + # order_id = _get_order_id_for_alarm(alarm_id) + # if order_id: + # await wo_client.auto_complete_order(order_id, f"已处理 by {user_id}") # ---- 第二步:标记误报 ---- elif action == "false": @@ -233,10 +233,10 @@ async def _process_card_button_click(msg: dict): operator_name=user_id, ) - # 自动结单 - order_id = _get_order_id_for_alarm(alarm_id) - if order_id: - await wo_client.auto_complete_order(order_id, f"标记误报 by {user_id}") + # 自动结单(工单暂未上线) + # order_id = _get_order_id_for_alarm(alarm_id) + # if order_id: + # await wo_client.auto_complete_order(order_id, f"标记误报 by {user_id}") except Exception as e: logger.error(f"处理卡片按钮点击失败: {e}", exc_info=True) diff --git a/app/services/notify_dispatch.py b/app/services/notify_dispatch.py index eb03823..3e9cbb0 100644 --- a/app/services/notify_dispatch.py +++ b/app/services/notify_dispatch.py @@ -52,7 +52,7 @@ async def process_alarm_notification(alarm_data: Dict): scene_id = alarm_data.get("scene_id", "") # 查找区域名称用于 VLM prompt(比 UUID 更有意义) - area_name_for_vlm, _ = _get_notify_persons(device_id, alarm_level) + area_name_for_vlm, _, _ = _get_notify_persons(device_id, alarm_level) roi_name = area_name_for_vlm if area_name_for_vlm != "未知区域" else scene_id # snapshot_url 可能是 COS object key,需转为可访问的预签名URL @@ -82,7 +82,7 @@ async def process_alarm_notification(alarm_data: Dict): # ========== 2. 查表获取通知人员 ========== description = vlm_result.get("description", "") area_name = area_name_for_vlm - _, persons = _get_notify_persons(device_id, alarm_level) + _, area_id_int, persons = _get_notify_persons(device_id, alarm_level) # 演示模式:数据库无人员时,使用配置的测试 userid if not persons and settings.wechat.test_uids: @@ -143,20 +143,20 @@ 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) + # ---- 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_id_int, + # 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) @@ -231,7 +231,7 @@ def _get_notify_persons(camera_id: str, alarm_level: int) -> tuple: 根据摄像头ID查找通知人员 Returns: - (area_name, [{"person_name": ..., "wechat_uid": ..., "role": ...}]) + (area_name, area_id, [{"person_name": ..., "wechat_uid": ..., "role": ...}]) """ db = get_session() try: @@ -240,7 +240,7 @@ def _get_notify_persons(camera_id: str, alarm_level: int) -> tuple: ).first() if not binding: - return ("未知区域", []) + return ("未知区域", 0, []) area = db.query(NotifyArea).filter( NotifyArea.area_id == binding.area_id, @@ -248,6 +248,7 @@ def _get_notify_persons(camera_id: str, alarm_level: int) -> tuple: ).first() area_name = area.area_name if area else "未知区域" + area_id = binding.area_id or 0 persons = db.query(AreaPersonBinding).filter( AreaPersonBinding.area_id == binding.area_id, @@ -264,11 +265,11 @@ def _get_notify_persons(camera_id: str, alarm_level: int) -> tuple: for p in persons ] - return (area_name, result) + return (area_name, area_id, result) except Exception as e: logger.error(f"查询通知人员失败: {e}") - return ("未知区域", []) + return ("未知区域", 0, []) finally: db.close() diff --git a/app/services/work_order_client.py b/app/services/work_order_client.py index ab11534..7ef177d 100644 --- a/app/services/work_order_client.py +++ b/app/services/work_order_client.py @@ -77,7 +77,7 @@ class WorkOrderClient: async def create_order( self, title: str, - area_id: str, + area_id: int, alarm_id: str, alarm_type: str, ) -> Optional[str]: @@ -111,7 +111,8 @@ class WorkOrderClient: logger.error(f"创建工单失败: {data}") return None - order_id = data.get("data", {}).get("orderId", "") + # API 返回 {"code":0, "data": 1234567890} — data 直接是 orderId + order_id = str(data.get("data", "")) logger.info(f"工单已创建: orderId={order_id}, alarmId={alarm_id}") return order_id @@ -134,7 +135,7 @@ class WorkOrderClient: return False body = { - "orderId": order_id, + "orderId": int(order_id) if order_id else 0, "remark": remark, } body_json = json.dumps(body, ensure_ascii=False, separators=(",", ":"))