2026-01-14 19:25:22 +08:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
<html lang="zh-CN">
|
|
|
|
|
|
<head>
|
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
|
<title>B2B AI 助手 - 测试页面</title>
|
|
|
|
|
|
<style>
|
|
|
|
|
|
body {
|
|
|
|
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
|
|
|
|
max-width: 1200px;
|
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
|
}
|
|
|
|
|
|
.container {
|
|
|
|
|
|
background: white;
|
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
|
padding: 40px;
|
|
|
|
|
|
box-shadow: 0 10px 40px rgba(0,0,0,0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
h1 {
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.subtitle {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
margin-bottom: 30px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.info-box {
|
|
|
|
|
|
background: #f8f9fa;
|
|
|
|
|
|
border-left: 4px solid #667eea;
|
|
|
|
|
|
padding: 15px 20px;
|
|
|
|
|
|
margin: 20px 0;
|
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.info-box h3 {
|
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
|
color: #667eea;
|
|
|
|
|
|
}
|
|
|
|
|
|
.feature-list {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
|
|
|
|
gap: 20px;
|
|
|
|
|
|
margin: 30px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
.feature-card {
|
|
|
|
|
|
background: #f8f9fa;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
.feature-card h4 {
|
|
|
|
|
|
color: #667eea;
|
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.test-questions {
|
|
|
|
|
|
background: #fff3cd;
|
|
|
|
|
|
border: 1px solid #ffc107;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
margin: 20px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
.test-questions h3 {
|
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
|
color: #856404;
|
|
|
|
|
|
}
|
|
|
|
|
|
.question-list {
|
|
|
|
|
|
list-style: none;
|
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
.question-list li {
|
|
|
|
|
|
background: white;
|
|
|
|
|
|
margin: 10px 0;
|
|
|
|
|
|
padding: 12px 15px;
|
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.3s;
|
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
|
}
|
|
|
|
|
|
.question-list li:hover {
|
|
|
|
|
|
background: #667eea;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
transform: translateX(5px);
|
|
|
|
|
|
}
|
|
|
|
|
|
.status {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
padding: 15px;
|
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
margin: 20px 0;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
}
|
|
|
|
|
|
.status.online {
|
|
|
|
|
|
background: #d4edda;
|
|
|
|
|
|
color: #155724;
|
|
|
|
|
|
}
|
|
|
|
|
|
.status.testing {
|
|
|
|
|
|
background: #fff3cd;
|
|
|
|
|
|
color: #856404;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|
|
|
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
|
|
|
<div class="container">
|
|
|
|
|
|
<h1>🤖 B2B AI 智能客服助手</h1>
|
|
|
|
|
|
<p class="subtitle">基于 LangGraph + MCP 的智能客服系统</p>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="status online">
|
|
|
|
|
|
✅ 系统状态:所有服务运行正常
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-16 16:28:47 +08:00
|
|
|
|
<div id="tokenStatus" class="status testing" style="display: none;">
|
|
|
|
|
|
🍪 Token 状态:检测中...
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-14 19:25:22 +08:00
|
|
|
|
<div class="info-box">
|
|
|
|
|
|
<h3>📝 如何测试</h3>
|
|
|
|
|
|
<ol>
|
|
|
|
|
|
<li>点击右下角的聊天图标打开对话窗口</li>
|
|
|
|
|
|
<li>输入你的名字开始对话</li>
|
|
|
|
|
|
<li>尝试下面的问题测试 AI 能力</li>
|
|
|
|
|
|
<li>查看 AI 如何理解并回答你的问题</li>
|
|
|
|
|
|
</ol>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="test-questions">
|
|
|
|
|
|
<h3>💬 推荐测试问题</h3>
|
|
|
|
|
|
<p style="color: #666; margin-bottom: 15px;">点击以下问题直接复制到聊天窗口:</p>
|
|
|
|
|
|
<ul class="question-list">
|
|
|
|
|
|
<li onclick="copyQuestion(this.textContent)">🕐 你们的营业时间是什么?</li>
|
2026-01-16 16:28:47 +08:00
|
|
|
|
<li onclick="copyQuestion(this.textContent)">📦 我的订单 202071324 怎么样了?</li>
|
|
|
|
|
|
<li onclick="copyQuestion(this.textContent)">🔍 查询订单 202071324</li>
|
2026-01-14 19:25:22 +08:00
|
|
|
|
<li onclick="copyQuestion(this.textContent)">📞 如何联系客服?</li>
|
|
|
|
|
|
<li onclick="copyQuestion(this.textContent)">🛍️ 我想退换货</li>
|
2026-01-16 16:28:47 +08:00
|
|
|
|
<li onclick="copyQuestion(this.textContent)">📦 订单 202071324 的物流信息</li>
|
2026-01-14 19:25:22 +08:00
|
|
|
|
</ul>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="feature-list">
|
|
|
|
|
|
<div class="feature-card">
|
|
|
|
|
|
<h4>🎯 智能意图识别</h4>
|
|
|
|
|
|
<p>自动识别客户需求并分类</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="feature-card">
|
|
|
|
|
|
<h4>📚 知识库查询</h4>
|
|
|
|
|
|
<p>快速检索 FAQ 和政策文档</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="feature-card">
|
|
|
|
|
|
<h4>📦 订单管理</h4>
|
|
|
|
|
|
<p>查询订单、售后等服务</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="feature-card">
|
|
|
|
|
|
<h4>🔄 多轮对话</h4>
|
|
|
|
|
|
<p>支持上下文理解的连续对话</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="info-box">
|
|
|
|
|
|
<h3>🔧 技术栈</h3>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<li><strong>前端:</strong>Chatwoot 客户支持平台</li>
|
|
|
|
|
|
<li><strong>AI 引擎:</strong>LangGraph + 智谱 AI (GLM-4.5)</li>
|
|
|
|
|
|
<li><strong>知识库:</strong>Strapi CMS + MCP</li>
|
|
|
|
|
|
<li><strong>业务系统:</strong>Hyperf PHP API</li>
|
|
|
|
|
|
<li><strong>缓存:</strong>Redis</li>
|
|
|
|
|
|
<li><strong>容器:</strong>Docker Compose</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
function copyQuestion(text) {
|
|
|
|
|
|
// 移除表情符号
|
|
|
|
|
|
const cleanText = text.replace(/^[^\s]+\s*/, '');
|
|
|
|
|
|
navigator.clipboard.writeText(cleanText).then(() => {
|
|
|
|
|
|
alert('问题已复制!请粘贴到聊天窗口中发送。');
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2026-01-16 16:28:47 +08:00
|
|
|
|
|
|
|
|
|
|
// ==================== Cookie Token 读取 ====================
|
|
|
|
|
|
|
|
|
|
|
|
function getCookie(name) {
|
|
|
|
|
|
const value = `; ${document.cookie}`;
|
|
|
|
|
|
const parts = value.split(`; ${name}=`);
|
|
|
|
|
|
if (parts.length === 2) return parts.pop().split(";").shift();
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function checkToken() {
|
|
|
|
|
|
const token = getCookie('token');
|
|
|
|
|
|
const statusDiv = document.getElementById('tokenStatus');
|
|
|
|
|
|
|
|
|
|
|
|
if (token) {
|
|
|
|
|
|
statusDiv.style.display = 'block';
|
|
|
|
|
|
statusDiv.className = 'status online';
|
|
|
|
|
|
statusDiv.innerHTML = `✅ Token 已找到 | 长度: ${token.length} 字符 | 前缀: ${token.substring(0, 20)}...`;
|
|
|
|
|
|
// 存储到 window 供后续使用
|
|
|
|
|
|
window._chatwootUserToken = token;
|
|
|
|
|
|
console.log('✅ Token 已从 Cookie 读取');
|
|
|
|
|
|
} else {
|
|
|
|
|
|
statusDiv.style.display = 'block';
|
|
|
|
|
|
statusDiv.className = 'status testing';
|
|
|
|
|
|
statusDiv.innerHTML = '⚠️ 未找到 Token | 请确保已登录商城 | Cookie 名称: token';
|
|
|
|
|
|
console.warn('⚠️ 未找到 Token,订单查询功能可能无法使用');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 页面加载时检查 Token
|
|
|
|
|
|
window.addEventListener('load', function() {
|
|
|
|
|
|
setTimeout(checkToken, 1000);
|
|
|
|
|
|
});
|
2026-01-14 19:25:22 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
2026-01-16 16:28:47 +08:00
|
|
|
|
<!-- Chatwoot Widget - 官方集成方式 -->
|
2026-01-14 19:25:22 +08:00
|
|
|
|
<script>
|
2026-01-16 16:28:47 +08:00
|
|
|
|
(function(d,t) {
|
|
|
|
|
|
var BASE_URL="http://localhost:3000";
|
|
|
|
|
|
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(){
|
|
|
|
|
|
window.chatwootSDK.run({
|
|
|
|
|
|
websiteToken: '39PNCMvbMk3NvB7uaDNucc6o',
|
|
|
|
|
|
baseUrl: BASE_URL,
|
|
|
|
|
|
locale: 'zh_CN',
|
|
|
|
|
|
userIdentifier: getCookie('token') || 'web_user_' + Date.now()
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const userToken = getCookie('token');
|
|
|
|
|
|
console.log('✅ Chatwoot Widget 已加载 (官方集成方式)');
|
|
|
|
|
|
console.log('Base URL:', BASE_URL);
|
|
|
|
|
|
console.log('Website Token: 39PNCMvbMk3NvB7uaDNucc6o');
|
|
|
|
|
|
console.log('Locale: zh_CN');
|
|
|
|
|
|
console.log('User Identifier:', userToken || 'web_user_' + Date.now());
|
|
|
|
|
|
|
|
|
|
|
|
// 设置用户信息(可选)
|
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
|
const token = getCookie('token');
|
|
|
|
|
|
if (token && window.$chatwoot) {
|
|
|
|
|
|
window.$chatwoot.setUser('user_' + Date.now(), {
|
|
|
|
|
|
email: 'user@example.com',
|
|
|
|
|
|
name: 'Website User',
|
|
|
|
|
|
phone_number: ''
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
console.log('✅ 用户信息已设置');
|
|
|
|
|
|
} else if (!token) {
|
|
|
|
|
|
console.warn('⚠️ 未找到 Token');
|
2026-01-14 19:25:22 +08:00
|
|
|
|
}
|
2026-01-16 16:28:47 +08:00
|
|
|
|
}, 2000);
|
|
|
|
|
|
}
|
|
|
|
|
|
g.onerror=function(){
|
|
|
|
|
|
console.error('❌ Chatwoot SDK 加载失败');
|
|
|
|
|
|
console.error('请确保 Chatwoot 运行在: ' + BASE_URL);
|
|
|
|
|
|
}
|
|
|
|
|
|
})(document,"script");
|
2026-01-14 19:25:22 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
</body>
|
|
|
|
|
|
</html>
|