Files
shanghai-residences/src/store/luxunStore.ts
T
zhongyidian e0fa47d21a 更新依赖项及历史人物相关内容资源
- 更新 package.json 和 package-lock.json 中的依赖项
- 新增/更新陈云、黄炎培、鲁迅、孙中山的音频文件
- 新增场景和组件的图片资源
- 清理未使用的音频和图片文件
- 优化多个组件和页面的实现逻辑
2026-04-20 13:27:18 +08:00

151 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<string, Set<number>>
// 体悟模块当前路由(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<string, Set<number>>
): Record<string, number[]> => {
const serialized: Record<string, number[]> = {}
for (const [place, exhibits] of Object.entries(visitedExhibits)) {
serialized[place] = Array.from(exhibits)
}
return serialized
}
// 将数组转换回 Set
const deserializeVisitedExhibits = (
serialized: Record<string, number[]> | undefined
): Record<string, Set<number>> => {
if (!serialized || typeof serialized !== 'object') {
return {}
}
const visitedExhibits: Record<string, Set<number>> = {}
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<LuxunStore>()(
persist(
(set, get) => ({
visitedExhibits: {},
reflectionRoute: 'reflection',
lastVisitedPlace: null,
markExhibitVisited: (place: string, exhibitId: number) => {
set((state) => {
const currentExhibits = state.visitedExhibits[place] || new Set<number>()
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)
}
}