dev-tmp1
luotaiqian 2026-08-18 10:04:43 +08:00
parent 9e4324f722
commit 4b4796fc3d
1 changed files with 135 additions and 16 deletions

View File

@ -76,6 +76,9 @@ public class QuestionExcelImporter {
/**
* Excelid
*
* @param file Excel
* @return
*/
public ParseResult parse(MultipartFile file) {
if (file == null || file.isEmpty()) {
@ -109,18 +112,22 @@ public class QuestionExcelImporter {
Map<String, Long> coursewareManagementIdByName = loadCoursewareIdByName(singleRows, multipleRows, judgeRows);
ParseResult parseResult = new ParseResult();
List<QuestionDO> questions = new ArrayList<>();
List<QuestionOptionDO> options = new ArrayList<>();
ParseResult parseResult = new ParseResult(errors);
convertChoiceRows(singleRows, sheetName(sheetNames, SINGLE_SHEET_NO)
, QuestionTypeEnum.SINGLE, coursewareManagementIdByName, questions, options, errors);
, QuestionTypeEnum.SINGLE, coursewareManagementIdByName, parseResult);
convertChoiceRows(multipleRows, sheetName(sheetNames, MULTIPLE_SHEET_NO)
, QuestionTypeEnum.MULTIPLE, coursewareManagementIdByName, questions, options, errors);
, QuestionTypeEnum.MULTIPLE, coursewareManagementIdByName, parseResult);
convertJudgeRows(judgeRows, sheetName(sheetNames, JUDGE_SHEET_NO)
, coursewareManagementIdByName, questions, options, errors);
return new ParseResult(questions, options, errors);
, coursewareManagementIdByName, parseResult);
return parseResult;
}
/**
* IllegalArgumentException
*
* @param file Excel
* @return
*/
private byte[] readBytes(MultipartFile file) {
try {
return file.getBytes();
@ -129,6 +136,12 @@ public class QuestionExcelImporter {
}
}
/**
* sheetsheetNo -> sheetNameMap
*
* @param bytes Excel
* @return sheet
*/
private Map<Integer, String> readSheetNames(byte[] bytes) {
ExcelReader excelReader = EasyExcel.read(new ByteArrayInputStream(bytes)).build();
try {
@ -141,10 +154,26 @@ public class QuestionExcelImporter {
}
}
/**
* sheet"sheet[n]"n1
*
* @param sheetNames sheet
* @param sheetNo sheet0
* @return sheet
*/
private String sheetName(Map<Integer, String> sheetNames, int sheetNo) {
return sheetNames.getOrDefault(sheetNo, String.format(SHEET_FALLBACK_NAME_TEMPLATE, sheetNo + 1));
}
/**
* sheetExcel2
*
* @param bytes Excel
* @param sheetNo sheet0
* @param headClass
* @param <T>
* @return
*/
private <T> List<T> readSheet(byte[] bytes, int sheetNo, Class<T> headClass) {
return EasyExcel.read(new ByteArrayInputStream(bytes))
.head(headClass)
@ -155,6 +184,11 @@ public class QuestionExcelImporter {
/**
* id -> id
*
* @param singleRows
* @param multipleRows
* @param judgeRows
* @return id
*/
private Map<String, Long> loadCoursewareIdByName(List<ChoiceQuestionImportRow> singleRows,
List<ChoiceQuestionImportRow> multipleRows,
@ -178,6 +212,12 @@ public class QuestionExcelImporter {
return idByName;
}
/**
*
*
* @param names
* @param coursewareName
*/
private void addCoursewareName(Set<String> names, String coursewareName) {
if (StringUtils.hasText(coursewareName)) {
names.add(coursewareName.trim());
@ -186,10 +226,16 @@ public class QuestionExcelImporter {
/**
* /sheet
*
* @param rows /
* @param sheetName sheet
* @param questionType /
* @param coursewareManagementIdByName id
* @param parseResult
*/
private void convertChoiceRows(List<ChoiceQuestionImportRow> rows, String sheetName, QuestionTypeEnum questionType,
Map<String, Long> coursewareManagementIdByName, List<QuestionDO> questions,
List<QuestionOptionDO> queOptions, List<PaperImportErrorVO> errors) {
Map<String, Long> coursewareManagementIdByName, ParseResult parseResult) {
List<PaperImportErrorVO> errors = parseResult.getErrors();
boolean single = questionType == QuestionTypeEnum.SINGLE;
for (int i = 0; i < rows.size(); i++) {
ChoiceQuestionImportRow row = rows.get(i);
@ -254,11 +300,20 @@ public class QuestionExcelImporter {
QuestionDO questionDO = buildChoiceQuestion(row, questionType, answerLetters, coursewareManagementId);
List<QuestionOptionDO> questionOptionDOS = buildOptions(questionDO.getId(), options, answerLetters);
questions.add(questionDO);
queOptions.addAll(questionOptionDOS);
parseResult.getQuestions().add(questionDO);
parseResult.getOptions().addAll(questionOptionDOS);
}
}
/**
* /id
*
* @param row /
* @param questionType
* @param answerLetters
* @param coursewareManagementId id
* @return
*/
private QuestionDO buildChoiceQuestion(ChoiceQuestionImportRow row, QuestionTypeEnum questionType,
List<String> answerLetters, Long coursewareManagementId) {
QuestionDO question = new QuestionDO();
@ -276,10 +331,15 @@ public class QuestionExcelImporter {
/**
* sheetT/F AB
*
* @param rows
* @param sheetName sheet
* @param coursewareManagementIdByName id
* @param parseResult
*/
private void convertJudgeRows(List<JudgeQuestionImportRow> rows, String sheetName,
Map<String, Long> coursewareManagementIdByName, List<QuestionDO> questions,
List<QuestionOptionDO> options, List<PaperImportErrorVO> errors) {
Map<String, Long> coursewareManagementIdByName, ParseResult parseResult) {
List<PaperImportErrorVO> errors = parseResult.getErrors();
for (int i = 0; i < rows.size(); i++) {
JudgeQuestionImportRow row = rows.get(i);
int rowIndex = i + HEAD_ROW_NUMBER + 1;
@ -322,12 +382,20 @@ public class QuestionExcelImporter {
optionTexts.put(OPTION_KEY_B, JUDGE_WRONG_OPTION_TEXT);
List<QuestionOptionDO> questionOptionDOS = buildOptions(question.getId(), optionTexts,
Collections.singletonList(correct ? OPTION_KEY_A : OPTION_KEY_B));
options.addAll(questionOptionDOS);
parseResult.getOptions().addAll(questionOptionDOS);
question.setAnswerQuestionOptionIds(joinCorrectOptionIds(questionOptionDOS));
questions.add(question);
parseResult.getQuestions().add(question);
}
}
/**
*
*
* @param questionId id
* @param optionTexts
* @param answerLetters
* @return
*/
private List<QuestionOptionDO> buildOptions(Long questionId, Map<String, String> optionTexts,
List<String> answerLetters) {
List<QuestionOptionDO> options = new ArrayList<>();
@ -347,6 +415,12 @@ public class QuestionExcelImporter {
return options;
}
/**
* id
*
* @param options
* @return id
*/
private String joinCorrectOptionIds(List<QuestionOptionDO> options) {
return options.stream()
.filter(option -> Boolean.TRUE.equals(option.getIsCorrect()))
@ -354,6 +428,12 @@ public class QuestionExcelImporter {
.collect(Collectors.joining(COMMA_DELIMITER));
}
/**
* JSR-303
*
* @param violations JSR-303
* @return
*/
private String joinViolationMessages(Set<? extends ConstraintViolation<?>> violations) {
return violations.stream()
.map(ConstraintViolation::getMessage)
@ -361,6 +441,12 @@ public class QuestionExcelImporter {
.collect(Collectors.joining(VIOLATION_DELIMITER));
}
/**
* /
*
* @param row /
* @return
*/
private boolean isEmptyChoiceRow(ChoiceQuestionImportRow row) {
return !StringUtils.hasText(row.getTitle())
&& !StringUtils.hasText(row.getOptionA())
@ -374,6 +460,12 @@ public class QuestionExcelImporter {
&& !StringUtils.hasText(row.getCoursewareName());
}
/**
*
*
* @param row
* @return
*/
private boolean isEmptyJudgeRow(JudgeQuestionImportRow row) {
return !StringUtils.hasText(row.getTitle())
&& !StringUtils.hasText(row.getAnswer())
@ -383,6 +475,12 @@ public class QuestionExcelImporter {
&& !StringUtils.hasText(row.getCoursewareName());
}
/**
* null
*
* @param text
* @return null
*/
private String trimToNull(String text) {
if (!StringUtils.hasText(text)) {
return null;
@ -402,7 +500,7 @@ public class QuestionExcelImporter {
private final List<QuestionDO> questions;
/**
*
*
*/
private final List<QuestionOptionDO> options;
@ -411,16 +509,37 @@ public class QuestionExcelImporter {
*/
private final List<PaperImportErrorVO> errors;
/**
*
*
* @param questions
* @param options
* @param 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);
}
/**
*
*
* @param errors
*/
public ParseResult(List<PaperImportErrorVO> errors) {
this.questions = new ArrayList<>(64);
this.options = new ArrayList<>(256);
this.errors = errors;
}
}
}