员工岗位可重新启用;调价认空运航线;会话存档跳号补拉;陆运报价按车型列回填

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
linmianxun
2026-10-28 19:48:47 +08:00
co-authored by Cursor
parent 2b528758b4
commit 56ba8e93b5
62 changed files with 2960 additions and 793 deletions
+60 -41
View File
@@ -323,8 +323,10 @@ LAND_TMS_RETRYING = "正在重新查询TMS报价。工单:{wo}"
_LAND_LCL_KEYS = ("起运港", "目的港", "品名", "体积", "毛重", "报价日期")
_LAND_FTL_KEYS = ("起运港", "目的港", "品名", "车型/数量", "报价日期")
_LAND_HK_FULL_KEYS = ("起运港", "目的港", "品名", "报价日期")
_LAND_FTL_TYPES = frozenset({"国内运输整车", "跨境整车", "中港零担/集拼"})
# 中港零担/集拼:核对卡/方案卡不展示车型/数量(中港整车要采车型/数量)
_LAND_HK_LCL_KEYS = ("起运港", "目的港", "品名", "报价日期")
_LAND_FTL_TYPES = frozenset({"国内运输整车", "跨境整车", "中港整车"})
_LAND_HK_NO_VEHICLE_TYPES = frozenset({"中港零担/集拼"})
_LAND_CUSTOMS_TYPES = frozenset({"跨境集拼", "跨境整车", "中港整车", "中港零担/集拼"})
_LAND_EXAMPLES = {
"起运港": "广州",
@@ -341,10 +343,10 @@ _LAND_EXAMPLES = {
def _land_cargo_keys(land_type: str, facts: dict[str, str] | None = None) -> tuple[str, ...]:
"""当前运输类型要展示的货物内部键。中港整车不要车型/数量。"""
"""当前运输类型要展示的货物内部键。仅中港零担/集拼不要车型/数量。"""
_ = facts
if land_type == "中港整车":
return _LAND_HK_FULL_KEYS
if land_type in _LAND_HK_NO_VEHICLE_TYPES:
return _LAND_HK_LCL_KEYS
if land_type in _LAND_FTL_TYPES:
return _LAND_FTL_KEYS
return _LAND_LCL_KEYS
@@ -629,7 +631,8 @@ def ask_clarify(
空运报价日期:说了就写成「报价日期:日期」,没说写成「报价日期(非必填):」,不进待补充。
海运报价日期写进已识别(销售说了用原话,没说用当天),不出现在待补充。
空运非必填一并列出,没填进待补充,不挡查价。
空运:仅当仍有必填缺口时,才把空着的非必填一并放进待补充;
必填已齐则返回空串,由核对卡引导回复「确定」,禁止只甩一堆非必填逼回复。
"""
src = dict(facts or {})
skip = {"报价日期"}
@@ -660,45 +663,59 @@ def ask_clarify(
val = known(src, key)
if val:
lines.append(f"{label}:{val}")
lines.append("")
lines.append(CLARIFY_PASTE_HINT)
any_missing = False
seq = 0
# 先判断有没有必填缺口。仅非必填空着时不发「请复制粘贴」,交给核对卡让销售直接回复确定。
required_items: list[tuple[str, str, str, str]] = []
if "运输方式" in missing_set:
any_missing = True
seq += 1
lines.append(_pending_field_block(seq, "运输方式", "空运"))
if not sea and not known(src, "起运港"):
any_missing = True
seq += 1
lines.append(_pending_field_block(seq, "起运地", _AIR_EXAMPLES["起运港"], optional=True))
required_items.append(("运输方式", "运输方式", "空运", ""))
for key, label, example in rows:
if key in missing_set:
any_missing = True
seq += 1
if sea and key == "运输分类":
lines.append(_pending_field_block(seq, "运输分类", "Port to Port、其他"))
required_items.append((key, "运输分类", "Port to Port、其他", ""))
else:
lines.append(
_pending_field_block(
seq,
label,
example,
unit=_PENDING_UNITS.get(key, ""),
)
required_items.append(
(key, label, example, _PENDING_UNITS.get(key, ""))
)
if not sea:
optional_pending = [
optional_pending: list[tuple[str, str, str]] = []
if not sea and required_items:
# 已有必填要补时,空运非必填一并列出;起运地排在目的地前面。
if not known(src, "起运港"):
optional_pending.append(
("起运港", "起运地", _AIR_EXAMPLES["起运港"])
)
optional_pending.extend(
(key, label, example)
for key, label, example in _AIR_OPTIONAL_CLARIFY
if key != "起运港" and not known(src, key)
]
for key, label, example in optional_pending:
any_missing = True
seq += 1
lines.append(_pending_field_block(seq, label, example, optional=True))
if not any_missing:
)
if not required_items:
return ""
lines.append("")
lines.append(CLARIFY_PASTE_HINT)
seq = 0
origin_block = ""
other_optional_blocks: list[str] = []
for key, label, example in optional_pending:
if key == "起运港":
seq += 1
origin_block = _pending_field_block(
seq, label, example, optional=True
)
# 起运地(非必填)紧挨目的地上面:有则先写起运地,再写必填缺口。
if origin_block:
lines.append(origin_block)
for _key, label, example, unit in required_items:
seq += 1
lines.append(
_pending_field_block(seq, label, example, unit=unit)
)
for key, label, example in optional_pending:
if key == "起运港":
continue
seq += 1
other_optional_blocks.append(
_pending_field_block(seq, label, example, optional=True)
)
lines.extend(other_optional_blocks)
return "\n".join(lines)
@@ -3179,19 +3196,21 @@ def air_no_tms_quote_to_lock(work_order_no: str) -> str:
def air_lock_need_params(missing=None) -> str:
"""
舱位编号、航司、航班号没齐时,只请航线补全。
舱位编号、航司、航班号(及报价日期空时)没齐时,只请航线补全。
这时还没锁舱,不能说 TMS 锁舱失败,也不能通知 IT。
缺哪项就点哪项;三项都缺时是产品指定的那一句。
缺哪项就点哪项;报价日期也空时示例末尾带日期。
"""
labels = [str(x).strip() for x in (missing or []) if str(x).strip()]
if not labels:
labels = ["舱位编号", "航司", "航班号"]
joined = "、".join(labels)
return (
f"锁舱参数不完整,缺少:{joined}。"
"请补充后再锁,例如:AIR-OPT01,南航,航班CZ327。"
)
# 报价日期空:产品指定示例带日期,避免航线补完舱位三项后再被单独拦一次。
if "报价日期" in labels:
example = "AIR-OPT01,南航,航班CZ327,2026-10-18"
else:
example = "AIR-OPT01,南航,航班CZ327"
return f"锁舱参数不完整,缺少:{joined}。请补充后再锁,例如:{example}。"
def air_lock_need_quote(work_order_no: str) -> str: