dev-tmp1
luotaiqian 2026-08-18 18:24:55 +08:00
parent 67854c604c
commit df2d0a4399
9 changed files with 60 additions and 37 deletions

View File

@ -28,4 +28,7 @@ public class PaperQuestionRelDO extends BaseEntity {
@ApiModelProperty("试题id")
private Long questionId;
@ApiModelProperty("试题号")
private Integer questionNum;
}

View File

@ -51,9 +51,6 @@ public class QuestionDO extends BaseEntity {
@ApiModelProperty("标签类型")
private String tagType;
@ApiModelProperty("试题号")
private Integer questionNum;
@ApiModelProperty("关联课件管理id")
private Long coursewareManagementId;
}

View File

@ -1,21 +1,23 @@
package org.qinan.cedu.service.impl;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.qinan.cedu.enums.DeleteEnum;
import org.qinan.cedu.enums.QuestionTypeEnum;
import org.qinan.cedu.mapper.PaperMapper;
import org.qinan.cedu.mapper.PaperQuestionRelMapper;
import org.qinan.cedu.mapper.QuestionMapper;
import org.qinan.cedu.mapper.QuestionOptionMapper;
import org.qinan.cedu.model.dto.PaperQuestionSaveDTO;
import org.qinan.cedu.model.entity.PaperDO;
import org.qinan.cedu.model.entity.PaperQuestionRelDO;
import org.qinan.cedu.model.entity.QuestionDO;
import org.qinan.cedu.model.entity.QuestionOptionDO;
import org.qinan.cedu.mapper.PaperQuestionRelMapper;
import org.qinan.cedu.service.PaperQuestionRelService;
import org.qinan.cedu.service.PaperService;
import org.qinan.cedu.service.QuestionOptionService;
import org.qinan.cedu.service.QuestionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
@ -31,27 +33,22 @@ import java.util.stream.Collectors;
*
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class PaperQuestionRelServiceImpl extends ServiceImpl<PaperQuestionRelMapper, PaperQuestionRelDO> implements PaperQuestionRelService {
@Autowired
@Lazy
private PaperService paperService;
@Autowired
private QuestionService questionService;
@Autowired
private QuestionOptionService questionOptionService;
private final PaperMapper paperMapper;
private final QuestionMapper questionMapper;
private final QuestionOptionMapper questionOptionMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public void savePaperQuestion(PaperQuestionSaveDTO dto) {
// 校验试卷存在
PaperDO paper = paperService.lambdaQuery()
boolean exists = paperMapper.exists(new LambdaQueryWrapper<PaperDO>()
.eq(PaperDO::getId, dto.getPaperId())
.eq(PaperDO::getDeleteEnum, DeleteEnum.FALSE.getCode())
.one();
if (paper == null) {
.eq(PaperDO::getDeleteEnum, DeleteEnum.FALSE.getCode()));
if (exists) {
throw new IllegalArgumentException("试卷不存在id=" + dto.getPaperId());
}
@ -115,8 +112,8 @@ public class PaperQuestionRelServiceImpl extends ServiceImpl<PaperQuestionRelMap
.map(option -> String.valueOf(option.getId()))
.collect(Collectors.joining(",")));
questionService.save(question);
questionOptionService.saveBatch(options);
questionMapper.insert(question);
Db.saveBatch(options);
// 追加绑定试卷试题(不清空已有绑定)
PaperQuestionRelDO rel = new PaperQuestionRelDO();
@ -140,7 +137,7 @@ public class PaperQuestionRelServiceImpl extends ServiceImpl<PaperQuestionRelMap
}
// 逻辑删除试题及其选项
boolean deleted = questionService.deleteById(questionId);
boolean deleted = questionMapper.deleteById(questionId) != 0;
if (!deleted) {
throw new IllegalArgumentException("试题不存在id=" + questionId);
}

View File

@ -4,7 +4,6 @@ import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
@ -39,6 +38,7 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@ -137,6 +137,9 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, PaperDO> implemen
if (questions.isEmpty()) {
return;
}
Map<Long, Integer> questionNumByQuestionId = rels.stream()
.filter(rel -> rel.getQuestionNum() != null)
.collect(Collectors.toMap(PaperQuestionRelDO::getQuestionId, PaperQuestionRelDO::getQuestionNum, (a, b) -> a));
List<QuestionOptionDO> newOptions = new ArrayList<>();
List<PaperQuestionRelDO> newRels = new ArrayList<>();
for (QuestionDO question : questions) {
@ -173,6 +176,7 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, PaperDO> implemen
PaperQuestionRelDO rel = new PaperQuestionRelDO();
rel.setPaperId(target.getId());
rel.setQuestionId(newQuestionId);
rel.setQuestionNum(questionNumByQuestionId.get(oldQuestionId));
rel.setCreateTime(now);
rel.setUpdateTime(now);
newRels.add(rel);
@ -223,8 +227,8 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, PaperDO> implemen
@Override
public List<Long> getQuestionIds(Long paperId) {
return paperQuestionRelMapper.selectList(new LambdaQueryWrapper<PaperQuestionRelDO>()
.eq(PaperQuestionRelDO::getPaperId, paperId)
.eq(PaperQuestionRelDO::getDeleteEnum, DeleteEnum.FALSE.getCode()))
.eq(PaperQuestionRelDO::getPaperId, paperId)
.eq(PaperQuestionRelDO::getDeleteEnum, DeleteEnum.FALSE.getCode()))
.stream()
.map(PaperQuestionRelDO::getQuestionId)
.collect(Collectors.toList());
@ -253,11 +257,18 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, PaperDO> implemen
Db.saveBatch(parseResult.getOptions());
List<QuestionDO> questions = parseResult.getQuestions();
// 绑定试卷试题
this.bindQuestions(paper.getId(), questions.stream()
.map(QuestionDO::getId)
.collect(Collectors.toList()));
// 绑定试卷试题(含试题号)
LocalDateTime now = LocalDateTime.now();
List<PaperQuestionRelDO> rels = new ArrayList<>(questions.size());
for (int i = 0; i < questions.size(); i++) {
PaperQuestionRelDO rel = new PaperQuestionRelDO();
rel.setPaperId(paper.getId());
rel.setQuestionId(questions.get(0).getId());
rel.setQuestionNum(i + 1);
InsertFieldDefaults.applyIgnoreOrgId(rel);
rels.add(rel);
}
Db.saveBatch(rels);
return new PaperImportVO(questions.size(), parseResult.getErrors());
}
}

