空运未填报价日期时不默认当天,查出舱位后由销售点选再写回日期。
包装类型里的托盘不再被抄进增值服务。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -13,7 +13,11 @@ from typing import Any
|
||||
|
||||
from agent.channel.h5.wecom_close import wecom_auto_close_script
|
||||
from agent.schema.air_route_options import (
|
||||
option_airline,
|
||||
option_endpoint_name,
|
||||
option_fee_lines,
|
||||
option_flight_date,
|
||||
option_schedule,
|
||||
option_total,
|
||||
parse_air_options,
|
||||
route_codes,
|
||||
@@ -197,7 +201,11 @@ def expired_air_route_page() -> str:
|
||||
def render_air_route_page(payload: dict[str, Any]) -> str:
|
||||
"""
|
||||
渲染选线路页。payload 来自 token:quote / facts / work_order_no。
|
||||
|
||||
cabin_pick 为真:没填报价日期,按舱位六项展示(含总价,不含费用明细)。
|
||||
"""
|
||||
if payload.get("cabin_pick"):
|
||||
return _render_cabin_page(payload)
|
||||
quote = dict(payload.get("quote") or {})
|
||||
facts = dict(payload.get("facts") or {})
|
||||
wo = html.escape(str(payload.get("work_order_no") or ""))
|
||||
@@ -235,6 +243,73 @@ def render_air_route_ok() -> str:
|
||||
)
|
||||
|
||||
|
||||
def _render_cabin_page(payload: dict[str, Any]) -> str:
|
||||
"""没填日期的舱位列表。顺序以 token 里已排好的 airOptions 为准。"""
|
||||
quote = dict(payload.get("quote") or {})
|
||||
facts = dict(payload.get("facts") or {})
|
||||
wo = html.escape(str(payload.get("work_order_no") or ""))
|
||||
options = parse_air_options(quote)
|
||||
rows = [_cabin_card(i, option, quote, facts) for i, option in enumerate(options)]
|
||||
count = len(options)
|
||||
body = (
|
||||
"<div class='wrap'>"
|
||||
"<header class='hero'>"
|
||||
f"<p class='wo'>{wo}</p>"
|
||||
"<h1>选择舱位</h1>"
|
||||
f"<p class='lead'>共 {count} 条舱位,点选一条后确定。价格是 TMS 返回的总价。</p>"
|
||||
"</header>"
|
||||
"<form method='post'>"
|
||||
+ "".join(rows)
|
||||
+ "<div class='bar'><div class='bar-inner'>"
|
||||
"<button type='submit'>选定这条</button>"
|
||||
"</div></div></form></div>"
|
||||
"<script>(function(){var f=document.querySelector('form');if(!f)return;"
|
||||
"function sync(){f.querySelectorAll('.opt').forEach(function(el){"
|
||||
"el.classList.toggle('is-on',!!(el.querySelector('input')||{}).checked);});}"
|
||||
"f.addEventListener('change',sync);})();</script>"
|
||||
)
|
||||
return _wrap("选择舱位", body)
|
||||
|
||||
|
||||
def _cabin_field(label: str, value: str) -> str:
|
||||
"""舱位一项。空值留空,不写横杠,避免把没返回的班期显示成占位符。"""
|
||||
shown = html.escape(value or "")
|
||||
return (
|
||||
"<li><span class='n'>"
|
||||
+ html.escape(label)
|
||||
+ "</span><span class='a'>"
|
||||
+ shown
|
||||
+ "</span></li>"
|
||||
)
|
||||
|
||||
|
||||
def _cabin_card(index: int, option: dict[str, Any], quote: dict[str, Any], facts: dict[str, str]) -> str:
|
||||
"""
|
||||
一张舱位:起运地、目的地、航班日期、班期、航司、总价。
|
||||
|
||||
不展示费用明细。班期用 TMS 原文。
|
||||
"""
|
||||
src = dict(option or {})
|
||||
fields = (
|
||||
("起运地", option_endpoint_name(src, "origin", facts)),
|
||||
("目的地", option_endpoint_name(src, "destination", facts)),
|
||||
("航班日期", option_flight_date(src)),
|
||||
("班期", option_schedule(src)),
|
||||
("航司", option_airline(src)),
|
||||
)
|
||||
field_html = "<ul class='fees'>" + "".join(_cabin_field(n, v) for n, v in fields) + "</ul>"
|
||||
total = html.escape(option_total(src, quote))
|
||||
return (
|
||||
"<label class='opt'>"
|
||||
f"<input type='radio' name='index' value='{index}' required />"
|
||||
"<div class='head'><span class='tick' aria-hidden='true'></span>"
|
||||
"<div class='route'><strong>舱位</strong></div></div>"
|
||||
f"{field_html}"
|
||||
f"<p class='total'><span>总价</span><b>{total}</b></p>"
|
||||
"</label>"
|
||||
)
|
||||
|
||||
|
||||
def _option_card(index: int, option: dict[str, Any], quote: dict[str, Any], facts: dict[str, str]) -> str:
|
||||
"""一张线路卡:航线、TMS 费用、总价。没有费用行就留空说明,不编造。"""
|
||||
src = dict(option or {})
|
||||
|
||||
@@ -33,15 +33,21 @@ def issue_air_route_token(
|
||||
work_order_no: str,
|
||||
quote: dict[str, Any],
|
||||
facts: dict[str, str] | None = None,
|
||||
cabin_pick: bool = False,
|
||||
ttl_seconds: int = AIR_ROUTE_TTL_SECONDS,
|
||||
) -> str:
|
||||
"""签发选线路 token。副作用:写 Redis 或内存。"""
|
||||
"""
|
||||
签发选线路 token。副作用:写 Redis 或内存。
|
||||
|
||||
cabin_pick=True:没填报价日期,页面按舱位六项展示,选定后不再查价。
|
||||
"""
|
||||
payload = json.dumps(
|
||||
{
|
||||
"sender_id": sender_id,
|
||||
"work_order_no": work_order_no,
|
||||
"quote": quote,
|
||||
"facts": dict(facts or {}),
|
||||
"cabin_pick": bool(cabin_pick),
|
||||
},
|
||||
ensure_ascii=False,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user