From e753437b86c160d142dbe197a1ae0685957ebf5f Mon Sep 17 00:00:00 2001
From: zdl <3489966805@qq.com>
Date: Thu, 20 Nov 2025 14:30:52 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E8=B0=83=E6=95=B4=E5=AE=A2=E6=9C=8D?=
=?UTF-8?q?=E9=85=8D=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.env.production | 33 +--
src/bytedesk-integration/App.jsx.example | 237 ------------------
.../config/bytedesk.config.js | 66 +----
src/components/GlobalComponents.js | 13 +-
4 files changed, 13 insertions(+), 336 deletions(-)
delete mode 100644 src/bytedesk-integration/App.jsx.example
diff --git a/.env.production b/.env.production
index 272cb4db..3eb056e9 100644
--- a/.env.production
+++ b/.env.production
@@ -1,13 +1,6 @@
# ========================================
# 生产环境配置
# ========================================
-# 使用方式: npm run build
-#
-# 工作原理:
-# 1. 此文件专门用于生产环境构建
-# 2. 构建时会将环境变量嵌入到打包文件中
-# 3. 确保 PostHog 等服务使用正确的生产配置
-# ========================================
# 环境标识
REACT_APP_ENV=production
@@ -17,13 +10,8 @@ NODE_ENV=production
REACT_APP_ENABLE_MOCK=false
# 🔧 调试模式(生产环境临时调试用)
-# 开启后会在全局暴露 window.__DEBUG__ 和 window.__TEST_NOTIFICATION__ 调试 API
-# ⚠️ 警告: 调试模式会记录所有 API 请求/响应,调试完成后请立即关闭!
-# 使用方法:
-# 1. 设置为 true 并重新构建
-# 2. 在浏览器控制台使用 window.__DEBUG__.help() 查看命令
-# 3. 调试完成后设置为 false 并重新构建
-REACT_APP_ENABLE_DEBUG=true
+# 开启后会在全局暴露 window.__DEBUG__
+REACT_APP_ENABLE_DEBUG=false
# 后端 API 地址(生产环境)
REACT_APP_API_URL=http://49.232.185.254:5001
@@ -49,20 +37,3 @@ TSC_COMPILE_ON_ERROR=true
IMAGE_INLINE_SIZE_LIMIT=10000
# Node.js 内存限制(适用于大型项目)
NODE_OPTIONS=--max_old_space_size=4096
-
-# ========================================
-# Bytedesk 客服系统配置
-# ========================================
-# Bytedesk 服务器地址(使用相对路径,通过 Nginx 代理)
-# ⚠️ 重要:生产环境必须使用相对路径,避免 Mixed Content 错误
-# Nginx 配置:location /bytedesk-api/ { proxy_pass http://43.143.189.195/; }
-REACT_APP_BYTEDESK_API_URL=/bytedesk-api
-
-# 组织 UUID(从管理后台 -> 设置 -> 组织信息 -> 组织UUID)
-REACT_APP_BYTEDESK_ORG=df_org_uid
-
-# 工作组 UUID(从管理后台 -> 客服管理 -> 工作组 -> 工作组UUID)
-REACT_APP_BYTEDESK_SID=df_wg_uid
-
-# 客服类型(2=人工客服, 1=机器人)
-REACT_APP_BYTEDESK_TYPE=2
diff --git a/src/bytedesk-integration/App.jsx.example b/src/bytedesk-integration/App.jsx.example
deleted file mode 100644
index b7bccc9d..00000000
--- a/src/bytedesk-integration/App.jsx.example
+++ /dev/null
@@ -1,237 +0,0 @@
-/**
- * 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/config/bytedesk.config.js b/src/bytedesk-integration/config/bytedesk.config.js
index 2a433f4b..727123ff 100644
--- a/src/bytedesk-integration/config/bytedesk.config.js
+++ b/src/bytedesk-integration/config/bytedesk.config.js
@@ -1,27 +1,10 @@
/**
* Bytedesk客服配置文件
* 通过代理访问 Bytedesk 服务器(解决 HTTPS 混合内容问题)
- *
- * 环境变量配置(.env文件):
- * REACT_APP_BYTEDESK_ORG=df_org_uid
- * REACT_APP_BYTEDESK_SID=df_wg_uid
- *
- * 架构说明:
- * - iframe 使用完整域名:https://valuefrontier.cn/bytedesk/chat/
- * - 使用 HTTPS 协议,解决生产环境 Mixed Content 错误
- * - 本地:CRACO 代理 /bytedesk → valuefrontier.cn/bytedesk
- * - 生产:前端 Nginx 代理 /bytedesk → 43.143.189.195
- * - baseUrl 保持官方 CDN(用于加载 SDK 外部模块)
- *
- * ⚠️ 注意:需要前端 Nginx 配置 /bytedesk/ 代理规则
- */
-
-// 从环境变量读取配置
-const BYTEDESK_ORG = process.env.REACT_APP_BYTEDESK_ORG || 'df_org_uid';
-const BYTEDESK_SID = process.env.REACT_APP_BYTEDESK_SID || 'df_wg_uid';
-
-/**
- * Bytedesk客服基础配置
+ - iframe 使用完整域名:https://valuefrontier.cn/bytedesk/chat/
+ - 使用 HTTPS 协议,解决生产环境 Mixed Content 错误
+ - 生产:前端 Nginx 代理 /bytedesk → 43.143.189.195
+ - baseUrl 保持官方 CDN(用于加载 SDK 外部模块)
*/
export const bytedeskConfig = {
// API服务地址(如果 SDK 需要调用 API)
@@ -61,9 +44,9 @@ export const bytedeskConfig = {
// 聊天配置(必需)
chatConfig: {
- org: BYTEDESK_ORG, // 组织ID
+ org: df_org_uid, // 组织ID
t: '1', // 类型: 1=人工客服, 2=机器人
- sid: BYTEDESK_SID, // 工作组ID
+ sid: df_wg_uid, // 工作组ID
},
};
@@ -111,45 +94,8 @@ export const getBytedeskConfigWithUser = (user) => {
return config;
};
-/**
- * 根据页面路径判断是否显示客服
- *
- * @param {string} pathname - 当前页面路径
- * @returns {boolean} 是否显示客服
- */
-export const shouldShowCustomerService = (pathname) => {
- // 在以下页面隐藏客服(黑名单)
- const blockedPages = [
- // '/home', // 登录页
- ];
-
- // 检查是否在黑名单
- if (blockedPages.some(page => pathname.startsWith(page))) {
- return false;
- }
-
- // 默认所有页面都显示客服
- return true;
-
- /* ============================================
- 白名单模式(备用,需要时取消注释)
- ============================================
- const allowedPages = [
- '/', // 首页
- '/home', // 主页
- '/products', // 产品页
- '/pricing', // 价格页
- '/contact', // 联系我们
- ];
-
- // 只在白名单页面显示客服
- return allowedPages.some(page => pathname.startsWith(page));
- ============================================ */
-};
-
export default {
bytedeskConfig,
getBytedeskConfig,
getBytedeskConfigWithUser,
- shouldShowCustomerService,
};
diff --git a/src/components/GlobalComponents.js b/src/components/GlobalComponents.js
index f6231c23..8ca4e954 100644
--- a/src/components/GlobalComponents.js
+++ b/src/components/GlobalComponents.js
@@ -14,7 +14,7 @@ import ScrollToTop from './ScrollToTop';
// Bytedesk客服组件
import BytedeskWidget from '../bytedesk-integration/components/BytedeskWidget';
-import { getBytedeskConfig, shouldShowCustomerService } from '../bytedesk-integration/config/bytedesk.config';
+import { getBytedeskConfig } from '../bytedesk-integration/config/bytedesk.config';
/**
* ConnectionStatusBar 包装组件
@@ -74,7 +74,6 @@ function ConnectionStatusBarWrapper() {
*/
export function GlobalComponents() {
const location = useLocation();
- const showBytedesk = shouldShowCustomerService(location.pathname);
return (
<>
@@ -91,12 +90,10 @@ export function GlobalComponents() {
{/* Bytedesk在线客服 - 根据路径条件性显示 */}
- {showBytedesk && (
-
- )}
+
>
);
}