""" 工单工具:查询我的工单、提交处理结果 """ 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)