# 章节摸底 + 按知识点顺序学习 方案文档 ## 1. 需求概述 ### 1.1 核心流程 ``` 章节摸底(20题) → 按知识点顺序学习 → 知识点达标(90%) → 下一个知识点 → 章节全部达标 → 下一章摸底 ``` ### 1.2 关键规则 1. **知识点来源**:section 直接绑定的知识点(不扩展子知识点) 2. **90%判断**:跳过没有题目的知识点 3. **智能组卷**:按顺序找第一个未达标知识点,最多2个知识点 4. **题目不够**:不从其他知识点补充,不够就不够 5. **章节流转**:所有知识点达标 → 下一章摸底 --- ## 2. assembleType 映射关系 ### 2.1 前端传入 → 后端实际处理 | 前端传入 | 后端实际处理 | 说明 | |---------|-------------|------| | 0 (旧摸底) | 0 → buildChapterDiagnosticParams | 章节摸底(新逻辑) | | 9 (原摸底) | 0 → buildChapterDiagnosticParams | 章节摸底(新逻辑) | | 1 (智能组卷) | 8 → buildChapterIntelligentParams | 按知识点顺序学习(新逻辑) | | 2/3/4/5 | 保持不变 | 原有逻辑不动 | ### 2.2 paper_type 值 | paper_type | 含义 | |------------|------| | 0 | 摸底(包括章节摸底) | | 1 | 智能组卷 | | 2 | 知识点组卷 | | 3 | 教材组卷 | | 5 | 追练 | --- ## 3. 数据库修改 ### 3.1 papers 表增加字段 ```sql ALTER TABLE papers ADD COLUMN diagnostic_chapter_id INT NULL COMMENT '摸底的章节ID'; ``` --- ## 4. 代码修改清单 ### 4.1 新增方法(不影响原有逻辑) | 文件 | 方法 | 用途 | |------|------|------| | ExamTypeStrategy.php | `buildChapterDiagnosticParams` | 章节摸底(新逻辑) | | ExamTypeStrategy.php | `buildChapterIntelligentParams` | 按知识点顺序学习(新逻辑) | | DiagnosticChapterService.php | `getChapterKnowledgePointsWithoutExpand` | 获取知识点(不扩展子知识点) | | DiagnosticChapterService.php | `getFirstUnmasteredKnowledgePointInOrder` | 按顺序找第一个未达标知识点 | | DiagnosticChapterService.php | `hasChapterDiagnostic` | 判断章节是否已摸底 | | StudentKnowledgeMastery.php | `allAtLeastSkipNoQuestions` | 判断达标(跳过无题知识点) | ### 4.2 修改方法 | 文件 | 方法 | 修改内容 | |------|------|---------| | ExamTypeStrategy.php | `buildParams` | 增加 assembleType 映射逻辑 | ### 4.3 保持不变的方法 - `buildDiagnosticParams`(原摸底) - `buildIntelligentAssembleParams`(原智能组卷) - `buildKnowledgePointAssembleParams`(知识点组卷) - `buildTextbookAssembleParams`(教材组卷) - `buildMistakeParams`(追练) - `buildGeneralParams`(通用) --- ## 5. 详细逻辑 ### 5.1 章节摸底 (buildChapterDiagnosticParams) ``` 1. 获取学生当前教材 2. 找第一个未完成摸底的章节: - 遍历章节,检查 papers 表是否有 paper_type=0 且 diagnostic_chapter_id=章节ID 的记录 - 如果没有,说明这个章节需要摸底 3. 获取该章节所有 section 绑定的知识点(不扩展子知识点) 4. 过滤掉没有题目的知识点 5. 用这些知识点出题(20题) 6. 保存时记录 diagnostic_chapter_id ``` ### 5.2 按知识点顺序学习 (buildChapterIntelligentParams) ``` 1. 获取当前应该学习的章节(第一个有未达标知识点的章节) 2. 检查该章节是否已摸底 - 如果没有摸底 → 返回章节摸底参数 3. 获取该章节所有知识点(按 section 顺序) 4. 按顺序遍历,找第一个未达标的知识点(跳过无题知识点) 5. 检查题目数量: - 如果不够20题,补充下一个未达标知识点 - 最多2个知识点 6. 如果所有知识点都达标 → 返回下一章的摸底参数 ``` ### 5.3 90%达标判断 (allAtLeastSkipNoQuestions) ``` 1. 遍历章节的所有知识点 2. 检查每个知识点是否有题目 - 没有题目 → 跳过 3. 检查掌握度是否 >= 90% - 有题但没有掌握度记录 → 视为 0%,未达标 4. 所有有题的知识点都达标 → 返回 true ``` --- ## 6. 执行步骤 1. [x] 创建方案文档 2. [x] 创建 migration 增加 diagnostic_chapter_id 字段 - 文件: `database/migrations/2026_02_01_000001_add_diagnostic_chapter_id_to_papers_table.php` 3. [x] 修改 StudentKnowledgeMastery 增加新方法 - `allAtLeastSkipNoQuestions`: 判断达标(跳过无题知识点) - `getFirstUnmasteredKpCode`: 获取第一个未达标的知识点 4. [x] 修改 DiagnosticChapterService 增加新方法 - `getChapterKnowledgePointsSimple`: 获取知识点(不扩展子知识点) - `hasChapterDiagnostic`: 判断章节是否已摸底 - `getFirstUndiagnosedChapter`: 获取第一个未摸底的章节 - `getCurrentLearningChapter`: 获取当前学习章节 - `getNextChapter`: 获取下一个章节 - `filterKpCodesWithQuestions`: 过滤有题的知识点 - `getUnmasteredKpCodesInOrder`: 按顺序获取未达标知识点 5. [x] 修改 ExamTypeStrategy 增加新方法和映射逻辑 - 修改 `buildParams`: 增加 assembleType 映射 - 新增 `buildChapterDiagnosticParams`: 章节摸底 - 新增 `buildChapterIntelligentParams`: 按知识点顺序学习 6. [x] 修改 QuestionBankService 保存 diagnostic_chapter_id 7. [x] 修改 Paper 模型增加 diagnostic_chapter_id 字段 8. [ ] 执行 migration 9. [ ] 测试验证 --- ## 7. 风险控制 - 所有原有方法保持不变 - 新增独立方法处理新逻辑 - 通过 assembleType 映射控制流程 - 即使新逻辑有问题,也不影响 assembleType=2/3/4/5 的原有功能