import { useState, useEffect, ReactNode } from 'react';
import { useLaunch } from '@tarojs/taro';
import { IntlProvider } from 'react-intl';
import { ConfigProvider } 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 ThemeSwitcher from './components/ThemeSwitcher';
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;