落地空运群内协同与锁舱出站。

群里按 BOT 通道激活当前工单、航线报价和成交跟进;没有 TMS 报价编号时用工单字段补齐仍调锁舱,避免被本地规则拦住。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-16 17:25:42 +08:00
co-authored by Cursor
parent 12219cacb1
commit d9029dec89
62 changed files with 6772 additions and 159 deletions
+101 -4
View File
@@ -248,7 +248,7 @@ class MemoryLedger:
quote=quote,
)
if picked is None:
out = {"ok": False, "error": "NO_TEMPLATE", "message": FAIL_MESSAGE}
out = {"ok": False, "error": "NO_TEMPLATE", "message": FAIL_MESSAGE, "facts": dict(facts or {})}
self.last_render = out
return out
ext = "pdf" if str(format).lower() == "pdf" else "xlsx"
@@ -260,6 +260,7 @@ class MemoryLedger:
"fileName": f"{work_order_no}_quote.{ext}",
"fileBase64": "UEsDBAoAAAAAA",
"needsPdf": False,
"facts": dict(facts or {}),
}
with self._lock:
ticket = self._tickets.get((work_order_no or "").strip())
@@ -359,6 +360,18 @@ class MemoryLedger:
with self._lock:
return dict(self._staff_by_wecom.get((wecom_id or "").strip()) or {})
def list_staff_by_role(self, *, role_code: str) -> list[dict[str, Any]]:
"""按岗位列出启用员工。空运群 @ 航线用。"""
want = (role_code or "").strip().lower()
hits: list[dict[str, Any]] = []
with self._lock:
for row in self._staff_by_wecom.values():
code = str(row.get("roleCode") or row.get("role_code") or "").strip().lower()
status = str(row.get("status") or "active").strip().lower()
if code == want and status not in {"disabled", "0", "停用"}:
hits.append(dict(row))
return hits
def find_staff_by_name(self, *, name: str) -> dict[str, Any]:
"""按员工姓名取企微 userid。"""
with self._lock:
@@ -442,9 +455,15 @@ class MemoryLedger:
ticket = self._tickets.get(work_order_no)
if ticket is None:
return {"ok": False, "error": "ticket_not_found"}
ticket.collab_facts.update(
{k: v for k, v in (facts or {}).items() if str(v or "").strip()}
)
for key, raw in (facts or {}).items():
name = str(key or "").strip()
if not name:
continue
val = str(raw or "").strip()
if val:
ticket.collab_facts[name] = val
else:
ticket.collab_facts.pop(name, None)
return {"ok": True, "facts": dict(ticket.collab_facts)}
def find_by_collab_chat(self, *, chat_id: str) -> MemoryTicket | None:
@@ -457,3 +476,81 @@ class MemoryLedger:
if ticket.collab_chat_id == raw:
return ticket
return None
def activate_air_group(self, *, chat_id: str, work_order_no: str) -> dict[str, Any]:
"""
空运群当前工单:一单一群,未结案才能激活。
不改六态。
"""
no = (work_order_no or "").strip()
room = (chat_id or "").strip()
with self._lock:
ticket = self._tickets.get(no)
if ticket is None:
return {"ok": False, "error": "ticket_not_found"}
if (ticket.business_line or "").upper() != "AIR":
return {"ok": False, "error": "not_air", "status": ticket.status}
if ticket.status in {"已成交", "未成交", "已关闭"}:
return {"ok": False, "error": "terminal", "status": ticket.status}
if ticket.collab_chat_id and ticket.collab_chat_id != room:
return {"ok": False, "error": "occupied", "other_chat_id": ticket.collab_chat_id}
for other in self._tickets.values():
if other.work_order_no != no and other.collab_chat_id == room:
if (other.business_line or "").upper() == "AIR":
other.collab_chat_id = ""
ticket.collab_chat_id = room
return {
"ok": True,
"work_order_no": no,
"chat_id": room,
"status": ticket.status,
"business_line": ticket.business_line,
}
def lock_cabin(
self,
*,
work_order_no: str,
option_no: str,
sender_id: str = "",
operator_name: str = "",
instruction_text: str = "",
) -> dict[str, Any]:
"""单测可注入 _cabin_lock_result;默认成功。"""
_ = sender_id, operator_name, instruction_text
forced = getattr(self, "_cabin_lock_result", None)
if isinstance(forced, dict):
return dict(forced)
no = (work_order_no or "").strip()
ticket = self.get_ticket(work_order_no=no)
quote = dict(ticket.quote or {}) if ticket else {}
return {
"ok": True,
"status": "LOCKED",
"lockId": f"CA-{no}-LOCK",
"quoteId": str(quote.get("quoteId") or f"QT-{no}"),
"optionNo": option_no,
"tmsRequestId": f"TMS-LOCK-{no}",
}
def release_cabin(
self,
*,
work_order_no: str,
lock_id: str,
sender_id: str = "",
operator_name: str = "",
instruction_text: str = "",
) -> dict[str, Any]:
_ = lock_id, sender_id, operator_name, instruction_text
forced = getattr(self, "_cabin_release_result", None)
if isinstance(forced, dict):
return dict(forced)
no = (work_order_no or "").strip()
return {
"ok": True,
"status": "RELEASED",
"releaseId": f"CA-{no}-RLSE",
"tmsRequestId": f"TMS-RLSE-{no}",
}