feat: 优化随机刷题模式和进度显示

功能改进:
- 随机模式下已答题目不再重复出现
- 所有题目回答完成后显示总结页面
- 进度显示从"题号/总数"改为"已答数/总数"

UI修复:
- 修复小屏幕下悬浮球进度环错位问题
- 使用 SVG viewBox 实现自适应缩放
- 新增超小屏幕(≤380px)优化

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
yanlongqi 2025-11-10 11:16:46 +08:00
parent c50cf9ee7b
commit aaf1b78f3f
3 changed files with 61 additions and 15 deletions

View File

@ -93,8 +93,8 @@
position: absolute;
top: 0;
left: 0;
width: 64px;
height: 64px;
width: 100%;
height: 100%;
transform: rotate(-90deg);
pointer-events: none;
}
@ -135,8 +135,9 @@
.statsCard {
padding: 6px 12px;
gap: 10px;
gap: 8px;
border-radius: 10px;
font-size: 12px;
}
.statsLabel {
@ -144,11 +145,11 @@
}
.statsValue {
font-size: 14px;
font-size: 13px;
}
.statsDivider {
height: 18px;
height: 16px;
}
.floatButton {
@ -156,13 +157,43 @@
height: 58px;
}
.progressRing {
width: 58px;
height: 58px;
.icon {
font-size: 22px;
}
}
// 超小屏幕优化
@media (max-width: 380px) {
.floatButtonWrapper {
right: 12px;
bottom: 75px;
}
.statsCard {
padding: 5px 10px;
gap: 6px;
border-radius: 8px;
}
.statsLabel {
font-size: 9px;
}
.statsValue {
font-size: 12px;
}
.statsDivider {
height: 14px;
}
.floatButton {
width: 54px;
height: 54px;
}
.icon {
font-size: 22px;
font-size: 20px;
}
}

View File

@ -32,7 +32,7 @@ const QuestionFloatButton: React.FC<QuestionFloatButtonProps> = ({
<div className={styles.statsRow}>
<span className={styles.statsLabel}></span>
<span className={styles.statsValue}>
{currentIndex + 1}/{totalQuestions}
{answeredCount}/{totalQuestions}
</span>
</div>
<div className={styles.statsDivider} />
@ -54,7 +54,7 @@ const QuestionFloatButton: React.FC<QuestionFloatButtonProps> = ({
{/* 悬浮球 */}
<div className={styles.floatButton} onClick={onClick}>
{/* 进度环 */}
<svg className={styles.progressRing} width="64" height="64">
<svg className={styles.progressRing} viewBox="0 0 64 64">
<circle
className={styles.progressRingCircle}
strokeWidth="3"

View File

@ -303,10 +303,25 @@ const QuestionPage: React.FC = () => {
// 随机模式:从题库中随机选择一题
if (randomMode) {
// 生成一个不等于当前索引的随机索引
do {
nextIndex = Math.floor(Math.random() * allQuestions.length);
} while (nextIndex === currentIndex && allQuestions.length > 1);
// 获取所有未答题目的索引
const unansweredIndexes: number[] = [];
for (let i = 0; i < allQuestions.length; i++) {
if (!answeredStatus.has(i)) {
unansweredIndexes.push(i);
}
}
// 如果所有题目都已回答,显示总结页面
if (unansweredIndexes.length === 0) {
setShowSummary(true);
// 清除进度
localStorage.removeItem(getStorageKey());
return;
}
// 从未答题目中随机选择一题
const randomIdx = Math.floor(Math.random() * unansweredIndexes.length);
nextIndex = unansweredIndexes[randomIdx];
} else {
// 顺序模式:检查是否完成所有题目
if (currentIndex + 1 >= allQuestions.length) {