diff --git a/frontend/src/stores/auth.ts b/frontend/src/stores/auth.ts new file mode 100644 index 0000000..08037dc --- /dev/null +++ b/frontend/src/stores/auth.ts @@ -0,0 +1,87 @@ +import { create } from 'zustand'; +import { persist } from 'zustand/middleware'; +import type { User, LoginPayload, RegisterPayload } from '@/types'; +import { authApi } from '@/api'; + +interface AuthState { + token: string | null; + user: User | null; + loading: boolean; + isAuthenticated: boolean; + + login: (data: LoginPayload) => Promise; + register: (data: RegisterPayload) => Promise; + fetchMe: () => Promise; + logout: () => void; + setUser: (user: User | null) => void; +} + +export const useAuthStore = create()( + persist( + (set) => ({ + token: null, + user: null, + loading: false, + isAuthenticated: false, + + login: async (data: LoginPayload) => { + set({ loading: true }); + try { + const res = await authApi.login(data); + localStorage.setItem('access_token', res.access_token); + set({ + token: res.access_token, + user: res.user, + isAuthenticated: true, + loading: false, + }); + } catch { + set({ loading: false }); + throw new Error('登录失败,请检查邮箱和密码'); + } + }, + + register: async (data: RegisterPayload) => { + set({ loading: true }); + try { + const res = await authApi.register(data); + localStorage.setItem('access_token', res.access_token); + set({ + token: res.access_token, + user: res.user, + isAuthenticated: true, + loading: false, + }); + } catch { + set({ loading: false }); + throw new Error('注册失败,请检查输入信息'); + } + }, + + fetchMe: async () => { + try { + const user = await authApi.me(); + set({ user, isAuthenticated: true, loading: false }); + } catch { + set({ loading: false }); + throw new Error('获取用户信息失败'); + } + }, + + logout: () => { + localStorage.removeItem('access_token'); + set({ token: null, user: null, isAuthenticated: false }); + }, + + setUser: (user: User | null) => set({ user }), + }), + { + name: 'auth-storage', + partialize: (state) => ({ + token: state.token, + user: state.user, + isAuthenticated: state.isAuthenticated, + }), + } + ) +);