feat: 前端优化 - 明暗模式、题型Tab分隔、移除统计

- 支持明暗主题切换,用户选择持久化到 localStorage
- 题型通过 Tab 按钮分隔展示,支持过滤
- 移除正确/错误统计和进度条
- 题型颜色通过 CSS 变量集中管理(--type-*)
- JS 抽取 QUESTION_TYPES 常量,便于扩展
- 更新架构文档反映上述变更

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
2026-09-02 18:40:50 +08:00
parent d3cba0e23c
commit 273b88219a
2 changed files with 130 additions and 77 deletions
+37 -25
View File
@@ -236,23 +236,21 @@ examination/
```
┌──────────────────────────────────────────┐
│ Header: 🎯 CS 知识应试强化 │
│ Header: 🎯 CS 知识应试强化 [🌙/☀️] │
├────────────┬─────────────────────────────┤
│ Sidebar │ Main Content │
│ │ │
│ 📚 主题 │ ┌─ Toolbar ──────────────┐ │
│ · gc-jvm │ │ 进度 ✅ ❌ ⏳ 按钮组 │ │
│ 📚 主题 │ ┌─ Tabs ─────────────────┐ │
│ · gc-jvm │ │ 全部 | 填空 | 选择 |.. │ │
│ · ai-so │ └────────────────────────┘ │
│ · ai-mm │ ┌─ Progress Bar ─────────┐ │
│ · ai-he │ └────────────────────────┘ │
│ · ai-at │ ┌─ Question Card ────────┐ │
│ │ │ #1 填空 ★★★ │ │
│ ──────── │ │ 题干 [____] │ │
│ 📥 导入 │ │ [检查] [显示答案] │ │
│ │ │ 💡 解析... │ │
│ │ └────────────────────────┘ │
│ · ai-mm │ ┌─ Toolbar ──────────────┐ │
│ · ai-he │ │ 重置 全部显示 提交全部 │ │
│ · ai-at │ └────────────────────────┘ │
│ │ ┌─ Question Card ────────┐ │
│ │ │ ... │ │
│ ──────── │ │ #1 ★★★ │ │
│ 📥 导入 │ │ 题干 [____] │ │
│ │ │ [检查] [显示答案] │ │
│ │ │ 💡 解析... │ │
│ │ └────────────────────────┘ │
└────────────┴─────────────────────────────┘
```
@@ -273,34 +271,48 @@ fetch topics/{slug}/meta.json ──→ 获取 question_files 列表
fetch topics/{slug}/{type}.json (并行) ──→ 合并 questions 数组
│
▼
renderQuiz() ──→ 按题型渲染题目卡片
renderQuiz() ──→ 渲染 Tab 栏 + 按当前 Tab 过滤题目卡片
│
│ 用户交互(选择/输入/检查/显示答案)
│ 用户交互(选择/输入/检查/显示答案/切换 Tab)
▼
answers 状态更新 ──→ re-render ──→ 更新统计
answers / activeTab 状态更新 ──→ re-render
```
### 4.3 状态管理
```javascript
// 题型配置(常量)
const QUESTION_TYPES = {
fill_blank: { label: '填空', color: '--type-fill_blank' },
single_choice: { label: '选择', color: '--type-single_choice' },
// ...
};
// 应用状态
let topics = []; // 从 index.json 加载的主题列表
let currentTopic = null; // 当前选中的主题 slug
let currentQuestions = []; // 当前主题的所有题目(合并自多个题型文件)
let answers = {}; // qId → { value, correct, revealed }
let customQuestions = []; // 通过导入功能临时添加的题目
let activeTab = 'all'; // 当前 Tab:'all' 或题型名称
```
### 4.4 题型渲染逻辑
### 4.4 题型配置与渲染
| 题型 | 渲染方式 | 判定逻辑 |
|------|----------|----------|
| fill_blank | 题干中的 `______` 替换为 `<input>` | `matchFillAnswer()` 根据 `answer_rule` 匹配 |
| single_choice | 选项列表,radio 样式 | `value === answer` |
| multiple_choice | 选项列表,checkbox 样式 | 数组比较 |
| true_false | 两个大按钮 | `value === answer` |
| short_answer | `<textarea>` | 关键词匹配(辅助) |
| code_reading | 代码块 + 子题列表 | 按子题类型分别判定 |
| scenario | 场景描述 + 子题列表 | 按子题类型分别判定 |
题型颜色通过 CSS 变量定义在 `:root` 中,新增题型只需:
1. 在 `QUESTION_TYPES` 添加配置
2. 在 `:root` 添加 `--type-{name}` 变量
3. CSS 自动生效(通过 `.q-card.type-{name}` 规则)
| 题型 | 渲染方式 | 判定逻辑 | 边框颜色变量 |
|------|----------|----------|--------------|
| fill_blank | 题干中的 `______` 替换为 `<input>` | `matchFillAnswer()` 根据 `answer_rule` 匹配 | `--type-fill_blank` |
| single_choice | 选项列表,radio 样式 | `value === answer` | `--type-single_choice` |
| multiple_choice | 选项列表,checkbox 样式 | 数组比较 | `--type-multiple_choice` |
| true_false | 两个大按钮 | `value === answer` | `--type-true_false` |
| short_answer | `<textarea>` | 关键词匹配(辅助) | `--type-short_answer` |
| code_reading | 代码块 + 子题列表 | 按子题类型分别判定 | `--type-code_reading` |
| scenario | 场景描述 + 子题列表 | 按子题类型分别判定 | `--type-scenario` |
## 5. 生成工作流