version 4

This commit is contained in:
2026-03-02 23:09:59 +08:00
parent 0e5ba7e27e
commit a93452d155

View File

@@ -90,11 +90,11 @@
<div class="daily-progress"> <div class="daily-progress">
<h4>今日进度</h4> <h4>今日进度</h4>
<div class="progress-bar"> <div class="progress-bar">
<div class="progress-fill" :style="{ width: ((dailyProgress.completed[currentSubject as keyof typeof dailyProgress.completed] || 0) / dailyLimits[currentSubject as keyof typeof dailyLimits]) * 100 + '%' }"></div> <div class="progress-fill" :style="{ width: ((dailyProgress.completed[currentSubject] || 0) / (dailyLimits[currentSubject] || 25)) * 100 + '%' }"></div>
</div> </div>
<span class="progress-text">{{ dailyProgress.completed[currentSubject as keyof typeof dailyProgress.completed] || 0 }}/{{ dailyLimits[currentSubject as keyof typeof dailyLimits] }} </span> <span class="progress-text">{{ dailyProgress.completed[currentSubject] || 0 }}/{{ dailyLimits[currentSubject] || 25 }} </span>
</div> </div>
<div v-for="(task, index) in (tasks[currentSubject as keyof typeof tasks] || [])" :key="index" class="task-card"> <div v-for="(task, index) in (tasks[currentSubject] || [])" :key="index" class="task-card">
<div class="task-icon">{{ task.icon }}</div> <div class="task-icon">{{ task.icon }}</div>
<div class="task-info"> <div class="task-info">
<h4 class="task-title">{{ task.title }}</h4> <h4 class="task-title">{{ task.title }}</h4>
@@ -394,8 +394,8 @@ const dailyProgress = ref({
// 检查是否达到每日上限 // 检查是否达到每日上限
const isDailyLimitReached = (subject: string) => { const isDailyLimitReached = (subject: string) => {
console.log('检查每日上限:', subject); console.log('检查每日上限:', subject);
const completed = dailyProgress.value.completed[subject as keyof typeof dailyProgress.value.completed] || 0; const completed = dailyProgress.value.completed[subject] || 0;
const limit = dailyLimits[subject as keyof typeof dailyLimits] || 25; const limit = dailyLimits[subject] || 25;
console.log('已完成:', completed, '上限:', limit); console.log('已完成:', completed, '上限:', limit);
return completed >= limit; return completed >= limit;
}; };
@@ -2362,7 +2362,7 @@ const startGame = (subject: string, taskIndex: number) => {
// 检查是否达到每日上限 // 检查是否达到每日上限
if (isDailyLimitReached(subject)) { if (isDailyLimitReached(subject)) {
const subjectName = subject === 'math' ? '数学' : subject === 'chinese' ? '语文' : subject === 'english' ? '英语' : subject === 'japanese' ? '日语' : subject === 'geography' ? '地理' : '科学'; const subjectName = subject === 'math' ? '数学' : subject === 'chinese' ? '语文' : subject === 'english' ? '英语' : subject === 'japanese' ? '日语' : subject === 'geography' ? '地理' : '科学';
const limit = dailyLimits[subject as keyof typeof dailyLimits]; const limit = dailyLimits[subject] || 25;
alert(`今日${subjectName}题目已达上限(${limit}题),明天再来挑战吧!`); alert(`今日${subjectName}题目已达上限(${limit}题),明天再来挑战吧!`);
return; return;
} }
@@ -2505,12 +2505,14 @@ const startGame = (subject: string, taskIndex: number) => {
// 检查数学答案 // 检查数学答案
const checkAnswer = (option: string) => { const checkAnswer = (option: string) => {
isCorrect.value = option === currentGame.value.answer; isCorrect.value = option === currentGame.value.answer;
const task = tasks.value[currentGame.value.subject as keyof typeof tasks.value][currentGame.value.taskIndex]; const subject = currentGame.value.subject;
const taskIndex = currentGame.value.taskIndex;
const task = tasks.value[subject] && tasks.value[subject][taskIndex] ? tasks.value[subject][taskIndex] : { reward: 5 };
let starsPerQuestion = 1; let starsPerQuestion = 1;
if (currentGame.value.subject === 'math' || currentGame.value.subject === 'chinese' || currentGame.value.subject === 'english') { if (subject === 'math' || subject === 'chinese' || subject === 'english') {
starsPerQuestion = Math.ceil(task.reward / 20); starsPerQuestion = Math.ceil((task.reward || 5) / 20);
} else if (currentGame.value.subject === 'science') { } else if (subject === 'science') {
starsPerQuestion = Math.ceil(task.reward / 10); starsPerQuestion = Math.ceil((task.reward || 5) / 10);
} }
feedbackMessage.value = isCorrect.value feedbackMessage.value = isCorrect.value
? `太棒了!回答正确!正确答案是 ${currentGame.value.answer}。获得 ${starsPerQuestion} 颗星星能量!` ? `太棒了!回答正确!正确答案是 ${currentGame.value.answer}。获得 ${starsPerQuestion} 颗星星能量!`
@@ -2526,12 +2528,14 @@ const checkChineseAnswer = (option?: string) => {
// 如果传入了选项,直接检查选项 // 如果传入了选项,直接检查选项
if (option !== undefined) { if (option !== undefined) {
isCorrect.value = option === currentGame.value.answer; isCorrect.value = option === currentGame.value.answer;
const task = tasks.value[currentGame.value.subject as keyof typeof tasks.value][currentGame.value.taskIndex]; const subject = currentGame.value.subject;
const taskIndex = currentGame.value.taskIndex;
const task = tasks.value[subject] && tasks.value[subject][taskIndex] ? tasks.value[subject][taskIndex] : { reward: 5 };
let starsPerQuestion = 1; let starsPerQuestion = 1;
if (currentGame.value.subject === 'math' || currentGame.value.subject === 'chinese' || currentGame.value.subject === 'english') { if (subject === 'math' || subject === 'chinese' || subject === 'english') {
starsPerQuestion = Math.ceil(task.reward / 20); starsPerQuestion = Math.ceil((task.reward || 5) / 20);
} else if (currentGame.value.subject === 'science') { } else if (subject === 'science') {
starsPerQuestion = Math.ceil(task.reward / 10); starsPerQuestion = Math.ceil((task.reward || 5) / 10);
} }
feedbackMessage.value = isCorrect.value feedbackMessage.value = isCorrect.value
? `太棒了!答对了!正确答案是 ${currentGame.value.answer}。获得 ${starsPerQuestion} 颗星星能量!` ? `太棒了!答对了!正确答案是 ${currentGame.value.answer}。获得 ${starsPerQuestion} 颗星星能量!`
@@ -2543,12 +2547,14 @@ const checkChineseAnswer = (option?: string) => {
} else { } else {
// 否则检查当前答案(拼字游戏) // 否则检查当前答案(拼字游戏)
isCorrect.value = currentAnswer.value === currentGame.value.answer; isCorrect.value = currentAnswer.value === currentGame.value.answer;
const task = tasks.value[currentGame.value.subject as keyof typeof tasks.value][currentGame.value.taskIndex]; const subject = currentGame.value.subject;
const taskIndex = currentGame.value.taskIndex;
const task = tasks.value[subject] && tasks.value[subject][taskIndex] ? tasks.value[subject][taskIndex] : { reward: 5 };
let starsPerQuestion = 1; let starsPerQuestion = 1;
if (currentGame.value.subject === 'math' || currentGame.value.subject === 'chinese' || currentGame.value.subject === 'english') { if (subject === 'math' || subject === 'chinese' || subject === 'english') {
starsPerQuestion = Math.ceil(task.reward / 20); starsPerQuestion = Math.ceil((task.reward || 5) / 20);
} else if (currentGame.value.subject === 'science') { } else if (subject === 'science') {
starsPerQuestion = Math.ceil(task.reward / 10); starsPerQuestion = Math.ceil((task.reward || 5) / 10);
} }
feedbackMessage.value = isCorrect.value feedbackMessage.value = isCorrect.value
? `太棒了!拼字正确!正确答案是 ${currentGame.value.answer}。获得 ${starsPerQuestion} 颗星星能量!` ? `太棒了!拼字正确!正确答案是 ${currentGame.value.answer}。获得 ${starsPerQuestion} 颗星星能量!`
@@ -2563,12 +2569,14 @@ const checkChineseAnswer = (option?: string) => {
// 检查英语答案 // 检查英语答案
const checkEnglishAnswer = (option: string) => { const checkEnglishAnswer = (option: string) => {
isCorrect.value = option === currentGame.value.answer; isCorrect.value = option === currentGame.value.answer;
const task = tasks.value[currentGame.value.subject as keyof typeof tasks.value][currentGame.value.taskIndex]; const subject = currentGame.value.subject;
const taskIndex = currentGame.value.taskIndex;
const task = tasks.value[subject] && tasks.value[subject][taskIndex] ? tasks.value[subject][taskIndex] : { reward: 5 };
let starsPerQuestion = 1; let starsPerQuestion = 1;
if (currentGame.value.subject === 'math' || currentGame.value.subject === 'chinese' || currentGame.value.subject === 'english') { if (subject === 'math' || subject === 'chinese' || subject === 'english') {
starsPerQuestion = Math.ceil(task.reward / 20); starsPerQuestion = Math.ceil((task.reward || 5) / 20);
} else if (currentGame.value.subject === 'science') { } else if (subject === 'science') {
starsPerQuestion = Math.ceil(task.reward / 10); starsPerQuestion = Math.ceil((task.reward || 5) / 10);
} }
feedbackMessage.value = isCorrect.value feedbackMessage.value = isCorrect.value
? `Great! Correct! The correct answer is ${currentGame.value.answer}. 获得 ${starsPerQuestion} 颗星星能量!` ? `Great! Correct! The correct answer is ${currentGame.value.answer}. 获得 ${starsPerQuestion} 颗星星能量!`
@@ -2582,12 +2590,14 @@ const checkEnglishAnswer = (option: string) => {
// 检查科学答案 // 检查科学答案
const checkScienceAnswer = () => { const checkScienceAnswer = () => {
isCorrect.value = true; // 科学实验只要完成就正确 isCorrect.value = true; // 科学实验只要完成就正确
const task = tasks.value[currentGame.value.subject as keyof typeof tasks.value][currentGame.value.taskIndex]; const subject = currentGame.value.subject;
const taskIndex = currentGame.value.taskIndex;
const task = tasks.value[subject] && tasks.value[subject][taskIndex] ? tasks.value[subject][taskIndex] : { reward: 5 };
let starsPerQuestion = 1; let starsPerQuestion = 1;
if (currentGame.value.subject === 'math' || currentGame.value.subject === 'chinese' || currentGame.value.subject === 'english' || currentGame.value.subject === 'japanese') { if (subject === 'math' || subject === 'chinese' || subject === 'english' || subject === 'japanese' || subject === 'geography') {
starsPerQuestion = Math.ceil(task.reward / 20); starsPerQuestion = Math.ceil((task.reward || 5) / 20);
} else if (currentGame.value.subject === 'science') { } else if (subject === 'science') {
starsPerQuestion = Math.ceil(task.reward / 10); starsPerQuestion = Math.ceil((task.reward || 5) / 10);
} }
feedbackMessage.value = `实验成功!你真棒!正确答案是 ${currentGame.value.answer}。获得 ${starsPerQuestion} 颗星星能量!`; feedbackMessage.value = `实验成功!你真棒!正确答案是 ${currentGame.value.answer}。获得 ${starsPerQuestion} 颗星星能量!`;
showFeedback.value = true; showFeedback.value = true;
@@ -2597,12 +2607,14 @@ const checkScienceAnswer = () => {
// 检查日语答案 // 检查日语答案
const checkJapaneseAnswer = (option: string) => { const checkJapaneseAnswer = (option: string) => {
isCorrect.value = option === currentGame.value.answer; isCorrect.value = option === currentGame.value.answer;
const task = tasks.value[currentGame.value.subject as keyof typeof tasks.value][currentGame.value.taskIndex]; const subject = currentGame.value.subject;
const taskIndex = currentGame.value.taskIndex;
const task = tasks.value[subject] && tasks.value[subject][taskIndex] ? tasks.value[subject][taskIndex] : { reward: 5 };
let starsPerQuestion = 1; let starsPerQuestion = 1;
if (currentGame.value.subject === 'math' || currentGame.value.subject === 'chinese' || currentGame.value.subject === 'english' || currentGame.value.subject === 'japanese') { if (subject === 'math' || subject === 'chinese' || subject === 'english' || subject === 'japanese' || subject === 'geography') {
starsPerQuestion = Math.ceil(task.reward / 20); starsPerQuestion = Math.ceil((task.reward || 5) / 20);
} else if (currentGame.value.subject === 'science') { } else if (subject === 'science') {
starsPerQuestion = Math.ceil(task.reward / 10); starsPerQuestion = Math.ceil((task.reward || 5) / 10);
} }
feedbackMessage.value = isCorrect.value feedbackMessage.value = isCorrect.value
? `すごい!回答正确!正确答案是 ${currentGame.value.answer}。获得 ${starsPerQuestion} 颗星星能量!` ? `すごい!回答正确!正确答案是 ${currentGame.value.answer}。获得 ${starsPerQuestion} 颗星星能量!`
@@ -2616,12 +2628,14 @@ const checkJapaneseAnswer = (option: string) => {
// 检查地理答案 // 检查地理答案
const checkGeographyAnswer = (option: string) => { const checkGeographyAnswer = (option: string) => {
isCorrect.value = option === currentGame.value.answer; isCorrect.value = option === currentGame.value.answer;
const task = tasks.value[currentGame.value.subject as keyof typeof tasks.value][currentGame.value.taskIndex]; const subject = currentGame.value.subject;
const taskIndex = currentGame.value.taskIndex;
const task = tasks.value[subject] && tasks.value[subject][taskIndex] ? tasks.value[subject][taskIndex] : { reward: 5 };
let starsPerQuestion = 1; let starsPerQuestion = 1;
if (currentGame.value.subject === 'math' || currentGame.value.subject === 'chinese' || currentGame.value.subject === 'english' || currentGame.value.subject === 'japanese' || currentGame.value.subject === 'geography') { if (subject === 'math' || subject === 'chinese' || subject === 'english' || subject === 'japanese' || subject === 'geography') {
starsPerQuestion = Math.ceil(task.reward / 20); starsPerQuestion = Math.ceil((task.reward || 5) / 20);
} else if (currentGame.value.subject === 'science') { } else if (subject === 'science') {
starsPerQuestion = Math.ceil(task.reward / 10); starsPerQuestion = Math.ceil((task.reward || 5) / 10);
} }
feedbackMessage.value = isCorrect.value feedbackMessage.value = isCorrect.value
? `太棒了!回答正确!正确答案是 ${currentGame.value.answer}。获得 ${starsPerQuestion} 颗星星能量!` ? `太棒了!回答正确!正确答案是 ${currentGame.value.answer}。获得 ${starsPerQuestion} 颗星星能量!`
@@ -2647,18 +2661,18 @@ const nextQuestion = () => {
// 每完成一题获得星星能量 // 每完成一题获得星星能量
const subject = currentGame.value.subject; const subject = currentGame.value.subject;
const taskIndex = currentGame.value.taskIndex; const taskIndex = currentGame.value.taskIndex;
const task = tasks.value[subject as keyof typeof tasks.value][taskIndex]; const task = tasks.value[subject] && tasks.value[subject][taskIndex] ? tasks.value[subject][taskIndex] : { reward: 5 };
// 计算每题的星星奖励(降低获得量) // 计算每题的星星奖励(降低获得量)
let starsPerQuestion = 1; let starsPerQuestion = 1;
if (subject === 'math' || subject === 'chinese' || subject === 'english' || subject === 'japanese' || subject === 'geography') { if (subject === 'math' || subject === 'chinese' || subject === 'english' || subject === 'japanese' || subject === 'geography') {
// 降低数学、语文、英语、日语、地理的奖励获得量 // 降低数学、语文、英语、日语、地理的奖励获得量
// 总奖励为5分成20题每题0.25颗向上取整为1颗 // 总奖励为5分成20题每题0.25颗向上取整为1颗
starsPerQuestion = Math.ceil(task.reward / 20); // 20题任务 starsPerQuestion = Math.ceil((task.reward || 5) / 20); // 20题任务
} else if (subject === 'science') { } else if (subject === 'science') {
// 降低科学的奖励获得量 // 降低科学的奖励获得量
// 总奖励为8-12分成10题每题0.8-1.2颗向上取整为1颗 // 总奖励为8-12分成10题每题0.8-1.2颗向上取整为1颗
starsPerQuestion = Math.ceil(task.reward / 15); // 15题任务的计算方式降低获得量 starsPerQuestion = Math.ceil((task.reward || 5) / 15); // 15题任务的计算方式降低获得量
} }
// 添加星星能量 // 添加星星能量
@@ -2670,27 +2684,41 @@ const nextQuestion = () => {
// 更新学科进度 // 更新学科进度
switch (subject) { switch (subject) {
case 'math': case 'math':
progress.value.math[taskType as keyof typeof progress.value.math]++; if (progress.value.math[taskType]) {
progress.value.math[taskType]++;
}
break; break;
case 'chinese': case 'chinese':
progress.value.chinese[taskType as keyof typeof progress.value.chinese]++; if (progress.value.chinese[taskType]) {
progress.value.chinese[taskType]++;
}
break; break;
case 'english': case 'english':
progress.value.english[taskType as keyof typeof progress.value.english]++; if (progress.value.english[taskType]) {
progress.value.english[taskType]++;
}
break; break;
case 'science': case 'science':
progress.value.science[taskType as keyof typeof progress.value.science]++; if (progress.value.science[taskType]) {
progress.value.science[taskType]++;
}
break; break;
case 'japanese': case 'japanese':
progress.value.japanese[taskType as keyof typeof progress.value.japanese]++; if (progress.value.japanese[taskType]) {
progress.value.japanese[taskType]++;
}
break; break;
case 'geography': case 'geography':
progress.value.geography[taskType as keyof typeof progress.value.geography]++; if (progress.value.geography[taskType]) {
progress.value.geography[taskType]++;
}
break; break;
} }
// 更新每日完成记录 // 更新每日完成记录
dailyProgress.value.completed[subject as keyof typeof dailyProgress.value.completed]++; if (dailyProgress.value.completed[subject] !== undefined) {
dailyProgress.value.completed[subject]++;
}
// 保存进度 // 保存进度
saveProgress(); saveProgress();
@@ -2698,7 +2726,7 @@ const nextQuestion = () => {
// 检查是否达到每日上限 // 检查是否达到每日上限
if (isDailyLimitReached(subject)) { if (isDailyLimitReached(subject)) {
const subjectName = subject === 'math' ? '数学' : subject === 'chinese' ? '语文' : subject === 'english' ? '英语' : subject === 'japanese' ? '日语' : subject === 'geography' ? '地理' : '科学'; const subjectName = subject === 'math' ? '数学' : subject === 'chinese' ? '语文' : subject === 'english' ? '英语' : subject === 'japanese' ? '日语' : subject === 'geography' ? '地理' : '科学';
const limit = dailyLimits[subject as keyof typeof dailyLimits]; const limit = dailyLimits[subject] || 25;
alert(`今日${subjectName}题目已达上限(${limit}题),明天再来挑战吧!`); alert(`今日${subjectName}题目已达上限(${limit}题),明天再来挑战吧!`);
currentGame.value = null; currentGame.value = null;
return; return;
@@ -2710,25 +2738,25 @@ const nextQuestion = () => {
switch (subject) { switch (subject) {
case 'math': case 'math':
gameDataSubject = gameData.math[taskType as keyof typeof gameData.math]; gameDataSubject = gameData.math[taskType];
break; break;
case 'chinese': case 'chinese':
gameDataSubject = gameData.chinese[taskType as keyof typeof gameData.chinese]; gameDataSubject = gameData.chinese[taskType];
break; break;
case 'english': case 'english':
gameDataSubject = gameData.english[taskType as keyof typeof gameData.english]; gameDataSubject = gameData.english[taskType];
break; break;
case 'science': case 'science':
gameDataSubject = gameData.science[taskType as keyof typeof gameData.science]; gameDataSubject = gameData.science[taskType];
break; break;
case 'japanese': case 'japanese':
gameDataSubject = gameData.japanese[taskType as keyof typeof gameData.japanese]; gameDataSubject = gameData.japanese[taskType];
break; break;
case 'geography': case 'geography':
gameDataSubject = gameData.geography[taskType as keyof typeof gameData.geography]; gameDataSubject = gameData.geography[taskType];
break; break;
default: default:
gameDataSubject = gameData[subject as keyof typeof gameData]; gameDataSubject = gameData[subject];
} }
if (gameDataSubject && currentQuestionIndex.value < gameDataSubject.length) { if (gameDataSubject && currentQuestionIndex.value < gameDataSubject.length) {
@@ -2762,7 +2790,9 @@ const nextQuestion = () => {
experimentResult.value = ''; experimentResult.value = '';
} else { } else {
// 完成所有题目 // 完成所有题目
task.completed = true; if (task) {
task.completed = true;
}
alert(`任务完成!`); alert(`任务完成!`);
currentGame.value = null; currentGame.value = null;
} }