更新依赖项及历史人物相关内容资源

- 更新 package.json 和 package-lock.json 中的依赖项
- 新增/更新陈云、黄炎培、鲁迅、孙中山的音频文件
- 新增场景和组件的图片资源
- 清理未使用的音频和图片文件
- 优化多个组件和页面的实现逻辑
This commit is contained in:
zhongyidian committed 2026-04-20 13:27:18 +08:00
1 parent b1d55b9464
commit e0fa47d21a
629 files changed
+24390 -2991

No files matched your search

+176
View File
@@ -0,0 +1,176 @@
import {
EndingOverlay,
ExhibitOverlay,
GuideSteps,
GuideStepsItem,
Image,
Title,
} from '@/components'
import Cursor from '@/components/cursor'
import { getBackgroundImage, getPublicPath, getStaticImage } from '@/lib/utils'
import { useRef, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { useNieerStore, saveNieerStore } from '@/store/nieerStore'
import { useCursorController } from '@/hooks/useCursorController'
const NieerPlace6 = () => {
const navigate = useNavigate()
const { moduleName } = useParams<{ moduleName: string }>()
const starName = 'nieer'
const place = 'place6'
const { markExhibitVisited, getVisitedExhibits } = useNieerStore()
const [activeExhibitId, setActiveExhibitId] = useState<1 | 2 | null>(null)
const [guide1Visible, setGuide1Visible] = useState(false)
const [guide1Step, setGuide1Step] = useState(0)
const total = 2
const visitedExhibits = getVisitedExhibits(place)
const visited = new Set(visitedExhibits)
const progressCount = visited.size
const completed = progressCount >= total
const [endingVisible, setEndingVisible] = useState(false)
// 是否已展示过结束语(用于控制“离开场景”按钮出现时机)
// 若用户刷新页面且已完成,则默认视为结束语已展示,避免卡住无法离开
const [endingShown, setEndingShown] = useState(() => completed)
const endingShownRef = useRef(false)
const subtitle = completed ? '已完成' : `${progressCount}/${total}`
const { isEnabled } = useCursorController({
initialEnabled: [1],
dependencies: {
2: [1],
},
visited: visitedExhibits,
})
if (!moduleName) return null
const exhibitSrcMap: Record<1 | 2, string> = {
1: 'nieer/place6/场景6展品1',
2: 'nieer/place6/场景6展品2',
}
const handleOpenExhibit = (id: 1 | 2) => {
setActiveExhibitId(id)
if (id === 1) {
setGuide1Step(0)
setGuide1Visible(true)
}
}
return (
<div
className="w-full h-full bg-cover bg-center bg-no-repeat"
style={{
backgroundImage: getBackgroundImage(`${starName}/${place}/场景6`),
}}
>
<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={() => navigate(`/${moduleName}/${starName}/place5`)}
/>
<Cursor
className="absolute left-90 bottom-130"
onClick={() => handleOpenExhibit(1)}
read={visited.has(1)}
disabled={!isEnabled(1)}
/>
<Cursor
className="absolute right-240 bottom-135"
onClick={() => handleOpenExhibit(2)}
read={visited.has(2)}
disabled={!isEnabled(2)}
/>
{/* 最后一个场景:完成后不显示“前进”按钮 */}
{completed && endingShown && !endingVisible && (
<Image
className="absolute bottom-0 right-0"
src={getStaticImage('components/place/离开场景')}
button
onClick={() => navigate(`/${moduleName}/${starName}/home`)}
/>
)}
<ExhibitOverlay
visible={activeExhibitId !== null}
src={activeExhibitId ? exhibitSrcMap[activeExhibitId] : ''}
onClose={() => {
const closingId = activeExhibitId
setActiveExhibitId(null)
setGuide1Visible(false)
if (closingId !== null) {
markExhibitVisited(place, closingId)
saveNieerStore()
// 仅在“关闭展品”这一刻触发结束语:当本次关闭导致完成时,弹出 EndingOverlay
const nextVisitedSize = visited.has(closingId) ? visited.size : visited.size + 1
const willComplete = nextVisitedSize >= total
if (willComplete && !endingShownRef.current) {
endingShownRef.current = true
setEndingShown(true)
setEndingVisible(true)
}
}
}}
/>
{/* 光标1对话(图1) */}
<GuideSteps
visible={guide1Visible}
currentStep={guide1Step}
onStepChange={setGuide1Step}
onVisibleChange={setGuide1Visible}
showMask={false}
highlightSelectors={[]}
zIndex={10001}
>
<GuideStepsItem
speaker="student"
audioSrc={getPublicPath('audio/nieer/mp3_nieer_place6_01.mp3')}
>
小沪,这些不同场景下奏响国歌的画面太让人感动了!在和平年代,这首歌还有什么特别的意义呢?
</GuideStepsItem>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/nieer/mp3_nieer_place6_02.mp3')}
>
和平年代里,它的精神力量依然不减。你看这张许海峰奥运夺金的照片,国歌奏响时,是民族自豪的宣告;神舟飞船升空时的国歌,是航天人攻坚克难的礼赞;
</GuideStepsItem>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/nieer/mp3_nieer_place6_03.mp3')}
>
抗震救灾现场的国歌,是全国人民众志成城的誓言。它就像一根精神纽带,无论在高光时刻还是艰难关头,都能凝聚起全国人民的力量,提醒我们不忘历史、砥砺前行。
</GuideStepsItem>
</GuideSteps>
{/* completed 后的结束语:统一使用 EndingOverlay */}
<EndingOverlay
visible={endingVisible}
text={
'从民族危机中觉醒的热血青年,到《义勇军进行曲》的谱曲者,聂耳用音符奏响了“救亡图存”的时代强音。' +
'而《义勇军进行曲》的影响远不止于此,接下来,请你化身国歌时空旅行者,踏入6个散落于岁月中的故事现场,' +
'一路聆听、一路共鸣,亲身体验这首旋律如何跨越时空,成为永远激荡在国人心中的精神号角吧!'
}
animationSpeed={200}
onContinue={() => setEndingVisible(false)}
/>
</div>
)
}
export default NieerPlace6