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

- 更新 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

+308
View File
@@ -0,0 +1,308 @@
import { ExhibitOverlay, GuideSteps, GuideStepsItem, Image, Title, Video } from '@/components'
import Cursor from '@/components/cursor'
import { useCursorController } from '@/hooks/useCursorController'
import { getBackgroundImage, getPublicPath, getStaticImage } from '@/lib/utils'
import { useMemo, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { saveRongdeshengStore, useRongdeshengStore } from '@/store/rongdeshengStore'
const starName = 'rongdesheng'
const place = 'place4'
const RongdeshengPlace4 = () => {
const navigate = useNavigate()
const { moduleName } = useParams<{ moduleName: string }>()
const { markExhibitVisited, getVisitedExhibits, setLastVisitedPlace } = useRongdeshengStore()
const persistedVisited = useMemo(
() => new Set(getVisitedExhibits(place) as (1 | 2 | 3 | 4)[]),
[getVisitedExhibits]
)
const [visited, setVisited] = useState<Set<1 | 2 | 3 | 4>>(() => new Set(persistedVisited))
const total = 4
const progressCount = visited.size
const completed = progressCount >= total
const subtitle = completed ? '已完成' : `${progressCount}/${total}`
// cursor:1 -> 2 -> 3 -> 4
const { isEnabled } = useCursorController({
initialEnabled: [1],
dependencies: {
2: [1],
3: [2],
4: [3],
},
visited,
})
const [activeExhibitId, setActiveExhibitId] = useState<1 | 2 | 3 | 4 | null>(null)
const [showVideo, setShowVideo] = useState(false)
const [guide1Visible, setGuide1Visible] = useState(false)
const [guide1Step, setGuide1Step] = useState(0)
const [guide1AfterVideoVisible, setGuide1AfterVideoVisible] = useState(false)
const [guide1AfterVideoStep, setGuide1AfterVideoStep] = useState(0)
const [guide2Visible, setGuide2Visible] = useState(false)
const [guide2Step, setGuide2Step] = useState(0)
const [guide3Visible, setGuide3Visible] = useState(false)
const [guide3Step, setGuide3Step] = useState(0)
const [guide4Visible, setGuide4Visible] = useState(false)
const [guide4Step, setGuide4Step] = useState(0)
if (!moduleName) return null
const exhibitSrcMap: Record<1 | 2 | 3 | 4, string> = {
1: 'rongdesheng/place4/场景4展品1',
2: 'rongdesheng/place4/场景4展品2',
3: 'rongdesheng/place4/场景4展品3',
4: 'rongdesheng/place4/场景4展品4',
}
const handleOpenExhibit = (id: 1 | 2 | 3 | 4) => {
setActiveExhibitId(id)
if (id === 1) {
setGuide1Step(0)
setGuide1Visible(true)
}
if (id === 2) {
setGuide2Step(0)
setGuide2Visible(true)
}
if (id === 3) {
setGuide3Step(0)
setGuide3Visible(true)
}
if (id === 4) {
setGuide4Step(0)
setGuide4Visible(true)
}
}
const handleVideoEnded = () => {
setShowVideo(false)
setGuide1AfterVideoStep(0)
setGuide1AfterVideoVisible(true)
}
return (
<div
className="w-full h-full bg-cover bg-center bg-no-repeat"
style={{
backgroundImage: getBackgroundImage(`${starName}/${place}/场景4`),
}}
>
<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}/place3`)}
/>
<Cursor
className="absolute left-73 bottom-145"
onClick={() => handleOpenExhibit(1)}
read={visited.has(1)}
disabled={!isEnabled(1)}
/>
<Cursor
className="absolute left-120 bottom-145"
onClick={() => handleOpenExhibit(2)}
read={visited.has(2)}
disabled={!isEnabled(2)}
/>
<Cursor
className="absolute left-165 bottom-145"
onClick={() => handleOpenExhibit(3)}
read={visited.has(3)}
disabled={!isEnabled(3)}
/>
{/* 展品 */}
<Cursor
className="absolute left-175 bottom-70"
onClick={() => handleOpenExhibit(4)}
read={visited.has(4)}
disabled={!isEnabled(4)}
/>
{completed && (
<Image
className="absolute bottom-0 right-0"
src={getStaticImage('components/place/离开场景')}
button
onClick={() => {
setLastVisitedPlace('place4')
saveRongdeshengStore()
navigate(`/${moduleName}/${starName}/home`)
}}
/>
)}
<ExhibitOverlay
visible={activeExhibitId !== null}
src={activeExhibitId ? exhibitSrcMap[activeExhibitId] : ''}
onClose={() => {
if (activeExhibitId === null) return
const closingId = activeExhibitId
setActiveExhibitId(null)
// 展品1在视频后对话结束再改状态;2/3/4关闭展品即改状态
if (closingId === 2 || closingId === 3 || closingId === 4) {
setVisited((prev) => {
const next = new Set(prev)
next.add(closingId)
markExhibitVisited(place, closingId)
saveRongdeshengStore()
return next
})
}
if (closingId === 1) {
setShowVideo(true)
}
}}
/>
{showVideo && (
<Video
src={getPublicPath('video/rongdesheng/rongdesheng_10.mp4')}
className="fixed inset-0 z-20000"
autoPlay
playsInline
showSkipButton
onEnded={handleVideoEnded}
onSkip={handleVideoEnded}
/>
)}
<GuideSteps
visible={guide1Visible}
onVisibleChange={setGuide1Visible}
currentStep={guide1Step}
onStepChange={setGuide1Step}
showMask={false}
highlightSelectors={[]}
zIndex={10001}
>
<GuideStepsItem
speaker="student"
audioSrc={getPublicPath('audio/rongdesheng/mp3_rongdesheng_22.mp3')}
>
荣德生先生竟然遭遇过绑架?这是怎么回事?他是怎么度过这次危机的?
</GuideStepsItem>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/rongdesheng/mp3_rongdesheng_23.mp3')}
>
1946年,荣德生先生在上海高恩路(现高安路)住所门前遭到绑架,绑匪勒索巨额款项,将他囚禁了35天。这是当时的新闻报道。面对突如其来的变故,荣氏企业内部沉着应对,在保障人身安全的前提下,积极与绑匪谈判,最终筹集款项将他赎回。
</GuideStepsItem>
</GuideSteps>
<GuideSteps
visible={guide1AfterVideoVisible}
onVisibleChange={(v) => {
setGuide1AfterVideoVisible(v)
if (!v) {
setVisited((prev) => {
const next = new Set(prev)
if (!next.has(1)) {
next.add(1)
markExhibitVisited(place, 1)
saveRongdeshengStore()
}
return next
})
}
}}
currentStep={guide1AfterVideoStep}
onStepChange={setGuide1AfterVideoStep}
showMask={false}
highlightSelectors={[]}
zIndex={10001}
>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/rongdesheng/mp3_rongdesheng_24.mp3')}
>
这次绑架事件让荣先生身心受到巨大创伤,但也让他更加看清了当时社会的动荡不安,坚定了他期盼国家安定、民族工业能平稳发展的愿望。
</GuideStepsItem>
</GuideSteps>
<GuideSteps
visible={guide2Visible}
onVisibleChange={setGuide2Visible}
currentStep={guide2Step}
onStepChange={setGuide2Step}
showMask={false}
highlightSelectors={[]}
zIndex={10001}
>
<GuideStepsItem
speaker="student"
audioSrc={getPublicPath('audio/rongdesheng/mp3_rongdesheng_25.mp3')}
>
“荣氏工业机构,绝不迁赴国外”,当时荣德生先生为什么阻止企业迁往国外啊?
</GuideStepsItem>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/rongdesheng/mp3_rongdesheng_26.mp3')}
>
1948年,解放战争接近尾声,很多实业家纷纷撤离大陆,前往台湾或海外。但荣德生先生专程从无锡来到上海,发表声明,明确表态绝不离开大陆。他在给海外亲友的信中写道:“民族工业的根基在大陆,离开这片土地,实业救国便成空谈。”
</GuideStepsItem>
<GuideStepsItem speaker="guide">
他不仅自己留下,还力排众议,阻止了荣氏企业迁台的计划,保住了大量的工厂设备、技术人才和生产资料。这份坚守,为新中国成立后的民族工业留存了重要力量,也体现了一位民族实业家的家国情怀。
</GuideStepsItem>
</GuideSteps>
<GuideSteps
visible={guide3Visible}
onVisibleChange={setGuide3Visible}
currentStep={guide3Step}
onStepChange={setGuide3Step}
showMask={false}
highlightSelectors={[]}
zIndex={10001}
>
<GuideStepsItem
speaker="student"
audioSrc={getPublicPath('audio/rongdesheng/mp3_rongdesheng_27.mp3')}
>
新中国成立后,荣氏的企业很快就复工了吗?政府对他的贡献给了肯定吗?
</GuideStepsItem>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/rongdesheng/mp3_rongdesheng_28.mp3')}
>
是的!新中国成立后,在政府的支持下,荣氏企业迅速恢复生产。荣德生先生一生致力于实业救国,为民族工业的发展作出了巨大贡献,政府也对他给予了高度肯定。
</GuideStepsItem>
</GuideSteps>
<GuideSteps
visible={guide4Visible}
onVisibleChange={setGuide4Visible}
currentStep={guide4Step}
onStepChange={setGuide4Step}
showMask={false}
highlightSelectors={[]}
zIndex={10001}
>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/rongdesheng/mp3_rongdesheng_29.mp3')}
>
晚年的荣先生依然关注民族工业的发展,积极建言献策,他创办的企业后来成为新中国轻工业的重要骨干,为国家的经济建设贡献了力量。
</GuideStepsItem>
</GuideSteps>
</div>
)
}
export default RongdeshengPlace4