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>
This commit is contained in:
zhongyidianandClaude Opus 4.7 committed 2026-05-13 10:15:26 +08:00
1 parent 68ba22a33f
commit 6d40e19346
184 files changed
+7663 -2203

No files matched your search

+1 -1
View File
@@ -40,7 +40,7 @@ const Maozedong = () => {
className="absolute right-37 top-22"
src={getStaticImage('components/革命先驱故居-返回')}
button
onClick={() => navigate(`/entrance/revolutionary`)}
onClick={() => navigate(`/revolutionary`)}
/>
<div className="absolute right-20 top-75 flex flex-col space-y-10">
+3 -1
View File
@@ -15,6 +15,7 @@ import { getBackgroundImage, getPublicPath, getStaticImage } from '@/lib/utils'
import { GuideSteps, GuideStepsItem } from '@/components'
import { BasketQuizPanel, DragQuizPanel, SuccessAlert } from '@/components/layout'
import { usePuzzleAnimation } from '@/contexts/PuzzleAnimationContext'
import { setCourseTimeProgress } from '@/lib/utils/api-common'
const starName = 'maozedong'
@@ -386,7 +387,7 @@ const MaozedongInternalization = () => {
{/* 过渡语 */}
<Narration
visible={showTransition}
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_27.mp3')}
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_28.mp3')}
onClose={() => {
setShowTransition(false)
setIntroDialogVisible(true)
@@ -512,6 +513,7 @@ const MaozedongInternalization = () => {
animationSpeed={200}
onContinue={() => {
setShowCompleted(false)
setCourseTimeProgress(3)
navigate('/menu')
}}
/>
+3 -3
View File
@@ -168,10 +168,10 @@ const MaozedongPlace1 = () => {
speaker="student"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_03.mp3')}
>
那参加中共一大时,毛主席对未来有什么想法吗?
那参加中共一大时,毛主席对未来有什么想法吗?
</GuideStepsItem>
<GuideStepsItem speaker="guide" audioSrc={getPublicPath('audio/maozedong/mp3_mzd_04.mp3')}>
当时全国只有50多个党员,毛主席所在的湖南也才几个。但他觉得,重要的是把马克思主义和中国的实际情况结合起来。就像种田,种子再好,也得看土壤——中国的“土壤”就是农民占大多数,这是和苏联不一样的地方。
当时全国只有50多个党员,毛主席所在的湖南也才几个。但他觉得,重要的是把马克思主义和中国的实际情况结合起来。就像种田,种子再好,也得看土壤——中国的”土壤”就是农民占大多数,这是和苏联不一样的地方。
</GuideStepsItem>
</GuideSteps>
@@ -307,7 +307,7 @@ const MaozedongPlace1 = () => {
firstLineIndent="2em"
>
{`同学你好,欢迎来到“走进故居·对话”学习模块!
此刻你正处在毛泽东旧居陈列馆里,接下来请跟着时光的脚步,一同回望毛泽东主席人生中4段风云激荡的岁月:摸索方向 确立信仰、播撒红色火种、吹响合作号角、唤起工农群众。准备好推开这扇门,走进那段滚烫的峥嵘岁月了吗?`}
此刻你正站在上海毛泽东旧居陈列馆的门口,接下来请跟着时光的脚步,一同回望毛泽东主席人生中4段风云激荡的岁月:摸索方向·确立信仰、播撒红色火种、吹响合作号角、唤起工农群众。准备好推开这扇门,走进那段滚烫的峥嵘岁月了吗?`}
</StudyGuideModal>
</div>
)
+10 -5
View File
@@ -235,8 +235,7 @@ const MaozedongPlace2 = () => {
speaker="student"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_05.mp3')}
>
中共一大定了“推翻资产阶级政权”的目标,但中共二大提
出了“反帝反封建的民主革命纲领”,为什么会有这样的转变呢?
中共一大定了“推翻资产阶级政权”的目标,但中共二大提出了“反帝反封建的民主革命纲领”,为什么会有这样的转变呢?
</GuideStepsItem>
<GuideStepsItem speaker="guide" audioSrc={getPublicPath('audio/maozedong/mp3_mzd_06.mp3')}>
中共一大时我们中国共产党刚成立,像刚学走路的孩子,
@@ -247,12 +246,18 @@ const MaozedongPlace2 = () => {
speaker="student"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_07.mp3')}
>
“眼前的敌人”?
“眼前的敌人”?
</GuideStepsItem>
<GuideStepsItem speaker="guide" audioSrc={getPublicPath('audio/maozedong/mp3_mzd_08.mp3')}>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_08_1.mp3')}
>
对!想想看1922年长沙的码头工人罢工,安源的路矿工人罢工,他们的敌人是谁?是外国资本家,是军阀。中共二大时毛主席虽然没有出席,但完全赞同“最低纲领”——打倒军阀、推翻帝国主义压迫,实现民族独立和人民民主。
</GuideStepsItem>
<GuideStepsItem speaker="guide">
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_08_2.mp3')}
>
这就像盖房子,得先把地基打好;等打倒了军阀和帝国主义,再谈社会主义也不迟。
</GuideStepsItem>
</GuideSteps>
+17 -7
View File
@@ -11,7 +11,7 @@ import {
} from '@/components'
import { useNavigate, useParams } from 'react-router-dom'
import { getBackgroundImage, getStaticImage, getPublicPath } from '@/lib/utils'
import { useEffect, useMemo, useRef, useState } from 'react'
import { useMemo, useRef, useState } from 'react'
import Cursor from '@/components/cursor'
import { useCursorController } from '@/hooks/useCursorController'
import SuccessAlert from '@/components/layout/alert/success-alert'
@@ -49,8 +49,9 @@ const MaozedongPlace3 = () => {
[getVisited]
)
const [visited, setVisited] = useState<Set<1 | 2 | 3>>(() => new Set(persistedVisited))
// 入场旁白
// 入场旁白(当前页面生命周期内仅展示一次)
const [narrationVisible, setNarrationVisible] = useState(false)
const narrationShownRef = useRef(false)
// 光标3对应的对话状态
const [guide3Visible, setGuide3Visible] = useState(false)
@@ -87,11 +88,15 @@ const MaozedongPlace3 = () => {
const completed = progressCount >= total
const subtitle = completed ? '已完成' : `${progressCount}/${total}`
useEffect(() => {
if (visited.has(1) && visited.has(2)) {
// 关闭展品1/2时,如果另一个已学且旁白未展示过,则弹出
const tryShowNarration = (justVisitedId: 1 | 2) => {
if (narrationShownRef.current) return
const otherId = justVisitedId === 1 ? 2 : 1
if (visited.has(otherId)) {
narrationShownRef.current = true
setNarrationVisible(true)
}
}, [visited])
}
if (!moduleName) return null
@@ -105,8 +110,10 @@ const MaozedongPlace3 = () => {
<Narration
visible={narrationVisible}
onClose={() => setNarrationVisible(false)}
animationSpeed={200}
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_12.mp3')}
text={`本党(国民党)为革命党,凡有利于革命的可采用,有害于革命的即应摒弃。——(毛泽东在国民党“一大”上的发言)`}
text="本党(国民党)为革命党,凡有利于革命的可采用,有害于革命的即应摒弃。"
attribution="——毛泽东在国民党“一大”上的发言"
/>
{/* 标题 */}
@@ -221,6 +228,9 @@ const MaozedongPlace3 = () => {
saveMaozedongStore()
return next
})
if (currentId === 1 || currentId === 2) {
tryShowNarration(currentId)
}
}
setActiveExhibitId(null)
}}
@@ -295,7 +305,7 @@ const MaozedongPlace3 = () => {
/>
<SuccessAlert
content="你理解了中共三大和国民党合作的核心内容及历史意义"
content="你理解了中共三大和国民党合作的核心内容及历史意义。"
visible={successAlert3Visible}
onContinue={() => {
setSuccessAlert3Visible(false)
+41 -26
View File
@@ -18,6 +18,7 @@ import SuccessAlert from '@/components/layout/alert/success-alert'
import ScaledPortal from '@/components/layout/ScaledPortal'
import { useMaozedongStore, saveMaozedongStore } from '@/store/maozedongStore'
import { usePuzzleAnimation } from '@/contexts/PuzzleAnimationContext'
import { setCourseTimeProgress } from '@/lib/utils/api-common'
// starName 固定为 maozedong
const starName = 'maozedong'
@@ -149,6 +150,8 @@ const MaozedongPlace4 = () => {
button
onClick={() => {
if (moduleName && starName) {
saveMaozedongStore()
setCourseTimeProgress(1)
navigate(`/${moduleName}/${starName}/home`)
}
}}
@@ -242,13 +245,18 @@ const MaozedongPlace4 = () => {
>
看来中共四大明确提出了“无产阶级领导权”和“工农联盟”,这和毛主席的实践有关吗?
</GuideStepsItem>
<GuideStepsItem speaker="guide" audioSrc={getPublicPath('audio/maozedong/mp3_mzd_16.mp3')}>
太有关系了!中共三大后毛主席到上海工作了一段时间,看到工人运动轰轰烈烈,
但农民还是“沉默的大多数”。
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_16_1.mp3')}
>
太有关系了!中共三大后毛主席到上海工作了一段时间,看到工人运动轰轰烈烈,但农民还是“沉默的大多数”。
</GuideStepsItem>
<GuideStepsItem speaker="guide">
后来毛主席回湖南,专门跑了湘潭、湘乡、衡山、
醴陵、长沙五县,发现农民不仅能革命,而且革命性极强——他们被剥削得最狠, 反抗起来也最坚决!
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_16_2.mp3')}
>
后来毛主席回湖南,专门跑了湘潭、湘乡、衡山、醴陵、长沙五县,发现农民不仅能革命,而且革命性极强——他们被剥削得最狠,
反抗起来也最坚决!
</GuideStepsItem>
</GuideSteps>
@@ -271,8 +279,7 @@ const MaozedongPlace4 = () => {
那中共四大为什么召开呢?
</GuideStepsItem>
<GuideStepsItem speaker="guide" audioSrc={getPublicPath('audio/maozedong/mp3_mzd_14.mp3')}>
因为此前中共三大虽然确定了国共合作的方针,但未明确解决
“谁领导革命”的问题。我们必须要明确“谁领导革命”“依靠谁革命” 这两个基本问题。
因为此前中共三大虽然确定了国共合作的方针,但未明确解决“谁领导革命”的问题。我们必须要明确“谁领导革命”“依靠谁革命”这两个基本问题。
</GuideStepsItem>
</GuideSteps>
@@ -294,13 +301,17 @@ const MaozedongPlace4 = () => {
>
所以毛主席觉得,光靠工人不够,得把农民拉进革命队伍?
</GuideStepsItem>
<GuideStepsItem speaker="guide" audioSrc={getPublicPath('audio/maozedong/mp3_mzd_18.mp3')}>
对!无产阶级要领导革命,必须联合农民——他们是工人阶级的“天然盟友”。
四大虽然还没有明确提出“农村包围城市”,但已经意识到农民问题的重要性。
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_18_01.mp3')}
>
对!无产阶级要领导革命,必须联合农民——他们是工人阶级的“天然盟友”。四大虽然还没有明确提出“农村包围城市”,但已经意识到农民问题的重要性。
</GuideStepsItem>
<GuideStepsItem speaker="guide">
后来毛主席常说:“国民革命的中心问题,就是农民问题,一切都要靠农民问题的解决。”
这句话的种子,就是在四大前后埋下的。
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_18_02.mp3')}
>
后来毛主席常说:“国民革命的中心问题,就是农民问题,一切都要靠农民问题的解决。”这句话的种子,就是在四大前后埋下的。
</GuideStepsItem>
</GuideSteps>
@@ -323,20 +334,24 @@ const MaozedongPlace4 = () => {
speaker="student"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_19.mp3')}
>
为有牺牲多壮志,敢教日月换新天。小沪,通过您的讲解,
我明白了中共一大到四大是在艰难探索中不断前进的——从建党的理想,
到制定民主革命纲领;从国共合作,到发现农民的力量。这些探索对我们今天有什么启示呢?
为有牺牲多壮志,敢教日月换新天。小沪,通过您的讲解,我明白了中共一大到四大是在艰难探索中不断前进的——从建党的理想,到制定民主革命纲领;从国共合作,到发现农民的力量。这些探索对我们今天有什么启示呢?
</GuideStepsItem>
<GuideStepsItem speaker="guide" audioSrc={getPublicPath('audio/maozedong/mp3_mzd_20.mp3')}>
同学问到了根子上!革命就像爬山,一开始可能看不清山顶的样子,
但只要沿着正确的方向,一步一步扎扎实实地走,总会离目标越来越近。
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_20_1.mp3')}
>
同学问到了根子上!革命就像爬山,一开始可能看不清山顶的样子,但只要沿着正确的方向,一步一步扎扎实实地走,总会离目标越来越近。
</GuideStepsItem>
<GuideStepsItem speaker="guide">
你们现在学历史,不能只记年代和事件,更要理解“为什么”——
为什么马克思主义要和中国实际相结合?为什么农民是革命的重要力量?
把这些道理想通了,将来不管做什么事,都能脚踏实地。
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_20_2.mp3')}
>
你们现在学历史,不能只记年代和事件,更要理解“为什么”——为什么马克思主义要和中国实际相结合?为什么农民是革命的重要力量?把这些道理想通了,将来不管做什么事,都能脚踏实地。
</GuideStepsItem>
<GuideStepsItem speaker="guide">
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/maozedong/mp3_mzd_20_3.mp3')}
>
“实事求是”这四个字,是我们党一路走来的法宝,希望你也能记住。
</GuideStepsItem>
</GuideSteps>
@@ -456,7 +471,7 @@ const MaozedongPlace4 = () => {
<SingleChoiceQuizPanel
visible={quizVisible && quizStep === 1}
zIndex={10000}
title="【单选】中共四大召开的时间是( )"
title="【单选】中共四大召开的时间是:"
options={[
{ value: 'A', label: 'A.1923年6月' },
{ value: 'B', label: 'B.1924年1月' },
+5 -19
View File
@@ -10,8 +10,10 @@ import { SuccessAlert } from '@/components/layout'
import { usePuzzleAnimation } from '@/contexts/PuzzleAnimationContext'
import { cn, getStaticImage } from '@/lib/utils'
import { getPublicPath } from '@/lib/utils'
import { setCourseTimeProgress } from '@/lib/utils/api-common'
import { useCallback, useMemo, useRef, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { saveMaozedongStore } from '@/store/maozedongStore'
// 光标组件 - 带旋转动画
// Safari 兼容:使用 onTouchEnd 和 -webkit-tap-highlight-color
@@ -38,7 +40,7 @@ const Cursor = ({ className, onClick }: { className?: string; onClick: () => voi
const firstQuizOptions = [
{
value: 'A',
label: 'A. 基层情况对决策至关重要,关乎无产阶级领导权、工农联盟议题能否贴合实际',
label: 'A. 优先高层协商',
},
{
value: 'B',
@@ -104,12 +106,6 @@ const FirstQuizCursor = ({ resume, unmute, onCorrect }: QuizCursorProps) => {
<SuccessAlert
visible={showSuccessAlert}
content="基于对史实的理解,毛主席的选择应当是深入基层、收集真实情况,再推进各项筹备与行动。"
onContinue={() => {
if (hasResumedRef.current) return
hasResumedRef.current = true
setShowSuccessAlert(false)
resume()
}}
onClose={() => {
if (hasResumedRef.current) return
hasResumedRef.current = true
@@ -152,12 +148,6 @@ const SecondQuizCursor = ({ resume, unmute, onCorrect }: QuizCursorProps) => {
visible={showSuccessAlert}
title="恭喜你,选择正确!"
content="当时毛泽东采用动员方式,以“钟英”为代号发出《关于召开四大致各地党组织的信》和《关于召开四大的通知》,在通知中阐明意义,各地党组织积极响应,为四大议题积累丰富实践依据,推动筹备深入。"
onContinue={() => {
if (hasResumedRef.current) return
hasResumedRef.current = true
setShowSuccessAlert(false)
resume()
}}
onClose={() => {
if (hasResumedRef.current) return
hasResumedRef.current = true
@@ -199,12 +189,6 @@ const EndingQuizCursor = ({ resume, unmute }: Omit<QuizCursorProps, 'onCorrect'>
visible={showSuccessAlert}
title="恭喜你,选择正确!"
content="毛泽东回湘后,深入农村,了解农民疾苦与诉求,为后续《湖南农民运动考察报告》奠基,让四大工农联盟思想在实践中持续深化,开始了领导工农运动的新征程。"
onContinue={() => {
if (hasResumedRef.current) return
hasResumedRef.current = true
setShowSuccessAlert(false)
resume()
}}
onClose={() => {
if (hasResumedRef.current) return
hasResumedRef.current = true
@@ -506,6 +490,8 @@ const Home = () => {
text="毛泽东在中共四大筹备期间的三次重要抉择,均锚定真实实践、扎根基层,为四大首次明确无产阶级领导权、工农联盟筑牢基础。虽因健康未参会,但其筹备工作与后续调研,如纽带般连接理论与实践,让党的革命理念在历史浪潮中,朝着正确方向坚定前行,成为早期共产党人探索革命道路的生动注脚,影响深远,照耀后世奋进征程。"
onContinue={() => {
setEndingVisible(false)
saveMaozedongStore()
setCourseTimeProgress(2)
navigate(`/${moduleName}/maozedong/home`)
}}
/>