feat: 添加客服组件
This commit is contained in:
140
src/bytedesk-integration/components/BytedeskWidget.jsx
Normal file
140
src/bytedesk-integration/components/BytedeskWidget.jsx
Normal file
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* Bytedesk客服Widget组件
|
||||
* 用于vf_react项目集成
|
||||
*
|
||||
* 使用方法:
|
||||
* import BytedeskWidget from './components/BytedeskWidget';
|
||||
* import { getBytedeskConfig } from './config/bytedesk.config';
|
||||
*
|
||||
* <BytedeskWidget
|
||||
* config={getBytedeskConfig()}
|
||||
* autoLoad={true}
|
||||
* />
|
||||
*/
|
||||
|
||||
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 <div id="bytedesk-widget-container" style={{ display: 'none' }} />;
|
||||
};
|
||||
|
||||
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;
|
||||
Reference in New Issue
Block a user