// 题目数据数组 const questions = [ // 简单难度题目 (5道) { difficulty: 'easy', text: '下列哪个物理量是矢量?', options: ['A. 质量', 'B. 时间', 'C. 位移', 'D. 路程'], answer: 'C', explanation: '矢量具有大小和方向,位移是矢量,其他选项均为标量。' }, { difficulty: 'easy', text: '下列哪个物理量是矢量?', options: ['A. 质量', 'B. 时间', 'C. 位移', 'D. 路程'], answer: 'C', explanation: '矢量具有大小和方向,位移是矢量,其他选项均为标量。' }, { difficulty: 'easy', text: '下列哪个物理量是矢量?', options: ['A. 质量', 'B. 时间', 'C. 位移', 'D. 路程'], answer: 'C', explanation: '矢量具有大小和方向,位移是矢量,其他选项均为标量。' }, { difficulty: 'easy', text: '下列哪个物理量是矢量?', options: ['A. 质量', 'B. 时间', 'C. 位移', 'D. 路程'], answer: 'C', explanation: '矢量具有大小和方向,位移是矢量,其他选项均为标量。' }, { difficulty: 'easy', text: '下列哪个物理量是矢量?', options: ['A. 质量', 'B. 时间', 'C. 位移', 'D. 路程'], answer: 'C', explanation: '矢量具有大小和方向,位移是矢量,其他选项均为标量。' }, // 中等难度题目 (5道) { difficulty: 'medium', text: '关于万有引力定律,下列说法正确的是?', options: [ 'A. 万有引力只存在于天体之间', 'B. 万有引力与物体质量成正比,与距离成反比', 'C. 万有引力的发现者是牛顿', 'D. 地球对苹果的引力大于苹果对地球的引力' ], answer: 'C', explanation: '万有引力存在于任何有质量的物体之间,A错误;万有引力与距离的平方成反比,B错误;牛顿发现了万有引力定律,C正确;物体间的引力是相互的,大小相等,D错误。' }, { difficulty: 'medium', text: '关于万有引力定律,下列说法正确的是?', options: [ 'A. 万有引力只存在于天体之间', 'B. 万有引力与物体质量成正比,与距离成反比', 'C. 万有引力的发现者是牛顿', 'D. 地球对苹果的引力大于苹果对地球的引力' ], answer: 'C', explanation: '万有引力存在于任何有质量的物体之间,A错误;万有引力与距离的平方成反比,B错误;牛顿发现了万有引力定律,C正确;物体间的引力是相互的,大小相等,D错误。' }, { difficulty: 'medium', text: '关于万有引力定律,下列说法正确的是?', options: [ 'A. 万有引力只存在于天体之间', 'B. 万有引力与物体质量成正比,与距离成反比', 'C. 万有引力的发现者是牛顿', 'D. 地球对苹果的引力大于苹果对地球的引力' ], answer: 'C', explanation: '万有引力存在于任何有质量的物体之间,A错误;万有引力与距离的平方成反比,B错误;牛顿发现了万有引力定律,C正确;物体间的引力是相互的,大小相等,D错误。' }, { difficulty: 'medium', text: '关于万有引力定律,下列说法正确的是?', options: [ 'A. 万有引力只存在于天体之间', 'B. 万有引力与物体质量成正比,与距离成反比', 'C. 万有引力的发现者是牛顿', 'D. 地球对苹果的引力大于苹果对地球的引力' ], answer: 'C', explanation: '万有引力存在于任何有质量的物体之间,A错误;万有引力与距离的平方成反比,B错误;牛顿发现了万有引力定律,C正确;物体间的引力是相互的,大小相等,D错误。' }, { difficulty: 'medium', text: '关于万有引力定律,下列说法正确的是?', options: [ 'A. 万有引力只存在于天体之间', 'B. 万有引力与物体质量成正比,与距离成反比', 'C. 万有引力的发现者是牛顿', 'D. 地球对苹果的引力大于苹果对地球的引力' ], answer: 'C', explanation: '万有引力存在于任何有质量的物体之间,A错误;万有引力与距离的平方成反比,B错误;牛顿发现了万有引力定律,C正确;物体间的引力是相互的,大小相等,D错误。' }, // 困难难度题目 (5道) { difficulty: 'hard', text: '相对论中质量与能量的关系表达式是?', options: ['A. E=mc²', 'B. F=ma', 'C. E=hv', 'D. P=mv'], answer: 'A', explanation: '爱因斯坦的质能方程E=mc²表明质量和能量可以相互转换。' }, { difficulty: 'hard', text: '相对论中质量与能量的关系表达式是?', options: ['A. E=mc²', 'B. F=ma', 'C. E=hv', 'D. P=mv'], answer: 'A', explanation: '爱因斯坦的质能方程E=mc²表明质量和能量可以相互转换。' }, { difficulty: 'hard', text: '相对论中质量与能量的关系表达式是?', options: ['A. E=mc²', 'B. F=ma', 'C. E=hv', 'D. P=mv'], answer: 'A', explanation: '爱因斯坦的质能方程E=mc²表明质量和能量可以相互转换。' }, { difficulty: 'hard', text: '相对论中质量与能量的关系表达式是?', options: ['A. E=mc²', 'B. F=ma', 'C. E=hv', 'D. P=mv'], answer: 'A', explanation: '爱因斯坦的质能方程E=mc²表明质量和能量可以相互转换。' }, { difficulty: 'hard', text: '相对论中质量与能量的关系表达式是?', options: ['A. E=mc²', 'B. F=ma', 'C. E=hv', 'D. P=mv'], answer: 'A', explanation: '爱因斯坦的质能方程E=mc²表明质量和能量可以相互转换。' }, ]; // 当前难度级别,初始为中等 let currentDifficulty = 'medium'; // 已完成的难度 const completedDifficulties = []; // 各难度得分情况 const scores = { easy: { score: 0, correct: 0, incorrect: 0 }, medium: { score: 0, correct: 0, incorrect: 0 }, hard: { score: 0, correct: 0, incorrect: 0 } }; // 学伴功能相关变量 let mediaRecorder; let audioChunks = []; let isRecording = false; let audioElement = null; let isPlaying = false; let currentQuestion = null; // DOM元素 const questionContainer = document.getElementById('question-container'); const submitBtn = document.getElementById('submit-btn'); const resultSection = document.getElementById('result-section'); const totalScoreElement = document.getElementById('total-score'); const correctCountElement = document.getElementById('correct-count'); const incorrectCountElement = document.getElementById('incorrect-count'); const navigationSection = document.getElementById('navigation-section'); const navigationMessage = document.getElementById('navigation-message'); const nextBtn = document.getElementById('next-btn'); const difficultyIndicator = document.querySelector('.difficulty-indicator'); // 学伴功能DOM元素 const recordingIndicator = document.getElementById('recordingIndicator'); const thinkingIndicator = document.getElementById('thinkingIndicator'); const resultContainer = document.getElementById('resultContainer'); const asrResultText = document.getElementById('asrResultText'); const feedbackResultText = document.getElementById('feedbackResultText'); const playAudioBtn = document.getElementById('playAudioBtn'); const audioProgress = document.getElementById('audioProgress'); const progressBar = document.getElementById('progressBar'); const audioTime = document.getElementById('audioTime'); // 初始化页面 document.addEventListener('DOMContentLoaded', () => { renderQuestions(currentDifficulty); // 绑定学伴答疑按钮事件 document.addEventListener('click', function(e) { if (e.target && e.target.classList.contains('ask-xueban-btn')) { currentQuestion = { number: e.target.dataset.question, difficulty: e.target.dataset.difficulty }; startRecording(); } }); }); // 渲染指定难度的题目 function renderQuestions(difficulty) { questionContainer.innerHTML = ''; // 筛选当前难度的题目 const filteredQuestions = questions.filter(q => q.difficulty === difficulty); // 生成题目HTML filteredQuestions.forEach((q, index) => { const questionNumber = index + 1; const questionElement = document.createElement('div'); questionElement.className = 'question'; questionElement.dataset.difficulty = q.difficulty; questionElement.dataset.question = questionNumber; questionElement.innerHTML = `
${getDifficultyName(q.difficulty)}难度 - 问题 ${questionNumber}
20分

