Commit 5d12e41f authored by liujiangnan's avatar liujiangnan

feat

parent db2cfe8a
This diff is collapsed.
......@@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>h5-template-generator</title>
<title>AI选择题播放</title>
<link href="./index.css" rel="stylesheet" >
<script type="text/javascript" src="//teach.cdn.ireadabc.com/h5template/h5-static-lib/js/jquery-1.12.3.min.js"></script>
<script type="text/javascript" src="//teach.cdn.ireadabc.com/h5template/h5-static-lib/js/air.js"></script>
......@@ -15,7 +15,90 @@
<script src="//teach.cdn.ireadabc.com/h5template/h5-static-lib/js/element-ui/index.js"></script>
</head>
<body>
<h1 id="test"></h1>
<div id="app">
<div class="question-container" v-if="questionData">
<!-- 题干部分 -->
<div class="question-section">
<div class="question-text" v-if="questionData.question">
<h3>{{ questionData.question }}</h3>
</div>
<div class="question-image" v-if="questionData.image_url">
<img :src="questionData.image_url" alt="题干图片">
</div>
<div class="question-audio" v-if="questionData.audio_url">
<el-button size="small" type="primary" @click="toggleQuestionAudio">
<i :class="questionData.isPlaying ? 'el-icon-video-pause' : 'el-icon-video-play'"></i>
{{ questionData.isPlaying ? '暂停' : '播放' }}题目音频
</el-button>
<audio ref="questionAudio" :src="questionData.audio_url" @ended="questionAudioEnded" style="display: none;"></audio>
</div>
</div>
<!-- 选项部分 -->
<div class="options-section">
<div class="option-item"
v-for="(option, index) in questionData.options"
:key="index"
@click="toggleOption(index)"
:class="{ 'selected': selectedOptions.includes(index) }">
<div class="option-content">
<div class="option-text" v-if="option.text">
<span class="option-text-content">{{ option.text }}</span>
</div>
<div class="option-image" v-if="option.image_url">
<img :src="option.image_url" alt="选项图片">
</div>
<div class="option-audio" v-if="option.audio_url">
<el-button size="mini" type="primary" @click.stop="toggleOptionAudio(index)">
<i :class="option.isPlaying ? 'el-icon-video-pause' : 'el-icon-video-play'"></i>
{{ option.isPlaying ? '暂停' : '播放' }}
</el-button>
<audio :ref="'optionAudio' + index" :src="option.audio_url" @ended="optionAudioEnded(index)" style="display: none;"></audio>
</div>
<div class="option-text">
<span class="option-label">{{ String.fromCharCode(65 + index) }}</span>
</div>
</div>
</div>
</div>
<!-- 提交按钮 -->
<div class="submit-section">
<el-button type="success" size="large" @click="submitAnswer" :disabled="selectedOptions.length === 0">
提交答案
</el-button>
</div>
<!-- 庆祝动画弹窗 -->
<div class="celebration-modal" v-if="showCelebration" @click="closeCelebration">
<div class="celebration-content">
<div class="celebration-icon">🎉</div>
<div class="celebration-text">回答正确!</div>
<div class="celebration-stars">
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
</div>
</div>
<div class="confetti-container">
<div class="confetti" v-for="n in 20" :key="n"></div>
</div>
</div>
<!-- 错误动画弹窗 -->
<div class="error-modal" v-if="showError" @click="closeError">
<div class="error-content">
<div class="error-icon"></div>
<div class="error-text">回答错误!</div>
</div>
</div>
</div>
</div>
</body>
<script src="./index.js"></script>
</html>
\ No newline at end of file
......@@ -7,37 +7,174 @@ window.air.hideAirClassLoading(key,data); //页面加载完成时,必须调
*/
//对应模板的名称,这个可以不写,但是最好是能写上,同时开发多个模板的情况下如果不写这个,本地缓存可能会存在混乱
var key = "h5_test";
$(function(){
window.courseware.getData(function(data){
//数据加载完,才算页面加载完成
//获取数据
if(data&&data.test){
$("#test").html("Hello "+data.test);
} else{
//一般来讲,如果没有获取到数据的话,给一组默认数据,用于演示模板的展示效果,方便别人了解这个模板
$("#test").html("Hello 我是演示信息!");
}
//数据渲染完成后,添加各种交互或者动画效果
//我这里简单做一个渐入渐出效果的例子
var flag = true;
setInterval(function(){
if(flag){
$("#test").fadeIn(500);
}else{
$("#test").fadeOut(500);
var key = "AI_QUESTION_CHOSE";
new Vue({
el: '#app',
data() {
return {
questionData: null,
selectedOptions: [],
showCelebration: false,
showError: false
}
},
created() {
window.courseware.getData((data) => {
if (data) {
this.questionData = data;
// 初始化选项的播放状态
if (this.questionData.options) {
this.questionData.options.forEach(option => {
option.isPlaying = false;
});
}
// 初始化题干播放状态
if (this.questionData) {
this.questionData.isPlaying = false;
}
} else {
// 默认演示数据
this.questionData = {
question: 'What is the capital of France?',
image_url: '',
audio_url: '',
audio_name: '',
isPlaying: false,
options: [
{
text: 'London',
image_url: '',
audio_url: '',
audio_name: '',
isPlaying: false,
is_correct: false
},
{
text: 'Paris',
image_url: '',
audio_url: '',
audio_name: '',
isPlaying: false,
is_correct: true
},
{
text: 'Berlin',
image_url: '',
audio_url: '',
audio_name: '',
isPlaying: false,
is_correct: false
}
]
};
}
// 页面加载完成,隐藏遮罩层
window.air.hideAirClassLoading(key, data);
}, key);
},
methods: {
// 题干音频播放/暂停
toggleQuestionAudio() {
const audio = this.$refs.questionAudio;
if (this.questionData.isPlaying) {
audio.pause();
this.questionData.isPlaying = false;
} else {
audio.play();
this.questionData.isPlaying = true;
}
},
// 题干音频播放结束
questionAudioEnded() {
this.questionData.isPlaying = false;
},
// 选项音频播放/暂停
toggleOptionAudio(optionIndex) {
const audio = this.$refs['optionAudio' + optionIndex][0];
if (this.questionData.options[optionIndex].isPlaying) {
audio.pause();
this.questionData.options[optionIndex].isPlaying = false;
} else {
audio.play();
this.questionData.options[optionIndex].isPlaying = true;
}
},
// 选项音频播放结束
optionAudioEnded(optionIndex) {
this.questionData.options[optionIndex].isPlaying = false;
},
// 选择/取消选择选项
toggleOption(optionIndex) {
const index = this.selectedOptions.indexOf(optionIndex);
if (index > -1) {
// 如果已选择,则取消选择
this.selectedOptions.splice(index, 1);
} else {
// 如果未选择,则添加选择
this.selectedOptions.push(optionIndex);
}
this.showResult = false;
},
// 提交答案
submitAnswer() {
if (this.selectedOptions.length === 0) {
return;
}
// 获取所有正确答案的索引
const correctOptions = this.questionData.options
.map((option, index) => option.is_correct ? index : -1)
.filter(index => index !== -1);
// 检查选择的答案是否正确
const isSelectionCorrect = this.selectedOptions.length === correctOptions.length &&
this.selectedOptions.every(selected => correctOptions.includes(selected));
if (isSelectionCorrect) {
// 回答正确,显示庆祝动画
this.showCelebration = true;
} else {
// 回答错误,显示错误动画并重置选择
this.showError = true;
// 延迟重置选择,让用户看到错误信息
setTimeout(() => {
this.resetAnswer();
}, 2000);
}
flag = !flag;
},1000)
},
// 重新选择
resetAnswer() {
this.selectedOptions = [];
this.showCelebration = false;
this.showError = false;
},
//在页面加载、事件、动画等都初始化完成后,一定要记得调用此方法,否则模板将是不可用的
window.air.hideAirClassLoading(key,data);
// 关闭庆祝弹窗
closeCelebration() {
this.showCelebration = false;
},
},key);
// 关闭错误弹窗
closeError() {
this.showError = false;
},
})
\ No newline at end of file
// 获取正确答案
getCorrectAnswer() {
const correctOptions = this.questionData.options
.map((option, index) => option.is_correct ? String.fromCharCode(65 + index) + '. ' + option.text : null)
.filter(text => text !== null);
return correctOptions.join('');
}
}
});
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment