feat:修改英文双引号

This commit is contained in:
kevinzhu committed 2026-04-30 09:17:31 +08:00
commit 4a2be3b4d0
1351 files changed
+56547

No files matched your search

+257
View File
@@ -0,0 +1,257 @@
import { useState, useEffect } from 'react'
import { Title, Image, Cursor, StudyGuideModal } from '@/components'
import { SuccessAlert } from '@/components/layout'
import { getBackgroundImage, getPublicPath, getStaticImage } from '@/lib/utils'
import { useNavigate, useParams } from 'react-router-dom'
import ChoiceDialog1 from './scene2/ChoiceDialog1'
import ChoiceDialog2 from './scene2/ChoiceDialog2'
import QuizDialog from './scene2/QuizDialog'
import {
useHuangyanpeiStore,
saveHuangyanpeiStore,
loadHuangyanpeiStore,
} from '@/store/huangyanpeiStore'
import { useCursorController } from '@/hooks/useCursorController'
const starName = 'huangyanpei'
const HuangyanpeiReflectionScene2 = () => {
const navigate = useNavigate()
const { moduleName } = useParams<{
moduleName: string
}>()
const [showGuideModal, setShowGuideModal] = useState(true)
const [showDialog1, setShowDialog1] = useState(false)
const [showDialog2, setShowDialog2] = useState(false)
const [choice2, setChoice2] = useState<'铁工科' | '商科' | null>(null)
const [showCompleteGuide, setShowCompleteGuide] = useState(false)
// 题目显示状态(ChoiceDialog1关闭后)
const [showQuiz, setShowQuiz] = useState(false)
// 题目成功提示状态
const [showQuizSuccess, setShowQuizSuccess] = useState(false)
// 使用持久化的reflection cursor状态
const scene = 'scene2'
const {
markReflectionCursorVisited,
getVisitedReflectionCursors,
setReflectionRoute,
reflectionScene2Choice,
setReflectionScene2Choice,
hasShownReflectionCompletionGuide,
markReflectionCompletionGuideShown,
} = useHuangyanpeiStore()
// 从 store 获取已完成的cursor,转换为 Set 用于兼容现有代码
const visitedCursors = getVisitedReflectionCursors(scene)
const visited = new Set(visitedCursors)
const { isEnabled } = useCursorController({
initialEnabled: [1],
dependencies: { 2: [1] },
visited: visitedCursors,
})
const progressCount = visited.size
const total = 2
const completed = progressCount >= total
const subtitle = completed ? '已完成' : `${progressCount}/${total}`
const subtitleClassName = completed
? 'text-[#fff998] [text-shadow:_0_8px_8px_rgba(0,0,0,0.35),_0_0_16px_rgba(0,0,0,0.25)]'
: undefined
// 进入页面时读取缓存中的 choice2
useEffect(() => {
let mounted = true
const syncChoice2FromCache = async () => {
await loadHuangyanpeiStore()
if (!mounted) {
return
}
const latestChoice2 = useHuangyanpeiStore.getState().reflectionScene2Choice
if (latestChoice2) {
setChoice2(latestChoice2)
}
}
void syncChoice2FromCache()
return () => {
mounted = false
}
}, [])
// 本地状态与 store 中的 choice2 保持同步
useEffect(() => {
if (reflectionScene2Choice && reflectionScene2Choice !== choice2) {
setChoice2(reflectionScene2Choice)
}
}, [reflectionScene2Choice, choice2])
// 两个任务都完成后,显示完成提示(仅一次)
useEffect(() => {
if (completed && choice2 && !hasShownReflectionCompletionGuide(scene)) {
const timer = setTimeout(() => {
setShowCompleteGuide(true)
markReflectionCompletionGuideShown(scene)
saveHuangyanpeiStore()
}, 500)
return () => clearTimeout(timer)
}
}, [
completed,
choice2,
scene,
hasShownReflectionCompletionGuide,
markReflectionCompletionGuideShown,
])
// 处理完成提示的继续按钮点击
const handleCompleteGuideContinue = () => {
setShowCompleteGuide(false)
// 根据选择决定导航目标
if (choice2 === '铁工科') {
setReflectionRoute('reflection3')
saveHuangyanpeiStore()
navigate(`/${moduleName}/${starName}/reflection3`)
} else if (choice2 === '商科') {
setReflectionRoute('reflection4')
saveHuangyanpeiStore()
navigate(`/${moduleName}/${starName}/reflection4`)
}
}
if (!moduleName) {
return null
}
return (
<div
className="w-full h-full bg-cover bg-center bg-no-repeat"
style={{
backgroundImage: getBackgroundImage(`huangyanpei/reflection/scene2/10_001`),
}}
>
<Title
title="跨越时空"
subtitle={subtitle}
subtitleClassName={subtitleClassName}
className="absolute top-10 left-1/2 -translate-x-1/2"
/>
<Image
className="absolute right-5 top-5"
src={getStaticImage('components/离开')}
button
onClick={() => {
navigate(`/${moduleName}/${starName}/home`)
}}
/>
{completed && (
<Image
className="absolute bottom-0 right-0 z-20"
src={getStaticImage('components/place/继续前进')}
button
onClick={() => handleCompleteGuideContinue()}
/>
)}
<StudyGuideModal
visible={showGuideModal}
onContinue={() => setShowGuideModal(false)}
audioSrc={getPublicPath('audio/huangyanpei/mp3_huangyanpei_24.mp3')}
>
欢迎来到浦东中学!{'\n'}
这是近代上海第一所完全中学,黄炎培先生当首任校长,在这里能学到更多实用知识,还能树立成才的理想哦。
</StudyGuideModal>
{choice2 && (
<img
className="absolute right-[234px] bottom-12.5"
src={getStaticImage('huangyanpei/reflection/scene2/10_003')}
alt="已解锁指示牌盖板"
/>
)}
{/* 互动展品光标1:显示第一个选择弹窗 */}
<Cursor
className="absolute left-118 bottom-105"
onClick={() => {
setShowDialog1(true)
}}
read={visited.has(1)}
disabled={!isEnabled(1)}
/>
{/* 互动展品光标2:显示第二个选择弹窗 */}
<Cursor
className="absolute right-74 bottom-68"
onClick={() => {
setShowDialog2(true)
}}
read={visited.has(2)}
disabled={!isEnabled(2)}
/>
{/* 第一个选择弹窗 */}
<ChoiceDialog1
visible={showDialog1}
onClose={() => {
setShowDialog1(false)
setShowQuiz(true)
}}
onSelect={() => {
markReflectionCursorVisited(scene, 1)
}}
/>
{/* 第二个选择弹窗 */}
<ChoiceDialog2
visible={showDialog2}
onClose={() => setShowDialog2(false)}
onSelect={(choice) => {
setChoice2(choice)
setReflectionScene2Choice(choice)
markReflectionCursorVisited(scene, 2)
saveHuangyanpeiStore()
}}
/>
<QuizDialog
visible={showQuiz}
onClose={() => setShowQuiz(false)}
onComplete={() => {
setShowQuiz(false)
setShowQuizSuccess(true)
}}
/>
{/* 题目成功提示 */}
<SuccessAlert
visible={showQuizSuccess}
title=""
content="恭喜你!选择正确。不愧是从川沙小学堂走出来!"
onContinue={() => {
setShowQuizSuccess(false)
}}
onClose={() => {
setShowQuizSuccess(false)
}}
/>
{/* 完成提示 */}
<StudyGuideModal
visible={showCompleteGuide}
onContinue={handleCompleteGuideContinue}
verticalAlign="center"
>
第二关完成!“职业方向锁定!”去新学校了解你的专业吧。
</StudyGuideModal>
</div>
)
}
export default HuangyanpeiReflectionScene2