feat:修改英文双引号
This commit is contained in:
commit
4a2be3b4d0
1351 files changed
+56547
No files matched your search
@@ -0,0 +1,316 @@
|
||||
import {
|
||||
ExhibitOverlay,
|
||||
GuideSteps,
|
||||
GuideStepsItem,
|
||||
Image,
|
||||
StudyGuideModal,
|
||||
Title,
|
||||
SelectFillQuizPanel,
|
||||
Video,
|
||||
type VideoRef,
|
||||
} from '@/components'
|
||||
import { useNavigate, useParams } from 'react-router-dom'
|
||||
import { getBackgroundImage, getPublicPath, getStaticImage } from '@/lib/utils'
|
||||
import { useMemo, useRef, useState } from 'react'
|
||||
import Cursor from '@/components/cursor'
|
||||
import { useCursorController } from '@/hooks/useCursorController'
|
||||
import SuccessAlert from '@/components/layout/alert/success-alert'
|
||||
import ScaledPortal from '@/components/layout/ScaledPortal'
|
||||
import type { SelectFillResult } from '@/components/layout/quiz'
|
||||
import { saveMaozedongStore, useMaozedongStore } from '@/store/maozedongStore'
|
||||
import { usePuzzleAnimation } from '@/contexts/PuzzleAnimationContext'
|
||||
|
||||
// starName 固定为 maozedong
|
||||
const starName = 'maozedong'
|
||||
|
||||
// 展品 ID 与资源路径映射,ID 用来做唯一标识
|
||||
const exhibitSrcMap: Record<1 | 2, string> = {
|
||||
1: 'maozedong/place1/场景1展品1',
|
||||
2: 'maozedong/place1/场景1展品2',
|
||||
}
|
||||
|
||||
const MaozedongPlace1 = () => {
|
||||
const navigate = useNavigate()
|
||||
const { moduleName } = useParams<{
|
||||
moduleName: string
|
||||
}>()
|
||||
|
||||
// 获取碎片动画触发方法
|
||||
const { triggerPuzzleAnimation } = usePuzzleAnimation()
|
||||
|
||||
// 接入持久化:记录本场景 place1 的已访问展品与断点
|
||||
const markVisited = useMaozedongStore((s) => s.markExhibitVisited)
|
||||
const getVisited = useMaozedongStore((s) => s.getVisitedExhibits)
|
||||
const setLastVisitedPlace = useMaozedongStore((s) => s.setLastVisitedPlace)
|
||||
const persistedVisited = useMemo(() => new Set(getVisited('place1') as (1 | 2)[]), [getVisited])
|
||||
|
||||
// 学习引导弹窗
|
||||
const [showGuideModal, setShowGuideModal] = useState(true)
|
||||
|
||||
// 对话结束后的学习引导弹窗
|
||||
const [showAfterDialogGuide, setShowAfterDialogGuide] = useState(false)
|
||||
|
||||
// 展品2的对话引导状态
|
||||
const [guideVisible2, setGuideVisible2] = useState(false)
|
||||
const [guideStep2, setGuideStep2] = useState(0)
|
||||
|
||||
// 当前激活的展品 ID
|
||||
const [activeExhibitId, setActiveExhibitId] = useState<1 | 2 | null>(null)
|
||||
// 已访问的展品(初始化自 store;随后每次关闭展品时写回)
|
||||
const [visited, setVisited] = useState<Set<1 | 2>>(() => new Set(persistedVisited))
|
||||
|
||||
// 展品2关闭后播放的视频 + 选择填空题
|
||||
const [showVideo2, setShowVideo2] = useState(false)
|
||||
const video2Ref = useRef<VideoRef>(null)
|
||||
const [quizVisible, setQuizVisible] = useState(false)
|
||||
const [successAlertVisible, setSuccessAlertVisible] = useState(false)
|
||||
|
||||
// Cursor 顺序控制:1 -> 2
|
||||
const { isEnabled } = useCursorController({
|
||||
initialEnabled: [2],
|
||||
dependencies: {
|
||||
1: [2],
|
||||
},
|
||||
visited,
|
||||
})
|
||||
|
||||
const handleOpenExhibit = (id: 1 | 2) => {
|
||||
setActiveExhibitId(id)
|
||||
// 根据展品ID显示对应的对话
|
||||
if (id === 1) {
|
||||
setGuideVisible2(true)
|
||||
setGuideStep2(0)
|
||||
}
|
||||
}
|
||||
|
||||
// 监听展品2对话引导步骤变化
|
||||
const handleGuideStepChange2 = (step: number) => {
|
||||
setGuideStep2(step)
|
||||
}
|
||||
|
||||
// 监听展品2对话引导完成
|
||||
const handleGuideVisibleChange2 = (visible: boolean) => {
|
||||
setGuideVisible2(visible)
|
||||
}
|
||||
|
||||
const progressCount = visited.size
|
||||
const total = 2
|
||||
const completed = progressCount >= total
|
||||
const subtitle = completed ? '已完成' : `${progressCount}/${total}`
|
||||
|
||||
if (!moduleName) return null
|
||||
|
||||
return (
|
||||
<div
|
||||
className="w-full h-full bg-cover bg-center bg-no-repeat"
|
||||
style={{
|
||||
backgroundImage: getBackgroundImage(`${starName}/place1/场景1`),
|
||||
}}
|
||||
>
|
||||
{/* 标题 */}
|
||||
<Title
|
||||
title="探索方向·确立信仰"
|
||||
subtitle={subtitle}
|
||||
className="absolute top-10 left-1/2 -translate-x-1/2"
|
||||
/>
|
||||
|
||||
<Image
|
||||
className="absolute right-5 top-5"
|
||||
src={getStaticImage('components/离开')}
|
||||
button
|
||||
onClick={() => {
|
||||
if (moduleName && starName) {
|
||||
navigate(`/${moduleName}/${starName}/home`)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 光标1 */}
|
||||
<Cursor
|
||||
className="absolute left-106 bottom-150"
|
||||
onClick={() => handleOpenExhibit(1)}
|
||||
read={visited.has(1)}
|
||||
disabled={!isEnabled(1)}
|
||||
/>
|
||||
{/* 光标2 */}
|
||||
<Cursor
|
||||
className="absolute left-170 bottom-135"
|
||||
onClick={() => handleOpenExhibit(2)}
|
||||
read={visited.has(2)}
|
||||
disabled={!isEnabled(2)}
|
||||
/>
|
||||
|
||||
{/* 继续前进 - 仅在完成所有展品后显示 */}
|
||||
{completed && (
|
||||
<Image
|
||||
className="absolute bottom-0 right-140"
|
||||
src={getStaticImage(`${starName}/place1/场景1继续前进`)}
|
||||
button
|
||||
onClick={() => {
|
||||
setLastVisitedPlace('place2')
|
||||
saveMaozedongStore()
|
||||
navigate(`/${moduleName}/${starName}/place2`)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 展品2的对话引导 */}
|
||||
<GuideSteps
|
||||
visible={guideVisible2}
|
||||
onVisibleChange={handleGuideVisibleChange2}
|
||||
currentStep={guideStep2}
|
||||
onStepChange={handleGuideStepChange2}
|
||||
showMask={false}
|
||||
highlightSelectors={[]}
|
||||
zIndex={10001}
|
||||
>
|
||||
<GuideStepsItem
|
||||
speaker="student"
|
||||
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_03.mp3')}
|
||||
>
|
||||
那参加中共一大时,毛主席对未来有什么想法吗?
|
||||
</GuideStepsItem>
|
||||
<GuideStepsItem speaker="guide" audioSrc={getPublicPath('audio/maozedong/mp3_mzd_04.mp3')}>
|
||||
当时全国只有50多个党员,毛主席所在的湖南也才几个。但他觉得,重要的是把马克思主义和中国的实际情况结合起来。就像种田,种子再好,也得看土壤——中国的“土壤”就是农民占大多数,这是和苏联不一样的地方。
|
||||
</GuideStepsItem>
|
||||
</GuideSteps>
|
||||
|
||||
{/* 展品遮罩层 */}
|
||||
<ExhibitOverlay
|
||||
visible={activeExhibitId !== null}
|
||||
src={activeExhibitId ? exhibitSrcMap[activeExhibitId] : ''}
|
||||
onOpen={() => {
|
||||
if (activeExhibitId === 2) {
|
||||
triggerPuzzleAnimation(1)
|
||||
}
|
||||
if (activeExhibitId === 1) {
|
||||
triggerPuzzleAnimation(2)
|
||||
}
|
||||
}}
|
||||
onClose={() => {
|
||||
if (activeExhibitId === 2) {
|
||||
setActiveExhibitId(null)
|
||||
setShowVideo2(true)
|
||||
return
|
||||
}
|
||||
|
||||
if (activeExhibitId !== null) {
|
||||
setVisited((prev) => {
|
||||
const next = new Set(prev)
|
||||
next.add(activeExhibitId)
|
||||
// 写回持久化
|
||||
markVisited('place1', activeExhibitId)
|
||||
return next
|
||||
})
|
||||
}
|
||||
setActiveExhibitId(null)
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 展品2关闭后播放的视频 */}
|
||||
{showVideo2 && (
|
||||
<Video
|
||||
ref={video2Ref}
|
||||
src={getPublicPath('video/maozedong/mzd_00.mp4')}
|
||||
className="fixed inset-0 z-20000"
|
||||
autoPlay
|
||||
playsInline
|
||||
showSkipButton
|
||||
onEnded={() => {
|
||||
setShowVideo2(false)
|
||||
setQuizVisible(true)
|
||||
}}
|
||||
onSkip={() => {
|
||||
setShowVideo2(false)
|
||||
setQuizVisible(true)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 展品2对话结束后的选择填空题 + 成功提示(使用 ScaledPortal) */}
|
||||
<ScaledPortal enabled={quizVisible || successAlertVisible} zIndex={10050}>
|
||||
<>
|
||||
<SelectFillQuizPanel
|
||||
visible={quizVisible}
|
||||
titlePrefix="【填空】毛泽东主席认为,到了"
|
||||
titleSuffix="年夏天,在理论上,而且在某种程度的行动上,他已成为一个马克思主义者了。"
|
||||
blanks={[{ id: 'd1' }, { id: 'd2' }, { id: 'd3' }, { id: 'd4' }]}
|
||||
options={[
|
||||
{ value: '0', label: '0' },
|
||||
{ value: '1', label: '1' },
|
||||
{ value: '2', label: '2' },
|
||||
{ value: '3', label: '3' },
|
||||
{ value: '4', label: '4' },
|
||||
{ value: '5', label: '5' },
|
||||
{ value: '6', label: '6' },
|
||||
{ value: '7', label: '7' },
|
||||
{ value: '8', label: '8' },
|
||||
{ value: '9', label: '9' },
|
||||
]}
|
||||
correctAnswers={{
|
||||
d1: '1',
|
||||
d2: '9',
|
||||
d3: '2',
|
||||
d4: '0',
|
||||
}}
|
||||
errorMessage="1920年5月5日到7月初,在上海居住的2个月期间,毛主席的思想完成了向马克思主义者的转变。请你再想想吧!"
|
||||
onSubmit={(_results: SelectFillResult[], isCorrect: boolean) => {
|
||||
if (isCorrect) {
|
||||
setQuizVisible(false)
|
||||
setSuccessAlertVisible(true)
|
||||
}
|
||||
}}
|
||||
onError={(_error: string) => {
|
||||
// 错误时仅提示,再让学生重做
|
||||
}}
|
||||
submitText="确定"
|
||||
zIndex={10000}
|
||||
/>
|
||||
|
||||
<SuccessAlert
|
||||
visible={successAlertVisible}
|
||||
onContinue={() => {
|
||||
setSuccessAlertVisible(false)
|
||||
setVisited((prev) => {
|
||||
const next = new Set(prev)
|
||||
next.add(2)
|
||||
markVisited('place1', 2)
|
||||
return next
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
</ScaledPortal>
|
||||
|
||||
{/* 学习引导词 */}
|
||||
<StudyGuideModal
|
||||
visible={showGuideModal}
|
||||
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_02.mp3')}
|
||||
onContinue={() => {
|
||||
setShowGuideModal(false)
|
||||
setShowAfterDialogGuide(true)
|
||||
}}
|
||||
ailgn="left"
|
||||
>
|
||||
1.场景中出现动态光点的展品表示未浏览,可通过点击光点来了解展品背后的故事,通过滚轮可以放大展品,浏览展品后蓝色动态光点会变为已浏览状态。
|
||||
{'\n'}
|
||||
2.在学习过程中会掉落拼图碎片,拼图碎片会自动收入拼图盒中,拼图盒可以点开查看当前拼图收集情况,点击单个拼图可以回到获得拼图的场景再次学习。
|
||||
{'\n'}
|
||||
3.所有动态光点的展品全部学习后才能进入下一个场景学习。
|
||||
</StudyGuideModal>
|
||||
|
||||
{/* 对话结束后的学习引导 */}
|
||||
<StudyGuideModal
|
||||
visible={showAfterDialogGuide}
|
||||
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_01.mp3')}
|
||||
onContinue={() => setShowAfterDialogGuide(false)}
|
||||
firstLineIndent="2em"
|
||||
>
|
||||
{`同学你好,欢迎来到“走进故居·对话”学习模块!
|
||||
此刻你正处在毛泽东旧居陈列馆里,接下来请跟着时光的脚步,一同回望毛泽东主席人生中4段风云激荡的岁月:摸索方向 确立信仰、播撒红色火种、吹响合作号角、唤起工农群众。准备好推开这扇门,走进那段滚烫的峥嵘岁月了吗?`}
|
||||
</StudyGuideModal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MaozedongPlace1
|
||||
Reference in new issue
Block a user