import { create } from 'zustand'; import { persist, createJSONStorage } from 'zustand/middleware'; import type { User, Event, Note, AIConversation, EventType } from '../types'; import { api } from '../services/api'; // 应用设置类型 interface AppSettings { showHolidays: boolean; // 是否显示节假日 } // 默认设置 const defaultSettings: AppSettings = { showHolidays: true, }; interface AppState { // Auth state user: User | null; isAuthenticated: boolean; isLoading: boolean; // Settings state settings: AppSettings; updateSettings: (settings: Partial) => void; // Data state events: Event[]; notes: Note | null; conversations: AIConversation[]; // Actions setUser: (user: User | null) => void; setLoading: (loading: boolean) => void; setEvents: (events: Event[]) => void; addEvent: (event: Event) => void; updateEvent: (id: string, updates: Partial) => void; deleteEvent: (id: string) => void; setNotes: (notes: Note | null) => void; updateNotesContent: (content: string) => void; setConversations: (conversations: AIConversation[]) => void; addConversation: (conversation: AIConversation) => void; // Data fetch actions fetchEvents: (type?: EventType) => Promise; fetchNotes: () => Promise; saveNotes: (content: string) => Promise; createEvent: (event: Partial) => Promise<{ error: any }>; updateEventById: (id: string, event: Partial) => Promise<{ error: any }>; deleteEventById: (id: string) => Promise<{ error: any }>; // Auth actions login: (email: string, password: string) => Promise<{ error: any }>; register: (email: string, password: string, nickname?: string) => Promise<{ error: any }>; logout: () => Promise; checkAuth: () => Promise; } export const useAppStore = create()( persist( (set) => ({ // Initial state user: null, isAuthenticated: false, isLoading: true, settings: defaultSettings, events: [], notes: null, conversations: [], // Settings updateSettings: (newSettings) => set((state) => ({ settings: { ...state.settings, ...newSettings }, })), // Setters setUser: (user) => set({ user, isAuthenticated: !!user }), setLoading: (isLoading) => set({ isLoading }), setEvents: (events) => set({ events }), addEvent: (event) => set((state) => ({ events: [...state.events, event] })), updateEvent: (id, updates) => set((state) => ({ events: state.events.map((e) => (e.id === id ? { ...e, ...updates } : e)), })), deleteEvent: (id) => set((state) => ({ events: state.events.filter((e) => e.id !== id), })), setNotes: (notes) => set({ notes }), updateNotesContent: (content) => set((state) => ({ notes: state.notes ? { ...state.notes, content } : null, })), setConversations: (conversations) => set({ conversations }), addConversation: (conversation) => set((state) => ({ conversations: [conversation, ...state.conversations], })), // Data fetch actions fetchEvents: async (type) => { try { const events = await api.events.list(type); set({ events }); } catch (error) { console.error('Failed to fetch events:', error); } }, fetchNotes: async () => { try { const notes = await api.notes.get(); set({ notes }); } catch (error) { console.error('Failed to fetch notes:', error); } }, saveNotes: async (content) => { try { const notes = await api.notes.update(content); set({ notes }); } catch (error) { console.error('Failed to save notes:', error); throw error; } }, createEvent: async (event) => { try { const newEvent = await api.events.create(event); set((state) => ({ events: [...state.events, newEvent] })); return { error: null }; } catch (error: any) { return { error: error.message || '创建失败' }; } }, updateEventById: async (id, event) => { try { // 乐观更新:立即更新本地状态 set((state) => ({ events: state.events.map((e) => e.id === id ? { ...e, ...event } : e ), })); // 发送 API 请求 await api.events.update(id, event); // 乐观更新已生效,不需要用 API 返回数据覆盖 // 避免 API 返回数据不完整导致状态丢失 return { error: null }; } catch (error: any) { // 失败时回滚,重新获取数据 const events = await api.events.list(); set({ events }); return { error: error.message || '更新失败' }; } }, deleteEventById: async (id) => { try { await api.events.delete(id); set((state) => ({ events: state.events.filter((e) => e.id !== id), })); return { error: null }; } catch (error: any) { return { error: error.message || '删除失败' }; } }, // Auth actions login: async (email, password) => { try { const { user, token, refreshToken } = await api.auth.login(email, password); api.setTokens(token, refreshToken); set({ user, isAuthenticated: true }); return { error: null }; } catch (error: any) { const errorMessage = error.message || '登录失败,请检查邮箱和密码'; return { error: errorMessage }; } }, register: async (email, password, nickname) => { try { const { user, token, refreshToken } = await api.auth.register(email, password, nickname); api.setTokens(token, refreshToken); set({ user, isAuthenticated: true }); return { error: null }; } catch (error: any) { const errorMessage = error.message || '注册失败,请稍后重试'; return { error: errorMessage }; } }, logout: async () => { try { await api.auth.logout(); } catch { // Ignore logout error } api.clearTokens(); set({ user: null, isAuthenticated: false, events: [], notes: null }); }, checkAuth: async () => { set({ isLoading: true }); const token = api.getToken(); if (!token) { set({ isAuthenticated: false, isLoading: false }); return; } try { const { user } = await api.auth.getCurrentUser(); set({ user, isAuthenticated: true, isLoading: false }); } catch { // Token invalid, try refresh try { const { token: newToken } = await api.auth.refreshToken(); const { user } = await api.auth.getCurrentUser(); const refreshToken = api.getRefreshToken()!; api.setTokens(newToken, refreshToken); set({ user, isAuthenticated: true, isLoading: false }); } catch { api.clearTokens(); set({ isAuthenticated: false, isLoading: false }); } } }, }), { name: 'qia-storage', storage: createJSONStorage(() => localStorage), partialize: (state) => ({ user: state.user, isAuthenticated: state.isAuthenticated, settings: state.settings, }), } ) );