${q.text}

${q.options.map((option, optIndex) => { const optionLetter = String.fromCharCode(65 + optIndex); return `
`; }).join('')}
${q.explanation}
`; questionContainer.appendChild(questionElement); }); } // 获取难度名称 function getDifficultyName(difficulty) { const names = { easy: '简单', medium: '中等', hard: '高级' }; return names[difficulty] || difficulty; } // 提交答案 submitBtn.addEventListener('click', () => { checkAnswers(); submitBtn.disabled = true; submitBtn.textContent = '已提交'; }); // 检查答案 function checkAnswers() { let correctCount = 0; let incorrectCount = 0; let totalScore = 0; // 获取当前难度的题目 const currentQuestions = questions.filter(q => q.difficulty === currentDifficulty); // 检查每道题的答案 currentQuestions.forEach((q, index) => { const questionNumber = index + 1; const selectedOption = document.querySelector(`input[name="q${q.difficulty}-${questionNumber}"]:checked`); const explanationElement = document.getElementById(`explanation-${q.difficulty}-${questionNumber}`); const optionsContainer = document.querySelector(`div[data-difficulty="${q.difficulty}"][data-question="${questionNumber}"] .options`); const allOptions = optionsContainer.querySelectorAll('.option'); // 显示解析 explanationElement.classList.add('show'); if (!selectedOption) { // 未答题 optionsContainer.style.border = '2px solid #f39c12'; return; } // 标记正确或错误 const selectedValue = selectedOption.value; if (selectedValue === q.answer) { // 正确 selectedOption.closest('.option').classList.add('correct'); correctCount++; totalScore += 20; } else { // 错误 selectedOption.closest('.option').classList.add('incorrect'); // 标记正确答案 allOptions.forEach(option => { if (option.querySelector(`input[value="${q.answer}"]`)) { option.classList.add('correct'); } }); incorrectCount++; } }); // 更新当前难度得分 scores[currentDifficulty] = { score: totalScore, correct: correctCount, incorrect: incorrectCount }; // 添加到已完成难度 if (!completedDifficulties.includes(currentDifficulty)) { completedDifficulties.push(currentDifficulty); } // 显示结果 showResults(); // 显示下一步建议 showNextRecommendation(); } // 显示结果 function showResults() { resultSection.style.display = 'block'; // 计算总得分 let totalScore = 0; let totalCorrect = 0; let totalIncorrect = 0; completedDifficulties.forEach(difficulty => { totalScore += scores[difficulty].score; totalCorrect += scores[difficulty].correct; totalIncorrect += scores[difficulty].incorrect; }); // 更新结果显示 totalScoreElement.textContent = totalScore; correctCountElement.textContent = totalCorrect; incorrectCountElement.textContent = totalIncorrect; // 滚动到结果区域 resultSection.scrollIntoView({ behavior: 'smooth' }); } // 显示下一步建议 function showNextRecommendation() { navigationSection.style.display = 'block'; const currentScore = scores[currentDifficulty]; if (currentDifficulty === 'medium') { if (currentScore.correct >= 3) { navigationMessage.textContent = `恭喜!您在${getDifficultyName(currentDifficulty)}难度中答对了${currentScore.correct}题,表现优秀,建议挑战高级难度。`; nextBtn.onclick = () => switchDifficulty('hard'); } else { navigationMessage.textContent = `您在${getDifficultyName(currentDifficulty)}难度中答对了${currentScore.correct}题,建议先尝试简单难度巩固基础。`; nextBtn.onclick = () => switchDifficulty('easy'); } } else if (currentDifficulty === 'easy') { navigationMessage.textContent = `您已完成${getDifficultyName(currentDifficulty)}难度,建议继续挑战中等难度。`; nextBtn.onclick = () => switchDifficulty('medium'); } else if (currentDifficulty === 'hard') { navigationMessage.textContent = `恭喜您完成了所有难度级别!您的总分为${scores.easy.score + scores.medium.score + scores.hard.score}分。`; nextBtn.style.display = 'none'; } navigationSection.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); } // 切换难度 function switchDifficulty(nextDifficulty) { currentDifficulty = nextDifficulty; difficultyIndicator.textContent = `当前难度:${getDifficultyName(nextDifficulty)}`; difficultyIndicator.className = `difficulty-indicator difficulty-${nextDifficulty}`; // 重置按钮状态 submitBtn.disabled = false; submitBtn.textContent = '提交答案'; // 隐藏结果和导航区域 resultSection.style.display = 'none'; navigationSection.style.display = 'none'; // 渲染新难度题目 renderQuestions(nextDifficulty); // 滚动到页面顶部 window.scrollTo({ top: 0, behavior: 'smooth' }); } // 学伴功能 - 开始录音 function startRecording() { if (isRecording) return; navigator.mediaDevices.getUserMedia({ audio: true }) .then(stream => { mediaRecorder = new MediaRecorder(stream); audioChunks = []; mediaRecorder.ondataavailable = event => { if (event.data.size > 0) audioChunks.push(event.data); }; mediaRecorder.onstop = () => { const audioBlob = new Blob(audioChunks, { type: 'audio/wav' }); uploadAudioToServer(audioBlob); }; mediaRecorder.start(); isRecording = true; recordingIndicator.style.display = 'flex'; // 设置最长录音时间为60秒 setTimeout(stopRecording, 60000); }) .catch(error => { console.error("获取麦克风权限失败:", error); alert("请授权麦克风权限以使用录音功能"); }); } // 学伴功能 - 停止录音 function stopRecording() { if (!isRecording || !mediaRecorder) return; mediaRecorder.stop(); isRecording = false; recordingIndicator.style.display = 'none'; if (mediaRecorder.stream) { mediaRecorder.stream.getTracks().forEach(track => track.stop()); } } // 学伴功能 - 上传音频到服务器 function uploadAudioToServer(audioBlob) { thinkingIndicator.style.display = 'flex'; resultContainer.style.display = 'none'; const formData = new FormData(); formData.append('file', audioBlob, 'recording.wav'); if (currentQuestion) { formData.append('question_number', currentQuestion.number); formData.append('difficulty', currentQuestion.difficulty); } fetch('/api/xueban/upload-audio', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { thinkingIndicator.style.display = 'none'; if (data.success) { asrResultText.textContent = data.asr_text || '未识别到内容'; feedbackResultText.textContent = data.feedback_text || '无反馈内容'; resultContainer.style.display = 'flex'; if (data.audio_url) { audioElement = new Audio(data.audio_url); audioElement.onloadedmetadata = function() { updateAudioTimeDisplay(); }; audioElement.ontimeupdate = function() { updateAudioProgress(); updateAudioTimeDisplay(); }; audioElement.onended = function() { isPlaying = false; updatePlayButton(); }; playAudioBtn.onclick = togglePlayAudio; audioProgress.onclick = function(e) { const rect = audioProgress.getBoundingClientRect(); const clickPosition = (e.clientX - rect.left) / rect.width; audioElement.currentTime = clickPosition * audioElement.duration; }; } } else { alert('音频处理失败: ' + data.message); } }) .catch(error => { thinkingIndicator.style.display = 'none'; alert('上传音频失败: ' + error.message); }); } // 学伴功能 - 切换音频播放/暂停 function togglePlayAudio() { if (!audioElement) return; isPlaying ? audioElement.pause() : audioElement.play(); isPlaying = !isPlaying; updatePlayButton(); } // 学伴功能 - 更新播放按钮状态 function updatePlayButton() { playAudioBtn.innerHTML = isPlaying ? `` : ``; } // 学伴功能 - 更新音频进度条 function updateAudioProgress() { if (audioElement && audioElement.duration) { progressBar.style.width = `${(audioElement.currentTime / audioElement.duration) * 100}%`; } } // 学伴功能 - 更新音频时间显示 function updateAudioTimeDisplay() { if (audioElement && audioElement.duration) { const currentTime = formatTime(audioElement.currentTime); const duration = formatTime(audioElement.duration); audioTime.textContent = `${currentTime} / ${duration}`; } } // 学伴功能 - 格式化时间为 MM:SS function formatTime(seconds) { const mins = Math.floor(seconds / 60); const secs = Math.floor(seconds % 60); return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; }