125 lines
4.2 KiB
Python
125 lines
4.2 KiB
Python
"""
|
|
企微内嵌 H5 成功后自动关页。
|
|
|
|
本文件职责:给附件上传成功、选线路成功页一段共用脚本。
|
|
手机端只调一次 WeixinJSBridge.closeWindow,关掉当前 H5 后留在询价对话里。
|
|
再调 ww/wx/window.close 会把询价小助手整个退出,回到企业微信首页。
|
|
电脑企微 5.x 内置页经常加载不了 JS-SDK,也不会打签名接口。
|
|
这时 ww.closeWindow 不会执行。电脑改用 WeixinJSBridge.invoke,再补 window.close,只关当前页。
|
|
失败、过期页不要挂这段。
|
|
副作用:只产出 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。
|
|
为何这样写:21:27 的上传日志里,成功页已经返回,但没有 jsapi 签名请求。
|
|
电脑企微没跑起 ww.register,只调 ww.closeWindow 等于没关。
|
|
电脑改为 invoke + window.close,不依赖签名先成功。手机仍只关一次。
|
|
"""
|
|
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();
|
|
}});
|
|
}};
|
|
}}
|
|
|
|
var closed = false;
|
|
|
|
function isPhone() {{
|
|
var ua = navigator.userAgent || "";
|
|
if (/wxwork/i.test(ua) && /Windows|Macintosh/i.test(ua) && !/Android|iPhone|iPad|iPod/i.test(ua)) {{
|
|
return false;
|
|
}}
|
|
return /Android|iPhone|iPad|iPod/i.test(ua);
|
|
}}
|
|
|
|
function closeOnce(fn) {{
|
|
if (closed) return;
|
|
closed = true;
|
|
try {{ fn(); }} catch (e) {{}}
|
|
}}
|
|
|
|
// 手机企微有 WeixinJSBridge:只关当前 H5。再调第二套关闭会把询价小助手整个退出,回到企业微信首页。
|
|
function closeMobile() {{
|
|
closeOnce(function () {{ WeixinJSBridge.call("closeWindow"); }});
|
|
}}
|
|
|
|
// 电脑企微:call 关不掉,JS-SDK 又经常没装上。invoke 关内置页,window.close 关独立窗口。
|
|
function closeDesktop() {{
|
|
try {{
|
|
if (typeof WeixinJSBridge !== "undefined" && typeof WeixinJSBridge.invoke === "function") {{
|
|
WeixinJSBridge.invoke("closeWindow", {{}}, function () {{}});
|
|
}}
|
|
}} catch (e) {{}}
|
|
try {{
|
|
if (window.ww && typeof ww.closeWindow === "function") {{
|
|
var ret = ww.closeWindow();
|
|
if (ret && ret.catch) ret.catch(function () {{}});
|
|
}} else if (window.wx && typeof wx.closeWindow === "function") {{
|
|
wx.closeWindow();
|
|
}}
|
|
}} catch (e) {{}}
|
|
try {{ window.close(); }} catch (e) {{}}
|
|
}}
|
|
|
|
function boot() {{
|
|
if (isPhone()) {{
|
|
if (typeof WeixinJSBridge !== "undefined") {{
|
|
setTimeout(closeMobile, {delay});
|
|
return;
|
|
}}
|
|
document.addEventListener("WeixinJSBridgeReady", function () {{
|
|
setTimeout(closeMobile, {delay});
|
|
}}, false);
|
|
return;
|
|
}}
|
|
setTimeout(closeDesktop, {delay});
|
|
if (!(window.ww && ww.register && corpId)) return;
|
|
ww.register({{
|
|
corpId: corpId,
|
|
agentId: agentId,
|
|
jsApiList: ["closeWindow"],
|
|
getConfigSignature: sign("corp"),
|
|
getAgentConfigSignature: sign("agent")
|
|
}}).then(function () {{
|
|
setTimeout(closeDesktop, {delay});
|
|
}}).catch(function () {{
|
|
setTimeout(closeDesktop, {delay});
|
|
}});
|
|
}}
|
|
|
|
if (document.readyState === "loading") {{
|
|
document.addEventListener("DOMContentLoaded", boot);
|
|
}} else {{
|
|
boot();
|
|
}}
|
|
}})();
|
|
</script>"""
|