电脑企微上传成功后关不掉当前页,分析看板线路筛选被挤窄、往下也滚不动。按销售实际操作补上关窗,并让看板整页可以滚动。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,7 +4,8 @@
|
|||||||
本文件职责:给附件上传成功、选线路成功页一段共用脚本。
|
本文件职责:给附件上传成功、选线路成功页一段共用脚本。
|
||||||
手机端只调一次 WeixinJSBridge.closeWindow,关掉当前 H5 后留在询价对话里。
|
手机端只调一次 WeixinJSBridge.closeWindow,关掉当前 H5 后留在询价对话里。
|
||||||
再调 ww/wx/window.close 会把询价小助手整个退出,回到企业微信首页。
|
再调 ww/wx/window.close 会把询价小助手整个退出,回到企业微信首页。
|
||||||
电脑企微即使注入了 WeixinJSBridge,这一下也关不掉当前页,必须按电脑走 JS-SDK。
|
电脑企微 5.x 内置页经常加载不了 JS-SDK,也不会打签名接口。
|
||||||
|
这时 ww.closeWindow 不会执行。电脑改用 WeixinJSBridge.invoke,再补 window.close,只关当前页。
|
||||||
失败、过期页不要挂这段。
|
失败、过期页不要挂这段。
|
||||||
副作用:只产出 HTML 片段;关窗签名走浏览器短请求,不占智能体请求线程做慢活。
|
副作用:只产出 HTML 片段;关窗签名走浏览器短请求,不占智能体请求线程做慢活。
|
||||||
"""
|
"""
|
||||||
@@ -24,8 +25,9 @@ def wecom_auto_close_script() -> str:
|
|||||||
成功页脚:加载企微 JS-SDK,register 后关掉当前 H5 窗口。
|
成功页脚:加载企微 JS-SDK,register 后关掉当前 H5 窗口。
|
||||||
|
|
||||||
线程:浏览器端执行。签名接口与复制页共用,ticket 已缓存在 Redis。
|
线程:浏览器端执行。签名接口与复制页共用,ticket 已缓存在 Redis。
|
||||||
为何这样写:电脑企微也会带上 WeixinJSBridge,但关不掉当前页。
|
为何这样写:21:27 的上传日志里,成功页已经返回,但没有 jsapi 签名请求。
|
||||||
若一发现桥就只走手机关闭,成功页会停在「正在返回企微」。手机仍只关一次。
|
电脑企微没跑起 ww.register,只调 ww.closeWindow 等于没关。
|
||||||
|
电脑改为 invoke + window.close,不依赖签名先成功。手机仍只关一次。
|
||||||
"""
|
"""
|
||||||
settings = get_settings()
|
settings = get_settings()
|
||||||
corp = escape((settings.wecom_corp_id or "").strip(), quote=True)
|
corp = escape((settings.wecom_corp_id or "").strip(), quote=True)
|
||||||
@@ -51,7 +53,11 @@ def wecom_auto_close_script() -> str:
|
|||||||
var closed = false;
|
var closed = false;
|
||||||
|
|
||||||
function isPhone() {{
|
function isPhone() {{
|
||||||
return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent || "");
|
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) {{
|
function closeOnce(fn) {{
|
||||||
@@ -65,13 +71,22 @@ def wecom_auto_close_script() -> str:
|
|||||||
closeOnce(function () {{ WeixinJSBridge.call("closeWindow"); }});
|
closeOnce(function () {{ WeixinJSBridge.call("closeWindow"); }});
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// 电脑企微即使有 WeixinJSBridge,也关不掉当前页。注册 JS-SDK 后再关一次。
|
// 电脑企微:call 关不掉,JS-SDK 又经常没装上。invoke 关内置页,window.close 关独立窗口。
|
||||||
// 不要调 window.close:手机会把询价小助手整个退出。
|
|
||||||
function closeDesktop() {{
|
function closeDesktop() {{
|
||||||
closeOnce(function () {{
|
try {{
|
||||||
if (window.ww && typeof ww.closeWindow === "function") ww.closeWindow();
|
if (typeof WeixinJSBridge !== "undefined" && typeof WeixinJSBridge.invoke === "function") {{
|
||||||
else if (window.wx && typeof wx.closeWindow === "function") wx.closeWindow();
|
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() {{
|
function boot() {{
|
||||||
@@ -85,21 +100,15 @@ def wecom_auto_close_script() -> str:
|
|||||||
}}, false);
|
}}, false);
|
||||||
return;
|
return;
|
||||||
}}
|
}}
|
||||||
var ready = Promise.resolve();
|
setTimeout(closeDesktop, {delay});
|
||||||
if (window.ww && ww.register && corpId) {{
|
if (!(window.ww && ww.register && corpId)) return;
|
||||||
ready = ww.register({{
|
ww.register({{
|
||||||
corpId: corpId,
|
corpId: corpId,
|
||||||
agentId: agentId,
|
agentId: agentId,
|
||||||
jsApiList: ["closeWindow"],
|
jsApiList: ["closeWindow"],
|
||||||
getConfigSignature: sign("corp"),
|
getConfigSignature: sign("corp"),
|
||||||
getAgentConfigSignature: sign("agent")
|
getAgentConfigSignature: sign("agent")
|
||||||
}}).catch(function () {{ return null; }});
|
}}).then(function () {{
|
||||||
}}
|
|
||||||
var timed = Promise.race([
|
|
||||||
ready,
|
|
||||||
new Promise(function (resolve) {{ setTimeout(resolve, 2500); }})
|
|
||||||
]);
|
|
||||||
timed.then(function () {{
|
|
||||||
setTimeout(closeDesktop, {delay});
|
setTimeout(closeDesktop, {delay});
|
||||||
}}).catch(function () {{
|
}}).catch(function () {{
|
||||||
setTimeout(closeDesktop, {delay});
|
setTimeout(closeDesktop, {delay});
|
||||||
|
|||||||
@@ -407,7 +407,10 @@ class AirRouteOptionsTests(unittest.TestCase):
|
|||||||
self.assertIn("closeWindow", ok)
|
self.assertIn("closeWindow", ok)
|
||||||
self.assertIn("wecom-jssdk", ok)
|
self.assertIn("wecom-jssdk", ok)
|
||||||
self.assertIn("jsapi-signature", ok)
|
self.assertIn("jsapi-signature", ok)
|
||||||
self.assertNotIn("window.close()", ok)
|
mobile = ok.split("function closeMobile()")[1].split("function closeDesktop()")[0]
|
||||||
|
desktop = ok.split("function closeDesktop()")[1].split("function boot()")[0]
|
||||||
|
self.assertNotIn("window.close()", mobile)
|
||||||
|
self.assertIn("window.close()", desktop)
|
||||||
self.assertNotIn("closeWindow", dead)
|
self.assertNotIn("closeWindow", dead)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,11 @@ class AttachmentUploadH5Tests(unittest.TestCase):
|
|||||||
self.assertIn("wecom-jssdk", ok)
|
self.assertIn("wecom-jssdk", ok)
|
||||||
self.assertIn("jsapi-signature", ok)
|
self.assertIn("jsapi-signature", ok)
|
||||||
self.assertIn("function isPhone()", ok)
|
self.assertIn("function isPhone()", ok)
|
||||||
self.assertNotIn("window.close()", ok)
|
self.assertIn("WeixinJSBridge.invoke", ok)
|
||||||
|
mobile = ok.split("function closeMobile()")[1].split("function closeDesktop()")[0]
|
||||||
|
desktop = ok.split("function closeDesktop()")[1].split("function boot()")[0]
|
||||||
|
self.assertNotIn("window.close()", mobile)
|
||||||
|
self.assertIn("window.close()", desktop)
|
||||||
self.assertNotIn("closeWindow", page)
|
self.assertNotIn("closeWindow", page)
|
||||||
self.assertNotIn("closeWindow", dead)
|
self.assertNotIn("closeWindow", dead)
|
||||||
|
|
||||||
|
|||||||
@@ -666,9 +666,11 @@ onUnmounted(() => document.removeEventListener("click", onDocClick));
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dash-route-menu {
|
.dash-route-menu {
|
||||||
|
/* 盖过图表区;宽度在 dashboard-prototype.css 里写成 360px,避免按按钮宽度收缩 */
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: calc(100% + 8px);
|
top: calc(100% + 8px);
|
||||||
|
z-index: 120;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dash-cost-footnote {
|
.dash-cost-footnote {
|
||||||
|
|||||||
@@ -43,10 +43,16 @@ body {
|
|||||||
padding: 16px 16px 40px !important;
|
padding: 16px 16px 40px !important;
|
||||||
gap: 12px !important;
|
gap: 12px !important;
|
||||||
min-width: 0 !important;
|
min-width: 0 !important;
|
||||||
overflow-x: hidden;
|
/*
|
||||||
flex: 1 1 auto !important;
|
* 主区被锁成一屏。flex-basis 用 auto 时,格子会按内容把内容区撑高,
|
||||||
|
* 再被主区裁掉,页面上就没有滚动条,鼠标也滚不动。
|
||||||
|
* basis 取 0、高度先归零,再由 flex 撑满顶栏下方,多出来的内容在这里滚。
|
||||||
|
*/
|
||||||
|
flex: 1 1 0% !important;
|
||||||
|
height: 0 !important;
|
||||||
min-height: 0 !important;
|
min-height: 0 !important;
|
||||||
overflow: auto !important;
|
overflow-x: hidden !important;
|
||||||
|
overflow-y: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -127,6 +133,7 @@ body {
|
|||||||
padding: 0 14px !important;
|
padding: 0 14px !important;
|
||||||
gap: 12px !important;
|
gap: 12px !important;
|
||||||
min-width: 0 !important;
|
min-width: 0 !important;
|
||||||
|
flex-shrink: 0 !important;
|
||||||
/* 允许用户下拉露出;业务 Teleport 区单独 overflow:hidden 防幽灵点击层 */
|
/* 允许用户下拉露出;业务 Teleport 区单独 overflow:hidden 防幽灵点击层 */
|
||||||
overflow: visible !important;
|
overflow: visible !important;
|
||||||
}
|
}
|
||||||
@@ -1070,6 +1077,7 @@ h6 {
|
|||||||
.admin-content:has(.ref-surface--metrics) {
|
.admin-content:has(.ref-surface--metrics) {
|
||||||
padding: 14px 14px 36px !important;
|
padding: 14px 14px 36px !important;
|
||||||
gap: 10px !important;
|
gap: 10px !important;
|
||||||
|
align-content: start !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 话术 ---- */
|
/* ---- 话术 ---- */
|
||||||
@@ -1523,3 +1531,37 @@ textarea.field.field-tall {
|
|||||||
background: #f8fbff !important;
|
background: #f8fbff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 分析看板比一屏高。整页被 html / 主区锁死时,内容区即使设了 overflow,
|
||||||
|
* 格子也会跟着内容长高,再被主区裁掉,滚轮没有可滚的对象。
|
||||||
|
* 看板单独放开文档滚动;列表页仍锁在一屏里,表格自己滚。
|
||||||
|
*/
|
||||||
|
html:has(.ref-surface--metrics),
|
||||||
|
body:has(.ref-surface--metrics) {
|
||||||
|
height: auto !important;
|
||||||
|
min-height: 100% !important;
|
||||||
|
overflow-x: hidden !important;
|
||||||
|
overflow-y: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app:has(.ref-surface--metrics),
|
||||||
|
.admin-shell:has(.ref-surface--metrics) {
|
||||||
|
height: auto !important;
|
||||||
|
min-height: 100vh !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-stage:has(.ref-surface--metrics) {
|
||||||
|
height: auto !important;
|
||||||
|
max-height: none !important;
|
||||||
|
min-height: 100vh !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-content:has(.ref-surface--metrics) {
|
||||||
|
height: auto !important;
|
||||||
|
max-height: none !important;
|
||||||
|
flex: none !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -776,9 +776,13 @@
|
|||||||
color: #155eef;
|
color: #155eef;
|
||||||
}
|
}
|
||||||
.ref-route-filter__menu {
|
.ref-route-filter__menu {
|
||||||
position: fixed;
|
/* 必须用固定宽度。百分比会按「线路筛选」按钮的宽度算,面板只剩一字宽,中文被挤成竖排,全选也被裁掉。 */
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: calc(100% + 8px);
|
||||||
z-index: 120;
|
z-index: 120;
|
||||||
width: min(360px, calc(100% - 24px));
|
width: 360px;
|
||||||
|
max-width: calc(100vw - 48px);
|
||||||
border: 1px solid #dfe5ee;
|
border: 1px solid #dfe5ee;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
@@ -797,12 +801,14 @@
|
|||||||
color: #0f172a;
|
color: #0f172a;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.ref-route-filter__menu-sub {
|
.ref-route-filter__menu-sub {
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
color: #64748b;
|
color: #64748b;
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.ref-route-filter__actions.tabs-pill {
|
.ref-route-filter__actions.tabs-pill {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
@@ -861,6 +867,7 @@
|
|||||||
}
|
}
|
||||||
.ref-route-chip__text {
|
.ref-route-chip__text {
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.month-range-picker {
|
.month-range-picker {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
Reference in New Issue
Block a user