import { createContext, useContext, useState, useEffect, ReactNode } from 'react'; import { User, AuthState } from '../../types/auth'; import { getToken, getUser, saveToken, saveUser, clearAuth, isTokenExpired, refreshAuthToken, generateToken, } from '../../lib/authStorage'; interface AuthContextType { authState: AuthState; login: (user: User) => void; logout: () => void; updateUser: (user: User) => void; checkAuth: () => boolean; } const AuthContext = createContext(undefined); export function AuthProvider({ children }: { children: ReactNode }) { const [authState, setAuthState] = useState({ isAuthenticated: false, user: null, token: null, refreshToken: null, }); // 初始化时检查登录状态 useEffect(() => { const initAuth = async () => { const token = getToken(); const user = getUser(); if (token && user) { // 检查token是否过期 if (isTokenExpired()) { // 尝试刷新token const refreshed = await refreshAuthToken(); if (refreshed) { setAuthState({ isAuthenticated: true, user, token: refreshed.token, refreshToken: refreshed.refreshToken, }); } else { // 刷新失败,自动使用默认账号登录 await autoLoginWithDefaultAccount(); } } else { setAuthState({ isAuthenticated: true, user, token, refreshToken: getToken(), }); } } else { // 没有登录信息,自动使用默认账号登录 await autoLoginWithDefaultAccount(); } }; // 自动登录默认账号 const autoLoginWithDefaultAccount = async () => { // 动态导入避免循环依赖 const { validatePasswordLogin } = await import('../../lib/authStorage'); // 使用默认管理员账号自动登录 const result = await validatePasswordLogin('admin', 'admin123', 'AUTO'); if (result.success && result.user) { const newToken = generateToken(); const newRefreshToken = generateToken(); saveToken(newToken, newRefreshToken); saveUser(result.user); setAuthState({ isAuthenticated: true, user: result.user, token: newToken, refreshToken: newRefreshToken, }); } else { // 自动登录失败,显示登录页面 setAuthState({ isAuthenticated: false, user: null, token: null, refreshToken: null, }); } }; initAuth(); }, []); // 定期检查token有效性 useEffect(() => { if (!authState.isAuthenticated) return; const interval = setInterval(async () => { if (isTokenExpired()) { const refreshed = await refreshAuthToken(); if (refreshed) { setAuthState(prev => ({ ...prev, token: refreshed.token, refreshToken: refreshed.refreshToken, })); } else { logout(); } } }, 5 * 60 * 1000); // 每5分钟检查一次 return () => clearInterval(interval); }, [authState.isAuthenticated]); const login = (user: User) => { const token = generateToken(); const refreshToken = generateToken(); saveToken(token, refreshToken); saveUser(user); setAuthState({ isAuthenticated: true, user, token, refreshToken, }); }; const logout = () => { clearAuth(); setAuthState({ isAuthenticated: false, user: null, token: null, refreshToken: null, }); }; const updateUser = (user: User) => { saveUser(user); setAuthState(prev => ({ ...prev, user, })); }; const checkAuth = (): boolean => { return authState.isAuthenticated && !isTokenExpired(); }; return ( {children} ); } export function useAuth() { const context = useContext(AuthContext); if (context === undefined) { throw new Error('useAuth must be used within an AuthProvider'); } return context; }