feat: 更新 ESLint 和 Prettier 配置,增强代码质量管理

- 在 .gitignore 中添加 public/audio/* 以忽略音频文件。
- 更新 bun.lock,添加 eslint-config-prettier 和 eslint-plugin-prettier 依赖,确保 ESLint 与 Prettier 的兼容性。
- 修改 eslint.config.ts,整合 Prettier 规则,优化代码风格一致性。
- 在 package.json 中添加 lint:fix 和 format 脚本,简化代码格式化和修复流程。
- 更新 tailwind.config.ts 和其他组件文件,统一代码风格,提升可读性。
This commit is contained in:
zhongyidian committed 2026-03-05 13:50:47 +08:00
1 parent 5d00adc1a5
commit 76c67b492e
216 files changed
+12454 -13976

No files matched your search

+179 -194
View File
@@ -8,120 +8,113 @@ import {
Video,
type VideoRef,
SingleChoiceQuizPanel,
} from "@/components";
import { useNavigate, useParams } from "react-router-dom";
import { getBackgroundImage, getStaticImage, getPublicPath } from "@/lib/utils";
import { useEffect, useRef, useState } from "react";
import Cursor from "@/components/cursor";
import { useCursorController } from "@/hooks/useCursorController";
import SuccessAlert from "@/components/layout/alert/success-alert";
import ScaledPortal from "@/components/layout/ScaledPortal";
} from '@/components'
import { useNavigate, useParams } from 'react-router-dom'
import { getBackgroundImage, getStaticImage, getPublicPath } from '@/lib/utils'
import { useEffect, useRef, useState } from 'react'
import Cursor from '@/components/cursor'
import { useCursorController } from '@/hooks/useCursorController'
import SuccessAlert from '@/components/layout/alert/success-alert'
import ScaledPortal from '@/components/layout/ScaledPortal'
// starName 固定为 maozedong
const starName = "maozedong";
const starName = 'maozedong'
// 展品 ID 与资源路径映射,ID 用来做唯一标识
const exhibitSrcMap: Record<1 | 2 | 3 | 4 | 5 , string> = {
1: "maozedong/place4/场景4展品1",
2: "maozedong/place4/场景4展品2_",
3: "maozedong/place4/场景4展品4",
4: "maozedong/place4/场景4展品5",
5: "maozedong/place4/场景4展品6",
};
const exhibitSrcMap: Record<1 | 2 | 3 | 4 | 5, string> = {
1: 'maozedong/place4/场景4展品1',
2: 'maozedong/place4/场景4展品2_',
3: 'maozedong/place4/场景4展品4',
4: 'maozedong/place4/场景4展品5',
5: 'maozedong/place4/场景4展品6',
}
const MaozedongPlace4 = () => {
const navigate = useNavigate();
const navigate = useNavigate()
const { moduleName } = useParams<{
moduleName: string;
}>();
moduleName: string
}>()
// 场景级引导对话显示状态(暂未使用,可根据需要开启)
const [visible, setVisible] = useState(false);
const [visible, setVisible] = useState(false)
// 当前激活的展品 ID
const [activeExhibitId, setActiveExhibitId] = useState<
1 | 2 | 3 | 4 | 5 | null
>(null);
const [activeExhibitId, setActiveExhibitId] = useState<1 | 2 | 3 | 4 | 5 | null>(null)
// 已访问的展品(本页内状态;如需持久化可接入 store)
const [visited, setVisited] = useState<Set<1 | 2 | 3 | 4 | 5 | 6>>(
() => new Set()
);
const [visited, setVisited] = useState<Set<1 | 2 | 3 | 4 | 5 | 6>>(() => new Set())
// 光标1的对话状态
const [guide1Visible, setGuide1Visible] = useState(false);
const [guide1Step, setGuide1Step] = useState(0);
const [guide1Visible, setGuide1Visible] = useState(false)
const [guide1Step, setGuide1Step] = useState(0)
// 光标3+光标5均查看后的总结对话
const [guide35Visible, setGuide35Visible] = useState(false);
const [guide35Step, setGuide35Step] = useState(0);
const [guide35Shown, setGuide35Shown] = useState(false);
const [guide35Visible, setGuide35Visible] = useState(false)
const [guide35Step, setGuide35Step] = useState(0)
const [guide35Shown, setGuide35Shown] = useState(false)
// 光标4(展品4)对话
const [guide4Visible, setGuide4Visible] = useState(false);
const [guide4Step, setGuide4Step] = useState(0);
const [guide4Visible, setGuide4Visible] = useState(false)
const [guide4Step, setGuide4Step] = useState(0)
// 关闭展品4后的结束语
const [endingVisible, setEndingVisible] = useState(false);
const [endingVisible, setEndingVisible] = useState(false)
// 光标2的对话状态
const [guide2Visible, setGuide2Visible] = useState(false);
const [guide2Step, setGuide2Step] = useState(0);
const [guide2Visible, setGuide2Visible] = useState(false)
const [guide2Step, setGuide2Step] = useState(0)
// 光标2的视频与题目状态
const [showVideo2, setShowVideo2] = useState(false);
const video2Ref = useRef<VideoRef>(null);
const [quizStep, setQuizStep] = useState(0); // 0 表示未开始,1-4 为四道题
const [quizVisible, setQuizVisible] = useState(false);
const [successAlertVisible, setSuccessAlertVisible] = useState(false);
const [successAlertContent, setSuccessAlertContent] = useState<string>("");
const [showVideo2, setShowVideo2] = useState(false)
const video2Ref = useRef<VideoRef>(null)
const [quizStep, setQuizStep] = useState(0) // 0 表示未开始,1-4 为四道题
const [quizVisible, setQuizVisible] = useState(false)
const [successAlertVisible, setSuccessAlertVisible] = useState(false)
const [successAlertContent, setSuccessAlertContent] = useState<string>('')
// Cursor 顺序控制:1 -> 2 -> 3 -> 4 -> 5 -> 6
const { isEnabled } = useCursorController({
initialEnabled: [2],
dependencies: {
1:[2],
3:[1],
4:[3,5],
5:[1],
1: [2],
3: [1],
4: [3, 5],
5: [1],
},
visited,
});
})
const handleOpenExhibit = (id: 1 | 2 | 3 | 4 | 5 ) => {
setActiveExhibitId(id);
const handleOpenExhibit = (id: 1 | 2 | 3 | 4 | 5) => {
setActiveExhibitId(id)
if (id === 1) {
setGuide1Step(0);
setGuide1Visible(true);
setGuide1Step(0)
setGuide1Visible(true)
}
if (id === 2) {
setGuide2Step(0);
setGuide2Visible(true);
setQuizStep(0);
setGuide2Step(0)
setGuide2Visible(true)
setQuizStep(0)
}
if (id === 4) {
setGuide4Step(0);
setGuide4Visible(true);
setGuide4Step(0)
setGuide4Visible(true)
}
};
}
// 光标3和光标5都已查看后,弹出一次总结对话(图1)
useEffect(() => {
if (guide35Shown) return;
if (!visited.has(3) || !visited.has(5)) return;
setGuide35Step(0);
setGuide35Visible(true);
setGuide35Shown(true);
}, [visited, guide35Shown]);
if (guide35Shown) return
if (!visited.has(3) || !visited.has(5)) return
setGuide35Step(0)
setGuide35Visible(true)
setGuide35Shown(true)
}, [visited, guide35Shown])
if (!moduleName) return null;
if (!moduleName) return null
const progressCount = visited.size;
const total = 5;
const completed = progressCount >= total;
const subtitle = completed
? "关于中共四大(已完成)"
: `关于中共四大(${progressCount}/${total})`;
const progressCount = visited.size
const total = 5
const completed = progressCount >= total
const subtitle = completed ? '关于中共四大(已完成)' : `关于中共四大(${progressCount}/${total})`
return (
<div
@@ -137,16 +130,18 @@ const MaozedongPlace4 = () => {
className="absolute top-10 left-1/2 -translate-x-1/2"
/>
{completed && (<Image
className="absolute right-0 bottom-0"
src={getStaticImage("components/place/离开场景")}
button
onClick={() => {
if (moduleName && starName) {
navigate(`/${moduleName}/${starName}/home`);
}
}}
/>)}
{completed && (
<Image
className="absolute right-0 bottom-0"
src={getStaticImage('components/place/离开场景')}
button
onClick={() => {
if (moduleName && starName) {
navigate(`/${moduleName}/${starName}/home`)
}
}}
/>
)}
{/* 光标1 */}
<Cursor
@@ -195,13 +190,11 @@ const MaozedongPlace4 = () => {
<GuideSteps
visible={visible}
onVisibleChange={(nextVisible) => {
setVisible(nextVisible);
setVisible(nextVisible)
}}
showMask={false}
>
<GuideStepsItem speaker="student">
小沪,毛泽东是如何组织和发动工农群众的?
</GuideStepsItem>
<GuideStepsItem speaker="student">小沪,毛泽东是如何组织和发动工农群众的?</GuideStepsItem>
<GuideStepsItem speaker="guide">
1925年,毛泽东回到湖南,深入农村调查研究,写出了《湖南农民运动考察报告》。
</GuideStepsItem>
@@ -225,7 +218,7 @@ const MaozedongPlace4 = () => {
currentStep={guide1Step}
onStepChange={setGuide1Step}
onVisibleChange={(nextVisible) => {
setGuide1Visible(nextVisible);
setGuide1Visible(nextVisible)
}}
showMask={false}
highlightSelectors={[]}
@@ -240,8 +233,7 @@ const MaozedongPlace4 = () => {
</GuideStepsItem>
<GuideStepsItem speaker="guide">
后来毛主席回湖南,专门跑了湘潭、湘乡、衡山、
醴陵、长沙五县,发现农民不仅能革命,而且革命性极强——他们被剥削得最狠,
反抗起来也最坚决!
醴陵、长沙五县,发现农民不仅能革命,而且革命性极强——他们被剥削得最狠, 反抗起来也最坚决!
</GuideStepsItem>
</GuideSteps>
@@ -251,19 +243,16 @@ const MaozedongPlace4 = () => {
currentStep={guide2Step}
onStepChange={setGuide2Step}
onVisibleChange={(nextVisible) => {
setGuide2Visible(nextVisible);
setGuide2Visible(nextVisible)
}}
showMask={false}
highlightSelectors={[]}
zIndex={10001}
>
<GuideStepsItem speaker="student">
那中共四大为什么召开呢?
</GuideStepsItem>
<GuideStepsItem speaker="student">那中共四大为什么召开呢?</GuideStepsItem>
<GuideStepsItem speaker="guide">
因为此前中共三大虽然确定了国共合作的方针,但未明确解决
“谁领导革命”的问题。我们必须要明确“谁领导革命”“依靠谁革命”
这两个基本问题。
“谁领导革命”的问题。我们必须要明确“谁领导革命”“依靠谁革命” 这两个基本问题。
</GuideStepsItem>
</GuideSteps>
@@ -273,7 +262,7 @@ const MaozedongPlace4 = () => {
currentStep={guide35Step}
onStepChange={setGuide35Step}
onVisibleChange={(nextVisible) => {
setGuide35Visible(nextVisible);
setGuide35Visible(nextVisible)
}}
showMask={false}
highlightSelectors={[]}
@@ -298,7 +287,7 @@ const MaozedongPlace4 = () => {
currentStep={guide4Step}
onStepChange={setGuide4Step}
onVisibleChange={(nextVisible) => {
setGuide4Visible(nextVisible);
setGuide4Visible(nextVisible)
}}
showMask={false}
highlightSelectors={[]}
@@ -331,44 +320,43 @@ const MaozedongPlace4 = () => {
把这些道理想通了,将来不管做什么事,都能脚踏实地。
</GuideStepsItem>
<GuideStepsItem speaker="guide">
“实事求是”这四个字,
是我们党一路走来的法宝,希望你也能记住。
“实事求是”这四个字, 是我们党一路走来的法宝,希望你也能记住。
</GuideStepsItem>
</GuideSteps>
{/* 展品遮罩层 */}
<ExhibitOverlay
visible={activeExhibitId !== null}
src={activeExhibitId ? exhibitSrcMap[activeExhibitId] : ""}
src={activeExhibitId ? exhibitSrcMap[activeExhibitId] : ''}
onClose={() => {
const currentId = activeExhibitId;
const currentId = activeExhibitId
// 展品2:关闭后播放视频和答题,全部正确后再标记已访问
if (currentId === 2) {
setGuide2Step(0);
setGuide2Visible(false);
setActiveExhibitId(null);
setShowVideo2(true);
return;
setGuide2Step(0)
setGuide2Visible(false)
setActiveExhibitId(null)
setShowVideo2(true)
return
}
// 展品4:关闭后出现结束语(EndingOverlay)
if (currentId === 4) {
setGuide4Step(0);
setGuide4Visible(false);
setActiveExhibitId(null);
setEndingVisible(true);
return;
setGuide4Step(0)
setGuide4Visible(false)
setActiveExhibitId(null)
setEndingVisible(true)
return
}
if (currentId !== null) {
setVisited((prev) => {
const next = new Set(prev);
next.add(currentId);
return next;
});
const next = new Set(prev)
next.add(currentId)
return next
})
}
setActiveExhibitId(null);
setActiveExhibitId(null)
}}
/>
@@ -377,13 +365,13 @@ const MaozedongPlace4 = () => {
visible={endingVisible}
text="我们通过毛主席在1921~1924年参加党的“一大、二大、三大、四大”等重大历史事件中所扮演的重要角色及他个人思想育理论成果的积累,深刻认识到早期共产党人一步一脚印探索中国革命道路的曲折历程。"
onContinue={() => {
setEndingVisible(false);
setEndingVisible(false)
// 结束语关闭后,标记展品4为已查看
setVisited((prev) => {
const next = new Set(prev);
next.add(4);
return next;
});
const next = new Set(prev)
next.add(4)
return next
})
}}
animationSpeed={200}
/>
@@ -392,15 +380,15 @@ const MaozedongPlace4 = () => {
{showVideo2 && (
<Video
ref={video2Ref}
src={getPublicPath("video/sunzhongshan/sunzhongshan_03.mp4")}
src={getPublicPath('video/sunzhongshan/sunzhongshan_03.mp4')}
className="fixed inset-0 z-20000"
autoPlay
playsInline
showSkipButton
onEnded={() => {
setShowVideo2(false);
setQuizStep(1);
setQuizVisible(true);
setShowVideo2(false)
setQuizStep(1)
setQuizVisible(true)
}}
/>
)}
@@ -414,31 +402,29 @@ const MaozedongPlace4 = () => {
zIndex={10000}
title="【单选】中共四大召开的时间是( )"
options={[
{ value: "A", label: "A.1923年6月" },
{ value: "B", label: "B.1924年1月" },
{ value: "C", label: "C.1925年1月" },
{ value: "D", label: "D.1926年7月" },
{ value: 'A', label: 'A.1923年6月' },
{ value: 'B', label: 'B.1924年1月' },
{ value: 'C', label: 'C.1925年1月' },
{ value: 'D', label: 'D.1926年7月' },
]}
correctAnswer="C"
onWrongSelect={(value) => {
if (value === "A") {
return "1923年6月,中共三大召开,确定了国共合作方针。请你再想想吧!";
if (value === 'A') {
return '1923年6月,中共三大召开,确定了国共合作方针。请你再想想吧!'
}
if (value === "B") {
return "1924年1月,国民党一大召开,国共合作正式形成。请你再想想吧!";
if (value === 'B') {
return '1924年1月,国民党一大召开,国共合作正式形成。请你再想想吧!'
}
if (value === "D") {
return "1926年7月,北伐战争开始。请你再想想吧!";
if (value === 'D') {
return '1926年7月,北伐战争开始。请你再想想吧!'
}
return "请结合时间线再仔细思考一下~";
return '请结合时间线再仔细思考一下~'
}}
onSubmit={(_value, isCorrect) => {
if (!isCorrect) return;
setQuizVisible(false);
setSuccessAlertContent(
"中共四大召开于1925年1月11日至22日,在上海。"
);
setSuccessAlertVisible(true);
if (!isCorrect) return
setQuizVisible(false)
setSuccessAlertContent('中共四大召开于1925年1月11日至22日,在上海。')
setSuccessAlertVisible(true)
}}
/>
@@ -448,29 +434,29 @@ const MaozedongPlace4 = () => {
zIndex={10000}
title="【单选】中共四大召开的地点是:"
options={[
{ value: "A", label: "A.北京" },
{ value: "B", label: "B.上海" },
{ value: "C", label: "C.广州" },
{ value: "D", label: "D.武汉" },
{ value: 'A', label: 'A.北京' },
{ value: 'B', label: 'B.上海' },
{ value: 'C', label: 'C.广州' },
{ value: 'D', label: 'D.武汉' },
]}
correctAnswer="B"
onWrongSelect={(value) => {
if (value === "A") {
return "现在中国共产党全国代表大会多在北京召开,但是中共四大不是哦!请你再想想吧!";
if (value === 'A') {
return '现在中国共产党全国代表大会多在北京召开,但是中共四大不是哦!请你再想想吧!'
}
if (value === "C") {
return "中共三大在广州召开,请你再想想吧!";
if (value === 'C') {
return '中共三大在广州召开,请你再想想吧!'
}
if (value === "D") {
return "中共五大在武汉召开,请你再想想吧!";
if (value === 'D') {
return '中共五大在武汉召开,请你再想想吧!'
}
return "请再仔细对照题干信息选择~";
return '请再仔细对照题干信息选择~'
}}
onSubmit={(_value, isCorrect) => {
if (!isCorrect) return;
setQuizVisible(false);
setSuccessAlertContent("");
setSuccessAlertVisible(true);
if (!isCorrect) return
setQuizVisible(false)
setSuccessAlertContent('')
setSuccessAlertVisible(true)
}}
/>
@@ -480,29 +466,29 @@ const MaozedongPlace4 = () => {
zIndex={10000}
title="【单选】中共四大第一次明确提出的重要问题是:"
options={[
{ value: "A", label: "A.党的建设问题" },
{ value: "B", label: "B.武装斗争问题" },
{ value: "C", label: "C.无产阶级领导权和工农联盟问题" },
{ value: "D", label: "D.土地革命问题" },
{ value: 'A', label: 'A.党的建设问题' },
{ value: 'B', label: 'B.武装斗争问题' },
{ value: 'C', label: 'C.无产阶级领导权和工农联盟问题' },
{ value: 'D', label: 'D.土地革命问题' },
]}
correctAnswer="C"
onWrongSelect={(value) => {
if (value === "A") {
return "古田会议更系统阐述党的建设问题哦!请你再想想吧!";
if (value === 'A') {
return '古田会议更系统阐述党的建设问题哦!请你再想想吧!'
}
if (value === "B") {
return "八七会议更系统阐述武装斗争问题哦!请你再想想吧!";
if (value === 'B') {
return '八七会议更系统阐述武装斗争问题哦!请你再想想吧!'
}
if (value === "D") {
return "八七会议后提出土地革命问题哦!请你再想想吧!";
if (value === 'D') {
return '八七会议后提出土地革命问题哦!请你再想想吧!'
}
return "请再仔细比较不同会议的主要议题~";
return '请再仔细比较不同会议的主要议题~'
}}
onSubmit={(_value, isCorrect) => {
if (!isCorrect) return;
setQuizVisible(false);
setSuccessAlertContent("");
setSuccessAlertVisible(true);
if (!isCorrect) return
setQuizVisible(false)
setSuccessAlertContent('')
setSuccessAlertVisible(true)
}}
/>
@@ -512,31 +498,31 @@ const MaozedongPlace4 = () => {
zIndex={10000}
title="【单选】中共四大确立的党的基本组织形式是:"
options={[
{ value: "A", label: "A.组" },
{ value: "B", label: "B.支部" },
{ value: 'A', label: 'A.组' },
{ value: 'B', label: 'B.支部' },
// { value: "C", label: "C.区委" },
// { value: "D", label: "D.中央局" },
]}
correctAnswer="B"
onWrongSelect={(value) => {
if (value === "A") {
return "中共四大以前党的基本组织形式是组或者小组,请你再想想吧!";
if (value === 'A') {
return '中共四大以前党的基本组织形式是组或者小组,请你再想想吧!'
}
return "请注意中共四大之后对基层组织形式的规定~";
return '请注意中共四大之后对基层组织形式的规定~'
}}
onSubmit={(_value, isCorrect) => {
if (!isCorrect) return;
setQuizVisible(false);
if (!isCorrect) return
setQuizVisible(false)
setSuccessAlertContent(
"中共四大明确“支部是党的基本组织”,规定“有三名党员即可成立一个支部”。"
);
setSuccessAlertVisible(true);
'中共四大明确“支部是党的基本组织”,规定“有三名党员即可成立一个支部”。'
)
setSuccessAlertVisible(true)
// 全部答对后标记展品2为已访问
setVisited((prev) => {
const next = new Set(prev);
next.add(2);
return next;
});
const next = new Set(prev)
next.add(2)
return next
})
}}
/>
@@ -545,22 +531,21 @@ const MaozedongPlace4 = () => {
visible={successAlertVisible}
content={successAlertContent}
onContinue={() => {
setSuccessAlertVisible(false);
setSuccessAlertVisible(false)
// 进入下一题
setQuizStep((prev) => {
const next = prev + 1;
const next = prev + 1
if (next >= 1 && next <= 4) {
setQuizVisible(true);
setQuizVisible(true)
}
return next;
});
return next
})
}}
/>
</>
</ScaledPortal>
</div>
);
};
export default MaozedongPlace4;
)
}
export default MaozedongPlace4