Skip to content

Commit 499f5d9

Browse files
committed
Show result.
1 parent af90e45 commit 499f5d9

2 files changed

Lines changed: 154 additions & 17 deletions

File tree

src/App.vue

Lines changed: 131 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ const startNewIdiom = () => {
6767
answer.value = customMode.currentIdiom.value!;
6868
guesses.value = result?.guesses || [];
6969
gameWon.value = result?.won || false;
70-
gameFailed.value = result?.completed && !result.won;
70+
gameFailed.value = (result?.completed && !result.won) || false;
7171
elapsedTime.value = result?.time || 0;
7272
if (result?.time) {
7373
const minutes = Math.floor(result.time / 60);
@@ -80,7 +80,7 @@ const startNewIdiom = () => {
8080
startTime.value = 0;
8181
return;
8282
}
83-
83+
8484
if (!customMode.nextIdiom()) {
8585
showCongrats.value = true;
8686
return;
@@ -136,12 +136,12 @@ const handleJumpTo = (index: number) => {
136136
if (customMode.isActive.value && customMode.viewIndex.value === customMode.currentIndex.value && guesses.value.length > 0 && !gameWon.value && !gameFailed.value) {
137137
customMode.saveCurrentProgress(guesses.value);
138138
}
139-
139+
140140
customMode.jumpToIdiom(index);
141141
const result = customMode.results.value[index];
142142
answer.value = customMode.currentIdiom.value!;
143143
guesses.value = result?.guesses || [];
144-
144+
145145
// 正确判断游戏状态
146146
if (result?.completed) {
147147
gameWon.value = result.won;
@@ -150,7 +150,7 @@ const handleJumpTo = (index: number) => {
150150
gameWon.value = false;
151151
gameFailed.value = false;
152152
}
153-
153+
154154
elapsedTime.value = result?.time || 0;
155155
if (result?.time) {
156156
const minutes = Math.floor(result.time / 60);
@@ -191,13 +191,13 @@ const initGame = async () => {
191191
const hex = b.toString(16);
192192
return hex.length === 1 ? '0' + hex : hex;
193193
}).join('').slice(0, 16);
194-
194+
195195
await customMode.init(idiomsList, quizId);
196196
const currentResult = customMode.results.value[customMode.currentIndex.value];
197197
answer.value = customMode.currentIdiom.value!;
198198
guesses.value = currentResult?.guesses || [];
199199
gameWon.value = currentResult?.won || false;
200-
gameFailed.value = currentResult?.completed && !currentResult.won;
200+
gameFailed.value = (currentResult?.completed && !currentResult.won) || false;
201201
elapsedTime.value = currentResult?.time || 0;
202202
if (currentResult?.time) {
203203
const minutes = Math.floor(currentResult.time / 60);
@@ -343,7 +343,7 @@ const handleSubmit = () => {
343343
}
344344
345345
guesses.value.push(currentInput.value);
346-
346+
347347
// 自定义模式下每次提交都保存进度(不改变完成状态)
348348
if (customMode.isActive.value) {
349349
customMode.saveCurrentProgress(guesses.value);
@@ -414,6 +414,22 @@ const closeCreateQuiz = () => {
414414
showCreateQuiz.value = false;
415415
};
416416
417+
const isAllCompleted = computed(() => {
418+
if (!customMode.isActive.value) return false;
419+
return customMode.results.value.every(r => r.completed);
420+
});
421+
422+
const totalStats = computed(() => {
423+
if (!customMode.isActive.value) return { totalAttempts: 0, totalTime: 0 };
424+
const totalAttempts = customMode.results.value.reduce((sum, r) => sum + r.guesses.length, 0);
425+
const totalTime = customMode.results.value.reduce((sum, r) => sum + r.time, 0);
426+
return { totalAttempts, totalTime };
427+
});
428+
429+
const showCompletionDialog = () => {
430+
showCongrats.value = true;
431+
};
432+
417433
</script>
418434

419435
<template>
@@ -432,7 +448,8 @@ const closeCreateQuiz = () => {
432448
<div v-else-if="guessedList.length > 0" class="progress">(你已完成 {{ guessedList.length }} 题)</div>
433449

434450
<ProgressNav v-if="customMode.isActive.value" :results="customMode.results.value"
435-
:currentIndex="customMode.currentIndex.value" :viewIndex="customMode.viewIndex.value" @jumpTo="handleJumpTo" />
451+
:currentIndex="customMode.currentIndex.value" :viewIndex="customMode.viewIndex.value"
452+
@jumpTo="handleJumpTo" />
436453

437454
<div class="guesses">
438455
<div v-for="(guess, guessIndex) in guessesWithPinyin" :key="guessIndex" class="guess-row">
@@ -453,25 +470,54 @@ const closeCreateQuiz = () => {
453470
<div class="congrats-icon">🎉</div>
454471
<h2 v-if="customMode.isActive.value">恭喜完成所有自定义题目!</h2>
455472
<h2 v-else>恭喜你完成了所有挑战!</h2>
473+
474+
<div v-if="customMode.isActive.value" class="results-summary">
475+
<div v-for="(result, index) in customMode.results.value" :key="index" class="result-item">
476+
<div class="result-header">
477+
<span class="result-number">第{{ index + 1 }}题</span>
478+
<span class="result-idiom">{{ result.idiom }}</span>
479+
<span :class="['result-status', result.won ? 'success' : 'failed']">
480+
{{ result.won ? '✅' : '❌' }}
481+
</span>
482+
</div>
483+
<div class="result-details">
484+
<span>尝试次数:{{ result.guesses.length }}</span>
485+
<span>用时:{{ Math.floor(result.time / 60) > 0 ? `${Math.floor(result.time /
486+
60)}分${result.time % 60}秒` : `${result.time}秒` }}</span>
487+
</div>
488+
</div>
489+
<div class="total-stats">
490+
<div>总尝试次数:{{ totalStats.totalAttempts }}</div>
491+
<div>总用时:{{ Math.floor(totalStats.totalTime / 60) > 0 ? `${Math.floor(totalStats.totalTime /
492+
60)}分${totalStats.totalTime % 60}秒` : `${totalStats.totalTime}秒` }}</div>
493+
</div>
494+
</div>
495+
456496
<p v-if="customMode.isActive.value">是否退出自定义模式?</p>
457497
<p v-else>是否重新开始?</p>
458498
<div class="congrats-buttons">
459499
<button v-if="customMode.isActive.value" @click="exitCustomMode">退出</button>
460500
<button v-else @click="resetAll">重新开始</button>
501+
<button v-if="customMode.isActive.value" @click="showCongrats = false"
502+
class="cancel-btn">取消</button>
461503
</div>
462504
</div>
463505
</div>
464506

465507
<div v-if="gameFailed" class="message failed">
466508
😔 很遗憾,没有猜对!
467-
<button v-if="!customMode.isActive.value || customMode.viewIndex.value === customMode.currentIndex.value" @click="startNewIdiom">下一题</button>
509+
<button v-if="!customMode.isActive.value || customMode.viewIndex.value === customMode.currentIndex.value"
510+
@click="isAllCompleted ? showCompletionDialog() : startNewIdiom()">{{ isAllCompleted ? '完成' : '下一题'
511+
}}</button>
468512
</div>
469513

470514
<div v-if="gameWon" class="message">
471515
🎉 恭喜你猜对了!
472516
<div>用时:{{ elapsedTimeStr }}<span v-if="elapsedTime === 0">(你一定开挂了!)</span></div>
473-
<div v-if="!customMode.isActive.value || customMode.viewIndex.value === customMode.currentIndex.value" class="action-buttons">
474-
<button @click="startNewIdiom">下一题</button>
517+
<div v-if="!customMode.isActive.value || customMode.viewIndex.value === customMode.currentIndex.value"
518+
class="action-buttons">
519+
<button @click="isAllCompleted ? showCompletionDialog() : startNewIdiom()">{{ isAllCompleted ? '完成' :
520+
'下一题' }}</button>
475521
<button v-if="!customMode.isActive.value" @click="shareCurrent" class="share-question-btn"
476522
title="分享当前题目">📤 分享题目</button>
477523
</div>
@@ -657,7 +703,9 @@ button:hover {
657703
padding: 40px;
658704
border-radius: 20px;
659705
text-align: center;
660-
max-width: 400px;
706+
max-width: 500px;
707+
max-height: 80vh;
708+
overflow-y: auto;
661709
animation: scaleIn 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
662710
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
663711
}
@@ -685,6 +733,76 @@ button:hover {
685733
justify-content: center;
686734
}
687735
736+
.cancel-btn {
737+
background: #9e9e9e;
738+
}
739+
740+
.cancel-btn:hover {
741+
background: #757575;
742+
}
743+
744+
.results-summary {
745+
margin: 20px 0;
746+
text-align: left;
747+
}
748+
749+
.result-item {
750+
background: #f5f5f5;
751+
padding: 12px;
752+
margin-bottom: 10px;
753+
border-radius: 8px;
754+
}
755+
756+
.result-header {
757+
display: flex;
758+
align-items: center;
759+
gap: 10px;
760+
margin-bottom: 8px;
761+
}
762+
763+
.result-number {
764+
font-weight: bold;
765+
color: #666;
766+
}
767+
768+
.result-idiom {
769+
font-size: 18px;
770+
font-weight: bold;
771+
color: #333;
772+
flex: 1;
773+
}
774+
775+
.result-status {
776+
font-size: 20px;
777+
}
778+
779+
.result-status.success {
780+
color: #4caf50;
781+
}
782+
783+
.result-status.failed {
784+
color: #f44336;
785+
}
786+
787+
.result-details {
788+
display: flex;
789+
gap: 15px;
790+
font-size: 14px;
791+
color: #666;
792+
}
793+
794+
.total-stats {
795+
margin-top: 15px;
796+
padding: 15px;
797+
background: #e3f2fd;
798+
border-radius: 8px;
799+
font-weight: bold;
800+
color: #1976d2;
801+
display: flex;
802+
justify-content: space-around;
803+
font-size: 16px;
804+
}
805+
688806
@keyframes fadeIn {
689807
from {
690808
opacity: 0;

src/composables/useCustomMode.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,24 @@ export function useCustomMode() {
6262
if (saved) {
6363
try {
6464
const data = JSON.parse(saved);
65+
// 确保 results 数组与 idioms 数组长度一致
66+
const results = idioms.map((idiom, index) => {
67+
const savedResult = data.results[index];
68+
if (savedResult) {
69+
return savedResult;
70+
}
71+
return {
72+
idiom,
73+
guesses: [],
74+
won: false,
75+
time: 0,
76+
completed: false
77+
};
78+
});
6579
state.value = {
6680
idioms,
67-
currentIndex: data.currentIndex,
68-
results: data.results
81+
currentIndex: Math.min(data.currentIndex, idioms.length - 1),
82+
results
6983
};
7084
return;
7185
} catch { }
@@ -129,7 +143,7 @@ export function useCustomMode() {
129143
const saveCurrentProgress = (guesses: string[]) => {
130144
if (!state.value) return;
131145

132-
const current = state.value.results[state.value.currentIndex];
146+
const current = state.value.results[state.value.currentIndex]!;
133147
state.value.results[state.value.currentIndex] = {
134148
...current,
135149
guesses: [...guesses]
@@ -140,9 +154,14 @@ export function useCustomMode() {
140154
const nextIdiom = (): boolean => {
141155
if (!state.value) return false;
142156

157+
// 检查是否还有下一题
158+
if (state.value.currentIndex >= state.value.idioms.length - 1) {
159+
return false;
160+
}
161+
143162
state.value.currentIndex++;
144163
save();
145-
return state.value.currentIndex < state.value.idioms.length;
164+
return true;
146165
};
147166

148167
const jumpToIdiom = (index: number) => {

0 commit comments

Comments
 (0)