| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- import {
- PropsWithChildren,
- useEffect,
- useRef,
- useCallback,
- useState,
- } from 'react';
- import SplashScreen from 'react-native-splash-screen';
- import Taro from '@tarojs/taro';
- import './app.scss';
- import AsyncStorage from '@react-native-async-storage/async-storage';
- import useRootStore from '@/store';
- import { ToastProvider } from '@/contexts/ToastContext';
- import { View } from '@tarojs/components';
- import { services } from '@/models'
- import NetInfo from '@react-native-community/netinfo';
- import WindowDimensionsProvider from './hooks/useWindowDimensions';
- import { getDictType, handleAreaData } from './api';
- import UpdateModal from '@/components/UpdateModal';
- const App = ({ children }: PropsWithChildren) => {
- const spaceCheckInterval = useRef<NodeJS.Timeout | null>(null);
- const {
- UPDATA_ANTHOR_TOKEN,
- UPDATA_SYSTEM_INFO,
- UPDATA_USER_INFO,
- UPDATE_NETWORK_STATUS,
- } = useRootStore.getState();
- const userInfo = useRootStore(state => state.userInfo);
- const [isOnline, setIsOnline] = useState<boolean>(true); // 网络状态状态
- const networkListenerRef = useRef<any>(null); // 存储网络监听器引用
- // 获取系统信息
- const getSystemInfo = useCallback(async () => {
- try {
- const res = await Taro.getSystemInfo();
- console.log('getSystemInfo:', res);
- UPDATA_SYSTEM_INFO(res as any);
- } catch (error) {
- console.error('获取系统信息失败:', error);
- }
- }, [UPDATA_SYSTEM_INFO]);
- // 获取存储的token
- const handleGetStorage = useCallback(async (): Promise<void> => {
- try {
- // 优先从Zustand store获取token
- const store = useRootStore.getState();
- console.log('Zustand store状态:', {
- isStorageReady: store.isStorageReady,
- hasToken: !!store.token,
- hasUserInfo: !!store.userInfo,
- token: store.token,
- userInfo: store.userInfo
- });
- // 等待存储准备完成
- if (store.isStorageReady) {
- if (store.token) {
- console.log('从Zustand store获取token成功:', store.token);
- UPDATA_ANTHOR_TOKEN(store.token);
- return;
- }
- } else {
- // 如果store还没准备好,等待一下再重试
- let retryCount = 0;
- const maxRetries = 10;
- const retryInterval = 100; // 100ms
- const checkStorageReady = async (): Promise<void> => {
- while (retryCount < maxRetries && !store.isStorageReady) {
- await new Promise(resolve => setTimeout(resolve, retryInterval));
- retryCount++;
- }
- if (store.isStorageReady && store.token) {
- console.log('等待后从Zustand store获取token成功:', store.token);
- UPDATA_ANTHOR_TOKEN(store.token);
- return;
- }
- // 如果Zustand没有数据,尝试从Taro存储获取作为备选
- try {
- const { data } = await Taro.getStorage({ key: 'ACCESS_TOKEN' });
- if (data) {
- console.log('从Taro存储获取token成功:', data);
- UPDATA_ANTHOR_TOKEN(data);
- }
- } catch (fallbackError) {
- console.log('从Taro存储获取token也失败,跳过');
- }
- };
- await checkStorageReady();
- }
- } catch (error) {
- console.error('获取token失败:', error);
- // 即使失败也继续,避免阻塞启动
- }
- }, [UPDATA_ANTHOR_TOKEN]);
- // 存储空间检查
- const storageSpaceHandler = useCallback(async () => {
- try {
- const keys = await AsyncStorage.getAllKeys();
- console.log('Stored keys count:', keys.length);
- } catch (error) {
- console.error('存储空间检查失败:', error);
- }
- }, []);
- // 获取用户信息
- const setUserInfo = useCallback(async () => {
- try {
- // 优先从Zustand store获取用户信息
- const store = useRootStore.getState();
- // 等待存储准备完成
- if (store.isStorageReady) {
- if (store.userInfo) {
- console.log('从Zustand store获取用户信息成功:', store.userInfo);
- await services.user.createUserFromServer(store.userInfo);
- return;
- }
- } else {
- // 如果store还没准备好,等待一下再重试
- let retryCount = 0;
- const maxRetries = 10;
- const retryInterval = 100; // 100ms
- const checkStorageReady = async (): Promise<void> => {
- while (retryCount < maxRetries && !store.isStorageReady) {
- await new Promise(resolve => setTimeout(resolve, retryInterval));
- retryCount++;
- }
- if (store.isStorageReady && store.userInfo) {
- console.log('等待后从Zustand store获取用户信息成功:', store.userInfo);
- await services.user.createUserFromServer(store.userInfo);
- return;
- }
- // 如果Zustand没有数据,尝试从Taro存储获取作为备选
- try {
- const { data: user } = await Taro.getStorage({ key: 'USER_INFO' });
- if (user) {
- console.log('从Taro存储获取用户信息成功:', user);
- UPDATA_USER_INFO(user); // 同步到Zustand store
- await services.user.createUserFromServer(user);
- } else {
- console.log('未找到用户信息,可能需要重新登录');
- }
- } catch (fallbackError) {
- console.log('从Taro存储获取用户信息也失败,跳过');
- }
- };
- await checkStorageReady();
- }
- } catch (error) {
- console.error('获取用户信息失败:', error);
- console.log('用户信息获取失败是正常的,可能用户未登录或首次启动');
- }
- }, [UPDATA_USER_INFO]);
- // 初始化应用
- const initApp = useCallback(async () => {
- try {
- await Promise.all([
- handleGetStorage(),
- getSystemInfo(),
- setUserInfo(),
- ]);
- } catch (error) {
- console.error('初始化应用失败:', error);
- } finally {
- // 无论成功失败都隐藏启动页
- SplashScreen.hide();
- }
- }, [handleGetStorage, getSystemInfo, setUserInfo]);
- // 初始化网络状态监听
- const setupNetworkListener = useCallback(() => {
- try {
- // 首先获取当前网络状态
- NetInfo.fetch().then(state => {
- const connected = state.isConnected ?? false;
- setIsOnline(connected);
- UPDATE_NETWORK_STATUS(connected);
- console.log('初始化网络状态:', connected);
- });
- // 订阅网络状态变化
- networkListenerRef.current = NetInfo.addEventListener(state => {
- const connected = state.isConnected ?? false;
- // 只有状态真正改变时才更新和记录日志
- setIsOnline(prevConnected => {
- if (prevConnected !== connected) {
- UPDATE_NETWORK_STATUS(connected);
- console.log('网络状态改变:', connected);
- }
- return connected;
- });
- });
- }
- catch (error) {
- console.error('设置网络监听失败:', error);
- }
- }, [UPDATE_NETWORK_STATUS]);
- useEffect(() => {
- const initializeApp = async () => {
- await initApp();
- // 启动存储空间检查定时器
- spaceCheckInterval.current = setInterval(storageSpaceHandler, 60_000);
- // 设置网络状态监听
- setupNetworkListener();
- };
- initializeApp();
- // 清理函数
- return () => {
- if (spaceCheckInterval.current) {
- clearInterval(spaceCheckInterval.current);
- }
- // 移除网络监听
- networkListenerRef.current();
- };
- }, [initApp, storageSpaceHandler, setupNetworkListener]);
- useEffect(() => {
- if (!isOnline) {
- Taro.showToast({ title: '当前网络不可用', icon: 'error' });
- }
- }, [isOnline]);
- useEffect(() => {
- const fetchDictData = async () => {
- try {
- await getDictType();
- await handleAreaData();
- } catch (error) {
- console.error('初始化数据失败:', error);
- }
- };
- fetchDictData();
- }, [userInfo.id]);
- return (
- <ToastProvider>
- <View style={{ height: '100%', overflow: 'hidden' }}>
- <WindowDimensionsProvider>
- {children}
- </WindowDimensionsProvider>
- {/* 应用更新弹窗 - 自包含组件 */}
- {/* <UpdateModal /> */}
- </View>
- </ToastProvider>
- );
- };
- export default App;
|