Files
shanghai-residences/src/pages/huangyanpei/reflection/scene4.tsx
T
zhongyidian a8723ab4aa feat: 添加音频资源和更新引导对话,提升学习体验
- 在多个场景中引入音频文件,增强互动性和沉浸感。
- 更新引导对话文本,确保信息准确性和一致性。
- 调整组件结构,清理冗余代码,提升可维护性。
- 引入结束窗口,鼓励用户深入了解黄炎培的教育理念。
2026-01-16 00:00:12 +08:00

236 lines
7.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState, useCallback, useRef } from "react";
import { Title, Image, Cursor, Video, StudyGuideModal } from "@/components";
import { MultipleChoiceQuizPanel } from "@/components/layout/quiz";
import { SuccessAlert, ErrorAlert } from "@/components/layout";
import { getBackgroundImage, getStaticImage, getPublicPath } from "@/lib/utils";
import { useNavigate, useParams } from "react-router-dom";
import TowelSalesDialog from "./scene4/TowelSalesDialog";
import type { VideoRef } from "@/components/video";
import { QuizDialog } from "./components";
const starName = "huangyanpei";
const HuangyanpeiReflectionScene4 = () => {
const navigate = useNavigate();
const { moduleName } = useParams<{
moduleName: string;
}>();
const [_activeExhibitId, _setActiveExhibitId] = useState<1 | 2 | null>(null);
const [visited, setVisited] = useState<Set<number>>(new Set());
const [showQuiz1, setShowQuiz1] = useState(false);
const [showSuccessAlert, setShowSuccessAlert] = useState(false);
const [showTowelDialog, setShowTowelDialog] = useState(false);
const [showVideo, setShowVideo] = useState(false);
const videoRef = useRef<VideoRef>(null);
const [showGuide1, setShowGuide1] = useState(true);
const [showErrorAlertForQuiz, setShowErrorAlertForQuiz] = useState(false);
//喇叭考题弹窗
const [showQuizDialog, setShowQuizDialog] = useState(false);
// 处理成功提示的继续和关闭
const handleSuccessAlertContinue = useCallback(() => {
setShowSuccessAlert(false);
// 更新visited状态
setVisited((prev) => {
const next = new Set(prev);
next.add(1);
return next;
});
}, []);
const handleSuccessAlertClose = useCallback(() => {
setShowSuccessAlert(false);
// 更新visited状态
setVisited((prev) => {
const next = new Set(prev);
next.add(1);
return next;
});
}, []);
if (!moduleName) {
return null;
}
const progressCount = visited.size;
const total = 3;
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/reflection/scene4/12_001`
),
}}
>
<Title
title="跨越时空"
subtitle={subtitle}
subtitleClassName={subtitleClassName}
className="absolute top-10 left-1/2 -translate-x-1/2"
/>
<Image
className="absolute left-5 top-5"
src={getStaticImage("huangyanpei/reflection/components/喇叭2")}
button
onClick={() => {
// 检查是否完成前两个任务(visited.has(1) && visited.has(2))
if (visited.has(1) && visited.has(2)) {
setShowQuizDialog(true);
} else {
setShowErrorAlertForQuiz(true);
}
}}
/>
<Image
className="absolute right-5 top-5"
src={getStaticImage("components/离开")}
button
onClick={() => {
navigate(`/${moduleName}/${starName}/reflection2`);
}}
/>
{/* 互动展品光标1 */}
<Cursor
className="absolute left-100 bottom-88"
onClick={() => setShowQuiz1(true)}
read={visited.has(1)}
/>
{/* 互动展品光标2 */}
<Cursor
className="absolute right-82 bottom-88"
onClick={() => setShowTowelDialog(true)}
read={visited.has(2)}
/>
{/* 选择题1:中华职校商科的核心教学目标 */}
<MultipleChoiceQuizPanel
visible={showQuiz1}
title={`【选题】中华职校商科的核心教学目标是什么? `}
options={[
{
value: "A",
label: "A. 教会学生投机倒把",
},
{
value: "B",
label: "B. 培养诚信经营人才",
},
{
value: "C",
label: "C. 推广国货支援实业",
},
{
value: "D",
label: "D. 只为个人发财致富",
},
]}
correctAnswer={["B", "C"]}
errorMessage="不对哦!黄先生倡导“商科要为民族工商业服务”,商科是要培养诚信经营、助力国货发展的人才,可不能想着投机发财呀,再选一次吧!"
minSelections={1}
onSubmit={(values: string[], isCorrect: boolean) => {
if (isCorrect) {
// 答题成功:关闭选择题,显示成功提示
setShowQuiz1(false);
setShowSuccessAlert(true);
}
}}
/>
{/* 答题成功提示 */}
<SuccessAlert
visible={showSuccessAlert}
title="满分!"
content="诚信是经商之本, 推广国货是商科学生的责任, 这正是黄先生的办学初衷。"
onContinue={handleSuccessAlertContinue}
onClose={handleSuccessAlertClose}
/>
{/* 毛巾推销语拖拽对话框 */}
<TowelSalesDialog
visible={showTowelDialog}
onClose={() => setShowTowelDialog(false)}
onComplete={() => {
// 完成拖拽后更新visited状态
setVisited((prev) => {
const next = new Set(prev);
next.add(2);
return next;
});
}}
/>
{completed && (
<Image
className="absolute bottom-0 right-4"
src={getStaticImage("components/place/继续前进")}
button
onClick={() => {
setShowVideo(true);
}}
/>
)}
{/* 第一段引导 */}
<StudyGuideModal
visible={showGuide1}
onContinue={() => {
setShowGuide1(false);
}}
audioSrc={getPublicPath("audio/huangyanpei/mp3_huangyanpei_26.mp3")}
>
终于到中华职业学校啦!这里是中国近代职教的摇篮,“免学费、包分配”,还能学真手艺,快来练就一技之长。
{"\n"}
现在要完成你的第一个任务:推销中华职校生产的“国货精品”——手工纽扣和纯棉毛巾!当年学生们就是带着这些国货,走街串巷做推销呢!
</StudyGuideModal>
{showVideo && (
<Video
ref={videoRef}
src={getPublicPath("video/huangyanpei/huangyanpei_09.mp4")}
className="h-full w-full"
autoPlay
showSkipButton
playsInline
onEnded={() => {
setShowVideo(false);
navigate(`/${moduleName}/${starName}/home`);
}}
/>
)}
<QuizDialog
visible={showQuizDialog}
onClose={() => setShowQuizDialog(false)}
onComplete={() => {
setShowQuizDialog(false);
setVisited((prev) => new Set(prev).add(3));
}}
/>
{/* 错误提示:请先完成前两个任务 */}
<ErrorAlert
visible={showErrorAlertForQuiz}
text="请先完成前两个任务吧!"
onClose={() => setShowErrorAlertForQuiz(false)}
/>
</div>
);
};
export default HuangyanpeiReflectionScene4;