import { create } from 'zustand' import { persist } from 'zustand/middleware' import { STORE_NAMES } from './storeNames' import { setUserDefine } from '@/lib/utils/api-common' interface LuxunStore { // 存储每个场景(place)的已访问展品ID集合 // 格式:{ place1: Set<1, 2>, place2: Set<1, 2>, ... } visitedExhibits: Record> // 体悟模块当前路由(reflection / reflection2 / reflection3) reflectionRoute: string setReflectionRoute: (route: string) => void // 上次访问的场景(place1~place4) lastVisitedPlace: string | null setLastVisitedPlace: (place: string) => void // 标记展品为已访问 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: {}, reflectionRoute: 'reflection', lastVisitedPlace: null, 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: {} }) }, setLastVisitedPlace: (place: string) => set({ lastVisitedPlace: place }), setReflectionRoute: (route: string) => set({ reflectionRoute: route }), }), { name: STORE_NAMES.LUXUN, partialize: (state) => ({ visitedExhibits: serializeVisitedExhibits(state.visitedExhibits), lastVisitedPlace: state.lastVisitedPlace, reflectionRoute: state.reflectionRoute, }), onRehydrateStorage: () => (state) => { if (state) { state.visitedExhibits = deserializeVisitedExhibits(state.visitedExhibits as any) if (state.lastVisitedPlace === undefined) { state.lastVisitedPlace = null } if ((state as any).reflectionRoute === undefined) { ;(state as any).reflectionRoute = 'reflection' } } }, } ) ) // ========== 易班平台数据保存(对话模块) ========== export const LUXUN_LESSON_ID = 'Lux_duihua' export const LUXUN_KEY = 7 export const saveLuxunStore = (): void => { const state = useLuxunStore.getState() const payload = { visitedExhibits: serializeVisitedExhibits(state.visitedExhibits), lastVisitedPlace: state.lastVisitedPlace, reflectionRoute: state.reflectionRoute, } try { setUserDefine(LUXUN_LESSON_ID, LUXUN_KEY, JSON.stringify(payload)) } catch (error) { console.error('Failed to save Luxun store', error) } }