# 架构文档 ## 1. 系统总览 ``` ┌─────────────────────────────────────────────────────┐ │ 用户浏览器 │ │ ┌───────────────────────────────────────────────┐ │ │ │ index.html (单文件 SPA) │ │ │ │ ┌─────────┐ ┌──────────┐ ┌─────────────┐ │ │ │ │ │ 导航栏 │ │ 做题区域 │ │ 导入模态框 │ │ │ │ │ └────┬────┘ └─────┬────┘ └──────┬──────┘ │ │ │ └───────┼─────────────┼──────────────┼──────────┘ │ └──────────┼─────────────┼──────────────┼─────────────┘ │ fetch │ fetch │ JSON.parse ▼ ▼ ▼ ┌─────────────────────────────────────────────────────┐ │ topics/ (数据层) │ │ ├── index.json ← 主题索引 │ │ └── {topic-slug}/ │ │ ├── meta.json ← 主题元信息(稳定) │ │ ├── fill_blank.json ← 填空题集 │ │ └── single_choice.json ← 单选题集 │ └─────────────────────────────────────────────────────┘ ▲ │ git push / pull ▼ ┌─────────────────────────────────────────────────────┐ │ Agent / LLM (生成层) │ │ ├── Claude Code Skill (generate / validate) │ │ ├── LLM + 提示词模板 (schema/prompt-template.md) │ │ └── JSON Schema 校验 (schema/question.schema.json) │ └─────────────────────────────────────────────────────┘ ``` ## 2. 目录结构 ``` examination/ ├── index.html # 前端入口(单文件 SPA) ├── topics/ # 题目数据 │ ├── index.json # 主题索引 │ └── {topic-slug}/ # 主题目录 │ ├── meta.json # 主题元信息 │ ├── fill_blank.json # 填空题 │ ├── single_choice.json # 单选题 │ ├── multiple_choice.json # 多选题(可选) │ ├── true_false.json # 判断题(可选) │ ├── short_answer.json # 简答题(可选) │ ├── code_reading.json # 代码阅读题(可选) │ └── scenario.json # 场景分析题(可选) ├── schema/ # Schema 与模板 │ ├── question.schema.json # 题目 JSON Schema(Draft-07) │ ├── prompt-template.md # LLM 生成提示词模板 │ └── templates/ # 各题型示例 │ ├── single_choice.json │ ├── multiple_choice.json │ ├── true_false.json │ ├── fill_blank.json │ ├── short_answer.json │ ├── code_reading.json │ └── scenario.json ├── docs/ # 文档 │ ├── requirements.md # 需求文档 │ └── architecture.md # 架构文档(本文件) ├── .gitignore # 排除 .ref/ └── README.md ``` ## 3. 数据模型 ### 3.1 主题索引 — `topics/index.json` ```json { "version": "1.0.0", "updated": "2026-09-02", "topics": [ { "slug": "gc-jvm", "name": "GC / JVM / 三色标记", "description": "...", "path": "topics/gc-jvm", "stats": { "total": 20, "by_type": { "fill_blank": 10, "single_choice": 10 } } } ] } ``` 前端加载此文件渲染主题列表,`stats` 字段用于展示题目数量。 ### 3.2 主题元信息 — `topics/{slug}/meta.json` ```json { "slug": "gc-jvm", "name": "GC / JVM / 三色标记", "description": "JVM 堆内存模型、GC 算法、三色标记法、垃圾收集器", "tags": ["jvm", "gc", "heap"], "difficulty_range": [1, 5], "schema_version": "1.0.0", "question_files": ["fill_blank", "single_choice"], "stats": { "total": 20, "by_type": { "fill_blank": 10, "single_choice": 10 } } } ``` - `question_files` 列出该主题包含的题型文件名(不含 `.json` 后缀) - 前端根据此列表动态加载对应的题目文件 - `stats` 在每次生成/追加题目后由 Agent 更新 ### 3.3 题目文件 — `topics/{slug}/{type}.json` ```json { "topic": "gc-jvm", "type": "fill_blank", "schema_version": "1.0.0", "generated": "2026-09-02T00:00:00Z", "questions": [ /* 题目数组 */ ] } ``` 每种题型一个文件,支持多 Agent 并行写入不同题型文件而无冲突。 ### 3.4 题目对象 #### 公共字段(所有题型必有) | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `id` | string | ✅ | 格式 `{type_short}-{seq}`,如 `fb-001` | | `type` | enum | ✅ | 题型标识 | | `difficulty` | integer | ✅ | 1-5 | | `tags` | string[] | ✅ | 细粒度知识点标签 | | `question` | string | ✅ | 题干 | | `explanation` | string | ✅ | 解析 | | `source` | string | ❌ | 来源 | | `related` | string[] | ❌ | 关联题目 id | #### 填空题 (`fill_blank`) ```json { "answer": ["老", "Old"], "answer_rule": "any" } ``` - `answer`: string[],可接受的答案列表 - `answer_rule`: `"any"`(任一匹配) | `"all"`(全部匹配) | `"ordered"`(按序匹配) #### 单选题 (`single_choice`) ```json { "options": { "A": "选项A", "B": "选项B", "C": "选项C", "D": "选项D" }, "answer": "B" } ``` #### 多选题 (`multiple_choice`) ```json { "options": { "A": "...", "B": "...", "C": "...", "D": "..." }, "answer": ["A", "C"] } ``` #### 判断题 (`true_false`) ```json { "answer": true } ``` #### 简答题 (`short_answer`) ```json { "answer": "参考答案文本", "keywords": ["关键词1", "关键词2"], "scoring_rubric": "评分标准说明" } ``` #### 代码阅读题 (`code_reading`) ```json { "code": "int x = 1;\nprintf(\"%d\", x);", "language": "c", "sub_questions": [ { "index": 1, "type": "single_choice", "question": "...", "options": {...}, "answer": "A", "explanation": "..." } ] } ``` #### 场景分析题 (`scenario`) ```json { "context": "一个电商系统在高峰期出现超卖问题...", "code": null, "sub_questions": [ { "index": 1, "type": "short_answer", "question": "...", "answer": "...", "keywords": [...], "explanation": "..." } ] } ``` ### 3.5 ID 编码规则 ``` {type_short}-{sequence} fb - 001 ``` | type_short | 题型 | |------------|------| | `sc` | single_choice | | `mc` | multiple_choice | | `tf` | true_false | | `fb` | fill_blank | | `sa` | short_answer | | `cr` | code_reading | | `sn` | scenario | ## 4. 前端架构 ### 4.1 页面结构 ``` ┌──────────────────────────────────────────┐ │ Header: 🎯 CS 知识应试强化 │ ├────────────┬─────────────────────────────┤ │ Sidebar │ Main Content │ │ │ │ │ 📚 主题 │ ┌─ Toolbar ──────────────┐ │ │ · gc-jvm │ │ 进度 ✅ ❌ ⏳ 按钮组 │ │ │ · ai-so │ └────────────────────────┘ │ │ · ai-mm │ ┌─ Progress Bar ─────────┐ │ │ · ai-he │ └────────────────────────┘ │ │ · ai-at │ ┌─ Question Card ────────┐ │ │ │ │ #1 填空 ★★★ │ │ │ ──────── │ │ 题干 [____] │ │ │ 📥 导入 │ │ [检查] [显示答案] │ │ │ │ │ 💡 解析... │ │ │ │ └────────────────────────┘ │ │ │ ┌─ Question Card ────────┐ │ │ │ │ ... │ │ │ │ └────────────────────────┘ │ └────────────┴─────────────────────────────┘ ``` ### 4.2 数据流 ``` 页面加载 │ ▼ fetch topics/index.json ──→ 渲染侧边栏主题列表 │ │ 用户点击主题 ▼ fetch topics/{slug}/meta.json ──→ 获取 question_files 列表 │ ▼ fetch topics/{slug}/{type}.json (并行) ──→ 合并 questions 数组 │ ▼ renderQuiz() ──→ 按题型渲染题目卡片 │ │ 用户交互(选择/输入/检查/显示答案) ▼ answers 状态更新 ──→ re-render ──→ 更新统计 ``` ### 4.3 状态管理 ```javascript let topics = []; // 从 index.json 加载的主题列表 let currentTopic = null; // 当前选中的主题 slug let currentQuestions = []; // 当前主题的所有题目(合并自多个题型文件) let answers = {}; // qId → { value, correct, revealed } let customQuestions = []; // 通过导入功能临时添加的题目 ``` ### 4.4 题型渲染逻辑 | 题型 | 渲染方式 | 判定逻辑 | |------|----------|----------| | fill_blank | 题干中的 `______` 替换为 `` | `matchFillAnswer()` 根据 `answer_rule` 匹配 | | single_choice | 选项列表,radio 样式 | `value === answer` | | multiple_choice | 选项列表,checkbox 样式 | 数组比较 | | true_false | 两个大按钮 | `value === answer` | | short_answer | `