落地陆运群内协同:按填写样例拉群并只列本单协同项,进群把私聊已抽到的字段带上。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
陆运文字询价确定性流程。
|
||||
|
||||
本文件职责:选项联动 → 按类型补货物 → 无工单号核对卡 →(确定后)建单查 TMS。
|
||||
本文件职责:三项选项各自必填(不联动)→ 按类型补货物 → 无工单号核对卡 →(确定后)建单查 TMS。
|
||||
查价后半段复用海运拉群/报价单/成交,拉人按线路类别,禁止陆运岗全员。
|
||||
禁止:字段齐了就建单;直连 TMS;把海运「出卡即查价」改掉。
|
||||
调用:handler 在 Worker/inbox 线程;禁止回调线程同步跑。
|
||||
@@ -23,6 +23,8 @@ from agent.schema.land_options import (
|
||||
harvest_land_options,
|
||||
looks_like_confirm,
|
||||
option_prompt,
|
||||
option_prompt_needs_sample,
|
||||
sample_pair_allowed,
|
||||
validate_land_options,
|
||||
)
|
||||
from agent.schema.tms_land_query import assemble_land_query
|
||||
@@ -112,7 +114,7 @@ class LandTextInquiryFlow(SeaTextInquiryFlow):
|
||||
subtype = str(snap.get("land_subtype") or facts.get("运输类型") or "").strip()
|
||||
if subtype and not str(facts.get("运输类型") or "").strip():
|
||||
facts["运输类型"] = subtype
|
||||
option_keys = ("运输类型", "线路类别", "运输分类", "中港装载方式")
|
||||
option_keys = ("运输类型", "线路类别", "运输分类")
|
||||
base = dict(sess.facts) if sess else {}
|
||||
cargo = {k: v for k, v in facts.items() if k not in option_keys}
|
||||
merged = dict(base)
|
||||
@@ -184,6 +186,23 @@ class LandTextInquiryFlow(SeaTextInquiryFlow):
|
||||
sess=sess,
|
||||
)
|
||||
|
||||
def _reply_land_options(
|
||||
self,
|
||||
reply: ReplyFn,
|
||||
facts: dict[str, str],
|
||||
*,
|
||||
message: str = "",
|
||||
) -> None:
|
||||
"""
|
||||
选项补问:先发文字清单,需要样例时再发表格图。
|
||||
|
||||
图片失败由出站回退文字样例。不在本方法上传素材。
|
||||
"""
|
||||
body = (message or "").strip() or option_prompt(current=facts)
|
||||
reply(body)
|
||||
if option_prompt_needs_sample(current=facts):
|
||||
reply(copy.land_sample_image_fallback(), copy.land_sample_image_payload())
|
||||
|
||||
def _confirm_or_hold(
|
||||
self,
|
||||
*,
|
||||
@@ -221,7 +240,7 @@ class LandTextInquiryFlow(SeaTextInquiryFlow):
|
||||
"""
|
||||
销售确定之后才建陆运工单并查 TMS。
|
||||
|
||||
核对卡阶段没有工单号。运输分类、中港装载方式写入工单 facts,不进入 assemble 出站。
|
||||
核对卡阶段没有工单号。运输分类写入工单 facts,不进入 assemble 出站。
|
||||
"""
|
||||
import uuid
|
||||
|
||||
@@ -363,10 +382,10 @@ class LandTextInquiryFlow(SeaTextInquiryFlow):
|
||||
facts=merged, business_line="LAND", land_subtype=land_type
|
||||
)
|
||||
cargo = dict(check["facts"])
|
||||
cargo.update({k: merged[k] for k in ("运输类型", "线路类别", "运输分类", "中港装载方式") if merged.get(k)})
|
||||
cargo.update({k: merged[k] for k in ("运输类型", "线路类别", "运输分类") if merged.get(k)})
|
||||
tms = assemble_land_query(cargo)
|
||||
cargo = dict(tms.get("facts") or cargo)
|
||||
cargo.update({k: merged[k] for k in ("运输类型", "线路类别", "运输分类", "中港装载方式") if merged.get(k)})
|
||||
cargo.update({k: merged[k] for k in ("运输类型", "线路类别", "运输分类") if merged.get(k)})
|
||||
missing = list(check.get("missing") or [])
|
||||
for key in tms.get("missing") or []:
|
||||
if key not in missing and key not in {"运输类型", "线路类别"}:
|
||||
@@ -412,7 +431,11 @@ class LandTextInquiryFlow(SeaTextInquiryFlow):
|
||||
return "wait_confirm"
|
||||
if state.get("stage") == "options_error":
|
||||
err = (state["opt"].get("errors") or [{}])[0]
|
||||
reply(str(err.get("message") or option_prompt(current=facts)))
|
||||
self._reply_land_options(
|
||||
reply,
|
||||
facts,
|
||||
message=str(err.get("message") or ""),
|
||||
)
|
||||
self._save(
|
||||
FlowSession(
|
||||
sender_id=sender_id,
|
||||
@@ -427,12 +450,11 @@ class LandTextInquiryFlow(SeaTextInquiryFlow):
|
||||
self._clear_parked_confirm(sender_id)
|
||||
return "need_land_options"
|
||||
if state["stage"] == "options_missing":
|
||||
body = option_prompt(current=facts)
|
||||
logger.info(
|
||||
"land.options_missing missing=%s",
|
||||
(state.get("opt") or {}).get("missing") or [],
|
||||
)
|
||||
reply(body)
|
||||
self._reply_land_options(reply, facts)
|
||||
self._save(
|
||||
FlowSession(
|
||||
sender_id=sender_id,
|
||||
@@ -574,6 +596,32 @@ class LandTextInquiryFlow(SeaTextInquiryFlow):
|
||||
|
||||
clear_pending_land_confirm(sender_id)
|
||||
|
||||
def _pull_collab_group(
|
||||
self,
|
||||
sess: FlowSession,
|
||||
reply: ReplyFn,
|
||||
card_meta: Optional[dict[str, Any]] = None,
|
||||
) -> str:
|
||||
"""
|
||||
点「拉产品进群协同」:先核填写样例,再按线路拉人建群。
|
||||
|
||||
类型+线路对不上样例:不建群,告诉销售重新开单。按钮保持可点。
|
||||
对得上则走海运同一套建群。
|
||||
"""
|
||||
facts = dict(sess.facts or {})
|
||||
land_type = str(facts.get("运输类型") or "").strip()
|
||||
route = str(facts.get("线路类别") or "").strip()
|
||||
if not sample_pair_allowed(land_type, route):
|
||||
logger.info(
|
||||
"land.group.reject pair type=%s route=%s wo=%s",
|
||||
land_type or "-",
|
||||
route or "-",
|
||||
sess.work_order_no or "-",
|
||||
)
|
||||
reply(copy.land_group_pair_rejected())
|
||||
return sess.phase or "wait_collab"
|
||||
return super()._pull_collab_group(sess, reply, card_meta=card_meta)
|
||||
|
||||
def _match_sea_staff(self, sess: FlowSession) -> list[dict[str, Any]]:
|
||||
"""按本单线路类别整词匹配产品·陆运,禁止全员。"""
|
||||
matcher = getattr(self._ledger, "match_land_staff", None)
|
||||
|
||||
Reference in New Issue
Block a user