| import React, { createContext, useContext, useState, useEffect, useCallback } from 'react'; |
| import { loginUser, registerUser, getUserInfo, logoutUser } from '../services/authApi'; |
| import { message } from 'antd'; |
| import { useNavigate } from 'react-router-dom'; // 导入 useNavigate |
| |
| const AuthContext = createContext(null); |
| |
| export const AuthProvider = ({ children }) => { |
| const [user, setUser] = useState(null); |
| const [loading, setLoading] = useState(true); // 初始加载状态 |
| const [isAuthenticated, setIsAuthenticated] = useState(false); |
| const navigate = useNavigate(); |
| |
| const loadAuthData = useCallback(() => { |
| setLoading(true); |
| try { |
| const storedToken = localStorage.getItem('authToken'); // 假设您使用token |
| const storedUser = localStorage.getItem('user'); |
| |
| if (storedToken && storedUser) { |
| setUser(JSON.parse(storedUser)); |
| setIsAuthenticated(true); |
| // 调用API获取最新的用户信息 |
| getUserInfo().then(response => { |
| if (response.data && response.data.user) { |
| setUser(response.data.user); |
| localStorage.setItem('user', JSON.stringify(response.data.user)); |
| } |
| }).catch(error => { |
| console.error("获取用户信息失败", error); |
| }); |
| } else { |
| setIsAuthenticated(false); |
| setUser(null); |
| } |
| } catch (error) { |
| console.error("Failed to load auth data from storage", error); |
| setIsAuthenticated(false); |
| setUser(null); |
| } finally { |
| setLoading(false); |
| } |
| }, []); |
| |
| useEffect(() => { |
| loadAuthData(); |
| }, [loadAuthData]); |
| |
| const login = async (credentials) => { |
| setLoading(true); |
| try { |
| const response = await loginUser(credentials); |
| const { token, user: userData } = response.data; |
| |
| localStorage.setItem('authToken', token); |
| localStorage.setItem('user', JSON.stringify(userData)); |
| setUser(userData); |
| setIsAuthenticated(true); |
| message.success('登录成功'); |
| return userData; |
| } catch (error) { |
| console.error("Login failed", error); |
| setIsAuthenticated(false); |
| setUser(null); |
| message.error(error.message || '登录失败,请检查用户名和密码'); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| const register = async (userData) => { |
| setLoading(true); |
| try { |
| const response = await registerUser(userData); |
| const { token, user: newUser } = response.data; |
| |
| localStorage.setItem('authToken', token); |
| localStorage.setItem('user', JSON.stringify(newUser)); |
| setUser(newUser); |
| setIsAuthenticated(true); |
| message.success('注册成功'); |
| return newUser; |
| } catch (error) { |
| console.error("Registration failed", error); |
| message.error(error.message || '注册失败,请稍后再试'); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| const logout = async () => { |
| try { |
| await logoutUser(); |
| localStorage.removeItem('authToken'); |
| localStorage.removeItem('user'); |
| localStorage.removeItem('permissions'); // 移除旧的权限存储 |
| setUser(null); |
| setIsAuthenticated(false); |
| message.success('已成功退出登录'); |
| navigate('/login'); |
| return true; |
| } catch (error) { |
| console.error("登出失败", error); |
| message.error('登出失败'); |
| return false; |
| } |
| }; |
| |
| const hasRole = useCallback((roleName) => { |
| return user?.role === roleName; |
| }, [user]); |
| |
| const value = { |
| user, |
| isAuthenticated, |
| loading, |
| login, |
| register, |
| logout, |
| hasRole, |
| reloadAuthData: loadAuthData // 暴露一个重新加载数据的方法 |
| }; |
| |
| return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>; |
| }; |
| |
| export const useAuth = () => { |
| const context = useContext(AuthContext); |
| if (context === undefined || context === null) { // 增加了对 null 的检查 |
| throw new Error('useAuth must be used within an AuthProvider'); |
| } |
| return context; |
| }; |