From 20c27ae2938195fd038994782cdcb5b176a3c634 Mon Sep 17 00:00:00 2001 From: jillion <439912596@qq.com> Date: Sun, 20 Sep 2026 19:50:42 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=9C=89=E4=BB=B7=E5=85=88=E5=8F=91?= =?UTF-8?q?=E5=87=BA=E4=BB=B7=E6=A0=BC=E6=98=8E=E7=BB=86=E6=96=87=E5=AD=97?= =?UTF-8?q?=E5=86=8D=E5=8F=91=E5=8D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 避免卡片写详见上一条时销售却先看到卡。 Co-authored-by: Cursor --- inquiry-agent/agent/policy/sea_text_flow.py | 15 ++++++++-- inquiry-agent/tests/test_sea_text_inquiry.py | 31 ++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/inquiry-agent/agent/policy/sea_text_flow.py b/inquiry-agent/agent/policy/sea_text_flow.py index 282d898..a4e52bb 100644 --- a/inquiry-agent/agent/policy/sea_text_flow.py +++ b/inquiry-agent/agent/policy/sea_text_flow.py @@ -11,6 +11,7 @@ from __future__ import annotations import logging import threading +import time from typing import Any, Optional from agent.ledger.http_ledger import HttpLedger @@ -41,6 +42,8 @@ class SeaTextInquiryFlow(AirTextInquiryFlow): """ bookmark_kind = "sea" + # 价格明细文字发出后稍等再发卡,避免企微先画出卡片。 + _detail_before_card_gap_sec = 0.8 def __init__(self, ledger: Any = None, group_client: Any = None) -> None: super().__init__(ledger=ledger) @@ -376,16 +379,18 @@ class SeaTextInquiryFlow(AirTextInquiryFlow): business_line: str = "", ) -> None: """ - 先发完整价格明细文本,再发带按钮的卡。 + 先发完整价格明细文本,等它真正发出,再发带按钮的卡。 企微只发卡时,引用条超长会被截断;文本不受限。 + 测服 WO202609200020:文字和卡同一拍入队,销售先看到卡, + 「详见上一条明细」对不上。只等这一条出站,不锁其它工单。 """ line = (business_line or getattr(self, "business_line", "") or "SEA").upper() if line not in {"SEA", "LAND"}: line = "SEA" src = dict(quote or {}) src["business_line"] = line - reply( + out_id = reply( copy.sea_quote_detail_text( work_order_no=work_order_no, quote=src, @@ -394,7 +399,13 @@ class SeaTextInquiryFlow(AirTextInquiryFlow): status=status, business_line=line, ) + ) or "" + self._wait_outbound_sent( + str(out_id), work_order_no=work_order_no, what="价格明细文本" ) + gap = float(getattr(self, "_detail_before_card_gap_sec", 0.8) or 0) + if out_id and gap > 0: + time.sleep(gap) reply( copy.sea_tms_hit_card( work_order_no=work_order_no, diff --git a/inquiry-agent/tests/test_sea_text_inquiry.py b/inquiry-agent/tests/test_sea_text_inquiry.py index b4bd465..72e9d42 100644 --- a/inquiry-agent/tests/test_sea_text_inquiry.py +++ b/inquiry-agent/tests/test_sea_text_inquiry.py @@ -535,6 +535,37 @@ class SeaTmsCardTests(unittest.TestCase): self.assertIn("时效:1天", sub) self.assertIn("报价有效期:2026-09-30", sub) + def test_sea_hit_sends_detail_text_before_card(self) -> None: + """ + 有价必须先发出价格明细文字,再发卡。 + + 测服 WO202609200020:卡上写「详见上一条明细」,销售却先看到卡。 + """ + steps: list[str] = [] + + def reply(text: str, extra=None) -> str: + kind = "card" if extra else "text" + steps.append(kind) + return f"out-{len(steps)}" + + def wait(out_id: str, *, work_order_no: str, what: str) -> None: + steps.append(f"wait:{out_id}") + + self.flow._wait_outbound_sent = wait # type: ignore[method-assign] + self.flow._detail_before_card_gap_sec = 0.0 + self.flow._emit_sea_hit( + reply, + work_order_no="WO202609200020", + quote={ + "total": "14298.53", + "currency": "CNY", + "source_label": "TMS标准报价", + "fee_lines": [{"name": "操作费", "amount": "1220", "currency": "CNY"}], + }, + ) + self.assertEqual(steps[:3], ["text", "wait:out-1", "card"]) + self.assertIn("card", steps) + def test_sea_hit_card_has_price_and_two_buttons(self) -> None: phase = self.flow.on_text( sender_id="s1",