import { create } from 'zustand' import { persist } from 'zustand/middleware' import { API_CONFIG, API_ENDPOINTS } from '../config/api' export interface User { id: number username: string name: string email?: string role: 'admin' | 'manager' | 'user' | 'finance' department?: string avatar?: string passport?: string driverLicense?: string token?: string } export interface AuthState { user: User | null token: string | null isAuthenticated: boolean isLoading: boolean hasHydrated: boolean // Actions login: (username: string, password: string) => Promise logout: () => void setUser: (user: User) => void setToken: (token: string) => void clearAuth: () => void } export const useAuthStore = create()( persist( (set) => ({ user: null, token: null, isAuthenticated: false, isLoading: false, hasHydrated: false, login: async (username: string, password: string) => { set({ isLoading: true }) try { // 调用后端API const response = await fetch(`${API_CONFIG.baseURL}${API_ENDPOINTS.auth.login}`, { method: 'POST', headers: API_CONFIG.headers, body: JSON.stringify({ username, password }), }) // 获取响应文本(只能读取一次) const responseText = await response.text() if (!response.ok) { let errorMessage = '登录失败' try { // 尝试解析为JSON const errorData = JSON.parse(responseText) errorMessage = errorData.message || errorMessage } catch { // 如果不是JSON,使用原始文本(如果非空) if (responseText && responseText.trim().length > 0) { errorMessage = responseText } else { // 根据状态码提供更具体的错误信息 if (response.status === 401) { errorMessage = '用户名或密码错误' } else if (response.status === 500) { errorMessage = '服务器内部错误,请稍后重试' } else { errorMessage = `登录失败 (状态码: ${response.status})` } } } throw new Error(errorMessage) } // 解析成功响应 const result = JSON.parse(responseText) // 登录响应数据中的用户信息直接在 data 字段下 const userData = result.data // 从返回数据中提取 token const token = userData.token // 移除 user 对象中的 token 字段(只保留在单独的 token 字段) const user = { id: userData.id, username: userData.username, name: userData.name, email: userData.email, role: userData.role, department: userData.department, avatar: userData.avatar, passport: userData.passport, driverLicense: userData.driverLicense } set({ user, token, isAuthenticated: true, isLoading: false, hasHydrated: true }) } catch (error) { set({ isLoading: false }) throw error } }, logout: () => { // 调用登出 API(可选) const authStorage = localStorage.getItem('auth-storage') if (authStorage) { try { const { state } = JSON.parse(authStorage) const token = state?.token if (token) { fetch(`${API_CONFIG.baseURL}${API_ENDPOINTS.auth.logout}`, { method: 'POST', headers: { ...API_CONFIG.headers, 'Authorization': `Bearer ${token}` } }).catch(() => {}) // 忽略错误 } } catch (e) { // 忽略解析错误 } } set({ user: null, token: null, isAuthenticated: false, hasHydrated: true }) }, setUser: (user: User) => { set({ user }) }, setToken: (token: string) => { set({ token }) }, clearAuth: () => { set({ user: null, token: null, isAuthenticated: false, hasHydrated: true }) } }), { name: 'auth-storage', onRehydrateStorage: () => () => { useAuthStore.setState({ hasHydrated: true }) } } ) )