Files
shanghai-residences/src/pages/huangyanpei/place/place1.tsx
T
zhongyidianandClaude Opus 4.7 6d40e19346 feat: update residence learning flows
Commit non-media application and asset changes while leaving audio, video, and environment files out of version control.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:15:26 +08:00

182 lines
6.6 KiB
TypeScript

import {
ExhibitOverlay,
GuideSteps,
GuideStepsItem,
Image,
Title,
StudyGuideModal,
} from '@/components'
import { useNavigate, useParams } from 'react-router-dom'
import { getBackgroundImage, getPublicPath, getStaticImage } from '@/lib/utils'
import { useState } from 'react'
import Cursor from '@/components/cursor'
import { usePuzzleAnimation } from '@/contexts/PuzzleAnimationContext'
import { useHuangyanpeiStore, saveHuangyanpeiStore } from '@/store/huangyanpeiStore'
// starName 固定为 huangyanpei
const starName = 'huangyanpei'
// 展品 ID 与资源路径映射,ID 用来做唯一标识
const exhibitSrcMap: Record<1, string> = {
1: 'huangyanpei/place1/3_003',
}
const HuangyanpeiPlace1 = () => {
const navigate = useNavigate()
const { moduleName } = useParams<{
moduleName: string
}>()
const { triggerPuzzleAnimation } = usePuzzleAnimation()
// 学习引导弹窗
const [showGuideModal, setShowGuideModal] = useState(true)
// 温馨提示弹窗
const [showAfterDialogGuide, setShowAfterDialogGuide] = useState(false)
// 温馨提示关闭后的引导对话显示状态
const [visible, setVisible] = useState(false)
// 当前激活的展品 ID(只存 ID,不直接存路径,便于作为唯一标识)
const [activeExhibitId, setActiveExhibitId] = useState<1 | null>(null)
// 使用持久化的访问状态
const place = 'place1'
const { markExhibitVisited, getVisitedExhibits, setLastVisitedPlace } = useHuangyanpeiStore()
// 从 store 获取已访问的展品,转换为 Set 用于兼容现有代码
const visitedExhibits = getVisitedExhibits(place)
const visited = new Set(visitedExhibits)
const handleOpenExhibit = (index: 1 | null) => {
setActiveExhibitId(index)
}
const progressCount = visited.size
const total = 1
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
return (
<div
className="w-full h-full bg-cover bg-center bg-no-repeat"
style={{
backgroundImage: getBackgroundImage(`huangyanpei/place1/3_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={() => {
if (moduleName && starName) {
navigate(`/${moduleName}/${starName}/home`)
}
}}
/>
{/* 展品1 */}
<Cursor
className="absolute left-[calc(50%-8px)] bottom-100"
onClick={() => handleOpenExhibit(1)}
read={visited.has(1)}
/>
{/* 继续前进 - 仅在完成所有展品后显示 */}
{completed && (
<Image
className="absolute bottom-0 right-0"
src={getStaticImage('components/place/继续前进')}
button
onClick={() => {
setLastVisitedPlace('place2')
saveHuangyanpeiStore()
navigate(`/${moduleName}/${starName}/place2`)
}}
/>
)}
{/* 遮罩层 */}
<ExhibitOverlay
visible={activeExhibitId !== null}
src={activeExhibitId ? exhibitSrcMap[activeExhibitId] : ''}
onOpen={() => {
if (activeExhibitId === 1) {
triggerPuzzleAnimation(1)
}
}}
onClose={() => {
if (activeExhibitId !== null) {
markExhibitVisited(place, activeExhibitId)
}
setActiveExhibitId(null)
}}
/>
{/* 学习引导 */}
<StudyGuideModal
visible={showGuideModal}
onContinue={() => {
setShowGuideModal(false)
setShowAfterDialogGuide(true)
}}
audioSrc={getPublicPath('audio/huangyanpei/mp3_huangyanpei_02.mp3')}
ailgn="left"
>
1.场景中出现动态光点的展品表示未浏览,可通过点击光点来了解展品背后的故事,通过滚轮可以放大展品,浏览展品后蓝色动态光点会变为已浏览状态。
{'\n'}
2.在学习过程中会掉落拼图碎片,拼图碎片会自动收入拼图盒中,拼图盒可以点开查看当前拼图收集情况,点击单个拼图可以回到获得拼图的场景再次学习。
{'\n'}
3.所有动态光点的展品全部学习后才能进入下一个场景学习。
</StudyGuideModal>
{/* 温馨提示关闭后的引导对话 */}
<GuideSteps visible={visible} onVisibleChange={setVisible} showMask={false}>
<GuideStepsItem
speaker="student"
audioSrc={getPublicPath('audio/huangyanpei/mp3_huangyanpei_03.mp3')}
>
小沪,这栋古色古香的江南大院,就是黄炎培先生从小生活、读书的地方吗?
</GuideStepsItem>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/huangyanpei/mp3_huangyanpei_04_1.mp3')}
>
没错,1878年10月1日,黄炎培先生就出生在当时江苏省川沙县城关镇(现上海市浦东新区川沙镇)的这处“内史第”,宅子原是他外祖父沈树镛家,也是他后来所说的“生于斯、读于斯、长于斯”之地。
</GuideStepsItem>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/huangyanpei/mp3_huangyanpei_04_2.mp3')}
>
1890年,川沙创办“观澜书院”,12岁的黄炎培以第一名的成绩考入,每天提着母亲亲手缝制的布书包,往返十里路求学,一点都不叫苦。1893年他去上海应县考,松江府复试名列前茅;1899年,在松江府试中更是以第一名的成绩中了秀才。
</GuideStepsItem>
</GuideSteps>
{/* 温馨提示 */}
<StudyGuideModal
visible={showAfterDialogGuide}
onContinue={() => {
setShowAfterDialogGuide(false)
setVisible(true)
}}
audioSrc={getPublicPath('audio/huangyanpei/mp3_huangyanpei_01.mp3')}
firstLineIndent="2em"
>
同学你好,欢迎来到“走进故居·对话”学习模块!{'\n'}
此刻你正站在黄炎培先生故居门前,接下来就跟着时光的脉络,拆解黄先生人生里5段滚烫的旅程:思想启蒙、教育实践、创立职教、延安对话、职教传薪。准备好一起走进这段炽热的岁月了吗?
</StudyGuideModal>
</div>
)
}
export default HuangyanpeiPlace1