新增 Bytedesk 在线客服功能,支持实时对话: 组件: - BytedeskWidget: 客服浮窗组件(右下角) - 配置文件: bytedesk.config.js 统一管理配置 - 环境变量示例: .env.bytedesk.example 集成方式: - GlobalComponents 引入 BytedeskWidget - public/index.html 加载 bytedesk-web.js 脚本 - 支持环境变量配置(ORG、SID、API_URL) 配置说明详见 src/bytedesk-integration/.env.bytedesk.example 🔧 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
262 lines
8.8 KiB
HTML
Executable File
262 lines
8.8 KiB
HTML
Executable File
<!--
|
||
/*!
|
||
|
||
=========================================================
|
||
* Argon Dashboard Chakra PRO - v1.0.0
|
||
=========================================================
|
||
|
||
* Product Page: https://www.creative-tim.com/product/argon-dashboard-chakra-pro
|
||
* Copyright 2022 Creative Tim (https://www.creative-tim.com/)
|
||
|
||
* Designed and Coded by Simmmple & Creative Tim
|
||
|
||
=========================================================
|
||
|
||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||
|
||
*/
|
||
-->
|
||
<!DOCTYPE html>
|
||
<html lang="en" dir="ltr" layout="admin">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta
|
||
name="viewport"
|
||
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||
/>
|
||
<meta name="theme-color" content="#000000" />
|
||
<!--
|
||
manifest.json provides metadata used when your web app is added to the
|
||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||
-->
|
||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.png" />
|
||
<link
|
||
rel="apple-touch-icon"
|
||
sizes="76x76"
|
||
href="%PUBLIC_URL%/apple-icon.png"
|
||
/>
|
||
|
||
|
||
|
||
<link rel="shortcut icon" type="image/x-icon" href="./favicon.png" />
|
||
|
||
<!--
|
||
Notice the use of %PUBLIC_URL% in the tags above.
|
||
It will be replaced with the URL of the `public` folder during the build.
|
||
Only files inside the `public` folder can be referenced from the HTML.
|
||
|
||
Unlike "/favicon.png" or "favicon.png", "%PUBLIC_URL%/favicon.png" will
|
||
work correctly both with client-side routing and a non-root public URL.
|
||
Learn how to configure a non-root public URL by running `npm run build`.
|
||
-->
|
||
<title>价值前沿——LLM赋能的分析平台</title>
|
||
</head>
|
||
<body>
|
||
<noscript> You need to enable JavaScript to run this app. </noscript>
|
||
<div id="root"></div>
|
||
<!--
|
||
This HTML file is a template.
|
||
If you open it directly in the browser, you will see an empty page.
|
||
|
||
You can add webfonts, meta tags, or analytics to this file.
|
||
The build step will place the bundled scripts into the <body> tag.
|
||
|
||
To begin the development, run `npm start` or `yarn start`.
|
||
To create a production bundle, use `npm run build` or `yarn build`.
|
||
-->
|
||
<script>
|
||
window.difyChatbotConfig = {
|
||
token: 'DwN8qAKtYFQtWskM',
|
||
baseUrl: 'https://app.valuefrontier.cn',
|
||
inputs: {
|
||
// You can define the inputs from the Start node here
|
||
// key is the variable name
|
||
// e.g.
|
||
// name: "NAME"
|
||
},
|
||
systemVariables: {
|
||
// user_id: 'YOU CAN DEFINE USER ID HERE',
|
||
// conversation_id: 'YOU CAN DEFINE CONVERSATION ID HERE, IT MUST BE A VALID UUID',
|
||
},
|
||
userVariables: {
|
||
// avatar_url: 'YOU CAN DEFINE USER AVATAR URL HERE',
|
||
// name: 'YOU CAN DEFINE USER NAME HERE',
|
||
},
|
||
}
|
||
|
||
// 根据路径控制Dify机器人显示(只在首页/和home页/home显示)
|
||
function controlDifyChatbot() {
|
||
const path = window.location.pathname;
|
||
const chatbotButton = document.getElementById('dify-chatbot-bubble-button');
|
||
const chatbotWindow = document.getElementById('dify-chatbot-bubble-window');
|
||
|
||
// 只在首页(/)和home页(/home)显示Dify机器人
|
||
// const shouldShowDify = (path === '/' || path === '/home');
|
||
// 完全不显示Dify机器人(只使用Bytedesk客服)
|
||
const shouldShowDify = false
|
||
|
||
if (chatbotButton) {
|
||
chatbotButton.style.display = shouldShowDify ? 'block' : 'none';
|
||
// 同时设置visibility确保完全隐藏
|
||
chatbotButton.style.visibility = shouldShowDify ? 'visible' : 'hidden';
|
||
}
|
||
|
||
if (chatbotWindow) {
|
||
chatbotWindow.style.display = shouldShowDify ? '' : 'none';
|
||
}
|
||
|
||
console.log('[Dify] Path:', path, 'Should show:', shouldShowDify, 'Button found:', !!chatbotButton);
|
||
}
|
||
|
||
// 轮询检查Dify按钮(因为Dify脚本加载是异步的)
|
||
let difyCheckCount = 0;
|
||
const difyCheckInterval = setInterval(function() {
|
||
const button = document.getElementById('dify-chatbot-bubble-button');
|
||
if (button || difyCheckCount > 50) { // 最多检查5秒
|
||
if (button) {
|
||
console.log('[Dify] Button found, applying control');
|
||
controlDifyChatbot();
|
||
}
|
||
clearInterval(difyCheckInterval);
|
||
}
|
||
difyCheckCount++;
|
||
}, 100);
|
||
|
||
// 页面加载时执行
|
||
window.addEventListener('load', function() {
|
||
setTimeout(controlDifyChatbot, 1000);
|
||
});
|
||
|
||
// 监听路由变化(React Router使用pushState)
|
||
window.addEventListener('popstate', controlDifyChatbot);
|
||
|
||
// 监听pushState和replaceState(捕获React Router导航)
|
||
const originalPushState = history.pushState;
|
||
const originalReplaceState = history.replaceState;
|
||
|
||
history.pushState = function() {
|
||
originalPushState.apply(history, arguments);
|
||
setTimeout(controlDifyChatbot, 50);
|
||
};
|
||
|
||
history.replaceState = function() {
|
||
originalReplaceState.apply(history, arguments);
|
||
setTimeout(controlDifyChatbot, 50);
|
||
};
|
||
|
||
// 使用MutationObserver监听DOM变化(捕获Dify按钮插入)
|
||
const observer = new MutationObserver(function(mutations) {
|
||
for (const mutation of mutations) {
|
||
if (mutation.addedNodes.length > 0) {
|
||
for (const node of mutation.addedNodes) {
|
||
if (node.id && (node.id.includes('dify') || node.id.includes('chatbot'))) {
|
||
console.log('[Dify] Detected chatbot element insertion:', node.id);
|
||
setTimeout(controlDifyChatbot, 100);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// 观察body的变化
|
||
window.addEventListener('DOMContentLoaded', function() {
|
||
observer.observe(document.body, {
|
||
childList: true,
|
||
subtree: true,
|
||
attributes: false
|
||
});
|
||
});
|
||
</script>
|
||
<script
|
||
src="https://app.valuefrontier.cn/embed.min.js"
|
||
id="DwN8qAKtYFQtWskM"
|
||
defer>
|
||
</script>
|
||
<style>
|
||
#dify-chatbot-bubble-button {
|
||
background-color: #1C64F2 !important;
|
||
width: 60px !important;
|
||
height: 60px !important;
|
||
box-shadow: 0 4px 12px rgba(28, 100, 242, 0.3) !important;
|
||
transition: all 0.3s ease !important;
|
||
}
|
||
|
||
#dify-chatbot-bubble-button:hover {
|
||
transform: scale(1.1) !important;
|
||
box-shadow: 0 6px 16px rgba(28, 100, 242, 0.4) !important;
|
||
}
|
||
|
||
#dify-chatbot-bubble-window {
|
||
width: 42rem !important;
|
||
height: 80vh !important;
|
||
max-height: calc(100vh - 2rem) !important;
|
||
position: fixed !important;
|
||
bottom: 100px !important;
|
||
right: 20px !important;
|
||
border-radius: 16px !important;
|
||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15) !important;
|
||
border: 1px solid rgba(28, 100, 242, 0.1) !important;
|
||
z-index: 9999 !important;
|
||
}
|
||
|
||
/* 确保Dify聊天窗口中的超链接正确显示 */
|
||
#dify-chatbot-bubble-window a,
|
||
#dify-chatbot-bubble-window a:link,
|
||
#dify-chatbot-bubble-window a:visited,
|
||
#dify-chatbot-bubble-window a:hover,
|
||
#dify-chatbot-bubble-window a:active {
|
||
color: #1C64F2 !important;
|
||
text-decoration: underline !important;
|
||
cursor: pointer !important;
|
||
pointer-events: auto !important;
|
||
}
|
||
|
||
/* 确保超链接在Dify消息区域中可见 */
|
||
#dify-chatbot-bubble-window .message-content a,
|
||
#dify-chatbot-bubble-window .markdown-content a,
|
||
#dify-chatbot-bubble-window [class*="message"] a {
|
||
color: #0066cc !important;
|
||
text-decoration: underline !important;
|
||
font-weight: 500 !important;
|
||
}
|
||
|
||
/* 桌面端大屏优化 */
|
||
@media (min-width: 1440px) {
|
||
#dify-chatbot-bubble-window {
|
||
width: 45rem !important;
|
||
height: 85vh !important;
|
||
}
|
||
}
|
||
|
||
/* 平板端适配 */
|
||
@media (max-width: 1024px) and (min-width: 641px) {
|
||
#dify-chatbot-bubble-window {
|
||
width: 38rem !important;
|
||
height: 75vh !important;
|
||
right: 15px !important;
|
||
bottom: 90px !important;
|
||
}
|
||
}
|
||
|
||
/* 移动端适配 */
|
||
@media (max-width: 640px) {
|
||
#dify-chatbot-bubble-window {
|
||
width: calc(100vw - 20px) !important;
|
||
height: 85vh !important;
|
||
max-height: 85vh !important;
|
||
right: 10px !important;
|
||
bottom: 80px !important;
|
||
left: 10px !important;
|
||
}
|
||
|
||
#dify-chatbot-bubble-button {
|
||
width: 56px !important;
|
||
height: 56px !important;
|
||
}
|
||
}
|
||
</style>
|
||
</body>
|
||
</html>
|