import { create } from "zustand"; import { persist } from "zustand/middleware"; interface LuxunStore { // 存储每个场景(place)的已访问展品ID集合 // 格式:{ place1: Set<1, 2>, place2: Set<1, 2>, ... } visitedExhibits: Record>; // 标记展品为已访问 markExhibitVisited: (place: string, exhibitId: number) => void; // 检查展品是否已访问 isExhibitVisited: (place: string, exhibitId: number) => boolean; // 获取某个场景已访问的展品ID数组 getVisitedExhibits: (place: string) => number[]; // 重置某个场景的访问记录 resetPlace: (place: string) => void; // 重置所有访问记录 resetAll: () => void; } // 将 Set 转换为数组以便序列化 const serializeVisitedExhibits = ( visitedExhibits: Record> ): Record => { const serialized: Record = {}; for (const [place, exhibits] of Object.entries(visitedExhibits)) { serialized[place] = Array.from(exhibits); } return serialized; }; // 将数组转换回 Set const deserializeVisitedExhibits = ( serialized: Record | undefined ): Record> => { if (!serialized || typeof serialized !== "object") { return {}; } const visitedExhibits: Record> = {}; for (const [place, exhibits] of Object.entries(serialized)) { if (Array.isArray(exhibits)) { visitedExhibits[place] = new Set(exhibits); } else { visitedExhibits[place] = new Set(); } } return visitedExhibits; }; export const useLuxunStore = create()( persist( (set, get) => ({ visitedExhibits: {}, markExhibitVisited: (place: string, exhibitId: number) => { set((state) => { const currentExhibits = state.visitedExhibits[place] || new Set(); if (!currentExhibits.has(exhibitId)) { const newExhibits = { ...state.visitedExhibits, [place]: new Set([...currentExhibits, exhibitId]), }; return { visitedExhibits: newExhibits }; } return state; }); }, isExhibitVisited: (place: string, exhibitId: number) => { const { visitedExhibits } = get(); return visitedExhibits[place]?.has(exhibitId) || false; }, getVisitedExhibits: (place: string) => { const { visitedExhibits } = get(); return Array.from(visitedExhibits[place] || []); }, resetPlace: (place: string) => { set((state) => { const newExhibits = { ...state.visitedExhibits }; delete newExhibits[place]; return { visitedExhibits: newExhibits }; }); }, resetAll: () => { set({ visitedExhibits: {} }); }, }), { name: "luxun-storage", partialize: (state) => ({ visitedExhibits: serializeVisitedExhibits(state.visitedExhibits), }), onRehydrateStorage: () => (state) => { if (state) { state.visitedExhibits = deserializeVisitedExhibits( state.visitedExhibits as any ); } }, } ) );