import { createContext, useContext, useState, useEffect, useCallback } from 'react'; const AuthContext = createContext(null); export const AuthProvider = ({ children }) => { const [user, setUser] = useState(null); const [token, setToken] = useState(null); const [loading, setLoading] = useState(true); const [authState, setAuthState] = useState({ isAuthenticated: false, isLoading: true, }); useEffect(() => { checkAuth(); }, []); const checkAuth = async () => { try { const savedToken = localStorage.getItem('token'); const savedUser = localStorage.getItem('user'); if (savedToken && savedUser) { setToken(savedToken); setUser(JSON.parse(savedUser)); setAuthState({ isAuthenticated: true, isLoading: false, }); } else { clearAuth(); } } catch (error) { console.error('Auth check failed:', error); clearAuth(); } finally { setLoading(false); } }; const clearAuth = () => { localStorage.removeItem('token'); localStorage.removeItem('user'); setToken(null); setUser(null); setAuthState({ isAuthenticated: false, isLoading: false, }); }; const login = async (username, password) => { try { const response = await fetch(`${import.meta.env.VITE_API_BASE_URL}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ username, password }), }); const data = await response.json(); if (data.success) { const { token: newToken, user: userData } = data.data; localStorage.setItem('token', newToken); localStorage.setItem('user', JSON.stringify(userData)); setToken(newToken); setUser(userData); setAuthState({ isAuthenticated: true, isLoading: false, }); return userData; } else { throw new Error(data.message || '登录失败'); } } catch (error) { console.error('Login failed:', error); throw error; } }; const logout = useCallback(async () => { try { const token = localStorage.getItem('token'); if (token) { await fetch(`${import.meta.env.VITE_API_BASE_URL}/auth/logout`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, }); } } catch (error) { console.error('Logout failed:', error); } finally { localStorage.removeItem('token'); localStorage.removeItem('user'); setToken(null); setUser(null); setAuthState({ isAuthenticated: false, isLoading: false, }); } }, []); const hasRole = useCallback((roles) => { if (!user) return false; if (Array.isArray(roles)) { return roles.includes(user.role); } return user.role === roles; }, [user]); const canEdit = useCallback((createdBy) => { if (!user) return false; if (user.role === 'admin') return true; if (user.role === 'market' && createdBy === user.id) return true; if (user.role === 'other') return 'partial'; return false; }, [user]); const value = { user, token, loading, authState, login, logout, checkAuth, hasRole, canEdit, isAuthenticated: authState.isAuthenticated, }; return ( {children} ); }; export const useAuth = () => { const context = useContext(AuthContext); if (!context) { throw new Error('useAuth must be used within AuthProvider'); } return context; }; export default AuthContext;