新增文本题库导入功能,题目新增“解析”字段

This commit is contained in:
2025-12-25 00:15:14 +08:00
parent e2a1555b46
commit dc9fc169ec
30 changed files with 1386 additions and 165 deletions

View File

@@ -0,0 +1,32 @@
# Change: 题库管理新增文本导入页面(`|` 分隔)与覆盖/增量导入
## Why
当前题库导入主要依赖 Excel 文件,使用门槛较高且不便于快速整理题目文本。需要提供“粘贴文本 → 解析预览 → 审阅删除 → 一键导入”的流程以提升题库维护效率。
## What Changes
- 新增管理端“文本导入题库”独立页面:
- 文本输入框粘贴题库文本
- 解析后生成题目列表供审阅,支持删除条目
- 支持导入模式:覆盖式导入、增量导入(按题目内容判断重复并覆盖)
- 所有题目新增字段“解析”0~255 字符串),用于详细解析该题的正确答案
- 文本导入格式调整:
- 字段分隔符从 `,` 改为 `|`,避免题干/解析中包含逗号导致字段错位
- 选择题的 4 个备选项使用 4 个独立字段表示(而不是在单字段内再分隔)
- 多选题的标准答案使用 `,` 分隔(因答案数量不确定,使用 `|` 易产生歧义)
- 判断题不包含备选项字段,但仍包含标准答案字段(“被选答案”不属于题库导入字段)
- 判断题默认分值为 0因此无论用户是否作答/如何作答,得分均为 0
- 文字描述题不包含备选项字段,且不包含标准答案字段
- 新增/调整后端导入接口以支持覆盖式/增量导入的服务端一致性处理(事务)
- 保持现有 Excel 导入/导出能力不变
## Impact
- Affected specs:
- `openspec/specs/api_response_schema.yaml`(所有新接口继续使用统一响应包裹)
- `openspec/specs/database_schema.yaml`(需为 `questions` 表新增字段;覆盖式导入需在事务内处理关联数据)
- `openspec/specs/tech_stack.yaml`(不引入新技术栈)
- Affected code:
- 前端:`src/pages/admin/*``src/App.tsx``src/services/api.ts`
- 后端:`api/server.ts``api/controllers/questionController.ts``api/models/question.ts`
## Risks / Trade-offs
- 文字描述题“无标准答案”将影响现有自动判分逻辑,需要明确导入后的判分策略与展示方式

View File

@@ -0,0 +1,66 @@
## ADDED Requirements
### Requirement: Admin Text-Based Question Import Page
系统 MUST 在管理端提供“文本导入题库”的独立页面,支持管理员粘贴文本题库并解析生成题目列表供审阅;管理员 MUST 能删除不正确条目后再提交导入。
#### Scenario: Paste, parse, review, and delete before import
- **GIVEN** 管理员进入“文本导入题库”页面
- **WHEN** 管理员粘贴题库文本并触发解析
- **THEN** 系统 MUST 展示解析后的题目列表用于审阅
- **AND** 系统 MUST 支持管理员删除列表中的任意条目
### Requirement: Text Import Format Uses Pipe Delimiter
系统 MUST 使用 `|` 作为文本导入字段分隔符,以避免题干中包含逗号时影响解析;选择题的备选项 MUST 使用 4 个独立字段表示;多选题的答案 MUST 使用 `,` 分隔。
#### Scenario: Parse line with commas in content
- **GIVEN** 管理员导入的题目内容包含逗号
- **WHEN** 系统按 `|` 解析字段
- **THEN** 系统 MUST 正确识别题目内容而不因逗号截断字段
### Requirement: Import Modes For Text Import
系统 MUST 支持以下导入模式:
- 覆盖式导入:导入前清理现有题库数据,并导入新的题目集合
- 增量导入:以题目内容为重复判断依据;若题目内容重复,系统 MUST 覆盖该题目的内容相关字段(题型、类别、选项、答案、分值)
#### Scenario: Overwrite import
- **GIVEN** 管理员已完成题目列表审阅
- **WHEN** 管理员选择“覆盖式导入”并提交
- **THEN** 系统 MUST 清理现有题库数据并导入新题目集合
#### Scenario: Incremental import with overwrite by content
- **GIVEN** 系统中已存在题目 `content = X`
- **WHEN** 管理员选择“增量导入”并提交包含 `content = X` 的题目
- **THEN** 系统 MUST 以题目内容为匹配依据覆盖该题目的题型、类别、选项、答案与分值
### Requirement: Questions Have Analysis Field
系统中每道题目 MUST 包含“解析”字段0~255 字符串),用于详细解析该题的正确答案;文本导入与后续题库管理编辑 MUST 支持维护该字段。
#### Scenario: Persist analysis from import
- **GIVEN** 管理员导入的题目包含“解析”
- **WHEN** 导入完成
- **THEN** 系统 MUST 在题库中保存该题的“解析”
### Requirement: Judgment And Text Question Import Rules
系统 MUST 在文本导入时按以下规则解析不同题型:
- 判断题 MUST 不包含备选项字段,但 MUST 包含标准答案字段
- 判断题 MUST 默认分值为 0
- 文字描述题 MUST 不包含备选项字段,且 MUST 不包含标准答案字段
#### Scenario: Import judgment question without options
- **GIVEN** 管理员导入判断题行不包含备选项字段
- **WHEN** 系统解析导入文本
- **THEN** 系统 MUST 解析成功并将标准答案保存为题目答案字段
- **AND** 系统 MUST 将该判断题分值保存为 0
#### Scenario: Import text question without standard answer
- **GIVEN** 管理员导入文字描述题行不包含标准答案字段
- **WHEN** 系统解析导入文本
- **THEN** 系统 MUST 解析成功并将题目答案字段保存为空字符串
### Requirement: Text Import API Uses Unified Envelope
系统 MUST 提供用于文本导入的管理端接口,并且接口响应 MUST 使用统一的响应包裹结构(包含 `success`,错误时包含 `message`,必要时包含 `errors`)。
#### Scenario: Import API success response
- **GIVEN** 管理员提交合法的文本解析结果与导入模式
- **WHEN** 后端导入完成
- **THEN** 系统 MUST 返回 `success: true` 且在 `data` 中包含导入结果统计

View File

@@ -0,0 +1,20 @@
## 1. 文本导入页面
- [ ] 1.1 新增“文本导入题库”路由与入口按钮
- [ ] 1.2 支持粘贴文本并解析为题目列表
- [ ] 1.3 支持列表审阅与删除条目
- [ ] 1.4 支持选择导入模式并提交导入
- [ ] 1.5 支持“解析”字段的展示与编辑
## 2. 后端接口
- [ ] 2.1 新增文本导入接口并保持统一响应结构
- [ ] 2.2 实现覆盖式导入(事务内清理并导入)
- [ ] 2.3 实现增量导入(按题目内容匹配并覆盖)
- [ ] 2.4 返回导入结果统计(新增/覆盖/跳过/失败明细)
- [ ] 2.5 为题目新增“解析”字段并完成数据库兼容迁移
- [ ] 2.6 调整文本导入解析规则(字段分隔符与不同题型字段结构)
- [ ] 2.7 调整题目校验规则(判断题/文字描述题的答案要求)
- [ ] 2.8 判断题分值规则:文本导入默认保存为 0 分
## 3. 测试与校验
- [ ] 3.1 添加接口测试覆盖覆盖式与增量导入(含新格式与“解析”字段)
- [ ] 3.2 运行 `npm run check``npm run build`