<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>第08讲:认识人民币与简单购物</title>
<style>
/* ================= 基础重置与全局样式 ================= */
:root {
--primary: #a29bfe; /* 薰衣草紫 */
--primary-dark: #6c5ce7;
--accent: #ffeaa7; /* 奶油黄 */
--success: #00b894; /* 薄荷绿 */
--error: #ff7675; /* 珊瑚红 */
--bg-color: #f0f3f5;
--text-main: #2d3436;
--text-sub: #636e72;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif; }
::-webkit-scrollbar { display: none; }
html, body { margin: 0; padding: 0; background: var(--bg-color); overflow: hidden; height: 100vh; }
/* 动态背景图案 */
body {
background-image: radial-gradient(#dfe6e9 1px, transparent 1px);
background-size: 20px 20px;
}
#app { height: 100vh; max-width: 480px; margin: 0 auto; background: rgba(255,255,255,0.95); display: flex; flex-direction: column; position: relative; box-shadow: 0 0 30px rgba(0,0,0,0.05); }
.content-area { flex: 1; overflow-y: auto; padding-bottom: 90px; scroll-behavior: smooth; padding-top: 10px; }
/* 通用动画类 */
.fade-in { animation: fadeIn 0.4s ease-out; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.shake { animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both; }
@keyframes shake { 10%, 90% { transform: translate3d(-1px, 0, 0); } 20%, 80% { transform: translate3d(2px, 0, 0); } 30%, 50%, 70% { transform: translate3d(-4px, 0, 0); } 40%, 60% { transform: translate3d(4px, 0, 0); } }
/* ================= 底部导航 (App Bar) ================= */
.bottom-nav {
position: fixed; bottom: 0; left: 50%; transform: translateX(-50%);
width: 100%; max-width: 480px; height: 75px;
background: rgba(255, 255, 255, 0.98);
border-top: 1px solid rgba(0,0,0,0.05);
display: flex; justify-content: space-around; align-items: center;
z-index: 9999; box-shadow: 0 -5px 20px rgba(0,0,0,0.03);
backdrop-filter: blur(10px);
padding-bottom: 10px;
}
.nav-item { flex: 1; display: flex; flex-direction: column; align-items: center; cursor: pointer; padding: 5px; color: #b2bec3; transition: all 0.3s; }
.nav-item.active { color: var(--primary-dark); transform: translateY(-3px); }
.nav-icon { font-size: 24px; margin-bottom: 2px; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.1)); }
.nav-label { font-size: 11px; font-weight: 600; }
/* ================= 顶部 Tab 导航 ================= */
.tab-nav {
display: flex; background: white; margin: 10px 20px 20px;
border-radius: 12px; padding: 5px; box-shadow: 0 4px 15px rgba(0,0,0,0.05);
}
.tab-item {
flex: 1; padding: 10px; text-align: center; cursor: pointer;
font-weight: 600; color: var(--text-sub); border-radius: 8px;
transition: all 0.3s; font-size: 14px;
}
.tab-item.active { background: #e0e7ff; color: var(--primary-dark); }
/* ================= 概念页 ================= */
.intro-page { padding: 30px 20px; text-align: center; }
.intro-emoji { font-size: 80px; margin-bottom: 20px; animation: float 3s ease-in-out infinite; }
@keyframes float { 0% { transform: translateY(0px); } 50% { transform: translateY(-10px); } 100% { transform: translateY(0px); } }
.intro-title { font-size: 28px; font-weight: 800; color: var(--text-main); margin-bottom: 20px; letter-spacing: 1px; }
.intro-story {
background: #fff; padding: 25px; border-radius: 20px; text-align: left;
font-size: 16px; line-height: 1.8; color: var(--text-sub);
box-shadow: 0 10px 25px rgba(0,0,0,0.05); margin-bottom: 25px;
}
.intro-why {
background: #fff8e1; color: #f57c00; padding: 15px; border-radius: 12px;
font-size: 15px; margin-bottom: 30px; border-left: 4px solid #ffb300; text-align: left;
}
.listen-btn {
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
color: white; border: none; padding: 16px 45px; border-radius: 50px;
font-size: 18px; font-weight: bold; cursor: pointer;
box-shadow: 0 8px 20px rgba(108, 92, 231, 0.3);
transition: all 0.2s; position: relative; overflow: hidden; display: block; margin: 0 auto;
}
.listen-btn:active { transform: scale(0.95); box-shadow: 0 4px 10px rgba(108, 92, 231, 0.3); }
/* ================= 演示页 ================= */
.demo-page { padding: 0 15px; }
.demo-section { display: none; }
.demo-section.active { display: block; animation: fadeIn 0.5s ease; }
.animation-area {
background: #ffffff;
border-radius: 20px; padding: 10px; min-height: 320px;
position: relative; overflow: hidden;
box-shadow: inset 0 0 20px rgba(0,0,0,0.03), 0 10px 20px rgba(0,0,0,0.05);
border: 1px solid rgba(0,0,0,0.05); margin-bottom: 20px;
display: flex; align-items: center; justify-content: center;
}
.svg-container { width: 100%; height: 100%; }
/* 公式与控制栏 */
.math-area {
background: #fff; border-left: 4px solid var(--accent);
border-radius: 0 12px 12px 0; padding: 15px; margin: 15px 0;
min-height: 60px; display: flex; align-items: center; justify-content: center;
box-shadow: 0 4px 15px rgba(0,0,0,0.05);
}
.math-formula { font-size: 20px; font-weight: 800; color: var(--text-main); text-align: center; }
.step-explanation {
background: #eef2ff; padding: 15px; border-radius: 12px;
color: var(--primary-dark); font-size: 15px; text-align: center;
line-height: 1.6; font-weight: 500; margin-bottom: 85px; /* 为底部按钮留空间 */
}
/* 悬浮控制按钮 - 放在动画区域两侧 */
.control-bar {
position: fixed; bottom: 85px; left: 50%; transform: translateX(-50%);
width: 90%; max-width: 460px; z-index: 100;
background: rgba(255, 255, 255, 0.9); backdrop-filter: blur(5px);
padding: 10px; border-radius: 20px;
box-shadow: 0 5px 20px rgba(0,0,0,0.1);
display: flex; justify-content: space-between; border: 1px solid rgba(0,0,0,0.05);
}
.step-btn {
background: var(--primary-dark); color: white; border: none;
padding: 12px 25px; border-radius: 15px; font-size: 15px; font-weight: bold;
cursor: pointer; transition: all 0.2s; box-shadow: 0 4px 10px rgba(108, 92, 231, 0.3);
}
.step-btn:disabled { background: #dcdde1; color: #a4b0be; box-shadow: none; cursor: not-allowed; }
.step-btn:active:not(:disabled) { transform: scale(0.95); }
/* ================= 讲解页 ================= */
.explain-page { padding: 20px; }
.explain-card {
background: white; border-radius: 16px; padding: 20px; margin-bottom: 15px;
box-shadow: 0 4px 15px rgba(0,0,0,0.04); transition: transform 0.2s;
border: 1px solid #f1f2f6; overflow: hidden;
}
.card-header {
display: flex; justify-content: space-between; align-items: center;
cursor: pointer; font-weight: 700; color: var(--text-main);
}
.card-content { margin-top: 10px; font-size: 15px; line-height: 1.6; color: var(--text-sub); }
/* ================= 练习/奥数 ================= */
.practice-page { padding: 20px; }
.question-card {
background: white; border-radius: 24px; padding: 30px 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.08);
}
.question-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 25px; border-bottom: 2px solid #f0f2f5; padding-bottom: 15px; }
.question-number { color: var(--primary-dark); font-weight: 800; }
.score-display { background: #fff3e0; color: #ff9800; padding: 5px 15px; border-radius: 20px; font-weight: 800; font-size: 14px; }
.question-text { font-size: 19px; line-height: 1.6; color: var(--text-main); margin-bottom: 30px; font-weight: 600; }
.option-btn {
display: block; width: 100%; padding: 18px; margin-bottom: 15px;
text-align: left; border: 2px solid #f0f2f5; border-radius: 16px;
background: white; font-size: 17px; cursor: pointer; color: var(--text-sub);
transition: all 0.2s; position: relative; overflow: hidden;
}
.option-btn:active:not(:disabled) { transform: scale(0.98); background: #fafafa; }
.option-btn.correct { background: #eafff3; border-color: #2ecc71; color: #2ecc71; font-weight: 600; }
.option-btn.wrong { background: #fff5f5; border-color: #ff6b6b; color: #ff6b6b; }
.option-btn.shaking { animation: shake 0.5s; }
.feedback-area { padding: 20px; border-radius: 16px; margin: 25px 0; font-size: 15px; line-height: 1.6; animation: fadeIn 0.3s ease; }
.feedback-correct { background: #eafff3; color: #27ae60; border: 1px solid #b8e9ca; }
.feedback-wrong { background: #fff5f5; color: #c0392b; border: 1px solid #ffcccc; }
.next-btn {
width: 100%; padding: 18px;
background: linear-gradient(135deg, var(--accent) 0%, #fab1a0 100%);
color: #d35400; border: none; border-radius: 16px;
font-size: 18px; font-weight: bold; cursor: pointer;
box-shadow: 0 10px 20px rgba(253, 203, 110, 0.3);
transition: transform 0.2s;
}
.next-btn:active { transform: scale(0.97); }
.hint-box { background: #fff8e1; border-left: 5px solid #ffca28; padding: 15px; border-radius: 8px; margin: 15px 0; font-size: 14px; color: #f57c00; font-weight: 500; }
.difficulty-badge { padding: 3px 10px; border-radius: 12px; font-size: 12px; font-weight: 700; margin-left: 8px; vertical-align: middle; }
.difficulty-3 { background: #ffebee; color: #c62828; }
/* ================= 完成页 ================= */
.completion-page { text-align: center; padding: 80px 20px; }
.completion-emoji { font-size: 100px; margin-bottom: 20px; animation: float 3s infinite; }
.final-score { font-size: 72px; font-weight: 800; color: var(--accent); margin-bottom: 40px; text-shadow: 4px 4px 0px rgba(0,0,0,0.1); }
.restart-btn {
background: linear-gradient(135deg, #00b894 0%, #00cec9 100%);
color: white; border: none; padding: 18px 50px; border-radius: 50px;
font-size: 18px; font-weight: bold; cursor: pointer; box-shadow: 0 10px 20px rgba(0,184,148,0.3);
}
/* ================= 秘籍页 ================= */
.secrets-container { padding: 30px 20px; overflow-x: auto; padding-bottom: 50px; }
.secrets-scroll { display: flex; gap: 20px; }
.secret-card {
flex: 0 0 280px; height: 360px;
background: white; border-radius: 30px; padding: 30px;
display: flex; flex-direction: column; justify-content: center; align-items: center;
box-shadow: 0 15px 35px rgba(0,0,0,0.15); transition: transform 0.3s;
}
.secret-card:nth-child(1) { border-top: 6px solid #ff9f43; }
.secret-card:nth-child(2) { border-top: 6px solid #54a0ff; }
.secret-card:nth-child(3) { border-top: 6px solid #5f27cd; }
.card-emoji { font-size: 60px; margin-bottom: 20px; }
.card-title { font-size: 22px; font-weight: 800; color: var(--text-main); margin-bottom: 15px; text-align: center; }
.card-desc { color: var(--text-sub); line-height: 1.6; text-align: center; font-size: 15px; }
</style>
</head>
<body>
<div id="app">
<div class="content-area">
<div v-show="currentPage === 1" class="intro-page fade-in">
<div class="intro-emoji">🛒</div>
<div class="intro-title">第08讲:认识人民币与简单购物</div>
<div class="intro-story">
小明要过生日啦,妈妈给了他一些钱去买糖果和朋友们分享。可是小明看着手里花花绿绿的纸币和硬币,有点发愁了:1张红色的“1元”能买几颗糖?一个蓝色的“5角”硬币呢?它们之间有什么关系呢?让我们和小明一起,走进人民币的奇妙世界吧!
</div>
<div class="intro-why">
<strong>为什么要学这个?</strong><br>
学会认钱和算钱,你就能自己独立去小卖部买东西,知道该付多少钱,该找回多少钱,成为一个精明的小管家!
</div>
<button class="listen-btn" @click="speak('人民币单位有元、角、分,1元等于10角,1角等于10分。买东西时,付的钱减去商品价格等于找回的钱。')">
听老师讲解 🔊
</button>
</div>
<div v-show="currentPage === 2" class="demo-page fade-in">
<div class="tab-nav">
<div class="tab-item" :class="{active: demoTab === 'shopping'}" @click="switchDemoTab('shopping')">购物演示</div>
<div class="tab-item" :class="{active: demoTab === 'convert'}" @click="switchDemoTab('convert')">单位换算</div>
</div>
<div class="demo-section" v-show="demoTab === 'shopping'">
<div class="animation-area">
<svg class="svg-container" viewBox="0 0 400 360" ref="svgShopping">
<rect x="0" y="0" width="400" height="360" fill="#f0f8ff"/>
<rect x="50" y="80" width="300" height="100" fill="#dfe6e9" stroke="#b2bec3" stroke-width="2" rx="10"/>
<rect x="70" y="100" width="60" height="60" fill="#ffcccc" rx="5"/>
<text x="100" y="135" text-anchor="middle" fill="#333" font-size="14">冰淇淋</text>
<text x="100" y="155" text-anchor="middle" fill="#d63031" font-size="16" font-weight="bold">5元</text>
<g id="bear" :opacity="shoppingStep >= 0 ? 1 : 0">
<circle cx="150" cy="250" r="25" fill="#a29bfe"/>
<circle cx="140" cy="240" r="5" fill="white"/>
<circle cx="160" cy="240" r="5" fill="white"/>
<path d="M150 260 Q145 265 150 270 Q155 265 150 260" fill="none" stroke="#fff" stroke-width="2"/>
<rect x="125" y="250" width="50" height="60" fill="#a29bfe" rx="10"/>
</g>
<g id="checkout" :opacity="shoppingStep >= 1 ? 1 : 0">
<rect x="250" y="200" width="100" height="80" fill="#74b9ff" rx="10"/>
<text x="300" y="250" text-anchor="middle" fill="white" font-size="16">收银台</text>
</g>
<g id="money10" :opacity="shoppingStep >= 2 ? 1 : 0">
<rect x="170" y="230" width="80" height="40" fill="#fdcb6e" rx="5" stroke="#e17055" stroke-width="2"/>
<text x="210" y="255" text-anchor="middle" fill="#d63031" font-size="14" font-weight="bold">10元</text>
</g>
<g id="equation" :opacity="shoppingStep >= 3 ? 1 : 0">
<rect x="130" y="50" width="140" height="40" fill="white" stroke="#6c5ce7" stroke-width="2" rx="10"/>
<text x="200" y="75" text-anchor="middle" fill="#333" font-size="20" font-weight="bold">10 - 5 = 5</text>
</g>
<g id="changeCoins" :opacity="shoppingStep >= 4 ? 1 : 0">
<circle cx="180" cy="300" r="12" fill="#b2bec3" stroke="#636e72"/>
<text x="180" y="305" text-anchor="middle" fill="#333" font-size="10" font-weight="bold">1元</text>
<circle cx="210" cy="300" r="12" fill="#b2bec3" stroke="#636e72"/>
<text x="210" y="305" text-anchor="middle" fill="#333" font-size="10" font-weight="bold">1元</text>
<circle cx="240" cy="300" r="12" fill="#b2bec3" stroke="#636e72"/>
<text x="240" y="305" text-anchor="middle" fill="#333" font-size="10" font-weight="bold">1元</text>
<circle cx="270" cy="300" r="12" fill="#b2bec3" stroke="#636e72"/>
<text x="270" y="305" text-anchor="middle" fill="#333" font-size="10" font-weight="bold">1元</text>
<circle cx="300" cy="300" r="12" fill="#b2bec3" stroke="#636e72"/>
<text x="300" y="305" text-anchor="middle" fill="#333" font-size="10" font-weight="bold">1元</text>
</g>
</svg>
</div>
<div class="math-area">
<div class="math-formula">{{ shoppingFormulas[shoppingStep] }}</div>
</div>
<div class="step-explanation">{{ shoppingSteps[shoppingStep] }}</div>
<div class="control-bar">
<button class="step-btn" @click="prevShoppingStep" :disabled="shoppingStep === 0">◀ 上一步</button>
<button class="step-btn" @click="nextShoppingStep" :disabled="shoppingStep === shoppingSteps.length - 1">下一步 ▶</button>
</div>
</div>
<div class="demo-section" v-show="demoTab === 'convert'">
<div class="animation-area">
<svg class="svg-container" viewBox="0 0 400 360" ref="svgConvert">
<rect x="0" y="0" width="400" height="360" fill="#f0f8ff"/>
<g id="yuan1" :opacity="convertStep >= 0 ? 1 : 0">
<rect x="100" y="120" width="100" height="50" fill="#fdcb6e" rx="5" stroke="#e17055" stroke-width="2"/>
<text x="150" y="150" text-anchor="middle" fill="#d63031" font-size="20" font-weight="bold">1元</text>
</g>
<g id="equal" :opacity="convertStep >= 1 ? 1 : 0">
<text x="200" y="155" text-anchor="middle" fill="#333" font-size="30" font-weight="bold">=</text>
</g>
<g id="tenJiao" :opacity="convertStep >= 1 ? 1 : 0">
<circle v-for="(n, idx) in 10" :key="idx" :cx="250 + (idx % 5) * 25" :cy="120 + Math.floor(idx / 5) * 30" r="10" fill="#b2bec3" stroke="#636e72"/>
<text x="300" y="190" text-anchor="middle" fill="#333" font-size="14">10个1角</text>
</g>
<g id="arrowDown" :opacity="convertStep >= 2 ? 1 : 0">
<text x="200" y="240" text-anchor="middle" fill="#333" font-size="20" font-weight="bold">↓</text>
<text x="200" y="260" text-anchor="middle" fill="#6c5ce7" font-size="16" font-weight="bold">1角 = 10分</text>
</g>
<g id="hundredFen" :opacity="convertStep >= 3 ? 1 : 0">
<circle v-for="(n, idx) in 20" :key="idx" :cx="100 + (idx % 10) * 20" :cy="280 + Math.floor(idx / 10) * 20" r="4" fill="#a29bfe"/>
<text x="200" y="330" text-anchor="middle" fill="#333" font-size="14">100个1分</text>
</g>
</svg>
</div>
<div class="math-area">
<div class="math-formula">{{ convertFormulas[convertStep] }}</div>
</div>
<div class="step-explanation">{{ convertSteps[convertStep] }}</div>
<div class="control-bar">
<button class="step-btn" @click="prevConvertStep" :disabled="convertStep === 0">◀ 上一步</button>
<button class="step-btn" @click="nextConvertStep" :disabled="convertStep === convertSteps.length - 1">下一步 ▶</button>
</div>
</div>
</div>
<div v-show="currentPage === 3" class="explain-page fade-in">
<div class="tab-nav">
<div class="tab-item" :class="{active: explainTab === 'unit'}" @click="switchExplainTab('unit')">基本单位</div>
<div class="tab-item" :class="{active: explainTab === 'calc'}" @click="switchExplainTab('calc')">找零计算</div>
<div class="tab-item" :class="{active: explainTab === 'example'}" @click="switchExplainTab('example')">典型例题</div>
</div>
<div v-if="explainTab === 'unit'">
<div class="explain-card">
<div class="card-header">人民币单位</div>
<div class="card-content">
元、角、分,就像大哥哥、小弟弟、小妹妹。
</div>
</div>
<div class="explain-card">
<div class="card-header">换算关系</div>
<div class="card-content">
1元=10角,1角=10分,就像1个大饼=10个小饼。
</div>
</div>
</div>
<div v-if="explainTab === 'calc'">
<div class="explain-card">
<div class="card-header">核心公式</div>
<div class="card-content">
付的钱 - 商品价格 = 找回的钱
</div>
</div>
<div class="explain-card">
<div class="card-header">生活例子</div>
<div class="card-content">
铅笔2元,橡皮1元,一共3元。给收银员阿姨5元,找回2元。
</div>
</div>
</div>
<div v-if="explainTab === 'example'">
<div class="explain-card" v-for="(example, index) in typicalExamples" :key="index">
<div class="card-header" @click="toggleExample(index)">
{{ example.title }}
<span>{{ example.show ? '▲' : '▼' }}</span>
</div>
<div class="card-content" v-show="example.show">
<strong>题目:</strong> {{ example.question }}<br><br>
<div class="example-answer">答案: {{ example.answer }}</div><br>
<strong>解析:</strong> {{ example.explanation }}
</div>
</div>
</div>
</div>
<div v-show="currentPage === 4" class="practice-page fade-in">
<div v-if="!practiceCompleted">
<div class="question-card">
<div class="question-header">
<div class="question-number">第 {{currentQuestion + 1}}/{{practiceQuestions.length}} 题</div>
<div class="score-display">⭐ {{score}}分</div>
</div>
<div class="question-text">{{practiceQuestions[currentQuestion].text}}</div>
<div class="options-container">
<button v-for="(option, index) in practiceQuestions[currentQuestion].options"
:key="'opt'+index"
class="option-btn"
:class="{
'correct': answered && option.correct,
'wrong': answered && selectedOption === index && !option.correct,
'shake': answered && selectedOption === index && !option.correct
}"
@click="selectOption(index, option.correct)"
:disabled="answered">
{{option.text}}
</button>
</div>
<div v-if="answered" class="feedback-area" :class="isCorrect ? 'feedback-correct' : 'feedback-wrong'">
<div v-if="isCorrect">
<strong>🎉 太棒了!</strong><br>
{{practiceQuestions[currentQuestion].explanation}}
</div>
<div v-else>
<strong>💡 让我们一起分析:</strong><br>
{{practiceQuestions[currentQuestion].explanation}}
</div>
</div>
<button v-if="answered" class="next-btn" @click="nextQuestion">
{{currentQuestion < practiceQuestions.length - 1 ? '下一题 →' : '完成练习 ✓'}}
</button>
</div>
</div>
<div v-else class="completion-page fade-in">
<div class="completion-emoji">🎉</div>
<div class="completion-title">课内练习完成!</div>
<div class="final-score">+{{score}} 分</div>
<button class="restart-btn" @click="switchPage(5)">挑战奥数题 🚀</button>
</div>
</div>
<div v-show="currentPage === 5" class="practice-page fade-in">
<div v-if="!olympiadCompleted">
<div class="question-card" style="border-top: 5px solid #ff9f43;">
<div class="question-header">
<div>
<span class="question-number">第 {{currentOlympiad + 1}}/{{olympiadQuestions.length}} 题</span>
<span class="difficulty-badge" :class="'difficulty-' + olympiadQuestions[currentOlympiad].difficulty">
{{olympiadQuestions[currentOlympiad].difficultyText}}
</span>
</div>
<div class="score-display">⭐ {{olympiadScore}}分</div>
</div>
<div class="question-text">{{olympiadQuestions[currentOlympiad].text}}</div>
<div class="options-container">
<button v-for="(option, index) in olympiadQuestions[currentOlympiad].options"
:key="'olopt'+index"
class="option-btn"
:class="{
'correct': olympiadAnswered && option.correct,
'wrong': olympiadAnswered && selectedOlympiadOption === index && !option.correct,
'shake': olympiadAnswered && selectedOlympiadOption === index && !option.correct
}"
@click="selectOlympiadOption(index, option.correct)"
:disabled="olympiadAnswered">
{{option.text}}
</button>
</div>
<div v-if="wrongAttempts > 0 && !olympiadAnswered" class="hint-box fade-in">
<strong>💡 提示:</strong>
{{ wrongAttempts === 1 ? olympiadQuestions[currentOlympiad].hint1 :
(wrongAttempts === 2 ? olympiadQuestions[currentOlympiad].hint2 : olympiadQuestions[currentOlympiad].hint3) }}
</div>
<div v-if="olympiadAnswered" class="feedback-area" :class="isOlympiadCorrect ? 'feedback-correct' : 'feedback-wrong'">
<div v-if="isOlympiadCorrect">
<strong>🏆 厉害!</strong><br>
{{olympiadQuestions[currentOlympiad].explanation}}
</div>
<div v-else>
<strong>📖 详细解析:</strong><br>
{{olympiadQuestions[currentOlympiad].explanation}}
</div>
</div>
<button v-if="olympiadAnswered || wrongAttempts >= 3" class="next-btn" @click="nextOlympiad">
{{currentOlympiad < olympiadQuestions.length - 1 ? '下一题 →' : '完成挑战 ✓'}}
</button>
</div>
</div>
<div v-else class="completion-page fade-in">
<div class="completion-emoji">👑</div>
<div class="completion-title">奥数挑战完成!</div>
<div class="final-score">+{{olympiadScore}} 分</div>
<button class="restart-btn" @click="switchPage(6)">查看通关秘籍 🎁</button>
</div>
</div>
<div v-show="currentPage === 6" class="secrets-container fade-in">
<div class="secrets-scroll">
<div class="secret-card">
<div class="card-emoji">🧠</div>
<div class="card-title">秘籍1:换算记忆法</div>
<div class="card-desc">记住1元=10角=100分,像楼梯一样一级一级换</div>
</div>
<div class="secret-card">
<div class="card-emoji">🎯</div>
<div class="card-title">秘籍2:凑整好算法</div>
<div class="card-desc">买东西时给整数的钱(5元、10元),找零更好算</div>
</div>
<div class="secret-card">
<div class="card-emoji">⚠️</div>
<div class="card-title">秘籍3:单位别弄错</div>
<div class="card-desc">算完记得看单位是元、角还是分</div>
</div>
</div>
</div>
</div>
<div class="bottom-nav">
<div class="nav-item" :class="{active: currentPage === 1}" @click="switchPage(1)">
<div class="nav-icon">💡</div><div class="nav-label">概念</div>
</div>
<div class="nav-item" :class="{active: currentPage === 2}" @click="switchPage(2)">
<div class="nav-icon">🎬</div><div class="nav-label">演示</div>
</div>
<div class="nav-item" :class="{active: currentPage === 3}" @click="switchPage(3)">
<div class="nav-icon">📝</div><div class="nav-label">讲解</div>
</div>
<div class="nav-item" :class="{active: currentPage === 4}" @click="switchPage(4)">
<div class="nav-icon">✏️</div><div class="nav-label">练习</div>
</div>
<div class="nav-item" :class="{active: currentPage === 5}" @click="switchPage(5)">
<div class="nav-icon">🏆</div><div class="nav-label">奥数</div>
</div>
<div class="nav-item" :class="{active: currentPage === 6}" @click="switchPage(6)">
<div class="nav-icon">🎁</div><div class="nav-label">秘籍</div>
</div>
</div>
</div>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/vue.global.prod.js"></script>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/gsap.min.js"></script>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/confetti.browser.min.js"></script>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
currentPage: 1,
// 演示页变量
demoTab: 'shopping',
shoppingStep: 0,
shoppingSteps: [
'小熊来到超市,看中了一个标价5元的冰淇淋。',
'小熊拿着冰淇淋走到收银台,兔子姐姐在等着它。',
'小熊掏出一张10元的纸币,准备付钱。',
'屏幕上显示找零的计算公式:10元 - 5元 = 5元。',
'兔子姐姐找给小熊5个1元的硬币,小熊开心地离开!'
],
shoppingFormulas: [
'商品价格:5元',
'准备付钱',
'付的钱:10元',
'10 - 5 = 5',
'找回:5元'
],
convertStep: 0,
convertSteps: [
'这是一张1元的纸币。',
'1元可以换成10个1角的硬币。',
'那么,1角又可以换成多少分呢?',
'1角=10分,所以1元总共可以换成100个1分的硬币!'
],
convertFormulas: [
'1元',
'1元 = 10角',
'1角 = 10分',
'1元 = 10角 = 100分'
],
// 讲解页变量
explainTab: 'unit',
typicalExamples: [
{ title: '例题1:基础题', question: '1元等于多少角?', answer: '10角', explanation: '第1步:这是最基本的换算;第2步:1元=10角(记住这个!);第3步:就像1块大饼可以切成10小块', show: false },
{ title: '例题2:进阶题', question: '买一个苹果3元,付了5元,应该找回多少钱?', answer: '2元', explanation: '第1步:付的钱是5元;第2步:苹果价格是3元;第3步:找回:5-3=2元', show: false },
{ title: '例题3:易错题', question: '小明有5角钱,买了一块橡皮3角,还剩多少钱?', answer: '2角', explanation: '【易错点】:有的小朋友看到5和3,算成5-3=2元,单位错了!【正确做法】:第1步:原有5角;第2步:花了3角;第3步:剩余:5角-3角=2角(注意单位!)', show: false }
],
// 练习题数据
practiceQuestions: [
{ text: '题目1:1元可以换成几个1角?', options: [{text: 'A.5个', correct: false}, {text: 'B.10个', correct: true}, {text: 'C.20个', correct: false}, {text: 'D.100个', correct: false}], explanation: '提示3:可以换成10个1角'},
{ text: '题目2:2元等于多少角?', options: [{text: 'A.10角', correct: false}, {text: 'B.20角', correct: true}, {text: 'C.5角', correct: false}, {text: 'D.2角', correct: false}], explanation: '提示3:2×10=20角'},
{ text: '题目3:买铅笔2元,付了10元,找回多少?', options: [{text: 'A.5元', correct: false}, {text: 'B.6元', correct: false}, {text: 'C.7元', correct: false}, {text: 'D.8元', correct: true}], explanation: '提示3:10-2=8元'},
{ text: '题目4:5角+5角=?', options: [{text: 'A.10角', correct: false}, {text: 'B.1元', correct: false}, {text: 'C.以上都对', correct: true}, {text: 'D.都不对', correct: false}], explanation: '提示3:10角=1元,所以都对'},
{ text: '题目5:买本子3元,买笔2元,一共多少钱?', options: [{text: 'A.4元', correct: false}, {text: 'B.5元', correct: true}, {text: 'C.6元', correct: false}, {text: 'D.7元', correct: false}], explanation: '提示3:3+2=5元'},
{ text: '题目6:小红有10元,买糖用了6元,还剩多少?', options: [{text: 'A.2元', correct: false}, {text: 'B.3元', correct: false}, {text: 'C.4元', correct: true}, {text: 'D.5元', correct: false}], explanation: '提示3:10-6=4元'},
{ text: '题目7:1元5角用数字怎么写?', options: [{text: 'A.1.5元', correct: true}, {text: 'B.15元', correct: false}, {text: 'C.1.05元', correct: false}, {text: 'D.10.5元', correct: false}], explanation: '提示3:写成1.5元'},
{ text: '题目8:买东西8元,给了10元,找回多少?', options: [{text: 'A.1元', correct: false}, {text: 'B.2元', correct: true}, {text: 'C.3元', correct: false}, {text: 'D.18元', correct: false}], explanation: '提示3:10-8=2元'}
],
currentQuestion: 0,
answered: false,
selectedOption: null,
isCorrect: false,
score: 0,
practiceCompleted: false,
// 奥数题数据
olympiadQuestions: [
{ text: '题目1:小明买3支铅笔,每支2元,一共要付多少钱?如果给收银员10元,找回多少?', options: [{text: 'A.付6元,找回4元', correct: true}, {text: 'B.付6元,找回3元', correct: false}, {text: 'C.付5元,找回4元', correct: false}, {text: 'D.付8元,找回2元', correct: false}], hint1: '先算3支铅笔多少钱', hint2: '2×3=6元', hint3: '10-6=4元找回', explanation: '每支铅笔:2元;买3支:2×3=6元;付10元,找回:10-6=4元', difficulty: 3, difficultyText: '⭐⭐⭐' },
{ text: '题目2:妈妈带20元去买菜,买白菜5元,买肉12元,还剩多少钱?', options: [{text: 'A.2元', correct: false}, {text: 'B.3元', correct: true}, {text: 'C.4元', correct: false}, {text: 'D.5元', correct: false}], hint1: '先算总共花了多少钱', hint2: '5+12=17元', hint3: '20-17=3元', explanation: '原有:20元;花费:5元+12元=17元;剩余:20-17=3元', difficulty: 3, difficultyText: '⭐⭐⭐' },
{ text: '题目3:小红有5元纸币和3个1元硬币,一共有多少钱?', options: [{text: 'A.5元', correct: false}, {text: 'B.6元', correct: false}, {text: 'C.7元', correct: false}, {text: 'D.8元', correct: true}], hint1: '5元纸币是5元', hint2: '3个1元硬币是多少?', hint3: '5+3=8元', explanation: '5元纸币:5元;3个1元硬币:3×1=3元;总共:5+3=8元', difficulty: 3, difficultyText: '⭐⭐⭐' },
{ text: '题目4:一瓶水2元5角,买两瓶要多少钱?', options: [{text: 'A.4元', correct: false}, {text: 'B.4元5角', correct: false}, {text: 'C.5元', correct: true}, {text: 'D.5元5角', correct: false}], hint1: '一瓶2元5角', hint2: '两瓶就是2倍', hint3: '2.5×2=5元', explanation: '一瓶:2元5角=2.5元;两瓶:2.5×2=5元;或者:2元×2=4元,5角×2=10角=1元,共5元', difficulty: 3, difficultyText: '⭐⭐⭐' },
{ text: '题目5:小军买零食花了3元8角,给了5元,应该找回多少?', options: [{text: 'A.1元1角', correct: false}, {text: 'B.1元2角', correct: true}, {text: 'C.2元2角', correct: false}, {text: 'D.1元8角', correct: false}], hint1: '5元减去3元8角', hint2: '5元=4元10角', hint3: '4元10角-3元8角=1元2角', explanation: '付的钱:5元=4元10角;花的钱:3元8角;找回:4元10角-3元8角=1元2角;或者:5-3.8=1.2元=1元2角', difficulty: 3, difficultyText: '⭐⭐⭐' },
{ text: '题目6:买4个苹果,每个1元5角,一共多少钱?', options: [{text: 'A.5元', correct: false}, {text: 'B.6元', correct: true}, {text: 'C.7元', correct: false}, {text: 'D.8元', correct: false}], hint1: '一个苹果1元5角', hint2: '4个就是4倍', hint3: '1.5×4=6元', explanation: '每个:1元5角=1.5元;4个:1.5×4=6元;或者:1元×4=4元,5角×4=20角=2元,共6元', difficulty: 3, difficultyText: '⭐⭐⭐' },
{ text: '题目7:换钱:用1张10元可以换几张5元?', options: [{text: 'A.1张', correct: false}, {text: 'B.2张', correct: true}, {text: 'C.3张', correct: false}, {text: 'D.5张', correct: false}], hint1: '10元里有几个5元?', hint2: '用除法计算', hint3: '10÷5=2张', explanation: '10元÷5元=2张', difficulty: 3, difficultyText: '⭐⭐⭐' },
{ text: '题目8:小明存钱罐里有8个1元硬币,5个5角硬币。一共有多少钱?', options: [{text: 'A.10元', correct: false}, {text: 'B.10元5角', correct: true}, {text: 'C.11元', correct: false}, {text: 'D.13元', correct: false}], hint1: '分别算两种硬币的总值', hint2: '8个1元=8元', hint3: '5个5角=2元5角,共10元5角', explanation: '8个1元:8×1=8元;5个5角:5×0.5=2.5元=2元5角;总共:8+2.5=10.5元=10元5角', difficulty: 3, difficultyText: '⭐⭐⭐' }
],
currentOlympiad: 0,
olympiadAnswered: false,
selectedOlympiadOption: null,
isOlympiadCorrect: false,
olympiadScore: 0,
olympiadCompleted: false,
wrongAttempts: 0
};
},
mounted() {
this.runShoppingAnimation();
this.runConvertAnimation();
},
methods: {
switchPage(page) {
this.stopSpeak();
this.currentPage = page;
window.scrollTo(0,0);
if (page === 2) {
this.shoppingStep = 0;
this.convertStep = 0;
this.$nextTick(() => {
this.runShoppingAnimation();
this.runConvertAnimation();
});
}
if (page === 4 && this.practiceCompleted) {
this.resetPractice();
}
if (page === 5 && this.olympiadCompleted) {
this.resetOlympiad();
}
},
stopSpeak() {
const isWeChat = /MicroMessenger/i.test(navigator.userAgent);
if (isWeChat) {
const audio = document.getElementById('tts-audio');
if (audio) {
audio.pause();
audio.currentTime = 0;
}
} else {
if (window.speechSynthesis) {
window.speechSynthesis.cancel();
}
}
},
switchDemoTab(tab) {
this.stopSpeak();
this.demoTab = tab;
},
switchExplainTab(tab) {
this.stopSpeak();
this.explainTab = tab;
},
speak(text) {
const isWeChat = /MicroMessenger/i.test(navigator.userAgent);
if (isWeChat) {
let audio = document.getElementById('tts-audio');
if (!audio) {
audio = document.createElement('audio');
audio.id = 'tts-audio';
audio.style.display = 'none';
document.body.appendChild(audio);
}
const url = `https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/tts.php?text=${encodeURIComponent(text)}&t=${Date.now()}`;
audio.src = url;
audio.play().catch(err => { console.log('语音播放失败:', err); });
} else {
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'zh-CN';
utterance.rate = 0.9;
window.speechSynthesis.speak(utterance);
}
},
runShoppingAnimation() {
if (typeof gsap === 'undefined') return;
const tl = gsap.timeline();
tl.to("#bear", { duration: 0.5, x: 100, opacity: 1 }, "step0");
tl.to("#checkout", { duration: 0.5, opacity: 1 }, "step1");
tl.to("#money10", { duration: 0.5, opacity: 1, x: 80 }, "step2");
tl.to("#equation", { duration: 0.5, opacity: 1, scale: 1.1, repeat: 1, yoyo: true }, "step3");
tl.to("#changeCoins", { duration: 0.5, opacity: 1, stagger: 0.1, scale: 1.2, repeat: 1, yoyo: true }, "step4");
tl.pause();
this.shoppingTl = tl;
},
nextShoppingStep() {
if (this.shoppingStep < this.shoppingSteps.length - 1) {
this.shoppingStep++;
if (this.shoppingTl) {
this.shoppingTl.tweenTo(`step${this.shoppingStep}`);
}
}
},
prevShoppingStep() {
if (this.shoppingStep > 0) {
this.shoppingStep--;
if (this.shoppingTl) {
this.shoppingTl.tweenTo(`step${this.shoppingStep}`);
}
}
},
runConvertAnimation() {
if (typeof gsap === 'undefined') return;
const tl = gsap.timeline();
tl.to("#yuan1", { duration: 0.5, opacity: 1, scale: 1.1, yoyo: true, repeat: 1 }, "cstep0");
tl.to("#equal", { duration: 0.5, opacity: 1 }, "cstep1");
tl.to("#tenJiao", { duration: 0.5, opacity: 1, stagger: 0.05, scale: 1.1, yoyo: true, repeat: 1 }, "cstep1");
tl.to("#arrowDown", { duration: 0.5, opacity: 1 }, "cstep2");
tl.to("#hundredFen", { duration: 0.5, opacity: 1, stagger: 0.02 }, "cstep3");
tl.pause();
this.convertTl = tl;
},
nextConvertStep() {
if (this.convertStep < this.convertSteps.length - 1) {
this.convertStep++;
if (this.convertTl) {
this.convertTl.tweenTo(`cstep${this.convertStep}`);
}
}
},
prevConvertStep() {
if (this.convertStep > 0) {
this.convertStep--;
if (this.convertTl) {
this.convertTl.tweenTo(`cstep${this.convertStep}`);
}
}
},
toggleExample(index) {
this.typicalExamples[index].show = !this.typicalExamples[index].show;
},
selectOption(index, correct) {
if (this.answered) return;
if (!correct) {
// 震动反馈
const btn = document.querySelectorAll('.option-btn')[index];
btn.classList.add('shake');
setTimeout(() => btn.classList.remove('shake'), 500);
}
this.answered = true;
this.selectedOption = index;
this.isCorrect = correct;
if (correct) {
this.score += 20;
if (typeof confetti !== 'undefined') {
confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } });
}
}
},
nextQuestion() {
if (this.currentQuestion < this.practiceQuestions.length - 1) {
this.currentQuestion++;
this.answered = false;
this.selectedOption = null;
} else {
this.practiceCompleted = true;
}
},
resetPractice() {
this.currentQuestion = 0;
this.answered = false;
this.selectedOption = null;
this.isCorrect = false;
this.score = 0;
this.practiceCompleted = false;
},
selectOlympiadOption(index, correct) {
if (this.olympiadAnswered) return;
if (correct) {
this.olympiadAnswered = true;
this.selectedOlympiadOption = index;
this.isOlympiadCorrect = true;
this.olympiadScore += 20;
this.wrongAttempts = 0;
if (typeof confetti !== 'undefined') {
confetti({ particleCount: 150, spread: 80, origin: { y: 0.6 } });
}
} else {
// 震动
const btn = document.querySelectorAll('.option-btn')[index];
btn.classList.add('shake');
setTimeout(() => btn.classList.remove('shake'), 500);
this.wrongAttempts++;
if (this.wrongAttempts >= 3) {
this.olympiadAnswered = true;
this.selectedOlympiadOption = index;
this.isOlympiadCorrect = false;
}
}
},
nextOlympiad() {
if (this.currentOlympiad < this.olympiadQuestions.length - 1) {
this.currentOlympiad++;
this.olympiadAnswered = false;
this.selectedOlympiadOption = null;
this.wrongAttempts = 0;
} else {
this.olympiadCompleted = true;
}
},
resetOlympiad() {
this.currentOlympiad = 0;
this.olympiadAnswered = false;
this.selectedOlympiadOption = null;
this.isOlympiadCorrect = false;
this.olympiadScore = 0;
this.olympiadCompleted = false;
this.wrongAttempts = 0;
}
}
}).mount('#app');
</script>
</body>
</html>
💡 这段代码完全由 AI 生成。
登录后可复制完整代码