Files
iot-device-management-service/app/routers/wechat_callback.py
16337 35386b8e6e feat: V1 VLM复核 + 企微通知 + 手动结单
- 新增3张通知路由表模型(notify_area, camera_area_binding, area_person_binding)
- 新增VLM复核服务,通过qwen3-vl-flash对告警截图二次确认
- 新增企微通知服务,告警确认后推送文本卡片给责任人
- 新增通知调度服务,编排VLM复核→查表路由→企微推送流水线
- 新增企微回调接口,支持手动结单/确认处理/标记误报
- 新增通知管理API,区域/摄像头绑定/人员绑定CRUD
- 告警上报主流程(edge_compat + yudao_aiot_alarm)接入异步通知
- 扩展配置项支持VLM和企微环境变量
- 添加openai==1.68.0依赖(通过DashScope兼容端点调用)
2026-03-06 13:35:40 +08:00

79 lines
2.3 KiB
Python

"""
企微回调路由
处理安保人员在企微卡片上的操作(确认处理/已处理完成/误报忽略)。
"""
from datetime import datetime
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from typing import Optional
from app.yudao_compat import YudaoResponse
from app.services.alarm_event_service import get_alarm_event_service, AlarmEventService
from app.utils.logger import logger
router = APIRouter(prefix="/api/wechat", tags=["企微回调"])
class AlarmActionRequest(BaseModel):
"""企微卡片操作请求"""
alarm_id: str
action: str # confirm / complete / ignore
operator_uid: str # 企微 userid
remark: Optional[str] = None
@router.post("/callback/alarm_action")
async def alarm_action_callback(
req: AlarmActionRequest,
service: AlarmEventService = Depends(get_alarm_event_service),
):
"""
企微告警操作回调(无认证,由企微服务端调用)
action:
- confirm: 确认处理 → handle_status=HANDLING
- complete: 已处理完成 → handle_status=DONE, alarm_status=CLOSED
- ignore: 误报忽略 → alarm_status=FALSE, handle_status=DONE
"""
action_map = {
"confirm": {
"alarm_status": "CONFIRMED",
"handle_status": "HANDLING",
"remark": "企微确认处理",
},
"complete": {
"alarm_status": "CLOSED",
"handle_status": "DONE",
"remark": "企微手动结单",
},
"ignore": {
"alarm_status": "FALSE",
"handle_status": "DONE",
"remark": "企微标记误报",
},
}
action_cfg = action_map.get(req.action)
if not action_cfg:
return YudaoResponse.error(400, f"无效操作: {req.action}")
result = service.handle_alarm(
alarm_id=req.alarm_id,
alarm_status=action_cfg["alarm_status"],
handle_status=action_cfg["handle_status"],
handler=req.operator_uid,
remark=req.remark or action_cfg["remark"],
)
if not result:
return YudaoResponse.error(404, "告警不存在")
logger.info(
f"企微操作: alarm={req.alarm_id}, action={req.action}, "
f"operator={req.operator_uid}"
)
return YudaoResponse.success(True)