feat: 完善课程引导与实战评价体验

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
zhongyidianandClaude Opus 4.7 committed 2026-05-09 09:53:06 +08:00
1 parent 6f8252472f
commit 1f8723aabd
122 files changed
+2595 -1325

No files matched your search

+28 -10
View File
@@ -15,6 +15,7 @@ interface InterviewSavePayload {
InterviewUnlockProgress?: number
interviewMenuVisible?: boolean
guideShown?: Record<string, boolean>
practiceScrollPage?: number
}
async function getYibanApi(): Promise<typeof import('@/utils/yiban') | null> {
@@ -55,6 +56,7 @@ export const useInterviewStore = defineStore(
//Interview-菜单 Overlay 是否可见
const interviewMenuVisible = ref<boolean>(false)
const guideShown = ref<Record<string, boolean>>({})
const practiceScrollPage = ref<number>(0)
//Actions
function saveInterviewStore(): void {
@@ -67,14 +69,21 @@ export const useInterviewStore = defineStore(
isInterviewUnlock: isInterviewUnlock.value,
InterviewUnlockProgress: InterviewUnlockProgress.value,
interviewMenuVisible: interviewMenuVisible.value,
guideShown: guideShown.value
guideShown: guideShown.value,
practiceScrollPage: practiceScrollPage.value,
}
getYibanApi()
.then(api =>
api?.setUserDefine(INTERVIEW_LESSON_ID, INTERVIEW_KEY, JSON.stringify(payload))
.then((api) =>
api?.setUserDefine(
INTERVIEW_LESSON_ID,
INTERVIEW_KEY,
JSON.stringify(payload),
),
)
.catch((error) =>
console.error('Failed to save Interview store', error),
)
.catch(error => console.error('Failed to save Interview store', error))
}
async function loadInterviewStore(): Promise<void> {
@@ -95,6 +104,7 @@ export const useInterviewStore = defineStore(
InterviewUnlockProgress.value = data.InterviewUnlockProgress ?? 0
interviewMenuVisible.value = data.interviewMenuVisible ?? false
guideShown.value = data.guideShown ?? {}
practiceScrollPage.value = data.practiceScrollPage ?? 0
} catch (error) {
console.error('Failed to load Interview store', error)
}
@@ -105,7 +115,7 @@ export const useInterviewStore = defineStore(
viewed.value[key] = true
InterviewUnlockProgress.value = Math.max(
InterviewUnlockProgress.value,
Math.min(completedStep.value + 1, 4)
Math.min(completedStep.value + 1, 4),
)
saveInterviewStore()
}
@@ -116,7 +126,7 @@ export const useInterviewStore = defineStore(
const completedStep = computed<number>(() => {
const isDone = (step: 1 | 2 | 3) =>
stepRouteNames[step].every(name => viewed.value[name] === true)
stepRouteNames[step].every((name) => viewed.value[name] === true)
if (isDone(1) && isDone(2) && isDone(3)) return 3
if (isDone(1) && isDone(2)) return 2
@@ -127,7 +137,7 @@ export const useInterviewStore = defineStore(
const progressPercent = computed<number>(() => {
const allRoutes = (Object.values(stepRouteNames) as string[][]).flat()
if (allRoutes.length === 0) return 0
const viewedCount = allRoutes.filter(name => viewed.value[name]).length
const viewedCount = allRoutes.filter((name) => viewed.value[name]).length
return Math.round((viewedCount / allRoutes.length) * 100)
})
@@ -173,6 +183,11 @@ export const useInterviewStore = defineStore(
saveInterviewStore()
}
function setPracticeScrollPage(value: number): void {
practiceScrollPage.value = value
saveInterviewStore()
}
function resetInterviewState(): void {
viewed.value = {}
isGuideInterviewTask.value = true
@@ -183,6 +198,7 @@ export const useInterviewStore = defineStore(
InterviewUnlockProgress.value = 0
interviewMenuVisible.value = false
guideShown.value = {}
practiceScrollPage.value = 0
saveInterviewStore()
}
@@ -197,6 +213,7 @@ export const useInterviewStore = defineStore(
setInterviewUnlockProgress,
setInterviewMenuVisible,
markGuideShown,
setPracticeScrollPage,
resetInterviewState,
loadInterviewStore,
saveInterviewStore,
@@ -211,10 +228,11 @@ export const useInterviewStore = defineStore(
isInterviewUnlock,
InterviewUnlockProgress,
interviewMenuVisible,
guideShown
guideShown,
practiceScrollPage,
}
},
{
persist: true
}
persist: true,
},
)