销售侧汇总统一叫费用合计,并认准空运费的金额。
企微跳转改为账号密码登录,报价卡上的费用按原金额改回;航线按单价数量金额报价时不再记成海运费。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,6 +11,7 @@ from __future__ import annotations
|
||||
import html
|
||||
from typing import Any
|
||||
|
||||
from agent.channel.h5.wecom_close import wecom_auto_close_script
|
||||
from agent.schema.air_route_options import (
|
||||
option_fee_lines,
|
||||
option_total,
|
||||
@@ -226,10 +227,11 @@ def render_air_route_page(payload: dict[str, Any]) -> str:
|
||||
|
||||
|
||||
def render_air_route_ok() -> str:
|
||||
"""选定成功。"""
|
||||
"""选定成功:短暂展示后关企微 H5。"""
|
||||
return _wrap(
|
||||
"已选定",
|
||||
"<div class='msg'><h1>已选定</h1><p>请回企微查看价格明细。</p></div>",
|
||||
"<div class='msg'><h1>已选定</h1><p>正在返回企微,请查看价格明细。</p></div>",
|
||||
auto_close=True,
|
||||
)
|
||||
|
||||
|
||||
@@ -272,12 +274,13 @@ def _option_card(index: int, option: dict[str, Any], quote: dict[str, Any], fact
|
||||
)
|
||||
|
||||
|
||||
def _wrap(title: str, body: str) -> str:
|
||||
"""整页壳:标题、viewport、共用样式。"""
|
||||
def _wrap(title: str, body: str, *, auto_close: bool = False) -> str:
|
||||
"""整页壳:标题、viewport、共用样式。成功页可挂企微关窗脚本。"""
|
||||
closer = wecom_auto_close_script() if auto_close else ""
|
||||
return (
|
||||
"<!doctype html><html lang='zh-CN'><head><meta charset='utf-8' />"
|
||||
"<meta name='viewport' content='width=device-width, initial-scale=1' />"
|
||||
f"<title>{html.escape(title)}</title>"
|
||||
f"<style>{_PAGE_CSS}</style></head><body>"
|
||||
f"{body}</body></html>"
|
||||
f"{body}{closer}</body></html>"
|
||||
)
|
||||
|
||||
@@ -56,10 +56,11 @@ def render_land_route_page(payload: dict[str, Any]) -> str:
|
||||
|
||||
|
||||
def render_land_route_ok() -> str:
|
||||
"""选定成功。"""
|
||||
"""选定成功:短暂展示后关企微 H5。"""
|
||||
return _wrap(
|
||||
"已选定",
|
||||
"<div class='msg'><h1>已选定</h1><p>请回企微查看价格明细。</p></div>",
|
||||
"<div class='msg'><h1>已选定</h1><p>正在返回企微,请查看价格明细。</p></div>",
|
||||
auto_close=True,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ from __future__ import annotations
|
||||
from html import escape
|
||||
import json
|
||||
|
||||
from agent.channel.h5.wecom_close import wecom_auto_close_script
|
||||
from agent.policy import inquiry_copy as copy
|
||||
|
||||
# 三页共用:浅底、白卡片、企微蓝主按钮。禁止在页面里写 userid。
|
||||
@@ -188,7 +189,8 @@ def _shell(*, title: str, body: str, tone: str = "ok") -> str:
|
||||
"""成功 / 拒绝 / 过期共用卡片壳,避免三页三种简陋白底。"""
|
||||
icons = {"ok": _ICON_OK, "warn": _ICON_WARN, "expired": _ICON_EXPIRED}
|
||||
icon = icons.get(tone, _ICON_WARN)
|
||||
extra = '<p class="back">请回企微查看识别结果。</p>' if tone == "ok" else ""
|
||||
extra = '<p class="back">正在返回企微,请查看识别结果。</p>' if tone == "ok" else ""
|
||||
closer = wecom_auto_close_script() if tone == "ok" else ""
|
||||
return f"""<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
@@ -210,6 +212,7 @@ def _shell(*, title: str, body: str, tone: str = "ok") -> str:
|
||||
{extra}
|
||||
</div>
|
||||
</div>
|
||||
{closer}
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
"""
|
||||
企微内嵌 H5 成功后自动关页。
|
||||
|
||||
本文件职责:给附件上传成功、选线路成功页一段共用脚本。
|
||||
手机端可走 WeixinJSBridge;企微 Windows 客户端没有这套桥,必须像复制工单号页一样
|
||||
先加载 wecom-jssdk、用现成 /inquiry-form/jsapi-signature 做 ww.register,再 closeWindow。
|
||||
失败、过期页不要挂这段。
|
||||
副作用:只产出 HTML 片段;关窗签名走浏览器短请求,不占智能体请求线程做慢活。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from html import escape
|
||||
|
||||
from agent.config import get_settings
|
||||
|
||||
# 签名完成后再稍停,让销售看见「已成功」。
|
||||
_CLOSE_DELAY_MS = 400
|
||||
|
||||
|
||||
def wecom_auto_close_script() -> str:
|
||||
"""
|
||||
成功页脚:加载企微 JS-SDK,register 后关掉当前 H5 窗口。
|
||||
|
||||
线程:浏览器端执行。签名接口与复制页共用,ticket 已缓存在 Redis。
|
||||
为何这样写:上一版只调 WeixinJSBridge,电脑端企微关不掉,会停在成功页。
|
||||
"""
|
||||
settings = get_settings()
|
||||
corp = escape((settings.wecom_corp_id or "").strip(), quote=True)
|
||||
agent = escape(str(settings.wecom_agent_id or "1000010").strip(), quote=True)
|
||||
delay = _CLOSE_DELAY_MS
|
||||
return f"""<script src="https://wwcdn.weixin.qq.com/node/wework/open/js/wecom-jssdk-2.3.2.js"></script>
|
||||
<script>
|
||||
(function () {{
|
||||
var corpId = "{corp}";
|
||||
var agentId = Number("{agent}") || 0;
|
||||
|
||||
function sign(kind) {{
|
||||
return function (url) {{
|
||||
return fetch("/inquiry-form/jsapi-signature?kind=" + encodeURIComponent(kind)
|
||||
+ "&url=" + encodeURIComponent(url))
|
||||
.then(function (r) {{
|
||||
if (!r.ok) throw new Error("sign");
|
||||
return r.json();
|
||||
}});
|
||||
}};
|
||||
}}
|
||||
|
||||
function nativeClose() {{
|
||||
try {{
|
||||
if (typeof WeixinJSBridge !== "undefined") {{
|
||||
WeixinJSBridge.call("closeWindow");
|
||||
}}
|
||||
}} catch (e) {{}}
|
||||
try {{
|
||||
if (window.ww && typeof ww.closeWindow === "function") {{
|
||||
ww.closeWindow();
|
||||
}}
|
||||
}} catch (e) {{}}
|
||||
try {{
|
||||
if (window.wx && typeof wx.closeWindow === "function") {{
|
||||
wx.closeWindow();
|
||||
}}
|
||||
}} catch (e) {{}}
|
||||
try {{ window.close(); }} catch (e) {{}}
|
||||
}}
|
||||
|
||||
function boot() {{
|
||||
if (typeof WeixinJSBridge !== "undefined") {{
|
||||
setTimeout(nativeClose, {delay});
|
||||
}}
|
||||
document.addEventListener("WeixinJSBridgeReady", nativeClose, false);
|
||||
var ready = Promise.resolve();
|
||||
if (window.ww && ww.register && corpId) {{
|
||||
ready = ww.register({{
|
||||
corpId: corpId,
|
||||
agentId: agentId,
|
||||
jsApiList: ["closeWindow"],
|
||||
getConfigSignature: sign("corp"),
|
||||
getAgentConfigSignature: sign("agent")
|
||||
}}).catch(function () {{ return null; }});
|
||||
}}
|
||||
ready.then(function () {{
|
||||
setTimeout(nativeClose, {delay});
|
||||
}}).catch(function () {{
|
||||
setTimeout(nativeClose, {delay});
|
||||
}});
|
||||
}}
|
||||
|
||||
if (document.readyState === "loading") {{
|
||||
document.addEventListener("DOMContentLoaded", boot);
|
||||
}} else {{
|
||||
boot();
|
||||
}}
|
||||
}})();
|
||||
</script>"""
|
||||
Reference in New Issue
Block a user