fix: 有价先发出价格明细文字再发卡
避免卡片写详见上一条时销售却先看到卡。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,6 +11,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
from agent.ledger.http_ledger import HttpLedger
|
from agent.ledger.http_ledger import HttpLedger
|
||||||
@@ -41,6 +42,8 @@ class SeaTextInquiryFlow(AirTextInquiryFlow):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
bookmark_kind = "sea"
|
bookmark_kind = "sea"
|
||||||
|
# 价格明细文字发出后稍等再发卡,避免企微先画出卡片。
|
||||||
|
_detail_before_card_gap_sec = 0.8
|
||||||
|
|
||||||
def __init__(self, ledger: Any = None, group_client: Any = None) -> None:
|
def __init__(self, ledger: Any = None, group_client: Any = None) -> None:
|
||||||
super().__init__(ledger=ledger)
|
super().__init__(ledger=ledger)
|
||||||
@@ -376,16 +379,18 @@ class SeaTextInquiryFlow(AirTextInquiryFlow):
|
|||||||
business_line: str = "",
|
business_line: str = "",
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
先发完整价格明细文本,再发带按钮的卡。
|
先发完整价格明细文本,等它真正发出,再发带按钮的卡。
|
||||||
|
|
||||||
企微只发卡时,引用条超长会被截断;文本不受限。
|
企微只发卡时,引用条超长会被截断;文本不受限。
|
||||||
|
测服 WO202609200020:文字和卡同一拍入队,销售先看到卡,
|
||||||
|
「详见上一条明细」对不上。只等这一条出站,不锁其它工单。
|
||||||
"""
|
"""
|
||||||
line = (business_line or getattr(self, "business_line", "") or "SEA").upper()
|
line = (business_line or getattr(self, "business_line", "") or "SEA").upper()
|
||||||
if line not in {"SEA", "LAND"}:
|
if line not in {"SEA", "LAND"}:
|
||||||
line = "SEA"
|
line = "SEA"
|
||||||
src = dict(quote or {})
|
src = dict(quote or {})
|
||||||
src["business_line"] = line
|
src["business_line"] = line
|
||||||
reply(
|
out_id = reply(
|
||||||
copy.sea_quote_detail_text(
|
copy.sea_quote_detail_text(
|
||||||
work_order_no=work_order_no,
|
work_order_no=work_order_no,
|
||||||
quote=src,
|
quote=src,
|
||||||
@@ -394,7 +399,13 @@ class SeaTextInquiryFlow(AirTextInquiryFlow):
|
|||||||
status=status,
|
status=status,
|
||||||
business_line=line,
|
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(
|
reply(
|
||||||
copy.sea_tms_hit_card(
|
copy.sea_tms_hit_card(
|
||||||
work_order_no=work_order_no,
|
work_order_no=work_order_no,
|
||||||
|
|||||||
@@ -535,6 +535,37 @@ class SeaTmsCardTests(unittest.TestCase):
|
|||||||
self.assertIn("时效:1天", sub)
|
self.assertIn("时效:1天", sub)
|
||||||
self.assertIn("报价有效期:2026-09-30", 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:
|
def test_sea_hit_card_has_price_and_two_buttons(self) -> None:
|
||||||
phase = self.flow.on_text(
|
phase = self.flow.on_text(
|
||||||
sender_id="s1",
|
sender_id="s1",
|
||||||
|
|||||||
Reference in New Issue
Block a user