import { useState, useEffect, ReactNode } from 'react'; import { useLaunch } from '@tarojs/taro'; import { IntlProvider } from 'react-intl'; import { ConfigProvider, Button } from 'antd'; import { Provider } from 'react-redux'; import store, { useAppDispatch, useAppSelector } from './states/store'; import { initializeProductState } from './states/productSlice'; import { loadI18nMessages } from './states/i18nSlice'; import './app.css'; import ProductSelector from './components/ProductSelector'; import { setTheme } from './states/themeSlice'; import QuotaAlertModal from './pages/security/QuotaAlertModal'; import AcquisitionTracer from './pages/exam/components/acquisitionTracer'; import FeatureNotAvailableFeedback from './components/FeatureNotAvailableFeedback'; import { setFeatureNotAvailableOpen } from './states/featureNotAvailableSlice'; import { setBusinessFlow } from './states/BusinessFlowSlice'; import { logger } from './log/logger'; console.log = logger.log; console.warn = logger.warn; console.error = logger.error; console.log(`process.env.USE_MSW: ${process.env.USE_MSW}`); console.log(`process.env.NODE_ENV: ${process.env.NODE_ENV}`); if (process.env.NODE_ENV === 'development' && process.env.USE_MSW === 'true') { import('../mocks/server') .then(({ server }): void => { server.start({ onUnhandledRequest: 'error', // 未处理的请求触发网络错误 }); console.log(`启动了MSW`); }) .catch((err): void => { console.warn('Mock server module not found:', err); }); } function AppContent({ children }: { children: ReactNode }): JSX.Element { const dispatch = useAppDispatch(); const { messages, loading, error, currentLocale } = useAppSelector( (state) => state.i18n ); const isFeatureNotAvailableOpen = useAppSelector( (state) => state.featureNotAvailable.isOpen ); const { currentTheme, themeType } = useAppSelector((state) => state.theme); const [isI18nReady, setIsI18nReady] = useState(false); useLaunch((): void => { console.log('App launched.'); }); useEffect(() => { // 先加载软件信息获取语言设置 store .dispatch(initializeProductState()) .unwrap() .then((productState) => { console.log(`初始化,拉取到产品信息:${JSON.stringify(productState)}`); // 从 current_locale 提取语言代码 const languageCode = productState.language; return dispatch(loadI18nMessages(languageCode)).unwrap(); }) .then(() => { setIsI18nReady(true); }) .catch((error) => { console.error('初始化失败:', error); // 阻止加载后面的页面 setIsI18nReady(false); }); }, [dispatch]); console.log('当前语言:', currentLocale); console.log('messages', messages); // children 是将要会渲染的页面 // IntlProvider 始终存在,使用默认值避免 useIntl 报错 return ( en,提供默认值 messages={(messages as Record) || {}} // 提供空对象作为默认值 > {/* 加载状态覆盖层 */} {(loading || !isI18nReady) && (
加载多语言资源中...
)} {/* 错误状态覆盖层 */} {error && (
多语言资源加载失败: {error}
)} {/* children 始终被渲染,满足 Taro 框架要求 */}
dispatch(setFeatureNotAvailableOpen(false))} onContinue={() => { dispatch(setFeatureNotAvailableOpen(false)); dispatch(setBusinessFlow('continueAfterFeatureNotAvailable')); }} /> {children} {process.env.NODE_ENV === 'development' && }
); } function App({ children }: { children: ReactNode }): JSX.Element { // 只在 Cypress 测试环境下暴露 store 到 window 对象 if ( typeof window !== 'undefined' && (window as unknown as { Cypress: unknown }).Cypress ) { (window as unknown as { store: typeof store }).store = store; } return ( {children} ); } export default App;