diff --git a/craco.config.js b/craco.config.js index ea05ae1e..6db9ef20 100644 --- a/craco.config.js +++ b/craco.config.js @@ -284,9 +284,19 @@ module.exports = { }, // 代理配置:将 /api 请求代理到后端服务器 - // 注意:Mock 模式下禁用 proxy,让 MSW 拦截请求 - ...(isMockMode() ? {} : { - proxy: { + // 注意:Mock 模式下禁用 /api 和 /concept-api,让 MSW 拦截请求 + // 但 /bytedesk 始终启用(客服系统不走 Mock) + proxy: { + '/bytedesk': { + target: 'https://valuefrontier.cn', // 统一使用生产环境 Nginx 代理 + changeOrigin: true, + secure: false, // 开发环境禁用 HTTPS 严格验证 + logLevel: 'debug', + ws: true, // 支持 WebSocket + // 不使用 pathRewrite,保留 /bytedesk 前缀,让生产 Nginx 处理 + }, + // Mock 模式下禁用其他代理 + ...(isMockMode() ? {} : { '/api': { target: 'http://49.232.185.254:5001', changeOrigin: true, @@ -300,15 +310,7 @@ module.exports = { logLevel: 'debug', pathRewrite: { '^/concept-api': '' }, }, - '/bytedesk': { - target: 'https://valuefrontier.cn', // 统一使用生产环境 Nginx 代理 - changeOrigin: true, - secure: false, // 开发环境禁用 HTTPS 严格验证 - logLevel: 'debug', - ws: true, // 支持 WebSocket - // 不使用 pathRewrite,保留 /bytedesk 前缀,让生产 Nginx 处理 - }, - }, - }), + }), + }, }, }; diff --git a/src/bytedesk-integration/components/BytedeskWidget.jsx b/src/bytedesk-integration/components/BytedeskWidget.jsx index 2d0a831b..38a56855 100644 --- a/src/bytedesk-integration/components/BytedeskWidget.jsx +++ b/src/bytedesk-integration/components/BytedeskWidget.jsx @@ -78,26 +78,43 @@ const BytedeskWidget = ({ document.body.appendChild(script); scriptRef.current = script; - // 清理函数 + // 清理函数 - 增强错误处理,防止 React 18 StrictMode 双重清理报错 return () => { console.log('[Bytedesk] 清理Widget'); // 移除脚本 - if (scriptRef.current && document.body.contains(scriptRef.current)) { - document.body.removeChild(scriptRef.current); + try { + if (scriptRef.current && scriptRef.current.parentNode) { + scriptRef.current.parentNode.removeChild(scriptRef.current); + } + scriptRef.current = null; + } catch (error) { + console.warn('[Bytedesk] 移除脚本失败(可能已被移除):', error.message); } // 移除Widget DOM元素 - const widgetElements = document.querySelectorAll('[class*="bytedesk"], [id*="bytedesk"]'); - widgetElements.forEach(el => { - if (el && el.parentNode) { - el.parentNode.removeChild(el); - } - }); + try { + const widgetElements = document.querySelectorAll('[class*="bytedesk"], [id*="bytedesk"]'); + widgetElements.forEach(el => { + try { + if (el && el.parentNode && el.parentNode.contains(el)) { + el.parentNode.removeChild(el); + } + } catch (err) { + // 忽略单个元素移除失败(可能已被移除) + } + }); + } catch (error) { + console.warn('[Bytedesk] 清理Widget DOM元素失败:', error.message); + } // 清理全局对象 - if (window.BytedeskWeb) { - delete window.BytedeskWeb; + try { + if (window.BytedeskWeb) { + delete window.BytedeskWeb; + } + } catch (error) { + console.warn('[Bytedesk] 清理全局对象失败:', error.message); } }; }, [config, autoLoad, onLoad, onError]);