diff --git a/src/bytedesk-integration/.env.bytedesk.example b/src/bytedesk-integration/.env.bytedesk.example
new file mode 100644
index 00000000..8bd1a900
--- /dev/null
+++ b/src/bytedesk-integration/.env.bytedesk.example
@@ -0,0 +1,156 @@
+################################################################################
+# Bytedesk客服系统环境变量配置示例
+#
+# 使用方法:
+# 1. 复制本文件到vf_react项目根目录(与package.json同级)
+# cp bytedesk-integration/.env.bytedesk.example .env.local
+#
+# 2. 根据实际部署环境修改配置值
+#
+# 3. 重启开发服务器使配置生效
+# npm start
+#
+# 注意事项:
+# - .env.local文件不应提交到Git(已在.gitignore中)
+# - 开发环境和生产环境应使用不同的配置文件
+# - 所有以REACT_APP_开头的变量会被打包到前端代码中
+################################################################################
+
+# ============================================================================
+# Bytedesk服务器配置(必需)
+# ============================================================================
+
+# Bytedesk后端服务地址(生产环境)
+# 格式: http://IP地址 或 https://域名
+# 示例: http://43.143.189.195 或 https://kefu.yourdomain.com
+REACT_APP_BYTEDESK_API_URL=http://43.143.189.195
+
+# ============================================================================
+# Bytedesk组织和工作组配置(必需)
+# ============================================================================
+
+# 组织ID(Organization UID)
+# 获取方式: 登录管理后台 -> 设置 -> 组织信息 -> 复制UID
+# 示例: df_org_uid
+REACT_APP_BYTEDESK_ORG=df_org_uid
+
+# 工作组ID(Workgroup SID)
+# 获取方式: 登录管理后台 -> 客服管理 -> 工作组 -> 复制工作组ID
+# 示例: df_wg_aftersales (售后服务组)
+REACT_APP_BYTEDESK_SID=df_wg_aftersales
+
+# ============================================================================
+# 可选配置
+# ============================================================================
+
+# 客服类型
+# 2 = 人工客服(默认)
+# 1 = 机器人客服
+# REACT_APP_BYTEDESK_TYPE=2
+
+# 语言设置
+# zh-cn = 简体中文(默认)
+# en = 英语
+# ja = 日语
+# ko = 韩语
+# REACT_APP_BYTEDESK_LOCALE=zh-cn
+
+# 客服图标位置
+# bottom-right = 右下角(默认)
+# bottom-left = 左下角
+# top-right = 右上角
+# top-left = 左上角
+# REACT_APP_BYTEDESK_PLACEMENT=bottom-right
+
+# 客服图标边距(像素)
+# REACT_APP_BYTEDESK_MARGIN_BOTTOM=20
+# REACT_APP_BYTEDESK_MARGIN_SIDE=20
+
+# 主题模式
+# system = 跟随系统(默认)
+# light = 亮色模式
+# dark = 暗色模式
+# REACT_APP_BYTEDESK_THEME_MODE=system
+
+# 主题色(十六进制颜色)
+# REACT_APP_BYTEDESK_THEME_COLOR=#0066FF
+
+# 是否自动弹出客服窗口(不推荐)
+# true = 页面加载后自动弹出
+# false = 需用户点击图标弹出(默认)
+# REACT_APP_BYTEDESK_AUTO_POPUP=false
+
+# ============================================================================
+# 开发环境专用配置
+# ============================================================================
+
+# 开发环境可以使用不同的服务器地址
+# 取消注释以下行使用本地或测试服务器
+# REACT_APP_BYTEDESK_API_URL_DEV=http://localhost:9003
+
+# ============================================================================
+# 配置示例 - 不同部署场景
+# ============================================================================
+
+# ---------- 示例1: 生产环境(域名访问) ----------
+# REACT_APP_BYTEDESK_API_URL=https://kefu.yourdomain.com
+# REACT_APP_BYTEDESK_ORG=prod_org_12345
+# REACT_APP_BYTEDESK_SID=prod_wg_sales
+
+# ---------- 示例2: 测试环境(IP访问) ----------
+# REACT_APP_BYTEDESK_API_URL=http://192.168.1.100
+# REACT_APP_BYTEDESK_ORG=test_org_abc
+# REACT_APP_BYTEDESK_SID=test_wg_support
+
+# ---------- 示例3: 本地开发环境 ----------
+# REACT_APP_BYTEDESK_API_URL=http://localhost:9003
+# REACT_APP_BYTEDESK_ORG=dev_org_local
+# REACT_APP_BYTEDESK_SID=dev_wg_test
+
+# ============================================================================
+# 故障排查
+# ============================================================================
+
+# 问题1: 客服图标不显示
+# 解决方案:
+# - 检查REACT_APP_BYTEDESK_API_URL是否可访问
+# - 确认.env文件在项目根目录
+# - 重启开发服务器(npm start)
+# - 查看浏览器控制台是否有错误
+
+# 问题2: 连接不上后端服务
+# 解决方案:
+# - 确认后端服务已启动(docker ps查看bytedesk-prod容器)
+# - 检查CORS配置(后端.env.production中的BYTEDESK_CORS_ALLOWED_ORIGINS)
+# - 确认防火墙未阻止80/443端口
+
+# 问题3: ORG或SID配置错误
+# 解决方案:
+# - 登录管理后台http://43.143.189.195/admin/
+# - 导航到"设置" -> "组织信息"获取ORG
+# - 导航到"客服管理" -> "工作组"获取SID
+# - 确保复制的ID没有多余空格
+
+# 问题4: 多工作组场景
+# 解决方案:
+# - 可以为不同页面配置不同的SID
+# - 在bytedesk.config.js中使用条件判断
+# - 示例: 售后页面用售后组SID,销售页面用销售组SID
+
+# ============================================================================
+# 安全提示
+# ============================================================================
+
+# 1. 不要在代码中硬编码API地址和ID
+# 2. .env.local文件不应提交到Git仓库
+# 3. 生产环境建议使用HTTPS
+# 4. 定期更新后端服务器的安全补丁
+# 5. 不要在公开的代码库中暴露组织ID和工作组ID
+
+# ============================================================================
+# 更多信息
+# ============================================================================
+
+# Bytedesk官方文档: https://docs.bytedesk.com
+# 技术支持: 访问http://43.143.189.195/chat/联系在线客服
+# GitHub: https://github.com/Bytedesk/bytedesk
diff --git a/src/bytedesk-integration/App.jsx.example b/src/bytedesk-integration/App.jsx.example
new file mode 100644
index 00000000..b7bccc9d
--- /dev/null
+++ b/src/bytedesk-integration/App.jsx.example
@@ -0,0 +1,237 @@
+/**
+ * vf_react App.jsx集成示例
+ *
+ * 本文件展示如何在vf_react项目中集成Bytedesk客服系统
+ *
+ * 集成步骤:
+ * 1. 将bytedesk-integration文件夹复制到src/目录
+ * 2. 在App.jsx中导入BytedeskWidget和配置
+ * 3. 添加BytedeskWidget组件(代码如下)
+ * 4. 配置.env文件(参考.env.bytedesk.example)
+ */
+
+import React, { useState, useEffect } from 'react';
+import { useLocation } from 'react-router-dom'; // 如果使用react-router
+import BytedeskWidget from './bytedesk-integration/components/BytedeskWidget';
+import { getBytedeskConfig, shouldShowCustomerService } from './bytedesk-integration/config/bytedesk.config';
+
+// ============================================================================
+// 方案一: 全局集成(推荐)
+// 适用场景: 客服系统需要在所有页面显示
+// ============================================================================
+
+function App() {
+ // ========== vf_react原有代码保持不变 ==========
+ // 这里是您原有的App.jsx代码
+ // 例如: const [user, setUser] = useState(null);
+ // 例如: const [theme, setTheme] = useState('light');
+ // ... 保持原有逻辑不变 ...
+
+ // ========== Bytedesk集成代码开始 ==========
+
+ const location = useLocation(); // 获取当前路径
+ const [showBytedesk, setShowBytedesk] = useState(false);
+
+ // 根据页面路径决定是否显示客服
+ useEffect(() => {
+ const shouldShow = shouldShowCustomerService(location.pathname);
+ setShowBytedesk(shouldShow);
+ }, [location.pathname]);
+
+ // 获取Bytedesk配置
+ const bytedeskConfig = getBytedeskConfig();
+
+ // 客服加载成功回调
+ const handleBytedeskLoad = (bytedesk) => {
+ console.log('[App] Bytedesk客服系统加载成功', bytedesk);
+ };
+
+ // 客服加载失败回调
+ const handleBytedeskError = (error) => {
+ console.error('[App] Bytedesk客服系统加载失败', error);
+ };
+
+ // ========== Bytedesk集成代码结束 ==========
+
+ return (
+
+ {/* ========== vf_react原有内容保持不变 ========== */}
+ {/* 这里是您原有的App.jsx JSX代码 */}
+ {/* 例如: */}
+ {/* 例如: ... */}
+ {/* ... 保持原有结构不变 ... */}
+
+ {/* ========== Bytedesk客服Widget ========== */}
+ {showBytedesk && (
+
+ )}
+
+ );
+}
+
+export default App;
+
+
+// ============================================================================
+// 方案二: 带用户信息集成
+// 适用场景: 需要将登录用户信息传递给客服端
+// ============================================================================
+
+/*
+import React, { useState, useEffect, useContext } from 'react';
+import { useLocation } from 'react-router-dom';
+import BytedeskWidget from './bytedesk-integration/components/BytedeskWidget';
+import { getBytedeskConfigWithUser, shouldShowCustomerService } from './bytedesk-integration/config/bytedesk.config';
+import { AuthContext } from './contexts/AuthContext'; // 假设您有用户认证Context
+
+function App() {
+ // 获取登录用户信息
+ const { user } = useContext(AuthContext);
+
+ const location = useLocation();
+ const [showBytedesk, setShowBytedesk] = useState(false);
+
+ useEffect(() => {
+ const shouldShow = shouldShowCustomerService(location.pathname);
+ setShowBytedesk(shouldShow);
+ }, [location.pathname]);
+
+ // 根据用户信息生成配置
+ const bytedeskConfig = user
+ ? getBytedeskConfigWithUser(user)
+ : getBytedeskConfig();
+
+ return (
+
+ // ... 您的原有代码 ...
+
+ {showBytedesk && (
+
+ )}
+
+ );
+}
+
+export default App;
+*/
+
+
+// ============================================================================
+// 方案三: 条件性加载
+// 适用场景: 只在特定条件下显示客服(如用户已登录、特定用户角色等)
+// ============================================================================
+
+/*
+import React, { useState, useEffect } from 'react';
+import BytedeskWidget from './bytedesk-integration/components/BytedeskWidget';
+import { getBytedeskConfig } from './bytedesk-integration/config/bytedesk.config';
+
+function App() {
+ const [user, setUser] = useState(null);
+ const [showBytedesk, setShowBytedesk] = useState(false);
+
+ useEffect(() => {
+ // 只有在用户登录且为普通用户时显示客服
+ if (user && user.role === 'customer') {
+ setShowBytedesk(true);
+ } else {
+ setShowBytedesk(false);
+ }
+ }, [user]);
+
+ const bytedeskConfig = getBytedeskConfig();
+
+ return (
+
+ // ... 您的原有代码 ...
+
+ {showBytedesk && (
+
+ )}
+
+ );
+}
+
+export default App;
+*/
+
+
+// ============================================================================
+// 方案四: 动态控制显示/隐藏
+// 适用场景: 需要通过按钮或其他交互控制客服显示
+// ============================================================================
+
+/*
+import React, { useState } from 'react';
+import BytedeskWidget from './bytedesk-integration/components/BytedeskWidget';
+import { getBytedeskConfig } from './bytedesk-integration/config/bytedesk.config';
+
+function App() {
+ const [showBytedesk, setShowBytedesk] = useState(false);
+ const bytedeskConfig = getBytedeskConfig();
+
+ const toggleBytedesk = () => {
+ setShowBytedesk(prev => !prev);
+ };
+
+ return (
+
+ // ... 您的原有代码 ...
+
+ {/* 自定义客服按钮 *\/}
+
+
+ {/* 客服Widget *\/}
+ {showBytedesk && (
+
+ )}
+
+ );
+}
+
+export default App;
+*/
+
+
+// ============================================================================
+// 重要提示
+// ============================================================================
+
+/**
+ * 1. CSS样式兼容性
+ * - Bytedesk Widget使用Shadow DOM,不会影响您的全局样式
+ * - Widget的样式可通过config中的theme配置调整
+ *
+ * 2. 性能优化
+ * - Widget脚本采用异步加载,不会阻塞页面渲染
+ * - 建议在非关键页面(如登录、支付页)隐藏客服
+ *
+ * 3. 错误处理
+ * - 如果客服脚本加载失败,不会影响主应用
+ * - 建议添加onError回调进行错误监控
+ *
+ * 4. 调试模式
+ * - 查看浏览器控制台的[Bytedesk]前缀日志
+ * - 检查Network面板确认脚本加载成功
+ *
+ * 5. 生产部署
+ * - 确保.env文件配置正确(特别是REACT_APP_BYTEDESK_API_URL)
+ * - 确保CORS已在后端配置(允许您的前端域名)
+ * - 在管理后台配置正确的工作组ID(sid)
+ */
diff --git a/src/bytedesk-integration/components/BytedeskWidget.jsx b/src/bytedesk-integration/components/BytedeskWidget.jsx
new file mode 100644
index 00000000..2d0a831b
--- /dev/null
+++ b/src/bytedesk-integration/components/BytedeskWidget.jsx
@@ -0,0 +1,140 @@
+/**
+ * Bytedesk客服Widget组件
+ * 用于vf_react项目集成
+ *
+ * 使用方法:
+ * import BytedeskWidget from './components/BytedeskWidget';
+ * import { getBytedeskConfig } from './config/bytedesk.config';
+ *
+ *
+ */
+
+import { useEffect, useRef } from 'react';
+import PropTypes from 'prop-types';
+
+const BytedeskWidget = ({
+ config,
+ autoLoad = true,
+ onLoad,
+ onError
+}) => {
+ const scriptRef = useRef(null);
+ const widgetRef = useRef(null);
+
+ useEffect(() => {
+ // 如果不自动加载或配置未设置,跳过
+ if (!autoLoad || !config) {
+ if (!config) {
+ console.warn('[Bytedesk] 配置未设置,客服组件未加载');
+ }
+ return;
+ }
+
+ console.log('[Bytedesk] 开始加载客服Widget...', config);
+
+ // 加载Bytedesk Widget脚本
+ const script = document.createElement('script');
+ script.src = 'https://www.weiyuai.cn/embed/bytedesk-web.js';
+ script.async = true;
+ script.id = 'bytedesk-web-script';
+
+ script.onload = () => {
+ console.log('[Bytedesk] Widget脚本加载成功');
+
+ try {
+ if (window.BytedeskWeb) {
+ console.log('[Bytedesk] 初始化Widget');
+ const bytedesk = new window.BytedeskWeb(config);
+ bytedesk.init();
+
+ widgetRef.current = bytedesk;
+ console.log('[Bytedesk] Widget初始化成功');
+
+ if (onLoad) {
+ onLoad(bytedesk);
+ }
+ } else {
+ throw new Error('BytedeskWeb对象未定义');
+ }
+ } catch (error) {
+ console.error('[Bytedesk] Widget初始化失败:', error);
+ if (onError) {
+ onError(error);
+ }
+ }
+ };
+
+ script.onerror = (error) => {
+ console.error('[Bytedesk] Widget脚本加载失败:', error);
+ if (onError) {
+ onError(error);
+ }
+ };
+
+ // 添加脚本到页面
+ document.body.appendChild(script);
+ scriptRef.current = script;
+
+ // 清理函数
+ return () => {
+ console.log('[Bytedesk] 清理Widget');
+
+ // 移除脚本
+ if (scriptRef.current && document.body.contains(scriptRef.current)) {
+ document.body.removeChild(scriptRef.current);
+ }
+
+ // 移除Widget DOM元素
+ const widgetElements = document.querySelectorAll('[class*="bytedesk"], [id*="bytedesk"]');
+ widgetElements.forEach(el => {
+ if (el && el.parentNode) {
+ el.parentNode.removeChild(el);
+ }
+ });
+
+ // 清理全局对象
+ if (window.BytedeskWeb) {
+ delete window.BytedeskWeb;
+ }
+ };
+ }, [config, autoLoad, onLoad, onError]);
+
+ // 不渲染任何可见元素(Widget会自动插入到body)
+ return ;
+};
+
+BytedeskWidget.propTypes = {
+ config: PropTypes.shape({
+ apiUrl: PropTypes.string.isRequired,
+ htmlUrl: PropTypes.string.isRequired,
+ placement: PropTypes.oneOf(['bottom-right', 'bottom-left', 'top-right', 'top-left']),
+ marginBottom: PropTypes.number,
+ marginSide: PropTypes.number,
+ autoPopup: PropTypes.bool,
+ locale: PropTypes.string,
+ bubbleConfig: PropTypes.shape({
+ show: PropTypes.bool,
+ icon: PropTypes.string,
+ title: PropTypes.string,
+ subtitle: PropTypes.string,
+ }),
+ theme: PropTypes.shape({
+ mode: PropTypes.oneOf(['light', 'dark', 'system']),
+ backgroundColor: PropTypes.string,
+ textColor: PropTypes.string,
+ }),
+ chatConfig: PropTypes.shape({
+ org: PropTypes.string.isRequired,
+ t: PropTypes.string.isRequired,
+ sid: PropTypes.string.isRequired,
+ }).isRequired,
+ }),
+ autoLoad: PropTypes.bool,
+ onLoad: PropTypes.func,
+ onError: PropTypes.func,
+};
+
+export default BytedeskWidget;
diff --git a/src/bytedesk-integration/config/bytedesk.config.js b/src/bytedesk-integration/config/bytedesk.config.js
new file mode 100644
index 00000000..e73aae49
--- /dev/null
+++ b/src/bytedesk-integration/config/bytedesk.config.js
@@ -0,0 +1,157 @@
+/**
+ * Bytedesk客服配置文件
+ * 指向43.143.189.195服务器
+ *
+ * 环境变量配置(.env文件):
+ * REACT_APP_BYTEDESK_API_URL=http://43.143.189.195
+ * REACT_APP_BYTEDESK_ORG=df_org_uid
+ * REACT_APP_BYTEDESK_SID=df_wg_aftersales
+ */
+
+// 从环境变量读取配置
+const BYTEDESK_API_URL = process.env.REACT_APP_BYTEDESK_API_URL || 'http://43.143.189.195';
+const BYTEDESK_ORG = process.env.REACT_APP_BYTEDESK_ORG || 'df_org_uid';
+const BYTEDESK_SID = process.env.REACT_APP_BYTEDESK_SID || 'df_wg_aftersales';
+
+/**
+ * Bytedesk客服基础配置
+ */
+export const bytedeskConfig = {
+ // API服务地址
+ apiUrl: BYTEDESK_API_URL,
+ // 聊天页面地址
+ htmlUrl: `${BYTEDESK_API_URL}/chat/`,
+
+ // 客服图标位置
+ placement: 'bottom-right', // bottom-right | bottom-left | top-right | top-left
+
+ // 边距设置(像素)
+ marginBottom: 20,
+ marginSide: 20,
+
+ // 自动弹出(不推荐)
+ autoPopup: false,
+
+ // 语言设置
+ locale: 'zh-cn', // zh-cn | en | ja | ko
+
+ // 客服图标配置
+ bubbleConfig: {
+ show: true, // 是否显示客服图标
+ icon: '💬', // 图标(emoji或图片URL)
+ title: '在线客服', // 鼠标悬停标题
+ subtitle: '点击咨询', // 副标题
+ },
+
+ // 主题配置
+ theme: {
+ mode: 'system', // light | dark | system
+ backgroundColor: '#0066FF', // 主题色
+ textColor: '#ffffff', // 文字颜色
+ },
+
+ // 聊天配置(必需)
+ chatConfig: {
+ org: BYTEDESK_ORG, // 组织ID
+ t: '2', // 类型: 2=客服, 1=机器人
+ sid: BYTEDESK_SID, // 工作组ID
+ },
+};
+
+/**
+ * 获取Bytedesk配置(根据环境自动切换)
+ *
+ * @returns {Object} Bytedesk配置对象
+ */
+export const getBytedeskConfig = () => {
+ // 开发环境配置
+ if (process.env.NODE_ENV === 'development') {
+ return {
+ ...bytedeskConfig,
+ apiUrl: 'http://43.143.189.195', // 指向测试服务器
+ htmlUrl: 'http://43.143.189.195/chat/',
+ };
+ }
+
+ // 生产环境配置
+ return bytedeskConfig;
+};
+
+/**
+ * 获取带用户信息的配置
+ * 用于已登录用户,自动传递用户信息到客服端
+ *
+ * @param {Object} user - 用户对象
+ * @param {string} user.id - 用户ID
+ * @param {string} user.name - 用户名
+ * @param {string} user.email - 用户邮箱
+ * @param {string} user.mobile - 用户手机号
+ * @returns {Object} 带用户信息的Bytedesk配置
+ */
+export const getBytedeskConfigWithUser = (user) => {
+ const config = getBytedeskConfig();
+
+ if (user && user.id) {
+ return {
+ ...config,
+ chatConfig: {
+ ...config.chatConfig,
+ // 传递用户信息(可选)
+ customParams: {
+ userId: user.id,
+ userName: user.name || 'Guest',
+ userEmail: user.email || '',
+ userMobile: user.mobile || '',
+ source: 'web', // 来源标识
+ },
+ },
+ };
+ }
+
+ return config;
+};
+
+/**
+ * 根据页面路径判断是否显示客服
+ *
+ * @param {string} pathname - 当前页面路径
+ * @returns {boolean} 是否显示客服
+ */
+export const shouldShowCustomerService = (pathname) => {
+ // 在以下页面显示客服
+ const allowedPages = [
+ '/', // 首页
+ '/home', // 主页
+ '/products', // 产品页
+ '/pricing', // 价格页
+ '/contact', // 联系我们
+ // 添加其他需要显示客服的页面...
+ ];
+
+ // 在以下页面隐藏客服
+ const blockedPages = [
+ '/login', // 登录页
+ '/register', // 注册页
+ '/payment', // 支付页
+ // 添加其他不需要客服的页面...
+ ];
+
+ // 检查是否在阻止列表
+ if (blockedPages.some(page => pathname.startsWith(page))) {
+ return false;
+ }
+
+ // 检查是否在允许列表(如果列表为空,默认全部显示)
+ if (allowedPages.length === 0) {
+ return true;
+ }
+
+ return allowedPages.some(page => pathname.startsWith(page));
+};
+
+export default {
+ bytedeskConfig,
+ getBytedeskConfig,
+ getBytedeskConfigWithUser,
+ shouldShowCustomerService,
+};