diff --git a/src/main/java/com/baobaot/exam/Controller/AdminController.java b/src/main/java/com/baobaot/exam/Controller/AdminController.java index 9f678af..3602261 100644 --- a/src/main/java/com/baobaot/exam/Controller/AdminController.java +++ b/src/main/java/com/baobaot/exam/Controller/AdminController.java @@ -33,6 +33,23 @@ public class AdminController { return "admin"; } + // API: 批量导入题目 + @PostMapping("/admin/api/questions/batch-import") + @ResponseBody + public ResponseEntity> batchImportQuestions(@RequestBody List> questions) { + Map result = new HashMap<>(); + try { + int importedCount = adminService.batchImportQuestions(questions); + result.put("success", true); + result.put("importedCount", importedCount); + result.put("message", "成功导入 " + importedCount + " 道题目"); + } catch (Exception e) { + result.put("success", false); + result.put("message", e.getMessage()); + } + return ResponseEntity.ok(result); + } + // API: 获取题目列表(支持全部、按类型、按分值、按标题模糊查询、联合查询) @GetMapping("/admin/api/questions") @ResponseBody @@ -173,7 +190,6 @@ public class AdminController { @RequestParam(required = false) String answerB, @RequestParam(required = false) String answerC, @RequestParam(required = false) String answerD, - @RequestParam(required = false) String answer, @RequestParam(required = false) String rAnswer, @RequestParam Integer score) { Map result = new HashMap<>(); @@ -198,9 +214,6 @@ public class AdminController { .answerB(answerB) .answerC(answerC) .answerD(answerD); - } else { - // 简答题 - builder.answer(answer); } adminService.updateQuestion(builder.build()); diff --git a/src/main/java/com/baobaot/exam/Service/adminService.java b/src/main/java/com/baobaot/exam/Service/adminService.java index 9f11345..fd95011 100644 --- a/src/main/java/com/baobaot/exam/Service/adminService.java +++ b/src/main/java/com/baobaot/exam/Service/adminService.java @@ -4,6 +4,7 @@ import com.baobaot.exam.dao.question; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; +import java.util.Map; public interface adminService extends IService { @@ -50,4 +51,11 @@ public interface adminService extends IService { * 更新题目 */ boolean updateQuestion(question q); + + /** + * 批量导入题目 + * @param questions 题目数据列表 + * @return 成功导入的题目数量 + */ + int batchImportQuestions(List> questions); } diff --git a/src/main/java/com/baobaot/exam/Service/impl/adminServiceImpl.java b/src/main/java/com/baobaot/exam/Service/impl/adminServiceImpl.java index d254c57..f8dfae5 100644 --- a/src/main/java/com/baobaot/exam/Service/impl/adminServiceImpl.java +++ b/src/main/java/com/baobaot/exam/Service/impl/adminServiceImpl.java @@ -6,8 +6,10 @@ import com.baobaot.exam.mapper.questionMapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.Map; @Service public class adminServiceImpl extends ServiceImpl implements adminService { @@ -33,7 +35,6 @@ public class adminServiceImpl extends ServiceImpl impl question q = question.builder() .title(title) .type(type) - .answer(answer) .rAnswer(r_answer) .score(score) .build(); @@ -84,4 +85,39 @@ public class adminServiceImpl extends ServiceImpl impl public boolean updateQuestion(question q) { return updateById(q); } + + @Override + @Transactional + public int batchImportQuestions(List> questions) { + int importedCount = 0; + + for (Map qData : questions) { + String title = (String) qData.get("title"); + Integer type = ((Number) qData.get("type")).intValue(); + Integer score = ((Number) qData.get("score")).intValue(); + + question.questionBuilder builder = question.builder() + .title(title) + .type(type) + .score(score); + + if (type == 1) { + // 选择题 + builder.answerA((String) qData.get("answerA")) + .answerB((String) qData.get("answerB")) + .answerC((String) qData.get("answerC")) + .answerD((String) qData.get("answerD")) + .rAnswer((String) qData.get("rAnswer")); + } else { + // 简答题 + builder.rAnswer((String) qData.get("rAnswer")); + } + + if (save(builder.build())) { + importedCount++; + } + } + + return importedCount; + } } diff --git a/src/main/java/com/baobaot/exam/dao/question.java b/src/main/java/com/baobaot/exam/dao/question.java index 3e8a441..86cf521 100644 --- a/src/main/java/com/baobaot/exam/dao/question.java +++ b/src/main/java/com/baobaot/exam/dao/question.java @@ -15,7 +15,6 @@ public class question { private Integer id; private String title; private Integer type; - private String answer; private String answerA; private String answerB; private String answerC; diff --git a/src/main/resources/templates/admin.html b/src/main/resources/templates/admin.html index 777bc57..5c2968c 100644 --- a/src/main/resources/templates/admin.html +++ b/src/main/resources/templates/admin.html @@ -304,6 +304,7 @@
+ 创建试卷 查看试卷 批改试卷 @@ -502,7 +503,6 @@ ID 题目 类型 - 选项/学生答案 正确答案 分值 操作 @@ -525,7 +525,7 @@ if (q.answerD) parts.push(`D: ${escapeHtml(q.answerD)}`); optionsHtml = parts.join('
'); } else { - optionsHtml = q.answer ? escapeHtml(q.answer) : '无答案'; + optionsHtml = '-'; } const rAnswerHtml = q.rAnswer ? @@ -630,6 +630,101 @@ let currentEditId = null; let currentEditType = null; + // 打开批量导入弹窗 + function openBatchImportModal() { + document.getElementById('batchImportModal').style.display = 'block'; + document.getElementById('batchImportJson').value = ''; + document.getElementById('batchImportResult').style.display = 'none'; + } + + // 关闭批量导入弹窗 + function closeBatchImportModal() { + document.getElementById('batchImportModal').style.display = 'none'; + document.getElementById('batchImportJson').value = ''; + document.getElementById('batchImportResult').style.display = 'none'; + } + + // 提交批量导入 + function submitBatchImport() { + const jsonText = document.getElementById('batchImportJson').value.trim(); + const resultDiv = document.getElementById('batchImportResult'); + + if (!jsonText) { + resultDiv.innerHTML = '
请输入JSON数据
'; + resultDiv.style.display = 'block'; + return; + } + + let questions; + try { + questions = JSON.parse(jsonText); + } catch (e) { + resultDiv.innerHTML = '
JSON格式错误: ' + e.message + '
'; + resultDiv.style.display = 'block'; + return; + } + + if (!Array.isArray(questions)) { + resultDiv.innerHTML = '
数据必须是JSON数组格式
'; + resultDiv.style.display = 'block'; + return; + } + + if (questions.length === 0) { + resultDiv.innerHTML = '
题目数组不能为空
'; + resultDiv.style.display = 'block'; + return; + } + + // 验证每道题的必填字段 + for (let i = 0; i < questions.length; i++) { + const q = questions[i]; + if (!q.title || q.title.trim() === '') { + resultDiv.innerHTML = '
第 ' + (i + 1) + ' 题缺少题目内容(title)
'; + resultDiv.style.display = 'block'; + return; + } + if (!q.type || (q.type !== 1 && q.type !== 2)) { + resultDiv.innerHTML = '
第 ' + (i + 1) + ' 题类型错误,type必须是1(选择题)或2(简答题)
'; + resultDiv.style.display = 'block'; + return; + } + if (!q.score || q.score < 0) { + resultDiv.innerHTML = '
第 ' + (i + 1) + ' 题分值错误
'; + resultDiv.style.display = 'block'; + return; + } + } + + // 发送请求 + fetch('/admin/api/questions/batch-import', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(questions) + }) + .then(res => res.json()) + .then(data => { + if (data.success) { + resultDiv.innerHTML = '
导入成功!共导入 ' + data.importedCount + ' 道题目
'; + resultDiv.style.display = 'block'; + loadAllQuestions(); + setTimeout(() => { + closeBatchImportModal(); + }, 1500); + } else { + resultDiv.innerHTML = '
导入失败: ' + (data.message || '未知错误') + '
'; + resultDiv.style.display = 'block'; + } + }) + .catch(err => { + console.error(err); + resultDiv.innerHTML = '
导入失败,请检查网络
'; + resultDiv.style.display = 'block'; + }); + } + // 打开编辑弹窗 function editQuestion(id, type) { currentEditId = id; @@ -676,7 +771,6 @@ document.getElementById('editEssayForm').style.display = 'block'; document.getElementById('editTypeLabel').textContent = '简答题'; - document.getElementById('editAnswer').value = q.answer || ''; document.getElementById('editRAnswerEssay').value = q.rAnswer || ''; } } @@ -705,7 +799,6 @@ formData.append('answerD', document.getElementById('editAnswerD').value); formData.append('rAnswer', document.getElementById('editRAnswer').value); } else { - formData.append('answer', document.getElementById('editAnswer').value); formData.append('rAnswer', document.getElementById('editRAnswerEssay').value); } @@ -756,8 +849,7 @@ if (answerD) parts.push(`D: ${escapeHtml(answerD)}`); optionsHtml = parts.join('
'); } else { - const answer = formData.get('answer'); - optionsHtml = answer ? escapeHtml(answer) : '无答案'; + optionsHtml = '-'; } const rAnswerHtml = rAnswer ? @@ -784,6 +876,49 @@ + + +