View File

@ -1,6 +1,8 @@
package org.qinan.cedu.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.qinan.cedu.model.entity.QuestionOptionDO;
import org.qinan.cedu.mapper.QuestionOptionMapper;
import org.qinan.cedu.service.QuestionOptionService;
@ -10,5 +12,7 @@ import org.springframework.stereotype.Service;
*
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class QuestionOptionServiceImpl extends ServiceImpl<QuestionOptionMapper, QuestionOptionDO> implements QuestionOptionService {
}

View File

@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.qinan.cedu.enums.DeleteEnum;
import org.qinan.cedu.enums.QuestionTypeEnum;
import org.qinan.cedu.mapper.QuestionMapper;
@ -32,6 +34,8 @@ import java.util.stream.Collectors;
*
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, QuestionDO> implements QuestionService {
@Autowired

View File

@ -299,7 +299,7 @@ public class QuestionExcelImporter {
}
QuestionDO questionDO = buildChoiceQuestion(row, questionType, answerLetters, coursewareManagementId);
questionDO.setQuestionNum(rowIndex - HEAD_ROW_NUMBER);
parseResult.getQuestionNumByQuestionId().put(questionDO.getId(), rowIndex - HEAD_ROW_NUMBER);
List<QuestionOptionDO> questionOptionDOS = buildOptions(questionDO.getId(), options, answerLetters);
questionDO.setAnswerQuestionOptionIds(joinCorrectOptionIds(questionOptionDOS));
@ -380,7 +380,7 @@ public class QuestionExcelImporter {
question.setAnalysis(row.getAnalysis().trim());
question.setTagType(row.getTagType().trim());
question.setCoursewareManagementId(coursewareManagementId);
question.setQuestionNum(rowIndex - HEAD_ROW_NUMBER);
parseResult.getQuestionNumByQuestionId().put(question.getId(), rowIndex - HEAD_ROW_NUMBER);
InsertFieldDefaults.applyIgnoreOrgId(question);
Map<String, String> optionTexts = new LinkedHashMap<>();
optionTexts.put(OPTION_KEY_A, JUDGE_CORRECT_OPTION_TEXT);
@ -509,6 +509,11 @@ public class QuestionExcelImporter {
*/
private final List<QuestionOptionDO> options;
/**
* id
*/
private final Map<Long, Integer> questionNumByQuestionId;
/**
*
*/
@ -524,6 +529,7 @@ public class QuestionExcelImporter {
public ParseResult(List<QuestionDO> questions, List<QuestionOptionDO> options, List<PaperImportErrorVO> errors) {
this.questions = questions;
this.options = options;
this.questionNumByQuestionId = new HashMap<>();
this.errors = errors;
}
@ -533,6 +539,7 @@ public class QuestionExcelImporter {
public ParseResult() {
this.questions = new ArrayList<>(64);
this.options = new ArrayList<>(256);
this.questionNumByQuestionId = new HashMap<>();
this.errors = new ArrayList<>(64);
}
@ -544,6 +551,7 @@ public class QuestionExcelImporter {
public ParseResult(List<PaperImportErrorVO> errors) {
this.questions = new ArrayList<>(64);
this.options = new ArrayList<>(256);
this.questionNumByQuestionId = new HashMap<>();
this.errors = errors;
}
}

View File

@ -4,7 +4,7 @@
<select id="pagePaperQuestions" resultType="org.qinan.cedu.model.vo.PaperQuestionVO">
SELECT q.id, q.title, q.score, q.answer_question_option_ids, q.analysis
, q.question_type, q.tag_type, q.question_num
, q.question_type, q.tag_type, pqr.question_num
, cm.courseware_name
FROM paper_question_rel pqr
JOIN question q ON pqr.question_id = q.id

View File

@ -81,7 +81,6 @@ CREATE TABLE `questionDO`
`score` decimal(5, 2) NOT NULL DEFAULT 0.00 COMMENT '分值',
`analysis` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '答案解析',
`tag_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '标签类型',
`question_num` int NULL DEFAULT NULL COMMENT '试题号',
`courseware_management_id` bigint NULL DEFAULT NULL COMMENT '关联课件管理id',
`delete_enum` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '删除标识true false',
`remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',