更新依赖项及历史人物相关内容资源

- 更新 package.json 和 package-lock.json 中的依赖项
- 新增/更新陈云、黄炎培、鲁迅、孙中山的音频文件
- 新增场景和组件的图片资源
- 清理未使用的音频和图片文件
- 优化多个组件和页面的实现逻辑
This commit is contained in:
zhongyidian committed 2026-04-20 13:27:18 +08:00
1 parent b1d55b9464
commit e0fa47d21a
629 files changed
+24390 -2991

No files matched your search

+227
View File
@@ -0,0 +1,227 @@
import { create } from 'zustand'
import { persist } from 'zustand/middleware'
import { STORE_NAMES } from './storeNames'
import { setUserDefine } from '@/lib/utils/api-common'
interface NieerStore {
// 存储每个场景(place)的已访问展品ID集合
// 格式:{ place1: Set<1,2>, place2: Set<1,2>, ... }
visitedExhibits: Record<string, Set<number>>
// 标记展品为已访问
markExhibitVisited: (place: string, exhibitId: number) => void
// 检查展品是否已访问
isExhibitVisited: (place: string, exhibitId: number) => boolean
// 获取某个场景已访问的展品ID数组
getVisitedExhibits: (place: string) => number[]
// 重置某个场景的访问记录
resetPlace: (place: string) => void
// 重置所有访问记录
resetAll: () => void
// ========== 断点续读 ==========
lastVisitedPlace: string | null
setLastVisitedPlace: (place: string) => void
// ========== 体悟模块状态 ==========
// 存储每个reflection场景的已完成cursor ID集合
visitedReflectionCursors: Record<string, Set<number>>
// 标记reflection cursor为已完成
markReflectionCursorVisited: (scene: string, cursorId: number) => void
// 检查reflection cursor是否已完成
isReflectionCursorVisited: (scene: string, cursorId: number) => boolean
// 获取某个reflection场景已完成的cursor ID数组
getVisitedReflectionCursors: (scene: string) => number[]
// 重置某个reflection场景的cursor记录
resetReflectionScene: (scene: string) => void
// 重置所有reflection cursor记录
resetAllReflectionCursors: () => void
// ========== 旅行箱成果 ==========
// 每个 scene 对应一次分享后的成果快照(用于旅行箱展示)
reflectionWorks: Record<number, Record<string, unknown>>
setReflectionWork: (sceneId: number, payload: Record<string, unknown>) => void
resetReflectionWorks: () => 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 useNieerStore = create<NieerStore>()(
persist(
(set, get) => ({
visitedExhibits: {},
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: {} })
},
lastVisitedPlace: null,
setLastVisitedPlace: (place: string) => set({ lastVisitedPlace: place }),
// ========== 体悟模块状态 ==========
visitedReflectionCursors: {},
reflectionWorks: {},
markReflectionCursorVisited: (scene: string, cursorId: number) => {
set((state) => {
const currentCursors = state.visitedReflectionCursors[scene] || new Set<number>()
if (!currentCursors.has(cursorId)) {
const newCursors = {
...state.visitedReflectionCursors,
[scene]: new Set([...currentCursors, cursorId]),
}
return { visitedReflectionCursors: newCursors }
}
return state
})
},
isReflectionCursorVisited: (scene: string, cursorId: number) => {
const { visitedReflectionCursors } = get()
return visitedReflectionCursors[scene]?.has(cursorId) || false
},
getVisitedReflectionCursors: (scene: string) => {
const { visitedReflectionCursors } = get()
return Array.from(visitedReflectionCursors[scene] || [])
},
resetReflectionScene: (scene: string) => {
set((state) => {
const newCursors = { ...state.visitedReflectionCursors }
delete newCursors[scene]
return { visitedReflectionCursors: newCursors }
})
},
resetAllReflectionCursors: () => {
set({ visitedReflectionCursors: {} })
},
setReflectionWork: (sceneId: number, payload: Record<string, unknown>) => {
set((state) => ({
reflectionWorks: {
...state.reflectionWorks,
[sceneId]: {
...state.reflectionWorks[sceneId],
...payload,
updatedAt: Date.now(),
},
},
}))
},
resetReflectionWorks: () => {
set({ reflectionWorks: {} })
},
}),
{
name: STORE_NAMES.NIEER,
partialize: (state) => ({
visitedExhibits: serializeVisitedExhibits(state.visitedExhibits),
visitedReflectionCursors: serializeVisitedExhibits(state.visitedReflectionCursors),
lastVisitedPlace: state.lastVisitedPlace,
reflectionWorks: state.reflectionWorks,
}),
onRehydrateStorage: () => (state) => {
if (state) {
state.visitedExhibits = deserializeVisitedExhibits(state.visitedExhibits as any)
state.visitedReflectionCursors = deserializeVisitedExhibits(
state.visitedReflectionCursors as any
)
if (state.lastVisitedPlace === undefined) {
state.lastVisitedPlace = null
}
if (!state.reflectionWorks || typeof state.reflectionWorks !== 'object') {
state.reflectionWorks = {}
}
}
},
}
)
)
// ========== 易班平台数据保存(与陈云对齐) ==========
export const NIEER_LESSON_ID = 'Nieer_duihua'
export const NIEER_KEY = 5
export const saveNieerStore = (): void => {
const state = useNieerStore.getState()
const payload = {
visitedExhibits: serializeVisitedExhibits(state.visitedExhibits),
lastVisitedPlace: state.lastVisitedPlace,
}
try {
setUserDefine(NIEER_LESSON_ID, NIEER_KEY, JSON.stringify(payload))
} catch (error) {
console.error('Failed to save Nieer store', error)
}
}