zhouxiantao
8 days ago 03193b2a27a2c23e10f3a2f298de9c1142116780
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**
 * @author 韩天尊
 * @time 2024-01-15
 * @version 1.0.0
 * @description 路由守卫组件,检查用户登录状态
 */
import React, { useEffect } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { useAppContext } from '../context/AppContext';
 
interface ProtectedRouteProps {
    children: React.ReactNode;
}
 
const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ children }) => {
    const navigate = useNavigate();
    const location = useLocation();
    const { state } = useAppContext();
    const [isInitialized, setIsInitialized] = React.useState(false);
 
    // 检查是否已完成初始化
    useEffect(() => {
        const token = localStorage.getItem('token');
        const user = localStorage.getItem('user');
        
        // 如果有token和user信息,说明可能正在初始化,等待一下
        if (token && user) {
            const timer = setTimeout(() => {
                setIsInitialized(true);
            }, 200);
            return () => clearTimeout(timer);
        } else {
            // 没有token和user,立即标记为已初始化
            setIsInitialized(true);
        }
    }, []);
 
    useEffect(() => {
        // 只有在初始化完成后才进行跳转检查
        if (isInitialized && !state.user && location.pathname !== '/login') {
            navigate('/login', { replace: true });
        }
    }, [isInitialized, state.user, location.pathname, navigate]);
 
    // 如果未初始化完成,显示加载状态
    if (!isInitialized) {
        return (
            <div style={{ 
                display: 'flex', 
                justifyContent: 'center', 
                alignItems: 'center', 
                height: '100vh',
                background: '#f5f5f5'
            }}>
                <div style={{ textAlign: 'center', color: '#666' }}>
                    <div style={{ 
                        width: '40px', 
                        height: '40px', 
                        border: '3px solid #f3f3f3',
                        borderTop: '3px solid #ff6b6b',
                        borderRadius: '50%',
                        animation: 'spin 1s linear infinite',
                        margin: '0 auto 20px'
                    }}></div>
                    <p>加载中...</p>
                </div>
            </div>
        );
    }
 
    // 如果用户未登录,不渲染子组件
    if (!state.user && location.pathname !== '/login') {
        return null;
    }
 
    return <>{children}</>;
};
 
export default ProtectedRoute;