- 在多个场景中引入音频文件,增强互动性和沉浸感。 - 更新引导对话文本,确保信息准确性和一致性。 - 调整组件结构,清理冗余代码,提升可维护性。 - 引入结束窗口,鼓励用户深入了解黄炎培的教育理念。
236 lines
7.3 KiB
TypeScript
236 lines
7.3 KiB
TypeScript
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;
|