fix: 注释工单对接代码,修复API响应解析和类型问题
- 工单创建/自动结单代码全部注释,待本地测试后启用 - 修复create_order响应解析:data直接是orderId,非嵌套对象 - 修复areaId类型:int(文档要求),非str - 修复auto-complete orderId类型:int - 两步卡片状态机和先到先得逻辑保留生效 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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 告警平台启动完成")
|
||||
|
||||
|
||||
@@ -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",
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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=(",", ":"))
|
||||
|
||||
Reference in New Issue
Block a user