feat: brand 白名单下发(站点覆盖/租户头像/CORS) + widget/chat 客户端 key 租户化 + 会话站点标
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
+34
-7
@@ -83,7 +83,7 @@
|
||||
|
||||
<div class="info">
|
||||
<p><strong>Current Page:</strong> <span id="pathname"></span></p>
|
||||
<p><strong>Storage Key:</strong> widget_invite_dismissed_<span id="storage-key"></span></p>
|
||||
<p><strong>Storage Key:</strong> widget_invite_dismissed_<slug>_<span id="storage-key"></span> (Task 10: key 按租户 slug 命名空间化)</p>
|
||||
<p><button class="btn" onclick="clearStorage()">Clear Storage & Refresh</button></p>
|
||||
</div>
|
||||
|
||||
@@ -92,7 +92,12 @@
|
||||
document.getElementById('storage-key').textContent = window.location.pathname;
|
||||
|
||||
function clearStorage() {
|
||||
sessionStorage.removeItem('widget_invite_dismissed_' + window.location.pathname);
|
||||
// Task 10: key 已租户化(widget_invite_dismissed_<slug>_<path>)——按前缀清扫全部
|
||||
try {
|
||||
Object.keys(sessionStorage).forEach(function (k) {
|
||||
if (k.indexOf('widget_invite_dismissed_') === 0) sessionStorage.removeItem(k);
|
||||
});
|
||||
} catch (e) {}
|
||||
location.reload();
|
||||
}
|
||||
|
||||
@@ -107,22 +112,36 @@
|
||||
};
|
||||
|
||||
var rebuildLoading = false, rebuildPending = null;
|
||||
function removeWidgetHosts() {
|
||||
// Task 10: host id 已租户化(cc-widget-host-<slug>),按前缀清扫
|
||||
var hosts = document.querySelectorAll('[id^="cc-widget-host-"]');
|
||||
for (var i = 0; i < hosts.length; i++) hosts[i].remove();
|
||||
}
|
||||
function rebuildWidget(extra) {
|
||||
if (rebuildLoading) { rebuildPending = extra || {}; return; } // 快速连点:只记最新意图,当前加载完接力重建
|
||||
rebuildLoading = true;
|
||||
document.getElementById("assertions").innerHTML = "<div>…rebuilding…</div>";
|
||||
document.querySelectorAll("#cc-widget-host").forEach(function (h) { h.remove(); });
|
||||
removeWidgetHosts();
|
||||
document.querySelectorAll("script[src*='widget.js']").forEach(function (s) { s.remove(); });
|
||||
try { sessionStorage.removeItem("widget_invite_dismissed_" + window.location.pathname); } catch (e) {}
|
||||
try {
|
||||
Object.keys(sessionStorage).forEach(function (k) {
|
||||
if (k.indexOf("widget_invite_dismissed_") === 0) sessionStorage.removeItem(k);
|
||||
});
|
||||
} catch (e) {}
|
||||
var s = document.createElement("script");
|
||||
s.src = "/static/widget.js?" + Date.now();
|
||||
var attrs = Object.assign({}, BASE_ATTRS, extra || {});
|
||||
Object.keys(attrs).forEach(function (k) { s.setAttribute(k, attrs[k]); });
|
||||
s.onload = function () {
|
||||
rebuildLoading = false;
|
||||
var hosts = document.querySelectorAll("#cc-widget-host");
|
||||
for (var i = 0; i < hosts.length - 1; i++) hosts[i].remove(); // 竞态兜底:只保留最后挂载
|
||||
runAssertions();
|
||||
// Task 10: 挂件改等 brand 端点落定后才挂载——脚本 onload 早于挂载,
|
||||
// 轮询 __chatWidgetDebug(boot 里同步设置,观察到场即 init 已完成)
|
||||
// 就绪再清竞态残留并跑断言
|
||||
waitForWidget(function () {
|
||||
var hosts = document.querySelectorAll('[id^="cc-widget-host-"]');
|
||||
for (var i = 0; i < hosts.length - 1; i++) hosts[i].remove(); // 竞态兜底:只保留最后挂载
|
||||
runAssertions(); // 挂件未就绪(超时)时其内部 !d 分支自行报红
|
||||
});
|
||||
var next = rebuildPending; rebuildPending = null;
|
||||
if (next) rebuildWidget(next);
|
||||
};
|
||||
@@ -134,6 +153,14 @@
|
||||
};
|
||||
document.body.appendChild(s);
|
||||
}
|
||||
function waitForWidget(cb) {
|
||||
var started = Date.now();
|
||||
(function poll() {
|
||||
if (window.__chatWidgetDebug) return cb(true);
|
||||
if (Date.now() - started > 5000) return cb(false); // brand 挂起/失败兜底
|
||||
setTimeout(poll, 100);
|
||||
})();
|
||||
}
|
||||
function applyColor(c) {
|
||||
rebuildWidget({ "data-color": c || document.getElementById("colorPicker").value });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user