diff --git a/app/services/agent/prompts.py b/app/services/agent/prompts.py index 57620ea..9ccb429 100644 --- a/app/services/agent/prompts.py +++ b/app/services/agent/prompts.py @@ -16,6 +16,12 @@ SYSTEM_PROMPT = """你是VSP物业AI助手,通过企业微信协助物业人 - SECURITY:安保工单(关联告警,含摄像头、告警类型等) - CLEAN:保洁工单(含保洁类型、难度、预计时长等) +## 查询技巧(重要) +- 用户问"有没有待处理/未完成的工单"时,必须用 list_orders(status="PENDING") 或 status="ASSIGNED" 查询,不要只用默认参数 +- 待处理工单可能是之前创建的,设置 status 参数后会自动忽略时间范围限制 +- query_order_stats 返回的 current_pending 和 current_assigned 是当前所有未完成工单数(不限时间) +- 查历史统计用 time_range 参数,查当前未处理用 status 参数 + ## 核心原则(严格遵守) - 所有数据必须来自工具调用结果,绝对不要编造工单ID、数量、人员等任何数据 - 如果工具返回错误或未找到数据,如实告知用户,不要猜测或补充 diff --git a/app/services/agent/tools/order_query.py b/app/services/agent/tools/order_query.py index 09e14d6..ccc518d 100644 --- a/app/services/agent/tools/order_query.py +++ b/app/services/agent/tools/order_query.py @@ -81,20 +81,29 @@ def _query_orders( end_time=None, limit: int = 100, assignee_name: Optional[str] = None, + skip_time_filter: bool = False, ): """查询 IoT 工单(跨库只读)""" from app.models_iot import get_iot_session, IotOpsOrder + from app.config import settings db = get_iot_session() try: q = db.query(IotOpsOrder).filter(IotOpsOrder.deleted == 0) + # 租户隔离 + try: + tid = int(settings.work_order.tenant_id) + q = q.filter(IotOpsOrder.tenant_id == tid) + except Exception: + pass if order_type and order_type != "ALL": q = q.filter(IotOpsOrder.order_type == order_type) if status: q = q.filter(IotOpsOrder.status == status) - if start_time: - q = q.filter(IotOpsOrder.create_time >= start_time) - if end_time: - q = q.filter(IotOpsOrder.create_time < end_time) + if not skip_time_filter: + if start_time: + q = q.filter(IotOpsOrder.create_time >= start_time) + if end_time: + q = q.filter(IotOpsOrder.create_time < end_time) if assignee_name: q = q.filter(IotOpsOrder.assignee_name.contains(assignee_name)) @@ -151,6 +160,16 @@ def query_order_stats(time_range: str = "today", order_type: str = "ALL") -> str start_time=start, end_time=end, limit=10000, ) + # 额外统计当前所有未完成工单(不限时间范围) + pending_orders, pending_total, _, _ = _query_orders( + order_type=order_type if order_type != "ALL" else None, + status="PENDING", limit=10000, skip_time_filter=True, + ) + assigned_orders, assigned_total, _, _ = _query_orders( + order_type=order_type if order_type != "ALL" else None, + status="ASSIGNED", limit=10000, skip_time_filter=True, + ) + # 按状态统计 status_count = {} for o in orders: @@ -180,6 +199,8 @@ def query_order_stats(time_range: str = "today", order_type: str = "ALL") -> str "by_order_type": {k: v for k, v in type_count.items() if v > 0}, "by_alarm_type": {ALARM_TYPE_NAMES.get(t, t): c for t, c in alarm_type_count.items()} if alarm_type_count else {}, "false_alarm_count": false_alarm_count, + "current_pending": pending_total, + "current_assigned": assigned_total, } return json.dumps(result, ensure_ascii=False) @@ -215,10 +236,15 @@ def list_orders( if config and assigned_to_me: user_id = config.get("configurable", {}).get("user_id", "") + # 查待处理工单时不限时间范围(待处理可能是之前创建的) + pending_statuses = {"PENDING", "ASSIGNED", "ARRIVED", "PAUSED"} + skip_time = status and status in pending_statuses + orders, total, sec_ext_map, clean_ext_map = _query_orders( order_type=order_type if order_type != "ALL" else None, status=status or None, start_time=start, end_time=end, limit=limit, + skip_time_filter=skip_time, ) items = []