|
@@ -1,31 +1,20 @@
|
|
|
package com.qmth.teachcloud.mark.service.impl;
|
|
|
|
|
|
-import java.util.*;
|
|
|
-import java.util.stream.Collectors;
|
|
|
-
|
|
|
-import javax.annotation.Resource;
|
|
|
-
|
|
|
-import com.qmth.teachcloud.common.entity.SysUser;
|
|
|
-import com.qmth.teachcloud.common.util.ServletUtil;
|
|
|
-import org.apache.commons.collections4.CollectionUtils;
|
|
|
-import org.apache.commons.collections4.MapUtils;
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-import org.springframework.transaction.annotation.Transactional;
|
|
|
-import org.springframework.web.multipart.MultipartFile;
|
|
|
-
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.qmth.teachcloud.common.bean.dto.mark.ObjectiveAnswerDto;
|
|
|
+import com.qmth.teachcloud.common.bean.result.ExcelResult;
|
|
|
import com.qmth.teachcloud.common.contant.SystemConstant;
|
|
|
import com.qmth.teachcloud.common.entity.MarkQuestion;
|
|
|
-import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
|
|
|
-import com.qmth.teachcloud.common.enums.ObjectivePolicy;
|
|
|
-import com.qmth.teachcloud.common.enums.QuestionType;
|
|
|
-import com.qmth.teachcloud.common.enums.UploadFileEnum;
|
|
|
+import com.qmth.teachcloud.common.entity.SysUser;
|
|
|
+import com.qmth.teachcloud.common.enums.*;
|
|
|
import com.qmth.teachcloud.common.service.TeachcloudCommonService;
|
|
|
+import com.qmth.teachcloud.common.util.ConvertUtil;
|
|
|
+import com.qmth.teachcloud.common.util.ExcelUtil;
|
|
|
import com.qmth.teachcloud.common.util.FileStoreUtil;
|
|
|
+import com.qmth.teachcloud.common.util.ServletUtil;
|
|
|
import com.qmth.teachcloud.mark.dto.mark.setting.MarkQuestionDto;
|
|
|
import com.qmth.teachcloud.mark.entity.MarkPaper;
|
|
|
import com.qmth.teachcloud.mark.mapper.MarkQuestionMapper;
|
|
@@ -34,6 +23,18 @@ import com.qmth.teachcloud.mark.params.MarkQuestionParams;
|
|
|
import com.qmth.teachcloud.mark.service.MarkGroupService;
|
|
|
import com.qmth.teachcloud.mark.service.MarkPaperService;
|
|
|
import com.qmth.teachcloud.mark.service.MarkQuestionService;
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
+import org.apache.commons.collections4.MapUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import java.util.stream.Stream;
|
|
|
|
|
|
/**
|
|
|
* <p>
|
|
@@ -202,6 +203,138 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
|
|
|
return this.list(lambdaQueryWrapper);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void objectiveAnswerSettingModelExport(Long examId, String paperNumber, HttpServletResponse response)
|
|
|
+ throws Exception {
|
|
|
+ List<ObjectiveAnswerDto> datasource = this.listQuestionByExamIdAndPaperNumberAndGroupNumber(examId, paperNumber,
|
|
|
+ null, true).stream().flatMap(e -> {
|
|
|
+ ObjectiveAnswerDto dto = new ObjectiveAnswerDto();
|
|
|
+ dto.setMainNumber(String.valueOf(e.getMainNumber()));
|
|
|
+ dto.setSubNumber(String.valueOf(e.getSubNumber()));
|
|
|
+ dto.setMainTitle(e.getMainTitle());
|
|
|
+ dto.setAnswer(e.getAnswer());
|
|
|
+ return Stream.of(dto);
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 生成excel文件
|
|
|
+ ExcelUtil.excelExport("客观题标答模板", ObjectiveAnswerDto.class, datasource, response);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ @Override
|
|
|
+ public void objectiveAnswerSettingImport(Long examId, String paperNumber, MultipartFile file) throws Exception {
|
|
|
+ List<MarkQuestion> willEditList = new ArrayList<>();
|
|
|
+ // 试卷结构
|
|
|
+ List<MarkQuestion> datasource = this.listQuestionByExamIdAndPaperNumberAndGroupNumber(examId, paperNumber, null,
|
|
|
+ true);
|
|
|
+ ExcelResult<ObjectiveAnswerDto> excelResult = ConvertUtil.analyzeExcel(file.getInputStream(), ObjectiveAnswerDto.class,
|
|
|
+ false, 0);
|
|
|
+ if (!excelResult.isSuccess()) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception(excelResult.getErrorMsg());
|
|
|
+ }
|
|
|
+ // 逻辑异常
|
|
|
+ List<String> logicErrorList = new ArrayList<>();
|
|
|
+ List<ObjectiveAnswerDto> objectiveAnswerDtoList = excelResult.getDatasource();
|
|
|
+ if (!Objects.equals(datasource.size(), objectiveAnswerDtoList.size())) {
|
|
|
+ logicErrorList.add("试卷结构试题数量和导入文件中的试题数量不一致");
|
|
|
+ }
|
|
|
+ Set<String> questionNumberSet = new HashSet<>();
|
|
|
+ // 构建题号-试题结构map
|
|
|
+ Map<String, MarkQuestion> markQuestionMap = datasource.stream()
|
|
|
+ .collect(Collectors.toMap(k -> k.getMainNumber() + SystemConstant.HYPHEN + k.getSubNumber(), v -> v));
|
|
|
+
|
|
|
+ for (int i = 0; i < objectiveAnswerDtoList.size(); i++) {
|
|
|
+ int rowIndex = i + 2;
|
|
|
+ ObjectiveAnswerDto cell = objectiveAnswerDtoList.get(i);
|
|
|
+ int exMainNumber = Integer.parseInt(cell.getMainNumber());
|
|
|
+ int exSubNumber = Integer.parseInt(cell.getSubNumber());
|
|
|
+ String exMainTitle = cell.getMainTitle();
|
|
|
+ String exAnswer = cell.getAnswer();
|
|
|
+
|
|
|
+ String key = exMainNumber + SystemConstant.HYPHEN + exSubNumber;
|
|
|
+ String unifyNotice = String.format("第[%s]行,大题号[%s],小题号[%s]的试题", rowIndex, exMainNumber, exSubNumber);
|
|
|
+ List<String> rowException = new ArrayList<>();
|
|
|
+ if (questionNumberSet.contains(key)) {
|
|
|
+ // 题号重复检验
|
|
|
+ rowException.add("题号和前面重复");
|
|
|
+ } else {
|
|
|
+ questionNumberSet.add(key);
|
|
|
+ if (markQuestionMap.containsKey(key)) {
|
|
|
+ MarkQuestion markQuestion = markQuestionMap.get(key);
|
|
|
+ markQuestion.setAnswer(exAnswer);
|
|
|
+ willEditList.add(markQuestion);
|
|
|
+ String mainTitle = markQuestion.getMainTitle();
|
|
|
+ if (!Objects.equals(exMainTitle, mainTitle)) {
|
|
|
+ rowException.add(String.format("大题名称[%s]错误", exMainTitle));
|
|
|
+ } else {
|
|
|
+ Integer questionType = markQuestion.getQuestionType();
|
|
|
+ Integer optionCount = markQuestion.getOptionCount();
|
|
|
+ List<String> optionScope = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ for (int j = 1; j <= optionCount; j++) {
|
|
|
+ String code = OptionsEnum.getCodeByIndex(j);
|
|
|
+ optionScope.add(code);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception(
|
|
|
+ String.format("第[%s]行,大题号[%s],小题号[%s]的试题答案可选选项解析失败", rowIndex, exMainNumber,
|
|
|
+ exSubNumber));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 答案选项越界校验
|
|
|
+ List<String> answerList = Arrays.asList(exAnswer.split(""));
|
|
|
+ if (CollectionUtils.isNotEmpty(answerList)) {
|
|
|
+ for (String answer : answerList) {
|
|
|
+ String outOfBoundsException = String.format("答案[%s]错误。答案只能从[%s]中选择", answer, String.join("", optionScope));
|
|
|
+ try {
|
|
|
+ OptionsEnum optionsEnum = OptionsEnum.getByCode(answer);
|
|
|
+ int optionIndex = optionsEnum.getIndex();
|
|
|
+ if (optionIndex > optionCount) {
|
|
|
+ // 答案选项超出范围
|
|
|
+ rowException.add(outOfBoundsException);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ rowException.add(outOfBoundsException);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ rowException.add("答案必填");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 答案和题型匹配校验
|
|
|
+ if (Objects.equals(questionType, 1)) {
|
|
|
+ // 单选题
|
|
|
+ if (answerList.size() > 1) {
|
|
|
+ rowException.add(String.format("为[单选题],答案[%s]错误", exAnswer));
|
|
|
+ }
|
|
|
+ } else if (Objects.equals(questionType, 2)) {
|
|
|
+ // 多选题
|
|
|
+
|
|
|
+ } else if (Objects.equals(questionType, 3)) {
|
|
|
+ // 判断题
|
|
|
+ if (answerList.size() > 1) {
|
|
|
+ rowException.add(String.format("为[判断题],答案[%s]错误", exAnswer));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ rowException.add("试题题型错误");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ rowException.add("题号错误,试卷中不存在该题号");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (CollectionUtils.isNotEmpty(rowException)) {
|
|
|
+ unifyNotice = unifyNotice + String.join(",", rowException);
|
|
|
+ logicErrorList.add(unifyNotice);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (CollectionUtils.isNotEmpty(logicErrorList)) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception(String.join(";\n", logicErrorList));
|
|
|
+ }
|
|
|
+ this.saveOrUpdateBatch(willEditList);
|
|
|
+ }
|
|
|
+
|
|
|
@Transactional
|
|
|
@Override
|
|
|
public void saveObjectiveQuestions(MarkObjectiveQuestionParams markObjectiveQuestionParams) {
|