2026-01-26 11:16:56 +08:00
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
|
2026-01-27 19:03:46 +08:00
|
|
|
|
<style>
|
|
|
|
|
|
body {
|
|
|
|
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
background: #f5f5f5;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.test-panel {
|
|
|
|
|
|
max-width: 800px;
|
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
|
background: white;
|
|
|
|
|
|
padding: 30px;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.test-panel h1 {
|
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.status-card {
|
|
|
|
|
|
background: #f8f9fa;
|
|
|
|
|
|
border-left: 4px solid #28a745;
|
|
|
|
|
|
padding: 15px;
|
|
|
|
|
|
margin: 20px 0;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.status-card.visitor {
|
|
|
|
|
|
border-left-color: #ffc107;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.status-card h3 {
|
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.status-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
padding: 8px 0;
|
|
|
|
|
|
border-bottom: 1px solid #e9ecef;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.status-item:last-child {
|
|
|
|
|
|
border-bottom: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.status-label {
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #495057;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.status-value {
|
|
|
|
|
|
color: #6c757d;
|
|
|
|
|
|
font-family: monospace;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.button-group {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 10px;
|
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.btn {
|
|
|
|
|
|
padding: 12px 24px;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.3s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.btn-primary {
|
|
|
|
|
|
background: #28a745;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.btn-primary:hover {
|
|
|
|
|
|
background: #218838;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.btn-secondary {
|
|
|
|
|
|
background: #6c757d;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.btn-secondary:hover {
|
|
|
|
|
|
background: #5a6268;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.btn-danger {
|
|
|
|
|
|
background: #dc3545;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.btn-danger:hover {
|
|
|
|
|
|
background: #c82333;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.btn-warning {
|
|
|
|
|
|
background: #ffc107;
|
|
|
|
|
|
color: #212529;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.btn-warning:hover {
|
|
|
|
|
|
background: #e0a800;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.log-section {
|
|
|
|
|
|
margin-top: 30px;
|
|
|
|
|
|
background: #1e1e1e;
|
|
|
|
|
|
color: #d4d4d4;
|
|
|
|
|
|
padding: 15px;
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
font-family: 'Courier New', monospace;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
max-height: 300px;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.log-section h3 {
|
|
|
|
|
|
color: #4ec9b0;
|
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.hidden {
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|
|
|
|
|
|
|
2026-01-26 11:16:56 +08:00
|
|
|
|
<body>
|
2026-01-27 19:03:46 +08:00
|
|
|
|
<div class="test-panel">
|
|
|
|
|
|
<h1>🧪 Chatwoot Widget 测试页面</h1>
|
|
|
|
|
|
<p style="color: #666; margin-bottom: 20px;">
|
|
|
|
|
|
<strong>测试流程:</strong><br>
|
|
|
|
|
|
1. 页面加载时以游客模式启动(不做任何处理)<br>
|
|
|
|
|
|
2. 点击"模拟用户登录":使用 reset() 清除聊天 + setUser() 设置用户(不刷新页面)<br>
|
|
|
|
|
|
3. 点击"用户退出":使用 reset() 清除内容并刷新页面
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
<div id="statusCard" class="status-card visitor">
|
|
|
|
|
|
<h3 id="statusTitle">👤 当前状态:游客模式</h3>
|
|
|
|
|
|
<div class="status-item">
|
|
|
|
|
|
<span class="status-label">User ID:</span>
|
|
|
|
|
|
<span class="status-value" id="displayUserId">无</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="status-item">
|
|
|
|
|
|
<span class="status-label">Token:</span>
|
|
|
|
|
|
<span class="status-value" id="displayToken">不存在</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="status-item">
|
|
|
|
|
|
<span class="status-label">登录状态:</span>
|
|
|
|
|
|
<span class="status-value" id="displayLoginStatus">未登录</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="button-group">
|
|
|
|
|
|
<button class="btn btn-primary" id="loginBtn" onclick="simulateLogin()">🔐 模拟用户登录</button>
|
|
|
|
|
|
<button class="btn btn-danger hidden" id="logoutBtn" onclick="simulateLogout()">🚪 用户退出</button>
|
|
|
|
|
|
<button class="btn btn-secondary" onclick="refreshPage()">🔄 刷新页面</button>
|
|
|
|
|
|
<button class="btn btn-secondary" onclick="openWidget()">💬 打开聊天</button>
|
|
|
|
|
|
<button class="btn btn-secondary" onclick="clearAllData()">🗑️ 清除所有数据</button>
|
|
|
|
|
|
<button class="btn btn-warning hidden" id="cancelRefreshBtn" onclick="cancelRefresh()">❌ 取消刷新</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div id="refreshNotice" class="hidden" style="margin-top: 15px; padding: 10px; background: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;">
|
|
|
|
|
|
<strong>⏳ 页面将在 <span id="countdown">2</span> 秒后自动刷新...</strong>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="log-section">
|
|
|
|
|
|
<h3>📋 控制台日志</h3>
|
|
|
|
|
|
<div id="logOutput">等待操作...</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-26 11:16:56 +08:00
|
|
|
|
</body>
|
|
|
|
|
|
|
|
|
|
|
|
<%
|
2026-01-27 19:03:46 +08:00
|
|
|
|
# 测试用的用户信息
|
|
|
|
|
|
# 检查 cookie 中是否有 token
|
|
|
|
|
|
token_present = cookies[:token].present?
|
2026-01-26 11:16:56 +08:00
|
|
|
|
|
2026-01-27 19:03:46 +08:00
|
|
|
|
if token_present
|
|
|
|
|
|
test_user_id = '211845'
|
|
|
|
|
|
test_user_hash = OpenSSL::HMAC.hexdigest(
|
|
|
|
|
|
'sha256',
|
|
|
|
|
|
@web_widget.hmac_token,
|
|
|
|
|
|
test_user_id.to_s
|
|
|
|
|
|
)
|
|
|
|
|
|
else
|
|
|
|
|
|
test_user_id = nil
|
|
|
|
|
|
test_user_hash = nil
|
|
|
|
|
|
end
|
2026-01-26 11:16:56 +08:00
|
|
|
|
%>
|
2026-01-27 19:03:46 +08:00
|
|
|
|
|
2026-01-26 11:16:56 +08:00
|
|
|
|
<script>
|
2026-01-27 19:03:46 +08:00
|
|
|
|
// 测试用的 JWT Token
|
|
|
|
|
|
const TEST_TOKEN = 'eyJ0eXAiOiJqd3QifQ.eyJzdWIiOiIxIiwiaXNzIjoiaHR0cDpcL1wvOiIsImV4cCI6MTc3MjAwNTk1MSwiaWF0IjoxNzY5NDEzOTUxLCJuYmYiOjE3Njk0MTM5NTEsInVzZXJJZCI6MjExODQ1LCJ0eXBlIjoyLCJ0ZW5hbnRJZCI6MiwidWlkIjoyMTE4NDUsInMiOiI4VG5wd2QiLCJqdGkiOiI5MjFlYzhhMDE2Yjk3MTA5OTI1MjgxMjUzZWQ1MzBkYSJ9.ql7ianUz3Scn_y0JbMXjeq56BVhjpQqt2_vrdq0kUL4';
|
|
|
|
|
|
|
|
|
|
|
|
// 测试用户信息
|
|
|
|
|
|
const TEST_USER = {
|
|
|
|
|
|
userId: '<%= test_user_id %>',
|
|
|
|
|
|
userHash: '<%= test_user_hash %>',
|
|
|
|
|
|
email: '211845@example.com',
|
|
|
|
|
|
name: '测试用户 211845'
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 当前状态
|
|
|
|
|
|
let isLoggedIn = false;
|
|
|
|
|
|
let currentUser = null;
|
|
|
|
|
|
let refreshTimer = null;
|
|
|
|
|
|
let countdownTimer = null;
|
|
|
|
|
|
let hadUserIdentifier = false; // 记录之前是否有过用户标识
|
|
|
|
|
|
|
2026-01-26 11:16:56 +08:00
|
|
|
|
// Helper function to get cookie value by name
|
|
|
|
|
|
function getCookie(name) {
|
|
|
|
|
|
const value = `; ${document.cookie}`;
|
|
|
|
|
|
const parts = value.split(`; ${name}=`);
|
|
|
|
|
|
if (parts.length === 2) return parts.pop().split(';').shift();
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-27 19:03:46 +08:00
|
|
|
|
// Helper function to set cookie
|
|
|
|
|
|
function setCookie(name, value, days = 7) {
|
|
|
|
|
|
const expires = new Date(Date.now() + days * 864e5).toUTCString();
|
|
|
|
|
|
document.cookie = name + '=' + value + '; expires=' + expires + '; path=/';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Helper function to delete cookie
|
|
|
|
|
|
function deleteCookie(name) {
|
|
|
|
|
|
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 日志输出
|
|
|
|
|
|
function addLog(message) {
|
|
|
|
|
|
const logOutput = document.getElementById('logOutput');
|
|
|
|
|
|
const timestamp = new Date().toLocaleTimeString();
|
|
|
|
|
|
logOutput.innerHTML += `<div>[${timestamp}] ${message}</div>`;
|
|
|
|
|
|
logOutput.scrollTop = logOutput.scrollHeight;
|
|
|
|
|
|
console.log(message);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新状态显示
|
|
|
|
|
|
function updateStatusDisplay() {
|
|
|
|
|
|
const token = getCookie('token');
|
|
|
|
|
|
const userId = currentUser ? currentUser.userId : null;
|
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('displayUserId').textContent = userId || '无';
|
|
|
|
|
|
document.getElementById('displayToken').textContent = token ? '存在' : '不存在';
|
|
|
|
|
|
document.getElementById('displayLoginStatus').textContent = isLoggedIn ? '已登录' : '未登录';
|
|
|
|
|
|
|
|
|
|
|
|
const statusCard = document.getElementById('statusCard');
|
|
|
|
|
|
const statusTitle = document.getElementById('statusTitle');
|
|
|
|
|
|
const loginBtn = document.getElementById('loginBtn');
|
|
|
|
|
|
const logoutBtn = document.getElementById('logoutBtn');
|
|
|
|
|
|
|
|
|
|
|
|
if (isLoggedIn) {
|
|
|
|
|
|
statusCard.className = 'status-card';
|
|
|
|
|
|
statusTitle.textContent = '✅ 当前状态:已登录';
|
|
|
|
|
|
loginBtn.classList.add('hidden');
|
|
|
|
|
|
logoutBtn.classList.remove('hidden');
|
|
|
|
|
|
} else {
|
|
|
|
|
|
statusCard.className = 'status-card visitor';
|
|
|
|
|
|
statusTitle.textContent = '👤 当前状态:游客模式';
|
|
|
|
|
|
loginBtn.classList.remove('hidden');
|
|
|
|
|
|
logoutBtn.classList.add('hidden');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化 Chatwoot Widget
|
2026-01-26 11:16:56 +08:00
|
|
|
|
window.chatwootSettings = {
|
|
|
|
|
|
hideMessageBubble: false,
|
|
|
|
|
|
position: '<%= @widget_position %>',
|
|
|
|
|
|
locale: 'zh_CN',
|
|
|
|
|
|
useBrowserLanguage: false,
|
|
|
|
|
|
type: '<%= @widget_type %>',
|
|
|
|
|
|
widgetStyle: '<%= @widget_style %>',
|
|
|
|
|
|
darkMode: '<%= @dark_mode %>',
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
(function(d,t) {
|
|
|
|
|
|
var BASE_URL = '';
|
|
|
|
|
|
var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
|
|
|
|
|
|
g.src= BASE_URL + "/packs/js/sdk.js";
|
|
|
|
|
|
g.async = true;
|
|
|
|
|
|
s.parentNode.insertBefore(g,s);
|
|
|
|
|
|
g.onload=function(){
|
2026-01-27 19:03:46 +08:00
|
|
|
|
addLog('✅ Chatwoot SDK 加载完成');
|
|
|
|
|
|
|
|
|
|
|
|
// 检查当前登录状态(仅用于显示)
|
2026-01-26 11:16:56 +08:00
|
|
|
|
const token = getCookie('token');
|
2026-01-27 19:03:46 +08:00
|
|
|
|
addLog('🔍 检查登录状态...');
|
|
|
|
|
|
addLog(' - Token 存在: ' + (token ? '是' : '否'));
|
|
|
|
|
|
addLog(' - userId (服务器): ' + ('<%= test_user_id %>' || '无'));
|
|
|
|
|
|
|
|
|
|
|
|
// 无论是否有 token,都以游客模式启动
|
|
|
|
|
|
// 用户信息通过点击登录按钮来设置
|
|
|
|
|
|
addLog('👤 游客模式启动(不做任何处理)');
|
|
|
|
|
|
hadUserIdentifier = false;
|
2026-01-26 11:16:56 +08:00
|
|
|
|
|
2026-01-27 19:03:46 +08:00
|
|
|
|
// 游客模式:不清除任何数据,保留现有会话
|
2026-01-26 11:16:56 +08:00
|
|
|
|
const widgetConfig = {
|
|
|
|
|
|
websiteToken: '<%= @web_widget.website_token %>',
|
|
|
|
|
|
baseUrl: BASE_URL,
|
|
|
|
|
|
locale: 'zh_CN',
|
|
|
|
|
|
useBrowserLanguage: false
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-01-27 19:03:46 +08:00
|
|
|
|
addLog('📝 初始化 widgetConfig (游客模式):');
|
|
|
|
|
|
addLog(' - websiteToken: ' + widgetConfig.websiteToken);
|
|
|
|
|
|
addLog(' - userIdentifier: (未设置)');
|
2026-01-26 11:16:56 +08:00
|
|
|
|
|
|
|
|
|
|
window.chatwootSDK.run(widgetConfig);
|
2026-01-27 19:03:46 +08:00
|
|
|
|
addLog('✅ 游客模式已启动');
|
|
|
|
|
|
updateStatusDisplay();
|
|
|
|
|
|
};
|
|
|
|
|
|
})(document,"script");
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟用户登录
|
|
|
|
|
|
function simulateLogin() {
|
|
|
|
|
|
addLog('🔐 开始模拟用户登录...');
|
|
|
|
|
|
|
|
|
|
|
|
// 设置 token cookie
|
|
|
|
|
|
setCookie('token', TEST_TOKEN);
|
2026-01-26 11:16:56 +08:00
|
|
|
|
|
2026-01-27 19:03:46 +08:00
|
|
|
|
// 验证 token 是否设置成功
|
|
|
|
|
|
const tokenCheck = getCookie('token');
|
|
|
|
|
|
if (tokenCheck) {
|
|
|
|
|
|
addLog('✅ Token 已设置到 cookie');
|
2026-01-26 11:16:56 +08:00
|
|
|
|
|
2026-01-27 19:03:46 +08:00
|
|
|
|
// 设置当前用户状态
|
|
|
|
|
|
isLoggedIn = true;
|
|
|
|
|
|
currentUser = TEST_USER;
|
|
|
|
|
|
|
|
|
|
|
|
addLog('🔄 使用 reset() 清除之前的聊天内容...');
|
|
|
|
|
|
if (window.$chatwoot && window.$chatwoot.reset) {
|
|
|
|
|
|
window.$chatwoot.reset();
|
|
|
|
|
|
addLog('✅ 已清除聊天内容和会话数据');
|
|
|
|
|
|
} else {
|
|
|
|
|
|
addLog('⚠️ Chatwoot reset() 方法不可用');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 等待 reset 完成后设置用户信息
|
2026-01-26 11:16:56 +08:00
|
|
|
|
setTimeout(function() {
|
2026-01-27 19:03:46 +08:00
|
|
|
|
addLog('👤 设置用户信息...');
|
|
|
|
|
|
if (window.$chatwoot && window.$chatwoot.setUser) {
|
|
|
|
|
|
window.$chatwoot.setUser(currentUser.userId, {
|
|
|
|
|
|
identifier_hash: currentUser.userHash,
|
|
|
|
|
|
email: currentUser.email,
|
|
|
|
|
|
name: currentUser.name,
|
2026-01-26 11:16:56 +08:00
|
|
|
|
phone_number: '',
|
2026-01-27 19:03:46 +08:00
|
|
|
|
custom_attributes: {
|
|
|
|
|
|
jwt_token: tokenCheck,
|
|
|
|
|
|
mall_token: tokenCheck,
|
|
|
|
|
|
login_status: 'logged_in'
|
|
|
|
|
|
}
|
2026-01-26 11:16:56 +08:00
|
|
|
|
});
|
2026-01-27 19:03:46 +08:00
|
|
|
|
addLog('✅ 用户信息已设置: ' + currentUser.name);
|
|
|
|
|
|
addLog('✅ 登录成功(无需刷新页面)');
|
|
|
|
|
|
} else {
|
|
|
|
|
|
addLog('⚠️ window.$chatwoot 未就绪');
|
2026-01-26 11:16:56 +08:00
|
|
|
|
}
|
2026-01-27 19:03:46 +08:00
|
|
|
|
updateStatusDisplay();
|
|
|
|
|
|
}, 500);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
addLog('❌ Token 设置失败');
|
2026-01-26 11:16:56 +08:00
|
|
|
|
}
|
2026-01-27 19:03:46 +08:00
|
|
|
|
}
|
2026-01-26 11:16:56 +08:00
|
|
|
|
|
2026-01-27 19:03:46 +08:00
|
|
|
|
// 模拟用户退出
|
|
|
|
|
|
function simulateLogout() {
|
|
|
|
|
|
addLog('🚪 开始模拟用户退出...');
|
2026-01-26 11:16:56 +08:00
|
|
|
|
|
2026-01-27 19:03:46 +08:00
|
|
|
|
// 删除 token cookie
|
|
|
|
|
|
deleteCookie('token');
|
|
|
|
|
|
isLoggedIn = false;
|
|
|
|
|
|
currentUser = null;
|
2026-01-26 11:16:56 +08:00
|
|
|
|
|
2026-01-27 19:03:46 +08:00
|
|
|
|
addLog('✅ Token 已从 cookie 删除');
|
|
|
|
|
|
|
|
|
|
|
|
// 使用 Chatwoot 官方的 reset() 方法清除用户和会话数据
|
|
|
|
|
|
if (window.$chatwoot && window.$chatwoot.reset) {
|
|
|
|
|
|
window.$chatwoot.reset();
|
|
|
|
|
|
addLog('✅ 已调用 Chatwoot reset() - 清除用户和会话数据');
|
|
|
|
|
|
} else {
|
|
|
|
|
|
addLog('⚠️ Chatwoot reset() 方法不可用');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 清除 localStorage 缓存
|
|
|
|
|
|
try {
|
|
|
|
|
|
const keysToRemove = [];
|
|
|
|
|
|
for (let i = 0; i < localStorage.length; i++) {
|
|
|
|
|
|
const key = localStorage.key(i);
|
|
|
|
|
|
if (key && (key.includes('chatwoot') || key.includes('cw_') || key.includes('widget'))) {
|
|
|
|
|
|
keysToRemove.push(key);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
keysToRemove.forEach(key => localStorage.removeItem(key));
|
|
|
|
|
|
addLog('🧹 已清除 ' + keysToRemove.length + ' 个 localStorage 缓存项');
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
addLog('⚠️ 清除缓存时出错: ' + e.message);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
addLog('⏳ 即将刷新页面以完成退出...');
|
|
|
|
|
|
|
|
|
|
|
|
// 显示刷新倒计时
|
|
|
|
|
|
document.getElementById('refreshNotice').classList.remove('hidden');
|
|
|
|
|
|
document.getElementById('cancelRefreshBtn').classList.remove('hidden');
|
|
|
|
|
|
document.getElementById('countdown').textContent = '2';
|
|
|
|
|
|
|
|
|
|
|
|
let countdown = 2;
|
|
|
|
|
|
countdownTimer = setInterval(() => {
|
|
|
|
|
|
countdown--;
|
|
|
|
|
|
document.getElementById('countdown').textContent = countdown;
|
|
|
|
|
|
if (countdown <= 0) {
|
|
|
|
|
|
clearInterval(countdownTimer);
|
|
|
|
|
|
addLog('🔄 正在刷新页面...');
|
|
|
|
|
|
location.reload();
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
|
|
|
|
refreshTimer = setTimeout(() => {
|
|
|
|
|
|
location.reload();
|
|
|
|
|
|
}, 2000);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 取消刷新
|
|
|
|
|
|
function cancelRefresh() {
|
|
|
|
|
|
if (refreshTimer) {
|
|
|
|
|
|
clearTimeout(refreshTimer);
|
|
|
|
|
|
refreshTimer = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (countdownTimer) {
|
|
|
|
|
|
clearInterval(countdownTimer);
|
|
|
|
|
|
countdownTimer = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('refreshNotice').classList.add('hidden');
|
|
|
|
|
|
document.getElementById('cancelRefreshBtn').classList.add('hidden');
|
|
|
|
|
|
|
|
|
|
|
|
addLog('✅ 已取消自动刷新');
|
|
|
|
|
|
addLog('⚠️ 注意:Chatwoot Widget 仍保持登录状态,需要手动刷新页面才能完全恢复游客模式');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 清除所有数据(包括会话)
|
|
|
|
|
|
function clearAllData() {
|
|
|
|
|
|
addLog('🗑️ 开始清除所有数据...');
|
|
|
|
|
|
|
|
|
|
|
|
// 使用 Chatwoot reset() 方法清除会话
|
|
|
|
|
|
if (window.$chatwoot && window.$chatwoot.reset) {
|
|
|
|
|
|
window.$chatwoot.reset();
|
|
|
|
|
|
addLog('✅ 已调用 Chatwoot reset() - 清除会话和用户数据');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 删除 token cookie
|
|
|
|
|
|
deleteCookie('token');
|
|
|
|
|
|
addLog('✅ Token 已删除');
|
|
|
|
|
|
|
|
|
|
|
|
// 清除 localStorage
|
|
|
|
|
|
try {
|
|
|
|
|
|
const keysToRemove = [];
|
|
|
|
|
|
for (let i = 0; i < localStorage.length; i++) {
|
|
|
|
|
|
const key = localStorage.key(i);
|
|
|
|
|
|
if (key && (key.includes('chatwoot') || key.includes('cw_') || key.includes('widget'))) {
|
|
|
|
|
|
keysToRemove.push(key);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
keysToRemove.forEach(key => localStorage.removeItem(key));
|
|
|
|
|
|
addLog('🧹 已清除 ' + keysToRemove.length + ' 个 localStorage 项');
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
addLog('⚠️ 清除 localStorage 时出错: ' + e.message);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
isLoggedIn = false;
|
|
|
|
|
|
currentUser = null;
|
|
|
|
|
|
hadUserIdentifier = false;
|
|
|
|
|
|
|
|
|
|
|
|
updateStatusDisplay();
|
|
|
|
|
|
addLog('✅ 所有数据已清除');
|
|
|
|
|
|
|
|
|
|
|
|
// 刷新页面
|
|
|
|
|
|
addLog('⏳ 即将刷新页面...');
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
location.reload();
|
|
|
|
|
|
}, 500);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 刷新页面
|
|
|
|
|
|
function refreshPage() {
|
|
|
|
|
|
addLog('🔄 正在刷新页面...');
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
location.reload();
|
|
|
|
|
|
}, 500);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打开聊天窗口
|
|
|
|
|
|
function openWidget() {
|
|
|
|
|
|
if (window.$chatwoot && window.$chatwoot.toggle) {
|
|
|
|
|
|
window.$chatwoot.toggle('open');
|
|
|
|
|
|
addLog('💬 聊天窗口已打开');
|
|
|
|
|
|
} else {
|
|
|
|
|
|
addLog('⚠️ Chatwoot 未就绪');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 事件监听
|
|
|
|
|
|
window.addEventListener('chatwoot:ready', function() {
|
|
|
|
|
|
addLog('✅ Chatwoot Widget 已就绪');
|
2026-01-26 11:16:56 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
2026-01-27 19:03:46 +08:00
|
|
|
|
window.addEventListener('chatwoot:on-message', function(e) {
|
|
|
|
|
|
addLog('📨 收到消息');
|
2026-01-26 11:16:56 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
window.addEventListener('chatwoot:opened', function() {
|
2026-01-27 19:03:46 +08:00
|
|
|
|
addLog('🔓 Widget 已打开');
|
2026-01-26 11:16:56 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
window.addEventListener('chatwoot:closed', function() {
|
2026-01-27 19:03:46 +08:00
|
|
|
|
addLog('🔒 Widget 已关闭');
|
2026-01-26 11:16:56 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
2026-01-27 19:03:46 +08:00
|
|
|
|
// 初始化
|
|
|
|
|
|
addLog('🚀 测试页面已加载');
|
2026-01-26 11:16:56 +08:00
|
|
|
|
</script>
|