150 lines
4.7 KiB
Python
150 lines
4.7 KiB
Python
|
|
"""
|
|||
|
|
工单工具:查询我的工单、提交处理结果
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import json
|
|||
|
|
from typing import List, Optional
|
|||
|
|
from langchain_core.tools import tool
|
|||
|
|
from langchain_core.runnables import RunnableConfig
|
|||
|
|
|
|||
|
|
from app.utils.logger import logger
|
|||
|
|
from .alarm_query import ALARM_TYPE_NAMES, _get_camera_display_name
|
|||
|
|
from .alarm_action import _get_order_id_for_alarm
|
|||
|
|
|
|||
|
|
|
|||
|
|
@tool
|
|||
|
|
def list_my_orders(config: RunnableConfig, status: str = "HANDLING") -> str:
|
|||
|
|
"""查询我的待处理工单列表
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
status: 工单状态筛选 HANDLING=处理中 ALL=全部
|
|||
|
|
"""
|
|||
|
|
from app.services.alarm_event_service import get_alarm_event_service
|
|||
|
|
svc = get_alarm_event_service()
|
|||
|
|
|
|||
|
|
user_id = config.get("configurable", {}).get("user_id", "")
|
|||
|
|
|
|||
|
|
alarms, total = svc.get_alarms(
|
|||
|
|
alarm_status="CONFIRMED",
|
|||
|
|
page=1,
|
|||
|
|
page_size=20,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
my_alarms = [a for a in alarms if a.handler == user_id]
|
|||
|
|
|
|||
|
|
if not my_alarms:
|
|||
|
|
return json.dumps({"total": 0, "items": [], "message": "当前没有待处理的工单"}, ensure_ascii=False)
|
|||
|
|
|
|||
|
|
items = []
|
|||
|
|
for a in my_alarms:
|
|||
|
|
cam_name = _get_camera_display_name(a.device_id)
|
|||
|
|
event_time = ""
|
|||
|
|
if a.event_time:
|
|||
|
|
try:
|
|||
|
|
event_time = a.event_time.strftime("%m-%d %H:%M")
|
|||
|
|
except Exception:
|
|||
|
|
event_time = str(a.event_time)[:16]
|
|||
|
|
items.append({
|
|||
|
|
"alarm_id": a.alarm_id,
|
|||
|
|
"type": ALARM_TYPE_NAMES.get(a.alarm_type, a.alarm_type),
|
|||
|
|
"camera": cam_name,
|
|||
|
|
"time": event_time,
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
return json.dumps({"total": len(my_alarms), "items": items}, ensure_ascii=False)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@tool
|
|||
|
|
async def submit_order_result(
|
|||
|
|
alarm_id: str,
|
|||
|
|
result_text: str,
|
|||
|
|
config: RunnableConfig,
|
|||
|
|
image_urls: Optional[List[str]] = None,
|
|||
|
|
) -> str:
|
|||
|
|
"""提交工单处理结果(文字描述+处理后照片URL)
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
alarm_id: 关联的告警ID
|
|||
|
|
result_text: 处理结果描述
|
|||
|
|
image_urls: 处理后照片URL列表(COS永久URL)
|
|||
|
|
"""
|
|||
|
|
from app.services.alarm_event_service import get_alarm_event_service
|
|||
|
|
from app.services.wechat_service import get_wechat_service
|
|||
|
|
|
|||
|
|
user_id = config.get("configurable", {}).get("user_id", "")
|
|||
|
|
svc = get_alarm_event_service()
|
|||
|
|
wechat = get_wechat_service()
|
|||
|
|
|
|||
|
|
if image_urls is None:
|
|||
|
|
image_urls = []
|
|||
|
|
|
|||
|
|
# 检查告警是否存在
|
|||
|
|
detail = svc.get_alarm(alarm_id)
|
|||
|
|
if not detail:
|
|||
|
|
return json.dumps({"error": f"未找到告警: {alarm_id}"}, ensure_ascii=False)
|
|||
|
|
|
|||
|
|
# 合并 session 中暂存的图片
|
|||
|
|
from app.services.session_manager import get_session_manager
|
|||
|
|
session = get_session_manager().get(user_id)
|
|||
|
|
if session.pending_images:
|
|||
|
|
image_urls = session.pending_images + image_urls
|
|||
|
|
session.pending_images = []
|
|||
|
|
|
|||
|
|
# 获取关联工单ID
|
|||
|
|
order_id = _get_order_id_for_alarm(alarm_id)
|
|||
|
|
|
|||
|
|
from app.services.work_order_client import get_work_order_client
|
|||
|
|
wo_client = get_work_order_client()
|
|||
|
|
|
|||
|
|
remark = f"企微Agent结单: {result_text}"
|
|||
|
|
if image_urls:
|
|||
|
|
remark += f" (附{len(image_urls)}张图片)"
|
|||
|
|
|
|||
|
|
if order_id and wo_client.enabled:
|
|||
|
|
if not await wo_client.submit_order(
|
|||
|
|
order_id,
|
|||
|
|
result=f"{result_text} by {user_id}",
|
|||
|
|
result_img_urls=image_urls or None,
|
|||
|
|
):
|
|||
|
|
remark += "(IoT降级)"
|
|||
|
|
|
|||
|
|
svc.handle_alarm(alarm_id=alarm_id, alarm_status="CLOSED",
|
|||
|
|
handle_status="DONE", handler=user_id, remark=remark)
|
|||
|
|
|
|||
|
|
# 持久化处理结果图片到 alarm_event_ext
|
|||
|
|
if image_urls:
|
|||
|
|
try:
|
|||
|
|
from app.models import get_session as get_db_session, AlarmEventExt
|
|||
|
|
db = get_db_session()
|
|||
|
|
try:
|
|||
|
|
ext = AlarmEventExt(
|
|||
|
|
alarm_id=alarm_id,
|
|||
|
|
ext_type="HANDLER_RESULT",
|
|||
|
|
ext_data={"result_text": result_text, "image_urls": image_urls, "handler": user_id},
|
|||
|
|
)
|
|||
|
|
db.add(ext)
|
|||
|
|
db.commit()
|
|||
|
|
except Exception as e:
|
|||
|
|
db.rollback()
|
|||
|
|
logger.error(f"持久化处理结果图片失败: {e}")
|
|||
|
|
finally:
|
|||
|
|
db.close()
|
|||
|
|
except Exception as e:
|
|||
|
|
logger.error(f"保存处理结果失败: {e}")
|
|||
|
|
|
|||
|
|
# 更新卡片到终态
|
|||
|
|
response_code = wechat.get_response_code(alarm_id)
|
|||
|
|
if response_code:
|
|||
|
|
await wechat.update_alarm_card_terminal(
|
|||
|
|
response_code=response_code, user_ids=[user_id],
|
|||
|
|
alarm_id=alarm_id, action="complete", operator_name=user_id,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
result = {
|
|||
|
|
"success": True,
|
|||
|
|
"message": f"工单已提交: {alarm_id}",
|
|||
|
|
"result": result_text,
|
|||
|
|
"images_count": len(image_urls),
|
|||
|
|
}
|
|||
|
|
return json.dumps(result, ensure_ascii=False)
|