// src/components/GlobalComponents.js // 集中管理应用的全局组件 import React from 'react'; import { useLocation } from 'react-router-dom'; import { useNotification } from '../contexts/NotificationContext'; import { logger } from '../utils/logger'; // Global Components import AuthModalManager from './Auth/AuthModalManager'; import NotificationContainer from './NotificationContainer'; import ConnectionStatusBar from './ConnectionStatusBar'; import ScrollToTop from './ScrollToTop'; // Bytedesk客服组件 import BytedeskWidget from '../bytedesk-integration/components/BytedeskWidget'; import { getBytedeskConfig, shouldShowCustomerService } from '../bytedesk-integration/config/bytedesk.config'; /** * ConnectionStatusBar 包装组件 * 需要在 NotificationProvider 内部使用,所以在这里包装 */ function ConnectionStatusBarWrapper() { const { connectionStatus, reconnectAttempt, maxReconnectAttempts, retryConnection } = useNotification(); const [isDismissed, setIsDismissed] = React.useState(false); // 监听连接状态变化 React.useEffect(() => { // 重连成功后,清除 dismissed 状态 if (connectionStatus === 'connected' && isDismissed) { setIsDismissed(false); // 从 localStorage 清除 dismissed 标记 localStorage.removeItem('connection_status_dismissed'); } // 从 localStorage 恢复 dismissed 状态 if (connectionStatus !== 'connected' && !isDismissed) { const dismissed = localStorage.getItem('connection_status_dismissed'); if (dismissed === 'true') { setIsDismissed(true); } } }, [connectionStatus, isDismissed]); const handleClose = () => { // 用户手动关闭,保存到 localStorage setIsDismissed(true); localStorage.setItem('connection_status_dismissed', 'true'); logger.info('App', 'Connection status bar dismissed by user'); }; return ( ); } /** * GlobalComponents - 全局组件容器 * 集中管理所有全局级别的组件,如弹窗、通知、状态栏等 * * 包含的组件: * - ConnectionStatusBarWrapper: Socket 连接状态条 * - ScrollToTop: 路由切换时自动滚动到顶部 * - AuthModalManager: 认证弹窗管理器 * - NotificationContainer: 通知容器 * - BytedeskWidget: Bytedesk在线客服 (条件性显示,在/和/home页隐藏) */ export function GlobalComponents() { const location = useLocation(); const showBytedesk = shouldShowCustomerService(location.pathname); return ( <> {/* Socket 连接状态条 */} {/* 路由切换时自动滚动到顶部 */} {/* 认证弹窗管理器 */} {/* 通知容器 */} {/* Bytedesk在线客服 - 根据路径条件性显示 */} {showBytedesk && ( )} ); } export default GlobalComponents;