fix: 修复开发/测试包模拟进度被易班同步覆盖的问题

进度模拟面板写入 puzzleStore 后,App 启动时易班同步会将其覆盖;
现在在同步完成后按 sessionStorage 中保存的模式重放模拟进度,
确保测试包的"到达某故居/全流程完成"调试入口生效。

同时纳入近期未提交的页面、组件、资源与环境变量改动。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
zhongyidianandClaude Opus 4.7 committed 2026-05-23 10:19:36 +08:00
1 parent 6d40e19346
commit 49ecabbf3a
155 files changed
+1956 -724

No files matched your search

+25 -14
View File
@@ -1,7 +1,7 @@
import { create } from 'zustand'
import { persist } from 'zustand/middleware'
import { STORE_NAMES } from './storeNames'
import { setUserDefine, getUserDefine } from '@/lib/utils/api-common'
import { setUserDefine, getUserDefineResult } from '@/lib/utils/api-common'
interface HuangyanpeiStore {
// 存储每个场景(place)的已访问展品ID集合
@@ -251,12 +251,19 @@ export const saveHuangyanpeiStore = (): void => {
export const loadHuangyanpeiStore = async (): Promise<void> => {
try {
const raw = await getUserDefine(HUANGYANPEI_LESSON_ID, HUANGYANPEI_KEY)
if (!raw) {
const result = await getUserDefineResult(HUANGYANPEI_LESSON_ID, HUANGYANPEI_KEY)
if (result.status !== 'success') {
useHuangyanpeiStore.setState({
visitedExhibits: {},
lastVisitedPlace: null,
reflectionRoute: 'reflection',
shownReflectionCompletionGuides: {},
reflectionScene2Choice: null,
})
return
}
const payload = JSON.parse(raw) as {
const payload = JSON.parse(result.content) as {
visitedExhibits?: Record<string, number[]>
lastVisitedPlace?: string | null
reflectionRoute?: string
@@ -264,17 +271,21 @@ export const loadHuangyanpeiStore = async (): Promise<void> => {
reflectionScene2Choice?: '铁工科' | '商科' | null
}
useHuangyanpeiStore.setState((state) => ({
visitedExhibits: payload.visitedExhibits
? deserializeVisitedExhibits(payload.visitedExhibits)
: state.visitedExhibits,
lastVisitedPlace: payload.lastVisitedPlace ?? state.lastVisitedPlace,
reflectionRoute: payload.reflectionRoute ?? state.reflectionRoute,
shownReflectionCompletionGuides:
payload.shownReflectionCompletionGuides ?? state.shownReflectionCompletionGuides,
reflectionScene2Choice: payload.reflectionScene2Choice ?? state.reflectionScene2Choice,
}))
useHuangyanpeiStore.setState({
visitedExhibits: deserializeVisitedExhibits(payload.visitedExhibits),
lastVisitedPlace: payload.lastVisitedPlace ?? null,
reflectionRoute: payload.reflectionRoute ?? 'reflection',
shownReflectionCompletionGuides: payload.shownReflectionCompletionGuides ?? {},
reflectionScene2Choice: payload.reflectionScene2Choice ?? null,
})
} catch (error) {
useHuangyanpeiStore.setState({
visitedExhibits: {},
lastVisitedPlace: null,
reflectionRoute: 'reflection',
shownReflectionCompletionGuides: {},
reflectionScene2Choice: null,
})
console.error('Failed to load Huangyanpei store', error)
}
}
+2
View File
@@ -192,6 +192,8 @@ export const saveZhanglepingStore = (): void => {
state.drawArtworkDataUrl.length <= REMOTE_MAX_DATA_URL_LENGTH ? state.drawArtworkDataUrl : ''
const payload = {
visitedExhibits: serializeVisited(state.visitedExhibits),
lastVisitedPlace: state.lastVisitedPlace,
reflectionRoute: state.reflectionRoute,
visitedReflectionCursors: serializeVisited(state.visitedReflectionCursors),
drawArtworkDataUrl: remoteArtworkDataUrl,