import { EndingOverlay, 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>(() => 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 [showEndingVideo, setShowEndingVideo] = 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) const [endingGuideVisible, setEndingGuideVisible] = useState(false) 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) } const handleEndingVideoEnded = () => { setShowEndingVideo(false) setEndingGuideVisible(true) } return (
<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 === 4) { setShowEndingVideo(true) } } 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} /> )} {showEndingVideo && ( <Video src={getPublicPath('video/rongdesheng/rongdesheng_11.mp4')} className="fixed inset-0 z-20000" autoPlay playsInline showSkipButton onEnded={handleEndingVideoEnded} onSkip={handleEndingVideoEnded} /> )} <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> <EndingOverlay visible={endingGuideVisible} audioSrc={getPublicPath('audio/rongdesheng/mp3_rongdesheng_30.mp3')} text="接下来,请你跨越时空,走进1915年的申新纺织厂,参与工厂的创办与运营中,在模拟决策中感受民族工业在风雨中崛起的力量。让我们带着这份感动与启发,传承爱国情怀,续写新时代的实业篇章。" animationSpeed={200} onContinue={() => setEndingGuideVisible(false)} /> </div> ) } export default RongdeshengPlace4