chore: CRM-NEW baseline
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Yehwang LibreDesk widget 接入脚本(新栈)
|
||||
*
|
||||
* 用法:页面里先设置 window.YehwangChatConfig,再引入本脚本。
|
||||
*
|
||||
* <script>
|
||||
* window.YehwangChatConfig = {
|
||||
* baseURL: 'http://192.168.31.61:9000',
|
||||
* inboxID: '10fd5207-d235-4c49-beaa-a65eed0ddd0e',
|
||||
* identityURL: 'http://192.168.31.61:4100/identity',
|
||||
* siteJWT: window.__SITE_JWT__ || null // 站点登录后注入
|
||||
* };
|
||||
* </script>
|
||||
* <script async src="/ai-snippet.js"></script>
|
||||
*
|
||||
* 有 siteJWT:走 bridge /identity 验签换 LibreDesk widget JWT(生产路径)。
|
||||
* 无 siteJWT:匿名访客。
|
||||
*/
|
||||
(function () {
|
||||
var cfg = window.YehwangChatConfig || {};
|
||||
var baseURL = String(cfg.baseURL || 'http://192.168.31.61:9000').replace(/\/+$/, '');
|
||||
var inboxID = cfg.inboxID || '10fd5207-d235-4c49-beaa-a65eed0ddd0e';
|
||||
var identityURL = cfg.identityURL || 'http://192.168.31.61:4100/identity';
|
||||
|
||||
var state = { loaded: false, userJWT: null };
|
||||
|
||||
function loadWidget() {
|
||||
if (state.loaded) return;
|
||||
state.loaded = true;
|
||||
window.LibredeskSettings = { baseURL: baseURL, inboxID: inboxID };
|
||||
if (state.userJWT) window.LibredeskSettings.userJWT = state.userJWT;
|
||||
var s = document.createElement('script');
|
||||
s.async = true;
|
||||
s.src = baseURL + '/widget.js';
|
||||
document.head.appendChild(s);
|
||||
}
|
||||
|
||||
function postIdentity(body) {
|
||||
return fetch(identityURL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
}).then(function (res) {
|
||||
if (!res.ok) throw new Error('identity HTTP ' + res.status);
|
||||
return res.json();
|
||||
});
|
||||
}
|
||||
|
||||
async function resolveUserJWT() {
|
||||
if (cfg.userJWT) return cfg.userJWT;
|
||||
if (cfg.siteJWT) {
|
||||
var out = await postIdentity({ token: cfg.siteJWT });
|
||||
return out.userJWT;
|
||||
}
|
||||
// 仅开发联调:直接传 email(需要 bridge IDENTITY_DEV_MODE=true)
|
||||
if (cfg.demoEmail) {
|
||||
var dev = await postIdentity({
|
||||
email: cfg.demoEmail,
|
||||
externalUserId: cfg.demoExternalId || cfg.demoEmail,
|
||||
firstName: cfg.demoFirstName || 'Customer',
|
||||
lastName: cfg.demoLastName || '',
|
||||
});
|
||||
return dev.userJWT;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function boot() {
|
||||
if (cfg.siteJWT || cfg.demoEmail || cfg.userJWT) {
|
||||
try {
|
||||
state.userJWT = await resolveUserJWT();
|
||||
} catch (e) {
|
||||
// 身份失败不阻塞 widget,降级为匿名会话
|
||||
console.warn('[YehwangChat] identity failed, fallback to anonymous:', e.message);
|
||||
}
|
||||
}
|
||||
loadWidget();
|
||||
}
|
||||
|
||||
window.YehwangChat = {
|
||||
/** 页面登录状态变化后可调用:重新设置 JWT 并重载(简单做法:刷新页面) */
|
||||
setSiteJWT: function (jwt) { cfg.siteJWT = jwt; },
|
||||
isLoggedIn: function () { return Boolean(state.userJWT); },
|
||||
};
|
||||
|
||||
boot();
|
||||
})();
|
||||
@@ -0,0 +1,99 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>crm-new · LibreDesk Widget 测试页</title>
|
||||
<style>
|
||||
body { font-family: -apple-system, "Segoe UI", "PingFang SC", sans-serif; margin: 0; background: #f4f7fb; color: #1f2937; }
|
||||
.card { max-width: 720px; margin: 48px auto; background: #fff; border-radius: 14px; padding: 28px 32px; box-shadow: 0 10px 30px rgba(0,0,0,.08); }
|
||||
h1 { font-size: 20px; margin: 0 0 4px; }
|
||||
.sub { color: #6b7280; font-size: 13px; margin-bottom: 20px; }
|
||||
label { display: block; font-size: 13px; color: #374151; margin: 14px 0 6px; }
|
||||
input { width: 100%; box-sizing: border-box; padding: 10px 12px; border: 1px solid #d1d5db; border-radius: 8px; font-size: 14px; }
|
||||
.row { display: flex; gap: 10px; margin-top: 18px; flex-wrap: wrap; }
|
||||
button { padding: 10px 16px; border: 0; border-radius: 8px; font-size: 14px; cursor: pointer; }
|
||||
.primary { background: #1f6feb; color: #fff; }
|
||||
.ghost { background: #eef2f7; color: #1f2937; }
|
||||
.badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; background: #e0f2fe; color: #0369a1; margin-left: 6px; }
|
||||
.hint { margin-top: 22px; font-size: 13px; color: #6b7280; border-top: 1px dashed #e5e7eb; padding-top: 16px; line-height: 1.9; }
|
||||
code { background: #f3f4f6; padding: 1px 5px; border-radius: 4px; font-size: 12px; }
|
||||
#status { margin-top: 12px; font-size: 13px; color: #065f46; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<h1>LibreDesk Widget 测试 <span class="badge" id="modeBadge">匿名</span></h1>
|
||||
<div class="sub">页面打开后右下角应出现聊天气泡(自动加载,无需点击)· v2</div>
|
||||
|
||||
<label>登录用户邮箱(dev 模式)</label>
|
||||
<input id="email" value="buyer@test-customer.nl" />
|
||||
|
||||
<label>站点 JWT(生产路径;留空则用上面的 dev 邮箱)</label>
|
||||
<input id="siteJwt" placeholder="由 yehwang 站点登录后注入" />
|
||||
|
||||
<div class="row">
|
||||
<button class="primary" onclick="reload('login')">切换为登录身份</button>
|
||||
<button class="ghost" onclick="reload('anonymous')">切换为匿名访客</button>
|
||||
<button class="ghost" onclick="location.href=location.pathname">重新加载</button>
|
||||
</div>
|
||||
|
||||
<div id="status"></div>
|
||||
|
||||
<div class="hint">
|
||||
<b>排查</b><br />
|
||||
· 气泡没出现:打开浏览器控制台看 <code>[YehwangChat]</code> / <code>Failed to initialize Libredesk Widget</code> 报错<br />
|
||||
· 登录身份:页面会先调 bridge <code>POST /identity</code> 拿 <code>userJWT</code>,再加载 widget<br />
|
||||
· 聊天窗口打不开:检查 LibreDesk 可信域名里是否有 <code>192.168.31.61:8088</code>(CSP frame-ancestors)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var params = new URLSearchParams(location.search);
|
||||
var mode = params.get('as') === 'login' ? 'login' : 'anonymous';
|
||||
var email = params.get('email') || 'buyer@test-customer.nl';
|
||||
document.getElementById('email').value = email;
|
||||
document.getElementById('modeBadge').textContent = mode === 'login' ? '登录身份' : '匿名';
|
||||
|
||||
function reload(nextMode) {
|
||||
var q = new URLSearchParams();
|
||||
q.set('as', nextMode);
|
||||
if (nextMode === 'login') {
|
||||
q.set('email', document.getElementById('email').value.trim());
|
||||
var jwt = document.getElementById('siteJwt').value.trim();
|
||||
if (jwt) q.set('siteJwt', jwt);
|
||||
}
|
||||
location.search = q.toString();
|
||||
}
|
||||
|
||||
function boot() {
|
||||
var cfg = {
|
||||
baseURL: 'http://192.168.31.61:9000',
|
||||
inboxID: '10fd5207-d235-4c49-beaa-a65eed0ddd0e',
|
||||
identityURL: 'http://192.168.31.61:4100/identity',
|
||||
};
|
||||
if (mode === 'login') {
|
||||
var siteJwt = params.get('siteJwt');
|
||||
if (siteJwt) cfg.siteJWT = siteJwt;
|
||||
else {
|
||||
cfg.demoEmail = email;
|
||||
cfg.demoFirstName = 'Jan';
|
||||
cfg.demoLastName = 'Jansen';
|
||||
}
|
||||
}
|
||||
window.YehwangChatConfig = cfg;
|
||||
var s = document.createElement('script');
|
||||
s.src = '/ai-snippet.js?v=' + Date.now();
|
||||
s.onload = function () {
|
||||
document.getElementById('status').textContent = mode === 'login'
|
||||
? '已按登录身份加载 widget(右下角气泡)'
|
||||
: '已按匿名访客加载 widget(右下角气泡)';
|
||||
};
|
||||
document.body.appendChild(s);
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot);
|
||||
else boot();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user