import { useParams, useNavigate, Navigate } from 'react-router-dom' import { useEffect, useMemo, useState } from 'react' import { Tutorial } from '@components/Tutorial' import { useTutorialStore } from '@stores/tutorialStore' import { isValidTutorialId, loadStepComponents, tutorialConfigMap, tutorialSummaries, } from '@/tutorial/loader' export function TutorialPage() { const { tutorialId, stepIndex } = useParams<{ tutorialId: string; stepIndex?: string }>() const navigate = useNavigate() const { setActiveTutorial, setCurrentStep, currentStepIndex } = useTutorialStore() const [StepComponents, setStepComponents] = useState>({}) // 验证教程 ID 有效性 if (!tutorialId || !isValidTutorialId(tutorialId)) { return } const activeTutorialConfig = tutorialConfigMap[tutorialId] || null // 加载步骤组件 useEffect(() => { if (!tutorialId) return setStepComponents(loadStepComponents(tutorialId)) }, [tutorialId]) // 设置教程配置 useEffect(() => { if (activeTutorialConfig && tutorialId) { setActiveTutorial(tutorialId, activeTutorialConfig) } }, [activeTutorialConfig, tutorialId, setActiveTutorial]) // 从 URL 同步步骤索引到 store useEffect(() => { if (stepIndex !== undefined) { const index = parseInt(stepIndex, 10) if (!isNaN(index) && index >= 0 && activeTutorialConfig && index < activeTutorialConfig.steps.length) { setCurrentStep(index) } } }, [stepIndex, activeTutorialConfig, setCurrentStep]) // 同步 store 步骤索引到 URL useEffect(() => { if (!tutorialId || !activeTutorialConfig) return const currentPath = `/${tutorialId}` const stepPath = currentStepIndex > 0 ? `/${currentStepIndex}` : '' // 只有当 URL 不匹配时才更新 const expectedPath = `${currentPath}${stepPath}` if (window.location.pathname !== expectedPath) { navigate(expectedPath, { replace: true }) } }, [tutorialId, currentStepIndex, activeTutorialConfig, navigate]) const tutorialOptions = useMemo( () => tutorialSummaries.map((item) => ({ id: item.id, title: item.title, })), [] ) const handleSelectTutorial = (newTutorialId: string) => { if (isValidTutorialId(newTutorialId)) { navigate(`/${newTutorialId}`) } } const handleBackToHub = () => { navigate('/') } const CurrentStep = StepComponents[currentStepIndex] if (!activeTutorialConfig) { return (

加载教程中...

) } if (!CurrentStep) { return (

加载步骤内容...

) } return ( 1} onSelectTutorial={handleSelectTutorial} onBackToHub={handleBackToHub} > ) }