| import React, { |
| createContext, |
| useContext, |
| useState, |
| useEffect, |
| useCallback, |
| } from "react"; |
| import { userLogin, registerUser, logoutUser, adminLogin as adminLoginAPI } from "@/api/auth"; |
| 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("token"); |
| const storedUser = localStorage.getItem("user"); |
| |
| console.log("Loading auth data - token:", !!storedToken, "user:", !!storedUser); |
| |
| if (storedToken && storedUser) { |
| try { |
| const userData = JSON.parse(storedUser); |
| // console.log("Parsed user data:", userData); |
| setUser(userData); |
| setIsAuthenticated(true); |
| } catch (parseError) { |
| console.error("Failed to parse stored user data:", parseError); |
| // 如果解析失败,清除损坏的数据 |
| localStorage.removeItem("token"); |
| localStorage.removeItem("user"); |
| setIsAuthenticated(false); |
| setUser(null); |
| } |
| } else { |
| console.log("No stored auth data found"); |
| 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 (params) => { |
| setLoading(true); |
| try { |
| const response = await userLogin(params); |
| // 检查响应是否成功 |
| if (response && response.data) { |
| const token = response.data.token; |
| const userData = response.data; |
| |
| console.log("Saving token:", token); |
| console.log("Saving user data:", userData); |
| |
| localStorage.setItem("token", token); |
| localStorage.setItem("user", JSON.stringify(userData)); |
| |
| setUser(userData); |
| setIsAuthenticated(true); |
| |
| message.success(response?.message || "登录成功"); |
| return userData; |
| } |
| } catch (error) { |
| console.log("login error", error); |
| setIsAuthenticated(false); |
| setUser(null); |
| message.error(error.message || "登录失败,请检查用户名和密码"); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| const adminLogin = async (params) => { |
| setLoading(true); |
| try { |
| const response = await adminLoginAPI(params); |
| |
| if (response && response.data) { |
| const token = response.data.token; |
| const adminData = response.data; |
| |
| console.log("Saving user data:", adminData); |
| |
| localStorage.setItem("token", token); |
| localStorage.setItem("user", JSON.stringify(adminData)); |
| |
| setUser(adminData); |
| setIsAuthenticated(true); |
| |
| message.success(response?.message || "登录成功"); |
| return adminData; |
| } |
| } catch (error) { |
| console.log("admin login error", error); |
| setIsAuthenticated(false); |
| setUser(null); |
| message.error(error.message || "管理员登录失败,请检查用户名和密码"); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| const register = async (userData) => { |
| setLoading(true); |
| try { |
| const response = await registerUser(userData); |
| |
| // 检查响应是否成功 |
| if (response.data && response.data.success) { |
| const { token, user: newUser } = response.data.data; |
| |
| localStorage.setItem("token", token); |
| localStorage.setItem("user", JSON.stringify(newUser)); |
| setUser(newUser); |
| setIsAuthenticated(true); |
| message.success("注册成功"); |
| return newUser; |
| } else { |
| throw new Error(response.data?.message || "注册失败"); |
| } |
| } catch (error) { |
| console.error("Registration failed", error); |
| message.error(error.message || "注册失败,请稍后再试"); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| const logout = async () => { |
| try { |
| await logoutUser(); |
| localStorage.removeItem("token"); |
| 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) => { |
| if (user?.uid.includes('admin')) { |
| return true; |
| } else { |
| return user?.role === roleName; |
| } |
| }, |
| [user] |
| ); |
| |
| const value = { |
| user, |
| isAuthenticated, |
| loading, |
| login, |
| adminLogin, |
| 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; |
| }; |