落地私聊空运询价与TMS报价回填,按后台模板出单。

查到价后把币种、单位、数量、单价、备注写入报价单,避免销售只看到光秃秃的金额。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-14 20:25:35 +08:00
co-authored by Cursor
parent cea3a6e51e
commit 99da1faf30
78 changed files with 8838 additions and 321 deletions
+50 -11
View File
@@ -1,7 +1,8 @@
"""
意图:模板卡 / 补问卡动作(骨架)。
意图:询价卡片按钮(跳过协同 / 采用 / 不采用 / 成交)。
正式:校验 clarification token 绑定的 waitVersion + 允许动作集合。
本文件职责:校验当前会话允许的动作后交给流程执行。
禁止:不校验 wait/允许集合就改主账;禁止一个函数处理未声明的新按钮。
"""
from __future__ import annotations
@@ -9,6 +10,10 @@ from __future__ import annotations
import logging
from typing import Any
from agent.channel.queue import get_message_store
from agent.policy import inquiry_copy as copy
from agent.policy.air_text_flow import get_air_text_flow
logger = logging.getLogger(__name__)
@@ -19,14 +24,48 @@ def handle_card_action(
wait_version: int,
action: str,
payload: dict[str, Any] | None = None,
) -> None:
"""骨架:仅记日志;无 sender_id 直接返回。"""
flow=None,
store=None,
) -> str:
"""
处理一次卡片动作。
wait_version:会话书签版本;错版本丢弃,不重放副作用。
payload 须带 task_id / event_key,才能找回点卡当时的工单。
"""
_ = thread_id
if not (sender_id or "").strip():
return
logger.info(
"handler.card_action stub sender=%s thread=%s wait=%s action=%s",
sender_id,
thread_id,
wait_version,
action,
return "reject_no_sender"
engine = flow or get_air_text_flow()
sess = engine.session_for_action(sender_id, payload)
if sess and wait_version and sess.wait_version != wait_version:
logger.info("card waitVersion 不匹配 expect=%s got=%s", sess.wait_version, wait_version)
return "card_discard"
msg_store = store or get_message_store()
def reply(text: str, extra: dict | None = None) -> None:
# 销售询价正文不加 [test];[test] 只给运维告警
body = text
extra = dict(extra or {})
wo = ""
if sess is not None:
wo = (sess.work_order_no or "").strip()
if not wo:
wo = copy.work_order_from_card_meta(payload)
code = str((payload or {}).get("response_code") or extra.get("response_code") or "")[:24]
ok, info = msg_store.enqueue_outbound(
touser=sender_id,
content=body,
dedupe_key=(
f"card:{sender_id}:{wo}:{code}:"
f"{sess.wait_version if sess else 0}:{action}:{body[:20]}"
),
payload=extra,
)
if not ok:
logger.warning("card 出站被去重 sender=%s wo=%s info=%s", sender_id, wo or "-", info)
return engine.on_button(
sender_id=sender_id, action=action, reply=reply, card_meta=payload
)