paper
parent
688d7e14b0
commit
8bc4e87607
|
|
@ -56,8 +56,4 @@ public class QuestionDO extends BaseEntity {
|
|||
|
||||
@ApiModelProperty("关联课件管理id")
|
||||
private Long coursewareManagementId;
|
||||
|
||||
@ApiModelProperty("试题选项列表")
|
||||
@TableField(exist = false)
|
||||
private List<QuestionOptionDO> options;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, PaperDO> implemen
|
|||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean bindQuestions(Long paperId, List<Long> questionIds) {
|
||||
paperQuestionRelService.remove(Wrappers.<PaperQuestionRelDO>lambdaQuery()
|
||||
Db.remove(Wrappers.<PaperQuestionRelDO>lambdaQuery()
|
||||
.eq(PaperQuestionRelDO::getPaperId, paperId));
|
||||
if (CollectionUtils.isEmpty(questionIds)) {
|
||||
return true;
|
||||
|
|
@ -219,7 +219,7 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, PaperDO> implemen
|
|||
rel.setUpdateTime(now);
|
||||
return rel;
|
||||
}).collect(Collectors.toList());
|
||||
return paperQuestionRelService.saveBatch(rels);
|
||||
return Db.saveBatch(rels);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -237,8 +237,8 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, PaperDO> implemen
|
|||
@Transactional(rollbackFor = Exception.class)
|
||||
public PaperImportVO importQuestions(PaperImportDTO importDTO) {
|
||||
QuestionExcelImporter.ParseResult parseResult = questionExcelImporter.parse(importDTO.getFile());
|
||||
List<QuestionDO> questions = parseResult.getQuestions();
|
||||
if (CollectionUtils.isEmpty(questions)) {
|
||||
|
||||
if (!CollectionUtils.isEmpty(parseResult.getErrors())) {
|
||||
// 没有任何校验通过的试题,不创建试卷,直接返回异常明细
|
||||
return new PaperImportVO(0, parseResult.getErrors());
|
||||
}
|
||||
|
|
@ -252,22 +252,10 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, PaperDO> implemen
|
|||
this.savePaper(paper);
|
||||
|
||||
// 保存试题和选项(id已预置雪花id)
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
List<QuestionOptionDO> options = new ArrayList<>();
|
||||
for (QuestionDO question : questions) {
|
||||
question.setCreateTime(now);
|
||||
question.setUpdateTime(now);
|
||||
question.setVersion(0);
|
||||
options.addAll(question.getOptions());
|
||||
}
|
||||
for (QuestionOptionDO option : options) {
|
||||
option.setCreateTime(now);
|
||||
option.setUpdateTime(now);
|
||||
option.setVersion(0);
|
||||
}
|
||||
Db.saveBatch(questions);
|
||||
Db.saveBatch(options);
|
||||
Db.saveBatch(parseResult.getQuestions());
|
||||
Db.saveBatch(parseResult.getOptions());
|
||||
|
||||
List<QuestionDO> questions = parseResult.getQuestions();
|
||||
// 绑定试卷试题
|
||||
this.bindQuestions(paper.getId(), questions.stream()
|
||||
.map(QuestionDO::getId)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import com.alibaba.excel.EasyExcel;
|
|||
import com.alibaba.excel.ExcelReader;
|
||||
import com.alibaba.excel.read.metadata.ReadSheet;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -16,7 +15,7 @@ import org.qinan.cedu.model.entity.CoursewareManagementDO;
|
|||
import org.qinan.cedu.model.entity.QuestionDO;
|
||||
import org.qinan.cedu.model.entity.QuestionOptionDO;
|
||||
import org.qinan.cedu.model.vo.PaperImportErrorVO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
|
@ -86,38 +85,40 @@ public class QuestionExcelImporter {
|
|||
Map<Integer, String> sheetNames = readSheetNames(bytes);
|
||||
|
||||
List<PaperImportErrorVO> errors = new ArrayList<>();
|
||||
List<ChoiceQuestionImportRow> singleRows;
|
||||
List<ChoiceQuestionImportRow> multipleRows;
|
||||
List<JudgeQuestionImportRow> judgeRows;
|
||||
List<ChoiceQuestionImportRow> singleRows = new ArrayList<>();
|
||||
List<ChoiceQuestionImportRow> multipleRows = new ArrayList<>();
|
||||
List<JudgeQuestionImportRow> judgeRows = new ArrayList<>();
|
||||
try {
|
||||
singleRows = readSheet(bytes, SINGLE_SHEET_NO, ChoiceQuestionImportRow.class);
|
||||
} catch (Exception e) {
|
||||
singleRows = new ArrayList<>();
|
||||
errors.add(new PaperImportErrorVO(null, sheetName(sheetNames, SINGLE_SHEET_NO)
|
||||
, READ_SINGLE_SHEET_FAIL_PREFIX + e.getMessage()));
|
||||
}
|
||||
try {
|
||||
multipleRows = readSheet(bytes, MULTIPLE_SHEET_NO, ChoiceQuestionImportRow.class);
|
||||
} catch (Exception e) {
|
||||
multipleRows = new ArrayList<>();
|
||||
errors.add(new PaperImportErrorVO(null, sheetName(sheetNames, MULTIPLE_SHEET_NO)
|
||||
, READ_MULTIPLE_SHEET_FAIL_PREFIX + e.getMessage()));
|
||||
}
|
||||
try {
|
||||
judgeRows = readSheet(bytes, JUDGE_SHEET_NO, JudgeQuestionImportRow.class);
|
||||
} catch (Exception e) {
|
||||
judgeRows = new ArrayList<>();
|
||||
errors.add(new PaperImportErrorVO(null, sheetName(sheetNames, JUDGE_SHEET_NO)
|
||||
, READ_JUDGE_SHEET_FAIL_PREFIX + e.getMessage()));
|
||||
}
|
||||
|
||||
Map<String, Long> coursewareManagementIdByName = loadCoursewareIdByName(singleRows, multipleRows, judgeRows);
|
||||
|
||||
ParseResult parseResult = new ParseResult();
|
||||
List<QuestionDO> questions = new ArrayList<>();
|
||||
convertChoiceRows(singleRows, sheetName(sheetNames, SINGLE_SHEET_NO), QuestionTypeEnum.SINGLE, coursewareManagementIdByName, questions, errors);
|
||||
convertChoiceRows(multipleRows, sheetName(sheetNames, MULTIPLE_SHEET_NO), QuestionTypeEnum.MULTIPLE, coursewareManagementIdByName, questions, errors);
|
||||
convertJudgeRows(judgeRows, sheetName(sheetNames, JUDGE_SHEET_NO), coursewareManagementIdByName, questions, errors);
|
||||
return new ParseResult(questions, errors);
|
||||
List<QuestionOptionDO> options = new ArrayList<>();
|
||||
convertChoiceRows(singleRows, sheetName(sheetNames, SINGLE_SHEET_NO)
|
||||
, QuestionTypeEnum.SINGLE, coursewareManagementIdByName, questions, options, errors);
|
||||
convertChoiceRows(multipleRows, sheetName(sheetNames, MULTIPLE_SHEET_NO)
|
||||
, QuestionTypeEnum.MULTIPLE, coursewareManagementIdByName, questions, options, errors);
|
||||
convertJudgeRows(judgeRows, sheetName(sheetNames, JUDGE_SHEET_NO)
|
||||
, coursewareManagementIdByName, questions, options, errors);
|
||||
return new ParseResult(questions, options, errors);
|
||||
}
|
||||
|
||||
private byte[] readBytes(MultipartFile file) {
|
||||
|
|
@ -188,7 +189,7 @@ public class QuestionExcelImporter {
|
|||
*/
|
||||
private void convertChoiceRows(List<ChoiceQuestionImportRow> rows, String sheetName, QuestionTypeEnum questionType,
|
||||
Map<String, Long> coursewareManagementIdByName, List<QuestionDO> questions,
|
||||
List<PaperImportErrorVO> errors) {
|
||||
List<QuestionOptionDO> queOptions, List<PaperImportErrorVO> errors) {
|
||||
boolean single = questionType == QuestionTypeEnum.SINGLE;
|
||||
for (int i = 0; i < rows.size(); i++) {
|
||||
ChoiceQuestionImportRow row = rows.get(i);
|
||||
|
|
@ -251,13 +252,15 @@ public class QuestionExcelImporter {
|
|||
continue;
|
||||
}
|
||||
|
||||
questions.add(buildChoiceQuestion(row, questionType, options, answerLetters, coursewareManagementId));
|
||||
QuestionDO questionDO = buildChoiceQuestion(row, questionType, answerLetters, coursewareManagementId);
|
||||
List<QuestionOptionDO> questionOptionDOS = buildOptions(questionDO.getId(), options, answerLetters);
|
||||
questions.add(questionDO);
|
||||
queOptions.addAll(questionOptionDOS);
|
||||
}
|
||||
}
|
||||
|
||||
private QuestionDO buildChoiceQuestion(ChoiceQuestionImportRow row, QuestionTypeEnum questionType,
|
||||
Map<String, String> optionTexts, List<String> answerLetters,
|
||||
Long coursewareManagementId) {
|
||||
List<String> answerLetters, Long coursewareManagementId) {
|
||||
QuestionDO question = new QuestionDO();
|
||||
question.setId(IdUtil.getSnowflakeNextId());
|
||||
question.setTitle(row.getTitle().trim());
|
||||
|
|
@ -267,8 +270,7 @@ public class QuestionExcelImporter {
|
|||
question.setAnalysis(row.getAnalysis().trim());
|
||||
question.setTagType(row.getTagType().trim());
|
||||
question.setCoursewareManagementId(coursewareManagementId);
|
||||
question.setOptions(buildOptions(question.getId(), optionTexts, answerLetters));
|
||||
question.setAnswerQuestionOptionIds(joinCorrectOptionIds(question.getOptions()));
|
||||
InsertFieldDefaults.applyIgnoreOrgId(question);
|
||||
return question;
|
||||
}
|
||||
|
||||
|
|
@ -277,7 +279,7 @@ public class QuestionExcelImporter {
|
|||
*/
|
||||
private void convertJudgeRows(List<JudgeQuestionImportRow> rows, String sheetName,
|
||||
Map<String, Long> coursewareManagementIdByName, List<QuestionDO> questions,
|
||||
List<PaperImportErrorVO> errors) {
|
||||
List<QuestionOptionDO> options, List<PaperImportErrorVO> errors) {
|
||||
for (int i = 0; i < rows.size(); i++) {
|
||||
JudgeQuestionImportRow row = rows.get(i);
|
||||
int rowIndex = i + HEAD_ROW_NUMBER + 1;
|
||||
|
|
@ -318,9 +320,10 @@ public class QuestionExcelImporter {
|
|||
Map<String, String> optionTexts = new LinkedHashMap<>();
|
||||
optionTexts.put(OPTION_KEY_A, JUDGE_CORRECT_OPTION_TEXT);
|
||||
optionTexts.put(OPTION_KEY_B, JUDGE_WRONG_OPTION_TEXT);
|
||||
question.setOptions(buildOptions(question.getId(), optionTexts,
|
||||
Collections.singletonList(correct ? OPTION_KEY_A : OPTION_KEY_B)));
|
||||
question.setAnswerQuestionOptionIds(joinCorrectOptionIds(question.getOptions()));
|
||||
List<QuestionOptionDO> questionOptionDOS = buildOptions(question.getId(), optionTexts,
|
||||
Collections.singletonList(correct ? OPTION_KEY_A : OPTION_KEY_B));
|
||||
options.addAll(questionOptionDOS);
|
||||
question.setAnswerQuestionOptionIds(joinCorrectOptionIds(questionOptionDOS));
|
||||
questions.add(question);
|
||||
}
|
||||
}
|
||||
|
|
@ -338,6 +341,7 @@ public class QuestionExcelImporter {
|
|||
option.setOptionText(entry.getValue());
|
||||
option.setIsCorrect(answerLetters.contains(entry.getKey()));
|
||||
option.setSortOrder(sortOrder++);
|
||||
InsertFieldDefaults.applyIgnoreOrgId(option);
|
||||
options.add(option);
|
||||
}
|
||||
return options;
|
||||
|
|
@ -390,7 +394,6 @@ public class QuestionExcelImporter {
|
|||
* 解析结果
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public static class ParseResult {
|
||||
|
||||
/**
|
||||
|
|
@ -398,9 +401,26 @@ public class QuestionExcelImporter {
|
|||
*/
|
||||
private final List<QuestionDO> questions;
|
||||
|
||||
/**
|
||||
* 校验通过的试题(含选项)
|
||||
*/
|
||||
private final List<QuestionOptionDO> options;
|
||||
|
||||
/**
|
||||
* 异常明细
|
||||
*/
|
||||
private final List<PaperImportErrorVO> errors;
|
||||
|
||||
public ParseResult(List<QuestionDO> questions, List<QuestionOptionDO> options, List<PaperImportErrorVO> errors) {
|
||||
this.questions = questions;
|
||||
this.options = options;
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
public ParseResult() {
|
||||
this.questions = new ArrayList<>(64);
|
||||
this.options = new ArrayList<>(256);
|
||||
this.errors = new ArrayList<>(64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue