import { useEffect, useState, useRef } from 'react'; import { Navigate, useLocation } from 'react-router'; import { Spin } from 'antd'; import { useAuthStore } from '@/stores/useAuthStore'; import { useDictStore } from '@/stores/useDictStore'; /** * Routes that do not require authentication. */ const WHITE_LIST = ['/login'] as const; interface AuthGuardProps { children: React.ReactNode; } const AuthGuard: React.FC = ({ children }) => { const location = useLocation(); const token = useAuthStore((s) => s.token); const userInfo = useAuthStore((s) => s.userInfo); const fetchPermissionInfo = useAuthStore((s) => s.fetchPermissionInfo); const fetchDictData = useDictStore((s) => s.fetchDictData); const isWhitelisted = WHITE_LIST.some( (path) => location.pathname === path || location.pathname.startsWith(path + '/'), ); const [loading, setLoading] = useState(!isWhitelisted && !userInfo && !!token); const isFetching = useRef(false); useEffect(() => { if (token && !userInfo && !isFetching.current) { isFetching.current = true; Promise.all([fetchPermissionInfo(), fetchDictData()]).finally(() => { isFetching.current = false; setLoading(false); }); } }, [token, userInfo, fetchPermissionInfo, fetchDictData]); if (!token && !isWhitelisted) { return ( ); } if (loading) { return (
); } return <>{children}; }; export default AuthGuard;