|
@@ -1,863 +1,868 @@
|
|
-package com.qmth.teachcloud.mark.service.impl;
|
|
|
|
-
|
|
|
|
-import com.alibaba.fastjson.JSON;
|
|
|
|
-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.core.metadata.IPage;
|
|
|
|
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
|
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
-import com.qmth.teachcloud.common.bean.dto.mark.MarkUser;
|
|
|
|
-import com.qmth.teachcloud.common.bean.dto.mark.ObjectiveAnswerDto;
|
|
|
|
-import com.qmth.teachcloud.common.bean.dto.mark.PictureConfig;
|
|
|
|
-import com.qmth.teachcloud.common.bean.params.mark.group.QuestionPictureConfigParams;
|
|
|
|
-import com.qmth.teachcloud.common.bean.result.ExcelResult;
|
|
|
|
-import com.qmth.teachcloud.common.bean.vo.FilePathVo;
|
|
|
|
-import com.qmth.teachcloud.common.contant.SystemConstant;
|
|
|
|
-import com.qmth.teachcloud.common.entity.MarkQuestion;
|
|
|
|
-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.bean.mark.DoubleMarkParam;
|
|
|
|
-import com.qmth.teachcloud.mark.bean.student.MarkStudentQuery;
|
|
|
|
-import com.qmth.teachcloud.mark.bean.vo.parseCard.pic.SubPictureConfig;
|
|
|
|
-import com.qmth.teachcloud.mark.dto.mark.MarkQuestionAnswerVo;
|
|
|
|
-import com.qmth.teachcloud.mark.dto.mark.MarkStudentVo;
|
|
|
|
-import com.qmth.teachcloud.mark.dto.mark.MarkPaperFileDto;
|
|
|
|
-import com.qmth.teachcloud.mark.dto.mark.manage.*;
|
|
|
|
-import com.qmth.teachcloud.mark.dto.mark.setting.MarkGroupTaskDto;
|
|
|
|
-import com.qmth.teachcloud.mark.dto.mark.setting.MarkQuestionDto;
|
|
|
|
-import com.qmth.teachcloud.mark.dto.mark.setting.MarkQuestionSubjectiveStepStatusDto;
|
|
|
|
-import com.qmth.teachcloud.mark.entity.MarkPaper;
|
|
|
|
-import com.qmth.teachcloud.mark.entity.MarkQuestionAnswer;
|
|
|
|
-import com.qmth.teachcloud.mark.entity.MarkTask;
|
|
|
|
-import com.qmth.teachcloud.mark.entity.MarkUserQuestion;
|
|
|
|
-import com.qmth.teachcloud.mark.enums.LockType;
|
|
|
|
-import com.qmth.teachcloud.mark.enums.MarkTaskStatus;
|
|
|
|
-import com.qmth.teachcloud.mark.lock.LockService;
|
|
|
|
-import com.qmth.teachcloud.mark.mapper.MarkQuestionMapper;
|
|
|
|
-import com.qmth.teachcloud.mark.params.MarkObjectiveQuestionParams;
|
|
|
|
-import com.qmth.teachcloud.mark.params.MarkQuestionParams;
|
|
|
|
-import com.qmth.teachcloud.mark.service.*;
|
|
|
|
-import com.qmth.teachcloud.mark.utils.Calculator;
|
|
|
|
-import com.qmth.teachcloud.mark.utils.CardParseUtils;
|
|
|
|
-import org.apache.commons.collections4.CollectionUtils;
|
|
|
|
-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.math.BigDecimal;
|
|
|
|
-import java.util.*;
|
|
|
|
-import java.util.stream.Collectors;
|
|
|
|
-import java.util.stream.Stream;
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * <p>
|
|
|
|
- * 小题信息表 服务实现类
|
|
|
|
- * </p>
|
|
|
|
- *
|
|
|
|
- * @author xf
|
|
|
|
- * @since 2023-09-22
|
|
|
|
- */
|
|
|
|
-@Service
|
|
|
|
-public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, MarkQuestion> implements MarkQuestionService {
|
|
|
|
-
|
|
|
|
- @Resource
|
|
|
|
- private TeachcloudCommonService teachcloudCommonService;
|
|
|
|
- @Resource
|
|
|
|
- private MarkPaperService markPaperService;
|
|
|
|
- @Resource
|
|
|
|
- private MarkQuestionAnswerService markQuestionAnswerService;
|
|
|
|
- @Resource
|
|
|
|
- private MarkUserQuestionService markUserQuestionService;
|
|
|
|
- @Resource
|
|
|
|
- private MarkUserClassService markUserClassService;
|
|
|
|
- @Resource
|
|
|
|
- private MarkStudentService markStudentService;
|
|
|
|
- @Resource
|
|
|
|
- private MarkTaskService markTaskService;
|
|
|
|
- @Resource
|
|
|
|
- private MarkArbitrateHistoryService markArbitrateHistoryService;
|
|
|
|
- @Resource
|
|
|
|
- private MarkService markService;
|
|
|
|
- @Resource
|
|
|
|
- private FileStoreUtil fileStoreUtil;
|
|
|
|
- @Resource
|
|
|
|
- private LockService lockService;
|
|
|
|
- @Resource
|
|
|
|
- private MarkSyncService markSyncService;
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public String assembleGroupQuestionsByExamIdAndPaperNumberAndNumber(Long examId, String paperNumber, Integer groupNumber) {
|
|
|
|
- return this.baseMapper.assembleQuestionsByExamIdAndPaperNumberAndNumber(examId, paperNumber, groupNumber);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<MarkQuestion> listQuestionByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
- QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
|
|
|
|
- LambdaQueryWrapper<MarkQuestion> lambdaQueryWrapper = queryWrapper.lambda();
|
|
|
|
- lambdaQueryWrapper.eq(MarkQuestion::getExamId, examId)
|
|
|
|
- .eq(MarkQuestion::getPaperNumber, paperNumber);
|
|
|
|
- lambdaQueryWrapper.orderByAsc(MarkQuestion::getMainNumber)
|
|
|
|
- .orderByAsc(MarkQuestion::getSubNumber);
|
|
|
|
- return this.list(queryWrapper);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Transactional
|
|
|
|
- @Override
|
|
|
|
- public void saveQuestions(MarkQuestionParams markQuestionParams) {
|
|
|
|
- SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
|
- Long examId = markQuestionParams.getExamId();
|
|
|
|
- String paperNumber = markQuestionParams.getPaperNumber();
|
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
-
|
|
|
|
- List<MarkQuestion> questions = markQuestionParams.getQuestions();
|
|
|
|
- if (CollectionUtils.isEmpty(questions)) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("没有可保存的结构数据");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 校验题号不能重复
|
|
|
|
- Map<String, Long> longMap = questions.stream().collect(Collectors.groupingBy(m -> m.getMainNumber() + SystemConstant.HYPHEN + m.getSubNumber(), Collectors.counting()));
|
|
|
|
- long count = longMap.entrySet().stream().filter(m -> m.getValue().intValue() > 1).count();
|
|
|
|
- if (count > 0) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("大题号-小题号有重复数据");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 查询已有结构信息
|
|
|
|
- List<MarkQuestion> markQuestionList = this.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- if (CollectionUtils.isEmpty(markQuestionList)) {
|
|
|
|
- for (MarkQuestion question : questions) {
|
|
|
|
- if (question.getTotalScore() < 0) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("小题满分不能小于0");
|
|
|
|
- }
|
|
|
|
- if (!question.getObjective() && (question.getIntervalScore() == null || question.getIntervalScore() <= 0)) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("间隔分必须大于0");
|
|
|
|
- }
|
|
|
|
- question.setExamId(examId);
|
|
|
|
- question.setPaperNumber(paperNumber);
|
|
|
|
- question.setPaperType(markPaper.getPaperType());
|
|
|
|
- question.setCreateId(sysUser.getId());
|
|
|
|
- question.setCreateTime(System.currentTimeMillis());
|
|
|
|
- // 用来判断是否保存过
|
|
|
|
- question.setUpdateId(sysUser.getId());
|
|
|
|
- question.setUpdateTime(System.currentTimeMillis());
|
|
|
|
- }
|
|
|
|
- this.saveBatch(questions);
|
|
|
|
- markQuestionAnswerService.deleteByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- markQuestionAnswerService.saveByMarkQuestion(examId, paperNumber, questions, false);
|
|
|
|
- } else {
|
|
|
|
- List<MarkQuestion> saveOrUpdateList = new ArrayList<>();
|
|
|
|
- for (MarkQuestion question : questions) {
|
|
|
|
- if (Objects.isNull(question.getId())) {
|
|
|
|
- question.setId(SystemConstant.getDbUuid());
|
|
|
|
- question.setExamId(examId);
|
|
|
|
- question.setPaperNumber(paperNumber);
|
|
|
|
- question.setPaperType(markPaper.getPaperType());
|
|
|
|
- saveOrUpdateList.add(question);
|
|
|
|
- } else {
|
|
|
|
- Optional<MarkQuestion> questionOptional = markQuestionList.stream().filter(m -> m.getId().equals(question.getId())).findFirst();
|
|
|
|
- if (questionOptional.isPresent()) {
|
|
|
|
- MarkQuestion markQuestion = questionOptional.get();
|
|
|
|
- if (markQuestion.getMarkedCount() != null && markQuestion.getMarkedCount() > 0 && markQuestion.getTotalScore() != null && markQuestion.getTotalScore().doubleValue() - question.getTotalScore().doubleValue() != 0) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("大题号" + markQuestion.getMainNumber() + "小题号" + markQuestion.getSubNumber() + "已阅卷,不能修改小题满分");
|
|
|
|
- }
|
|
|
|
- // 主观题改客观题
|
|
|
|
- if (markQuestion.getMarkedCount() != null && markQuestion.getMarkedCount() > 0 && !markQuestion.getObjective() && question.getObjective()) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("大题号" + markQuestion.getMainNumber() + "小题号" + markQuestion.getSubNumber() + "已阅卷,不能修改为客观题题型");
|
|
|
|
- }
|
|
|
|
- if (question.getTotalScore() < 0) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("小题满分不能小于0");
|
|
|
|
- }
|
|
|
|
- if (!QuestionType.findByValue(question.getQuestionType()).getObjective() && question.getIntervalScore() <= 0) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("间隔分必须大于0");
|
|
|
|
- }
|
|
|
|
- // 客观题变主观题
|
|
|
|
- if (markQuestion.getObjective() && !question.getObjective()) {
|
|
|
|
- // 清除判分策略
|
|
|
|
- markQuestionAnswerService.deleteByExamIdAndPaperNumberAndMainNumberAndSubNumber(examId, paperNumber, markQuestion.getMainNumber(), markQuestion.getSubNumber());
|
|
|
|
- }
|
|
|
|
- // 客观题
|
|
|
|
- if (question.getObjective()) {
|
|
|
|
- markQuestion.setOptionCount(question.getOptionCount());
|
|
|
|
- if (!markQuestion.getQuestionType().equals(question.getQuestionType())) {
|
|
|
|
- // 清除判分策略
|
|
|
|
- markQuestionAnswerService.resetObjectivePolicyByExamIdAndPaperNumberAndMainNumberAndSubNumber(examId, paperNumber, markQuestion.getMainNumber(), markQuestion.getSubNumber());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // 大题号
|
|
|
|
- markQuestion.setMainNumber(question.getMainNumber());
|
|
|
|
- // 小题号
|
|
|
|
- markQuestion.setSubNumber(question.getSubNumber());
|
|
|
|
- // 大题名称
|
|
|
|
- markQuestion.setMainTitle(question.getMainTitle());
|
|
|
|
- // 题型
|
|
|
|
- markQuestion.setQuestionType(question.getQuestionType());
|
|
|
|
- markQuestion.setObjective(question.getObjective());
|
|
|
|
- markQuestion.setTotalScore(question.getTotalScore());
|
|
|
|
- markQuestion.setIntervalScore(question.getIntervalScore());
|
|
|
|
- // 用来判断是否保存过
|
|
|
|
- markQuestion.setUpdateId(sysUser.getId());
|
|
|
|
- markQuestion.setUpdateTime(System.currentTimeMillis());
|
|
|
|
- saveOrUpdateList.add(markQuestion);
|
|
|
|
- markQuestionList.remove(markQuestion);
|
|
|
|
- } else {
|
|
|
|
- question.setId(SystemConstant.getDbUuid());
|
|
|
|
- question.setExamId(examId);
|
|
|
|
- question.setPaperNumber(paperNumber);
|
|
|
|
- question.setPaperType(markPaper.getPaperType());
|
|
|
|
- question.setCreateId(sysUser.getId());
|
|
|
|
- question.setCreateTime(System.currentTimeMillis());
|
|
|
|
- // 用来判断是否保存过
|
|
|
|
- question.setUpdateId(sysUser.getId());
|
|
|
|
- question.setUpdateTime(System.currentTimeMillis());
|
|
|
|
- saveOrUpdateList.add(question);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // 删除的结构
|
|
|
|
- if (CollectionUtils.isNotEmpty(markQuestionList)) {
|
|
|
|
- List<Long> deleteIds = markQuestionList.stream().map(MarkQuestion::getId).collect(Collectors.toList());
|
|
|
|
- this.removeByIds(deleteIds);
|
|
|
|
-
|
|
|
|
- markQuestionList.stream().filter(m -> m.getObjective()).forEach(m -> {
|
|
|
|
- markQuestionAnswerService.deleteByExamIdAndPaperNumberAndMainNumberAndSubNumber(examId, paperNumber, m.getMainNumber(), m.getSubNumber());
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- this.saveOrUpdateBatch(saveOrUpdateList);
|
|
|
|
- markQuestionAnswerService.saveByMarkQuestion(examId, paperNumber, saveOrUpdateList, false);
|
|
|
|
- }
|
|
|
|
- // 更新客观题满分、主观题满分、总分
|
|
|
|
- List<MarkQuestion> markQuestions = this.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- Double objectiveScore = markQuestions.stream().filter(m -> m.getObjective()).collect(Collectors.summingDouble(m -> m.getTotalScore()));
|
|
|
|
- Double subjectiveScore = markQuestions.stream().filter(m -> !m.getObjective()).collect(Collectors.summingDouble(m -> m.getTotalScore()));
|
|
|
|
- Double totalScore = markQuestions.stream().collect(Collectors.summingDouble(m -> m.getTotalScore()));
|
|
|
|
- UpdateWrapper<MarkPaper> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(MarkPaper::getObjectiveScore, objectiveScore)
|
|
|
|
- .set(MarkPaper::getSubjectiveScore, subjectiveScore)
|
|
|
|
- .set(MarkPaper::getTotalScore, totalScore)
|
|
|
|
- .set(MarkPaper::getQuestionStatus, true)
|
|
|
|
- .eq(MarkPaper::getExamId, examId)
|
|
|
|
- .eq(MarkPaper::getPaperNumber, paperNumber);
|
|
|
|
- markPaperService.update(updateWrapper);
|
|
|
|
-
|
|
|
|
- // 主观题结构有变动
|
|
|
|
- List<MarkQuestion> subjectiveQuestions = questions.stream().filter(m -> m.getObjective()).collect(Collectors.toList());
|
|
|
|
- List<MarkQuestion> subjectiveMarkQuestionList = markQuestionList.stream().filter(m -> m.getObjective()).collect(Collectors.toList());
|
|
|
|
- if (!CollectionUtils.isEqualCollection(subjectiveQuestions, subjectiveMarkQuestionList)) {
|
|
|
|
- // 未分组的题目
|
|
|
|
-// long unGroupQuestionCount = this.countByExamIdAndPaperNumberAndObjectiveAndGroupNumberIsNull(examId, paperNumber, false);
|
|
|
|
-// // 考生主观题重新统分
|
|
|
|
-// markService.checkStudentSubjectiveScore(examId, markPaper.getCoursePaperId(), unGroupQuestionCount);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 更新分组状态
|
|
|
|
- markService.updateMarkGroupStatus(examId, paperNumber);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public void objectiveAnswerSettingModelExport(Long examId, String paperNumber, String paperType, HttpServletResponse response)
|
|
|
|
- throws Exception {
|
|
|
|
- List<MarkQuestionAnswerVo> datasource = this.listQuestionAnswerByExamIdAndPaperNumberAndPaperType(examId, paperNumber,
|
|
|
|
- paperType, true);
|
|
|
|
- List<ObjectiveAnswerDto> objectiveAnswerDtoList = datasource.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, objectiveAnswerDtoList, response);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Transactional
|
|
|
|
- @Override
|
|
|
|
- public void objectiveAnswerSettingImport(Long examId, String paperNumber, String paperType, MultipartFile file) throws Exception {
|
|
|
|
- // 试卷结构
|
|
|
|
- List<MarkQuestionAnswer> datasource = markQuestionAnswerService.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, paperType);
|
|
|
|
- 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<String, MarkQuestion> markQuestionMap = this.listQuestionByExamIdAndPaperNumber(examId, paperNumber).stream().collect(Collectors.toMap(k -> k.getMainNumber() + SystemConstant.HYPHEN + k.getSubNumber(), v -> v));
|
|
|
|
- // 构建题号-试题结构map
|
|
|
|
- Map<String, MarkQuestionAnswer> markQuestionAnswerMapMap = datasource.stream().collect(Collectors.toMap(k -> k.getMainNumber() + SystemConstant.HYPHEN + k.getSubNumber(), v -> v));
|
|
|
|
-
|
|
|
|
- List<MarkQuestionAnswer> willEditList = new ArrayList<>();
|
|
|
|
- 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 (markQuestionAnswerMapMap.containsKey(key)) {
|
|
|
|
- MarkQuestionAnswer markQuestion = markQuestionAnswerMapMap.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 = markQuestionMap.get(key).getQuestionType();
|
|
|
|
- Integer optionCount = markQuestionMap.get(key).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));
|
|
|
|
- }
|
|
|
|
- markQuestionAnswerService.saveOrUpdateBatch(willEditList);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Transactional
|
|
|
|
- @Override
|
|
|
|
- public void saveObjectiveQuestions(MarkObjectiveQuestionParams markObjectiveQuestionParams) {
|
|
|
|
- for (MarkQuestionAnswer answer : markObjectiveQuestionParams.getObjectiveInfo()) {
|
|
|
|
- if (StringUtils.isBlank(answer.getAnswer())) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("答案不能为空");
|
|
|
|
- }
|
|
|
|
- if (answer.getObjectivePolicy() != null && answer.getObjectivePolicy().equals(ObjectivePolicy.LEAK)) {
|
|
|
|
- if (answer.getObjectivePolicyScore() == null) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("漏选给分不能没有计分规则");
|
|
|
|
- }
|
|
|
|
- if (answer.getObjectivePolicyScore() > (answer.getTotalScore() / answer.getAnswer().length())) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("漏选给分计分规则有误");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- UpdateWrapper<MarkQuestionAnswer> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(MarkQuestionAnswer::getAnswer, answer.getAnswer())
|
|
|
|
- .set(MarkQuestionAnswer::getUpdateTime, System.currentTimeMillis());
|
|
|
|
- if (answer.getObjectivePolicy() != null) {
|
|
|
|
- updateWrapper.lambda().set(MarkQuestionAnswer::getObjectivePolicy, answer.getObjectivePolicy());
|
|
|
|
- }
|
|
|
|
- if (answer.getObjectivePolicyScore() != null) {
|
|
|
|
- updateWrapper.lambda().set(MarkQuestionAnswer::getObjectivePolicyScore, answer.getObjectivePolicyScore());
|
|
|
|
- }
|
|
|
|
- updateWrapper.lambda().eq(MarkQuestionAnswer::getId, answer.getId());
|
|
|
|
- markQuestionAnswerService.update(updateWrapper);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 统分
|
|
|
|
- markStudentService.calcObjectiveScore(markObjectiveQuestionParams.getExamId(), markObjectiveQuestionParams.getPaperNumber());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public String uploadSubjectiveFile(Long examId, String paperNumber, String paperType, MultipartFile file, String md5) {
|
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- if (markPaper == null) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("课程不存在");
|
|
|
|
- }
|
|
|
|
- List<MarkPaperFileDto> subjectiveAnswerFileDtoList = new ArrayList<>();
|
|
|
|
- if (StringUtils.isNotBlank(markPaper.getAnswerFilePath())) {
|
|
|
|
- subjectiveAnswerFileDtoList = JSON.parseArray(markPaper.getAnswerFilePath(), MarkPaperFileDto.class);
|
|
|
|
- }
|
|
|
|
- String answerFilePath = fileStoreUtil.uploadFile(file, md5, UploadFileEnum.PDF);
|
|
|
|
-
|
|
|
|
- MarkPaperFileDto subjectiveAnswerFileDto = null;
|
|
|
|
- for (MarkPaperFileDto answerFileDto : subjectiveAnswerFileDtoList) {
|
|
|
|
- if (paperType.equals(answerFileDto.getPaperType())) {
|
|
|
|
- answerFileDto.setFilePathVo(JSON.parseObject(answerFilePath, FilePathVo.class));
|
|
|
|
- subjectiveAnswerFileDto = answerFileDto;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (subjectiveAnswerFileDto == null) {
|
|
|
|
- subjectiveAnswerFileDto = new MarkPaperFileDto();
|
|
|
|
- subjectiveAnswerFileDto.setPaperType(paperType);
|
|
|
|
- subjectiveAnswerFileDto.setFilePathVo(JSON.parseObject(answerFilePath, FilePathVo.class));
|
|
|
|
- subjectiveAnswerFileDtoList.add(subjectiveAnswerFileDto);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- UpdateWrapper<MarkPaper> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(MarkPaper::getAnswerFilePath, JSON.toJSONString(subjectiveAnswerFileDtoList))
|
|
|
|
- .eq(MarkPaper::getExamId, examId)
|
|
|
|
- .eq(MarkPaper::getPaperNumber, paperNumber);
|
|
|
|
- markPaperService.update(updateWrapper);
|
|
|
|
- return teachcloudCommonService.filePreview(answerFilePath);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<MarkPaperFileDto> previewAnswerFileByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- List<MarkPaperFileDto> markPaperFileDtos = new ArrayList<>();
|
|
|
|
- if (markPaper != null && StringUtils.isNotBlank(markPaper.getAnswerFilePath())) {
|
|
|
|
- markPaperFileDtos = JSON.parseArray(markPaper.getAnswerFilePath(), MarkPaperFileDto.class);
|
|
|
|
- for (MarkPaperFileDto markPaperFileDto : markPaperFileDtos) {
|
|
|
|
- markPaperFileDto.setUrl(teachcloudCommonService.filePreview(JSON.toJSONString(markPaperFileDto.getFilePathVo())));
|
|
|
|
- markPaperFileDto.setFilePathVo(null);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return markPaperFileDtos;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<MarkPaperFileDto> previewPaperFileByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- List<MarkPaperFileDto> markPaperFileDtos = new ArrayList<>();
|
|
|
|
- if (markPaper != null && StringUtils.isNotBlank(markPaper.getPaperFilePath())) {
|
|
|
|
- markPaperFileDtos = JSON.parseArray(markPaper.getPaperFilePath(), MarkPaperFileDto.class);
|
|
|
|
- for (MarkPaperFileDto markPaperFileDto : markPaperFileDtos) {
|
|
|
|
- markPaperFileDto.setUrl(teachcloudCommonService.filePreview(JSON.toJSONString(markPaperFileDto.getFilePathVo())));
|
|
|
|
- markPaperFileDto.setFilePathVo(null);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return markPaperFileDtos;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<MarkQuestion> listByExamIdAndPaperNumberAndPaperIndexAndPageIndex(Long examId, String paperNumber,
|
|
|
|
- Integer paperIndex, Integer pageIndex, boolean isObjective) {
|
|
|
|
- QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
|
|
|
|
- queryWrapper.lambda().eq(MarkQuestion::getExamId, examId)
|
|
|
|
- .eq(MarkQuestion::getPaperNumber, paperNumber)
|
|
|
|
- .eq(MarkQuestion::getPaperIndex, paperIndex)
|
|
|
|
- .eq(MarkQuestion::getPageIndex, pageIndex)
|
|
|
|
- .eq(MarkQuestion::getObjective, isObjective)
|
|
|
|
- .orderByAsc(MarkQuestion::getMainNumber)
|
|
|
|
- .orderByAsc(MarkQuestion::getSubNumber);
|
|
|
|
- return this.list(queryWrapper);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public MarkQuestionDto pageQuestionsByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
- MarkQuestionDto markQuestionDto = new MarkQuestionDto();
|
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- // 试卷结构,默认只取A卷
|
|
|
|
- List<MarkQuestion> markQuestionList = this.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- markQuestionDto.setQuestionSubmit(markPaper.getQuestionStatus());
|
|
|
|
- markQuestionDto.setObjectiveSubmit(markQuestionAnswerService.countByExamIdAndPaperNumber(examId, paperNumber) > 0);
|
|
|
|
- markQuestionDto.setQuestions(markQuestionList);
|
|
|
|
- return markQuestionDto;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public long countByExamIdAndPaperNumberAndObjectiveAndGroupNumberIsNull(Long examId, String paperNumber, boolean objective) {
|
|
|
|
- // todo 2025-02-25
|
|
|
|
-// QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
|
|
|
|
-// queryWrapper.lambda().eq(MarkQuestion::getExamId, examId)
|
|
|
|
-// .eq(MarkQuestion::getPaperNumber, paperNumber)
|
|
|
|
-// .eq(MarkQuestion::getObjective, objective)
|
|
|
|
-// .isNull(MarkQuestion::getGroupNumber);
|
|
|
|
-// return this.count(queryWrapper);
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<MarkQuestion> listByExamIdAndPaperNumberAndObjective(Long examId, String paperNumber, Boolean objective) {
|
|
|
|
- QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
|
|
|
|
- LambdaQueryWrapper<MarkQuestion> lambdaQueryWrapper = queryWrapper.lambda();
|
|
|
|
- lambdaQueryWrapper.eq(MarkQuestion::getExamId, examId)
|
|
|
|
- .eq(MarkQuestion::getPaperNumber, paperNumber)
|
|
|
|
- .eq(MarkQuestion::getObjective, objective);
|
|
|
|
- lambdaQueryWrapper.orderByAsc(MarkQuestion::getMainNumber)
|
|
|
|
- .orderByAsc(MarkQuestion::getSubNumber);
|
|
|
|
- return this.list(queryWrapper);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public void deleteByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
- UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().eq(MarkQuestion::getExamId, examId)
|
|
|
|
- .eq(MarkQuestion::getPaperNumber, paperNumber);
|
|
|
|
- this.remove(updateWrapper);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Transactional
|
|
|
|
- @Override
|
|
|
|
- public void updateMarkPaperScore(Long examId, String paperNumber) {
|
|
|
|
- List<MarkQuestion> markQuestions = this.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- Double objectiveScore = markQuestions.stream().filter(MarkQuestion::getObjective)
|
|
|
|
- .mapToDouble(MarkQuestion::getTotalScore).sum();
|
|
|
|
- Double subjectiveScore = markQuestions.stream().filter(m -> !m.getObjective())
|
|
|
|
- .mapToDouble(MarkQuestion::getTotalScore).sum();
|
|
|
|
- Double totalScore = markQuestions.stream().mapToDouble(MarkQuestion::getTotalScore).sum();
|
|
|
|
- UpdateWrapper<MarkPaper> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(MarkPaper::getObjectiveScore, objectiveScore)
|
|
|
|
- .set(MarkPaper::getSubjectiveScore, subjectiveScore)
|
|
|
|
- .set(MarkPaper::getTotalScore, totalScore)
|
|
|
|
- .eq(MarkPaper::getExamId, examId)
|
|
|
|
- .eq(MarkPaper::getPaperNumber, paperNumber);
|
|
|
|
- markPaperService.update(updateWrapper);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<MarkQuestionAnswerVo> listQuestionAnswerByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType, Boolean objective) {
|
|
|
|
- return this.baseMapper.listQuestionAnswerByExamIdAndPaperNumberAndPaperType(examId, paperNumber, paperType, objective);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<MarkQuestion> listByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
- QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
|
|
|
|
- queryWrapper.lambda().eq(MarkQuestion::getExamId, examId)
|
|
|
|
- .eq(MarkQuestion::getPaperNumber, paperNumber);
|
|
|
|
- return this.list(queryWrapper);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public void deleteByExamIdAndPaperNumberAndObjective(Long examId, String paperNumber, boolean objective) {
|
|
|
|
- UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().eq(MarkQuestion::getExamId, examId)
|
|
|
|
- .eq(MarkQuestion::getPaperNumber, paperNumber)
|
|
|
|
- .eq(MarkQuestion::getObjective, objective);
|
|
|
|
- this.remove(updateWrapper);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public MarkGroupTaskDto listGroupTaskByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
- MarkGroupTaskDto markGroupTaskDto = new MarkGroupTaskDto();
|
|
|
|
- markGroupTaskDto.setExamId(examId);
|
|
|
|
- markGroupTaskDto.setPaperNumber(paperNumber);
|
|
|
|
-
|
|
|
|
- // 主观题信息
|
|
|
|
- List<MarkQuestion> markQuestionList = listByExamIdAndPaperNumberAndObjective(examId, paperNumber, false);
|
|
|
|
- for (MarkQuestion m : markQuestionList) {
|
|
|
|
- if (StringUtils.isNotBlank(m.getPicList())) {
|
|
|
|
- m.setPictureConfigs(JSON.parseArray(m.getPicList(), PictureConfig.class));
|
|
|
|
- }
|
|
|
|
- // 评卷员
|
|
|
|
- List<MarkUser> markUserList = markUserQuestionService.listGroupUserByExamIdAndPaperNumberAndQuestionIdAndClassName(examId, paperNumber, m.getId(), null);
|
|
|
|
- m.setMarkers(markUserList.stream().filter(MarkUser::getEnable).collect(Collectors.toList()));
|
|
|
|
- }
|
|
|
|
- markGroupTaskDto.setQuestions(markQuestionList);
|
|
|
|
- // 分班阅参数
|
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- markGroupTaskDto.setClassMark(markPaper != null && markPaper.getClassMark());
|
|
|
|
- markGroupTaskDto.setDoubleMark(markPaper != null && markPaper.getDoubleMark());
|
|
|
|
- markGroupTaskDto.setMergeMarker(markPaper != null && markPaper.getMergeMarker());
|
|
|
|
- return markGroupTaskDto;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public void updatePicListByQuestionId(QuestionPictureConfigParams questionPictureConfigParams) {
|
|
|
|
- List<PictureConfig> pictureConfigs = questionPictureConfigParams.getPictureConfigs();
|
|
|
|
- if (CollectionUtils.isEmpty(pictureConfigs)) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("没有评卷区数据");
|
|
|
|
- }
|
|
|
|
- UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(MarkQuestion::getPicList, JSON.toJSONString(pictureConfigs))
|
|
|
|
- .in(MarkQuestion::getId, questionPictureConfigParams.getQuestionIds());
|
|
|
|
- this.update(updateWrapper);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public Integer countCurrentCountByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
- int total = 0;
|
|
|
|
- List<MarkQuestion> markQuestionList = this.listByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- if (CollectionUtils.isNotEmpty(markQuestionList)) {
|
|
|
|
- for (MarkQuestion markQuestion : markQuestionList) {
|
|
|
|
- total += markService.applyCurrentCount(markQuestion);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return total;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public MarkGroupSummaryProgressDto summaryGroupProgress(Long examId, String paperNumber) {
|
|
|
|
- MarkGroupSummaryProgressDto markGroupSummaryProgressDto = new MarkGroupSummaryProgressDto();
|
|
|
|
-
|
|
|
|
- // totalInfo
|
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- if (markPaper == null) {
|
|
|
|
- return markGroupSummaryProgressDto;
|
|
|
|
- }
|
|
|
|
- markGroupSummaryProgressDto.setClassMark(markPaper.getClassMark());
|
|
|
|
- MarkGroupTotalProgressDto markGroupTotalProgressDto = new MarkGroupTotalProgressDto();
|
|
|
|
- markGroupTotalProgressDto.setStudentCount(markPaper.getStudentCount());
|
|
|
|
- markGroupTotalProgressDto.setUploadCount(markStudentService.countUploadedByExamIdAndPaperNumber(examId, paperNumber));
|
|
|
|
- markGroupTotalProgressDto.setAbsentCount(markStudentService.countAbsentByExamIdAndPaperNumber(examId, paperNumber));
|
|
|
|
-
|
|
|
|
- int totalCount = markTaskService.countByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- int markedCount = markTaskService.countByExamIdAndPaperNumberAndStatusIn(examId, paperNumber, Arrays.asList(MarkTaskStatus.MARKED, MarkTaskStatus.ARBITRATED));
|
|
|
|
- markGroupTotalProgressDto.setPercent(Calculator.divide2String(Calculator.multiply(markedCount, 100), Double.valueOf(totalCount), 2));
|
|
|
|
- markGroupSummaryProgressDto.setTotalInfo(markGroupTotalProgressDto);
|
|
|
|
-
|
|
|
|
- // groupInfo
|
|
|
|
- List<MarkGroupProgressDto> markGroupProgressDtoList = new ArrayList<>();
|
|
|
|
- List<MarkQuestion> markQuestionList = this.listByExamIdAndPaperNumberAndObjective(examId, paperNumber, false);
|
|
|
|
- for (MarkQuestion markQuestion : markQuestionList) {
|
|
|
|
- MarkGroupProgressDto markGroupProgressDto = new MarkGroupProgressDto();
|
|
|
|
- markGroupProgressDto.setQuestionId(markQuestion.getId());
|
|
|
|
- markGroupProgressDto.setTotalScore(markQuestion.getTotalScore());
|
|
|
|
- markGroupProgressDto.setQuestionNumber(markQuestion.getQuestionNumber());
|
|
|
|
- List<MarkUser> markUserList = markUserQuestionService.listGroupUserByExamIdAndPaperNumberAndQuestionIdAndClassName(examId, paperNumber, markQuestion.getId(), null);
|
|
|
|
- markGroupProgressDto.setMarkerCount(markUserList.size());
|
|
|
|
- markGroupProgressDto.setTaskCount(markQuestion.getTaskCount());
|
|
|
|
- markGroupProgressDto.setMarkedCount(markQuestion.getMarkedCount());
|
|
|
|
- markGroupProgressDto.setLeftCount(markGroupProgressDto.getTaskCount() - markGroupProgressDto.getMarkedCount());
|
|
|
|
- markGroupProgressDto.setCurrentCount(markService.applyCurrentCount(markQuestion));
|
|
|
|
- markGroupProgressDto.setPercent(Calculator.divide2String(Calculator.multiply(markGroupProgressDto.getMarkedCount(), 100), Double.valueOf(markGroupProgressDto.getTaskCount()), 2));
|
|
|
|
- markGroupProgressDto.setArbitrateCount(markArbitrateHistoryService.waitArbitrateCount(examId, paperNumber, markQuestion.getId(), null));
|
|
|
|
- markGroupProgressDtoList.add(markGroupProgressDto);
|
|
|
|
- }
|
|
|
|
- markGroupSummaryProgressDto.setGroupInfo(markGroupProgressDtoList);
|
|
|
|
- return markGroupSummaryProgressDto;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public IPage<MarkGroupClassProgressDto> summaryGroupClassProgress(Long examId, String paperNumber, String className, Integer pageNumber, Integer pageSize) {
|
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- if (markPaper.getClassMark()) {
|
|
|
|
- Page<MarkGroupClassProgressDto> page = new Page<>(pageNumber, pageSize);
|
|
|
|
- IPage<MarkGroupClassProgressDto> markGroupClassProgressDtoIPage = markUserClassService.pageClassByExamIdAndPaperNumber(page, examId, paperNumber, className);
|
|
|
|
- for (MarkGroupClassProgressDto markGroupClassProgressDto : markGroupClassProgressDtoIPage.getRecords()) {
|
|
|
|
- Long questionId = markGroupClassProgressDto.getQuestionId();
|
|
|
|
- List<MarkTask> totalMarkTaskList = new ArrayList<>();
|
|
|
|
- List<MarkUser> totalMarkUserList = new ArrayList<>();
|
|
|
|
- totalMarkTaskList.addAll(markTaskService.listByExamIdAndPaperNumberAndQuestionIdAndUserIdAndClassName(examId, paperNumber, questionId, null, markGroupClassProgressDto.getClassName()));
|
|
|
|
- totalMarkUserList.addAll(markUserQuestionService.listGroupUserByExamIdAndPaperNumberAndQuestionIdAndClassName(examId, paperNumber, questionId, markGroupClassProgressDto.getClassName()));
|
|
|
|
-
|
|
|
|
- MarkQuestion markQuestion = this.getById(questionId);
|
|
|
|
- List<MarkUser> markUserList = markUserClassService.listClassMarkerByExamIdAndPaperNumberAndQuestionIdAndClassName(examId, paperNumber, questionId, markGroupClassProgressDto.getClassName());
|
|
|
|
- int count = 0;
|
|
|
|
- for (MarkUser markUser : markUserList) {
|
|
|
|
- MarkUserQuestion markUserQuestion = markUserQuestionService.getByExamIdAndPaperNumberAndQuestionIdAndUserId(examId, paperNumber, questionId, markUser.getUserId());
|
|
|
|
- if (markUserQuestion != null) {
|
|
|
|
- int markerCount = markService.applyCurrentCount(markQuestion, markUserQuestion.getId());
|
|
|
|
- count += markerCount;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 待仲裁数量
|
|
|
|
- int arbitrateCount = markArbitrateHistoryService.waitArbitrateCount(examId, paperNumber, questionId, markGroupClassProgressDto.getClassName());
|
|
|
|
- markGroupClassProgressDto.setQuestionNumber(markQuestion.getQuestionNumber());
|
|
|
|
- markGroupClassProgressDto.setMarkerCount(totalMarkUserList.size());
|
|
|
|
- markGroupClassProgressDto.setTaskCount(totalMarkTaskList.size());
|
|
|
|
- markGroupClassProgressDto.setMarkedCount(markTaskService.markedCount(totalMarkTaskList));
|
|
|
|
- markGroupClassProgressDto.setLeftCount(markGroupClassProgressDto.getTaskCount() - markGroupClassProgressDto.getMarkedCount());
|
|
|
|
- markGroupClassProgressDto.setCurrentCount(count);
|
|
|
|
- markGroupClassProgressDto.setPercent(Calculator.divide2String(Calculator.multiply(markGroupClassProgressDto.getMarkedCount(), 100), Double.valueOf(markGroupClassProgressDto.getTaskCount()), 2));
|
|
|
|
- markGroupClassProgressDto.setArbitrateCount(arbitrateCount);
|
|
|
|
- }
|
|
|
|
- return markGroupClassProgressDtoIPage;
|
|
|
|
- }
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<MarkGroupQuestionsDto> listGroupQuestions(Long examId, String paperNumber) {
|
|
|
|
- List<MarkQuestion> markQuestionList = this.listByExamIdAndPaperNumberAndObjective(examId, paperNumber, false);
|
|
|
|
- List<MarkGroupQuestionsDto> markGroupQuestionsDtoList = new ArrayList<>();
|
|
|
|
- for (MarkQuestion markQuestion : markQuestionList) {
|
|
|
|
- MarkGroupQuestionsDto markGroupQuestionsDto = new MarkGroupQuestionsDto();
|
|
|
|
- markGroupQuestionsDto.setQuestionId(markQuestion.getId());
|
|
|
|
- markGroupQuestionsDto.setQuestionNumber(markQuestion.getQuestionNumber());
|
|
|
|
- markGroupQuestionsDtoList.add(markGroupQuestionsDto);
|
|
|
|
- }
|
|
|
|
- return markGroupQuestionsDtoList;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public void updateTaskCount(Long questionId, int taskCount) {
|
|
|
|
- UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(MarkQuestion::getTaskCount, taskCount)
|
|
|
|
- .eq(MarkQuestion::getId, questionId);
|
|
|
|
- this.update(updateWrapper);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public void updateMarkedCount(Long questionId, int count) {
|
|
|
|
- UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(MarkQuestion::getMarkedCount, count)
|
|
|
|
- .eq(MarkQuestion::getId, questionId);
|
|
|
|
- this.update(updateWrapper);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public void updateDoubleMarkByQuestionId(DoubleMarkParam doubleMarkParam) {
|
|
|
|
- Long examId = doubleMarkParam.getExamId();
|
|
|
|
- String paperNumber = doubleMarkParam.getPaperNumber();
|
|
|
|
- Long questionId = doubleMarkParam.getQuestionId();
|
|
|
|
- List<MarkTaskStatus> markTaskStatuses = Arrays.asList(MarkTaskStatus.MARKED, MarkTaskStatus.WAIT_ARBITRATE, MarkTaskStatus.PROBLEM, MarkTaskStatus.REJECTED, MarkTaskStatus.ARBITRATED);
|
|
|
|
- if (markTaskService.countByExamIdAndPaperNumberAndQuestionIdAndStatusIn(examId, paperNumber, questionId, markTaskStatuses) > 0) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("该题已开始评卷,不允许修改");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- MarkQuestion markQuestion = this.getById(questionId);
|
|
|
|
-
|
|
|
|
- UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(MarkQuestion::getDoubleRate, doubleMarkParam.getDoubleRate())
|
|
|
|
- .set(MarkQuestion::getArbitrateThreshold, doubleMarkParam.getArbitrateThreshold())
|
|
|
|
- .set(MarkQuestion::getScorePolicy, doubleMarkParam.getScorePolicy())
|
|
|
|
- .eq(MarkQuestion::getId, doubleMarkParam.getQuestionId());
|
|
|
|
- this.update(updateWrapper);
|
|
|
|
-
|
|
|
|
- // 单、又评切换、双评比例修改,删除任务
|
|
|
|
- if (!markQuestion.getDoubleRate().equals(doubleMarkParam.getDoubleRate())) {
|
|
|
|
- this.updateMarkedCount(questionId, 0);
|
|
|
|
- this.updateTaskCount(questionId, 0);
|
|
|
|
- if (lockService.trylock(LockType.QUESTION_UPDATE, questionId)) {
|
|
|
|
- markSyncService.deleteMarkTask(markQuestion);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public MarkQuestionSubjectiveStepStatusDto stepStatus(Long examId, String paperNumber) {
|
|
|
|
- List<MarkQuestion> markQuestionList = this.listByExamIdAndPaperNumberAndObjective(examId, paperNumber, false);
|
|
|
|
- Boolean subjectiveStruct = false, subjectiveMarker = false, subjectiveMarkerClass = false, objectiveAnswer = false;
|
|
|
|
- if (CollectionUtils.isNotEmpty(markQuestionList)) {
|
|
|
|
- // 主观题结构,小题分是否设置
|
|
|
|
- long countStruct = markQuestionList.stream().filter(m -> m.getTotalScore() == null || m.getIntervalScore() == null).count();
|
|
|
|
- subjectiveStruct = countStruct == 0;
|
|
|
|
-
|
|
|
|
- if (subjectiveStruct) {
|
|
|
|
- // 主观题设置评卷员
|
|
|
|
- long countPic = markQuestionList.stream().filter(m -> StringUtils.isBlank(m.getPicList())).count();
|
|
|
|
- subjectiveMarker = countPic == 0;
|
|
|
|
- if (subjectiveMarker) {
|
|
|
|
- for (MarkQuestion markQuestion : markQuestionList) {
|
|
|
|
- List<MarkUserQuestion> markUserQuestionList = markUserQuestionService.listByExamIdAndPaperNumberAndQuestionId(examId, paperNumber, markQuestion.getId());
|
|
|
|
- if (CollectionUtils.isEmpty(markUserQuestionList)) {
|
|
|
|
- subjectiveMarker = false;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (subjectiveMarker) {
|
|
|
|
- // 分班阅
|
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
- subjectiveMarkerClass = markPaper != null && markPaper.getClassMark();
|
|
|
|
- if (subjectiveMarkerClass) {
|
|
|
|
- MarkStudentQuery markStudentQuery = new MarkStudentQuery();
|
|
|
|
- markStudentQuery.setExamId(examId);
|
|
|
|
- markStudentQuery.setPaperNumber(paperNumber);
|
|
|
|
- List<MarkStudentVo> markStudentList = markStudentService.listMarkStudentVo(markStudentQuery);
|
|
|
|
- List<String> teachClasses = markStudentList.stream().filter(m -> StringUtils.isNotBlank(m.getTeachClassName())).map(MarkStudentVo::getTeachClassName).distinct().collect(Collectors.toList());
|
|
|
|
- for (MarkQuestion markQuestion : markQuestionList) {
|
|
|
|
- List<String> classNames = markUserQuestionService.countClassByExamIdAndPaperNumberAndQuestionId(examId, paperNumber, markQuestion.getId());
|
|
|
|
- if (!CollectionUtils.isEqualCollection(teachClasses, classNames)) {
|
|
|
|
- subjectiveMarkerClass = false;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (subjectiveMarkerClass) {
|
|
|
|
- // 客观题标答
|
|
|
|
- List<MarkQuestionAnswer> markQuestionAnswerList = markQuestionAnswerService.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, null);
|
|
|
|
- long countAnswer = markQuestionAnswerList.stream().filter(m -> StringUtils.isBlank(m.getAnswer()) || m.getObjectivePolicy() == null).count();
|
|
|
|
- objectiveAnswer = countAnswer == 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return new MarkQuestionSubjectiveStepStatusDto(subjectiveStruct, subjectiveMarker, subjectiveMarkerClass, objectiveAnswer);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public void updatePic(String content, List<MarkQuestion> markQuestions) {
|
|
|
|
- List<SubPictureConfig> pictureConfigs = CardParseUtils.parseCardPic(content, markQuestions);
|
|
|
|
- List<SubPictureConfig> subPictureConfigList;
|
|
|
|
- for (MarkQuestion markQuestion : markQuestions) {
|
|
|
|
- // 填空题区域为一个整体
|
|
|
|
- if (markQuestion.getQuestionType() == 4) {
|
|
|
|
- subPictureConfigList = pictureConfigs.stream().filter(m -> m.getMainNumber().equals(markQuestion.getMainNumber())).collect(Collectors.toList());
|
|
|
|
- } else {
|
|
|
|
- subPictureConfigList = pictureConfigs.stream().filter(m -> m.getQuestionNumber().equals(markQuestion.getQuestionNumber())).collect(Collectors.toList());
|
|
|
|
- }
|
|
|
|
- markQuestion.setPicList(SubPictureConfig.transfer(subPictureConfigList));
|
|
|
|
- }
|
|
|
|
- this.updateBatchById(markQuestions);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public long countUnBindMarkerByExamIdAndPaperNumberAndObjective(Long examId, String paperNumber, boolean objective) {
|
|
|
|
- return this.baseMapper.countUnBindMarkerByExamIdAndPaperNumberAndObjective(examId, paperNumber, objective);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public long countByExamIdAndPaperNumberAndObjective(Long examId, String paperNumber, boolean objective) {
|
|
|
|
- QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
|
|
|
|
- queryWrapper.lambda().eq(MarkQuestion::getExamId, examId)
|
|
|
|
- .eq(MarkQuestion::getPaperNumber, paperNumber)
|
|
|
|
- .eq(MarkQuestion::getObjective, objective);
|
|
|
|
- return this.count(queryWrapper);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
|
|
+package com.qmth.teachcloud.mark.service.impl;
|
|
|
|
+
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
+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.core.metadata.IPage;
|
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
+import com.qmth.teachcloud.common.bean.dto.mark.MarkUser;
|
|
|
|
+import com.qmth.teachcloud.common.bean.dto.mark.ObjectiveAnswerDto;
|
|
|
|
+import com.qmth.teachcloud.common.bean.dto.mark.PictureConfig;
|
|
|
|
+import com.qmth.teachcloud.common.bean.params.mark.group.QuestionPictureConfigParams;
|
|
|
|
+import com.qmth.teachcloud.common.bean.result.ExcelResult;
|
|
|
|
+import com.qmth.teachcloud.common.bean.vo.FilePathVo;
|
|
|
|
+import com.qmth.teachcloud.common.contant.SystemConstant;
|
|
|
|
+import com.qmth.teachcloud.common.entity.MarkQuestion;
|
|
|
|
+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.bean.mark.DoubleMarkParam;
|
|
|
|
+import com.qmth.teachcloud.mark.bean.student.MarkStudentQuery;
|
|
|
|
+import com.qmth.teachcloud.mark.bean.vo.parseCard.pic.SubPictureConfig;
|
|
|
|
+import com.qmth.teachcloud.mark.dto.mark.MarkQuestionAnswerVo;
|
|
|
|
+import com.qmth.teachcloud.mark.dto.mark.MarkStudentVo;
|
|
|
|
+import com.qmth.teachcloud.mark.dto.mark.MarkPaperFileDto;
|
|
|
|
+import com.qmth.teachcloud.mark.dto.mark.manage.*;
|
|
|
|
+import com.qmth.teachcloud.mark.dto.mark.setting.MarkGroupTaskDto;
|
|
|
|
+import com.qmth.teachcloud.mark.dto.mark.setting.MarkQuestionDto;
|
|
|
|
+import com.qmth.teachcloud.mark.dto.mark.setting.MarkQuestionSubjectiveStepStatusDto;
|
|
|
|
+import com.qmth.teachcloud.mark.entity.MarkPaper;
|
|
|
|
+import com.qmth.teachcloud.mark.entity.MarkQuestionAnswer;
|
|
|
|
+import com.qmth.teachcloud.mark.entity.MarkTask;
|
|
|
|
+import com.qmth.teachcloud.mark.entity.MarkUserQuestion;
|
|
|
|
+import com.qmth.teachcloud.mark.enums.LockType;
|
|
|
|
+import com.qmth.teachcloud.mark.enums.MarkTaskStatus;
|
|
|
|
+import com.qmth.teachcloud.mark.lock.LockService;
|
|
|
|
+import com.qmth.teachcloud.mark.mapper.MarkQuestionMapper;
|
|
|
|
+import com.qmth.teachcloud.mark.params.MarkObjectiveQuestionParams;
|
|
|
|
+import com.qmth.teachcloud.mark.params.MarkQuestionParams;
|
|
|
|
+import com.qmth.teachcloud.mark.service.*;
|
|
|
|
+import com.qmth.teachcloud.mark.utils.Calculator;
|
|
|
|
+import com.qmth.teachcloud.mark.utils.CardParseUtils;
|
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
|
+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.math.BigDecimal;
|
|
|
|
+import java.util.*;
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
+import java.util.stream.Stream;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * <p>
|
|
|
|
+ * 小题信息表 服务实现类
|
|
|
|
+ * </p>
|
|
|
|
+ *
|
|
|
|
+ * @author xf
|
|
|
|
+ * @since 2023-09-22
|
|
|
|
+ */
|
|
|
|
+@Service
|
|
|
|
+public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, MarkQuestion> implements MarkQuestionService {
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ private TeachcloudCommonService teachcloudCommonService;
|
|
|
|
+ @Resource
|
|
|
|
+ private MarkPaperService markPaperService;
|
|
|
|
+ @Resource
|
|
|
|
+ private MarkQuestionAnswerService markQuestionAnswerService;
|
|
|
|
+ @Resource
|
|
|
|
+ private MarkUserQuestionService markUserQuestionService;
|
|
|
|
+ @Resource
|
|
|
|
+ private MarkUserClassService markUserClassService;
|
|
|
|
+ @Resource
|
|
|
|
+ private MarkStudentService markStudentService;
|
|
|
|
+ @Resource
|
|
|
|
+ private MarkTaskService markTaskService;
|
|
|
|
+ @Resource
|
|
|
|
+ private MarkArbitrateHistoryService markArbitrateHistoryService;
|
|
|
|
+ @Resource
|
|
|
|
+ private MarkService markService;
|
|
|
|
+ @Resource
|
|
|
|
+ private FileStoreUtil fileStoreUtil;
|
|
|
|
+ @Resource
|
|
|
|
+ private LockService lockService;
|
|
|
|
+ @Resource
|
|
|
|
+ private MarkSyncService markSyncService;
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public String assembleGroupQuestionsByExamIdAndPaperNumberAndNumber(Long examId, String paperNumber, Integer groupNumber) {
|
|
|
|
+ return this.baseMapper.assembleQuestionsByExamIdAndPaperNumberAndNumber(examId, paperNumber, groupNumber);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<MarkQuestion> listQuestionByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
+ QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
|
|
|
|
+ LambdaQueryWrapper<MarkQuestion> lambdaQueryWrapper = queryWrapper.lambda();
|
|
|
|
+ lambdaQueryWrapper.eq(MarkQuestion::getExamId, examId)
|
|
|
|
+ .eq(MarkQuestion::getPaperNumber, paperNumber);
|
|
|
|
+ lambdaQueryWrapper.orderByAsc(MarkQuestion::getMainNumber)
|
|
|
|
+ .orderByAsc(MarkQuestion::getSubNumber);
|
|
|
|
+ return this.list(queryWrapper);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Transactional
|
|
|
|
+ @Override
|
|
|
|
+ public void saveQuestions(MarkQuestionParams markQuestionParams) {
|
|
|
|
+ SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
|
+ Long examId = markQuestionParams.getExamId();
|
|
|
|
+ String paperNumber = markQuestionParams.getPaperNumber();
|
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+
|
|
|
|
+ List<MarkQuestion> questions = markQuestionParams.getQuestions();
|
|
|
|
+ if (CollectionUtils.isEmpty(questions)) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("没有可保存的结构数据");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 校验题号不能重复
|
|
|
|
+ Map<String, Long> longMap = questions.stream().collect(Collectors.groupingBy(m -> m.getMainNumber() + SystemConstant.HYPHEN + m.getSubNumber(), Collectors.counting()));
|
|
|
|
+ long count = longMap.entrySet().stream().filter(m -> m.getValue().intValue() > 1).count();
|
|
|
|
+ if (count > 0) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("大题号-小题号有重复数据");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 查询已有结构信息
|
|
|
|
+ List<MarkQuestion> markQuestionList = this.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ if (CollectionUtils.isEmpty(markQuestionList)) {
|
|
|
|
+ for (MarkQuestion question : questions) {
|
|
|
|
+ if (question.getTotalScore() < 0) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("小题满分不能小于0");
|
|
|
|
+ }
|
|
|
|
+ if (!question.getObjective() && (question.getIntervalScore() == null || question.getIntervalScore() <= 0)) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("间隔分必须大于0");
|
|
|
|
+ }
|
|
|
|
+ question.setExamId(examId);
|
|
|
|
+ question.setPaperNumber(paperNumber);
|
|
|
|
+ question.setPaperType(markPaper.getPaperType());
|
|
|
|
+ question.setCreateId(sysUser.getId());
|
|
|
|
+ question.setCreateTime(System.currentTimeMillis());
|
|
|
|
+ // 用来判断是否保存过
|
|
|
|
+ question.setUpdateId(sysUser.getId());
|
|
|
|
+ question.setUpdateTime(System.currentTimeMillis());
|
|
|
|
+ }
|
|
|
|
+ this.saveBatch(questions);
|
|
|
|
+ markQuestionAnswerService.deleteByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ markQuestionAnswerService.saveByMarkQuestion(examId, paperNumber, questions, false);
|
|
|
|
+ } else {
|
|
|
|
+ List<MarkQuestion> saveOrUpdateList = new ArrayList<>();
|
|
|
|
+ for (MarkQuestion question : questions) {
|
|
|
|
+ if (Objects.isNull(question.getId())) {
|
|
|
|
+ question.setId(SystemConstant.getDbUuid());
|
|
|
|
+ question.setExamId(examId);
|
|
|
|
+ question.setPaperNumber(paperNumber);
|
|
|
|
+ question.setPaperType(markPaper.getPaperType());
|
|
|
|
+ saveOrUpdateList.add(question);
|
|
|
|
+ } else {
|
|
|
|
+ Optional<MarkQuestion> questionOptional = markQuestionList.stream().filter(m -> m.getId().equals(question.getId())).findFirst();
|
|
|
|
+ if (questionOptional.isPresent()) {
|
|
|
|
+ MarkQuestion markQuestion = questionOptional.get();
|
|
|
|
+ if (markQuestion.getMarkedCount() != null && markQuestion.getMarkedCount() > 0 && markQuestion.getTotalScore() != null && markQuestion.getTotalScore().doubleValue() - question.getTotalScore().doubleValue() != 0) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("大题号" + markQuestion.getMainNumber() + "小题号" + markQuestion.getSubNumber() + "已阅卷,不能修改小题满分");
|
|
|
|
+ }
|
|
|
|
+ // 主观题改客观题
|
|
|
|
+ if (markQuestion.getMarkedCount() != null && markQuestion.getMarkedCount() > 0 && !markQuestion.getObjective() && question.getObjective()) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("大题号" + markQuestion.getMainNumber() + "小题号" + markQuestion.getSubNumber() + "已阅卷,不能修改为客观题题型");
|
|
|
|
+ }
|
|
|
|
+ if (question.getTotalScore() < 0) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("小题满分不能小于0");
|
|
|
|
+ }
|
|
|
|
+ if (!QuestionType.findByValue(question.getQuestionType()).getObjective() && question.getIntervalScore() <= 0) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("间隔分必须大于0");
|
|
|
|
+ }
|
|
|
|
+ // 客观题变主观题
|
|
|
|
+ if (markQuestion.getObjective() && !question.getObjective()) {
|
|
|
|
+ // 清除判分策略
|
|
|
|
+ markQuestionAnswerService.deleteByExamIdAndPaperNumberAndMainNumberAndSubNumber(examId, paperNumber, markQuestion.getMainNumber(), markQuestion.getSubNumber());
|
|
|
|
+ }
|
|
|
|
+ // 客观题
|
|
|
|
+ if (question.getObjective()) {
|
|
|
|
+ markQuestion.setOptionCount(question.getOptionCount());
|
|
|
|
+ if (!markQuestion.getQuestionType().equals(question.getQuestionType())) {
|
|
|
|
+ // 清除判分策略
|
|
|
|
+ markQuestionAnswerService.resetObjectivePolicyByExamIdAndPaperNumberAndMainNumberAndSubNumber(examId, paperNumber, markQuestion.getMainNumber(), markQuestion.getSubNumber());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 大题号
|
|
|
|
+ markQuestion.setMainNumber(question.getMainNumber());
|
|
|
|
+ // 小题号
|
|
|
|
+ markQuestion.setSubNumber(question.getSubNumber());
|
|
|
|
+ // 大题名称
|
|
|
|
+ markQuestion.setMainTitle(question.getMainTitle());
|
|
|
|
+ // 题型
|
|
|
|
+ markQuestion.setQuestionType(question.getQuestionType());
|
|
|
|
+ markQuestion.setObjective(question.getObjective());
|
|
|
|
+ markQuestion.setTotalScore(question.getTotalScore());
|
|
|
|
+ markQuestion.setIntervalScore(question.getIntervalScore());
|
|
|
|
+ // 用来判断是否保存过
|
|
|
|
+ markQuestion.setUpdateId(sysUser.getId());
|
|
|
|
+ markQuestion.setUpdateTime(System.currentTimeMillis());
|
|
|
|
+ saveOrUpdateList.add(markQuestion);
|
|
|
|
+ markQuestionList.remove(markQuestion);
|
|
|
|
+ } else {
|
|
|
|
+ question.setId(SystemConstant.getDbUuid());
|
|
|
|
+ question.setExamId(examId);
|
|
|
|
+ question.setPaperNumber(paperNumber);
|
|
|
|
+ question.setPaperType(markPaper.getPaperType());
|
|
|
|
+ question.setCreateId(sysUser.getId());
|
|
|
|
+ question.setCreateTime(System.currentTimeMillis());
|
|
|
|
+ // 用来判断是否保存过
|
|
|
|
+ question.setUpdateId(sysUser.getId());
|
|
|
|
+ question.setUpdateTime(System.currentTimeMillis());
|
|
|
|
+ saveOrUpdateList.add(question);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 删除的结构
|
|
|
|
+ if (CollectionUtils.isNotEmpty(markQuestionList)) {
|
|
|
|
+ List<Long> deleteIds = markQuestionList.stream().map(MarkQuestion::getId).collect(Collectors.toList());
|
|
|
|
+ this.removeByIds(deleteIds);
|
|
|
|
+
|
|
|
|
+ markQuestionList.stream().filter(m -> m.getObjective()).forEach(m -> {
|
|
|
|
+ markQuestionAnswerService.deleteByExamIdAndPaperNumberAndMainNumberAndSubNumber(examId, paperNumber, m.getMainNumber(), m.getSubNumber());
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ this.saveOrUpdateBatch(saveOrUpdateList);
|
|
|
|
+ markQuestionAnswerService.saveByMarkQuestion(examId, paperNumber, saveOrUpdateList, false);
|
|
|
|
+ }
|
|
|
|
+ // 更新客观题满分、主观题满分、总分
|
|
|
|
+ List<MarkQuestion> markQuestions = this.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ Double objectiveScore = markQuestions.stream().filter(m -> m.getObjective()).collect(Collectors.summingDouble(m -> m.getTotalScore()));
|
|
|
|
+ Double subjectiveScore = markQuestions.stream().filter(m -> !m.getObjective()).collect(Collectors.summingDouble(m -> m.getTotalScore()));
|
|
|
|
+ Double totalScore = markQuestions.stream().collect(Collectors.summingDouble(m -> m.getTotalScore()));
|
|
|
|
+ UpdateWrapper<MarkPaper> updateWrapper = new UpdateWrapper<>();
|
|
|
|
+ updateWrapper.lambda().set(MarkPaper::getObjectiveScore, objectiveScore)
|
|
|
|
+ .set(MarkPaper::getSubjectiveScore, subjectiveScore)
|
|
|
|
+ .set(MarkPaper::getTotalScore, totalScore)
|
|
|
|
+ .set(MarkPaper::getQuestionStatus, true)
|
|
|
|
+ .eq(MarkPaper::getExamId, examId)
|
|
|
|
+ .eq(MarkPaper::getPaperNumber, paperNumber);
|
|
|
|
+ markPaperService.update(updateWrapper);
|
|
|
|
+
|
|
|
|
+ // 主观题结构有变动
|
|
|
|
+ List<MarkQuestion> subjectiveQuestions = questions.stream().filter(m -> m.getObjective()).collect(Collectors.toList());
|
|
|
|
+ List<MarkQuestion> subjectiveMarkQuestionList = markQuestionList.stream().filter(m -> m.getObjective()).collect(Collectors.toList());
|
|
|
|
+ if (!CollectionUtils.isEqualCollection(subjectiveQuestions, subjectiveMarkQuestionList)) {
|
|
|
|
+ // 未分组的题目
|
|
|
|
+// long unGroupQuestionCount = this.countByExamIdAndPaperNumberAndObjectiveAndGroupNumberIsNull(examId, paperNumber, false);
|
|
|
|
+// // 考生主观题重新统分
|
|
|
|
+// markService.checkStudentSubjectiveScore(examId, markPaper.getCoursePaperId(), unGroupQuestionCount);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 更新分组状态
|
|
|
|
+ markService.updateMarkGroupStatus(examId, paperNumber);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void objectiveAnswerSettingModelExport(Long examId, String paperNumber, String paperType, HttpServletResponse response)
|
|
|
|
+ throws Exception {
|
|
|
|
+ List<MarkQuestionAnswerVo> datasource = this.listQuestionAnswerByExamIdAndPaperNumberAndPaperType(examId, paperNumber,
|
|
|
|
+ paperType, true);
|
|
|
|
+ List<ObjectiveAnswerDto> objectiveAnswerDtoList = datasource.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, objectiveAnswerDtoList, response);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Transactional
|
|
|
|
+ @Override
|
|
|
|
+ public void objectiveAnswerSettingImport(Long examId, String paperNumber, String paperType, MultipartFile file) throws Exception {
|
|
|
|
+ // 试卷结构
|
|
|
|
+ List<MarkQuestionAnswer> datasource = markQuestionAnswerService.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, paperType);
|
|
|
|
+ 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<String, MarkQuestion> markQuestionMap = this.listQuestionByExamIdAndPaperNumber(examId, paperNumber).stream().collect(Collectors.toMap(k -> k.getMainNumber() + SystemConstant.HYPHEN + k.getSubNumber(), v -> v));
|
|
|
|
+ // 构建题号-试题结构map
|
|
|
|
+ Map<String, MarkQuestionAnswer> markQuestionAnswerMapMap = datasource.stream().collect(Collectors.toMap(k -> k.getMainNumber() + SystemConstant.HYPHEN + k.getSubNumber(), v -> v));
|
|
|
|
+
|
|
|
|
+ List<MarkQuestionAnswer> willEditList = new ArrayList<>();
|
|
|
|
+ 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 (markQuestionAnswerMapMap.containsKey(key)) {
|
|
|
|
+ MarkQuestionAnswer markQuestion = markQuestionAnswerMapMap.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 = markQuestionMap.get(key).getQuestionType();
|
|
|
|
+ Integer optionCount = markQuestionMap.get(key).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));
|
|
|
|
+ }
|
|
|
|
+ markQuestionAnswerService.saveOrUpdateBatch(willEditList);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Transactional
|
|
|
|
+ @Override
|
|
|
|
+ public void saveObjectiveQuestions(MarkObjectiveQuestionParams markObjectiveQuestionParams) {
|
|
|
|
+ for (MarkQuestionAnswer answer : markObjectiveQuestionParams.getObjectiveInfo()) {
|
|
|
|
+ if (StringUtils.isBlank(answer.getAnswer())) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("答案不能为空");
|
|
|
|
+ }
|
|
|
|
+ if (answer.getObjectivePolicy() != null && answer.getObjectivePolicy().equals(ObjectivePolicy.LEAK)) {
|
|
|
|
+ if (answer.getObjectivePolicyScore() == null) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("漏选给分不能没有计分规则");
|
|
|
|
+ }
|
|
|
|
+ if (answer.getObjectivePolicyScore() > (answer.getTotalScore() / answer.getAnswer().length())) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("漏选给分计分规则有误");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ UpdateWrapper<MarkQuestionAnswer> updateWrapper = new UpdateWrapper<>();
|
|
|
|
+ updateWrapper.lambda().set(MarkQuestionAnswer::getAnswer, answer.getAnswer())
|
|
|
|
+ .set(MarkQuestionAnswer::getUpdateTime, System.currentTimeMillis());
|
|
|
|
+ if (answer.getObjectivePolicy() != null) {
|
|
|
|
+ updateWrapper.lambda().set(MarkQuestionAnswer::getObjectivePolicy, answer.getObjectivePolicy());
|
|
|
|
+ }
|
|
|
|
+ if (answer.getObjectivePolicyScore() != null) {
|
|
|
|
+ updateWrapper.lambda().set(MarkQuestionAnswer::getObjectivePolicyScore, answer.getObjectivePolicyScore());
|
|
|
|
+ }
|
|
|
|
+ updateWrapper.lambda().eq(MarkQuestionAnswer::getId, answer.getId());
|
|
|
|
+ markQuestionAnswerService.update(updateWrapper);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 统分
|
|
|
|
+ markStudentService.calcObjectiveScore(markObjectiveQuestionParams.getExamId(), markObjectiveQuestionParams.getPaperNumber());
|
|
|
|
+
|
|
|
|
+ //发送阅卷待办短信
|
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(markObjectiveQuestionParams.getExamId(), markObjectiveQuestionParams.getPaperNumber());
|
|
|
|
+ Objects.requireNonNull(markPaper, "未找到试卷信息");
|
|
|
|
+ markUserQuestionService.smsMarkTask(markObjectiveQuestionParams.getExamId(), markPaper.getCourseId(), markObjectiveQuestionParams.getPaperNumber());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public String uploadSubjectiveFile(Long examId, String paperNumber, String paperType, MultipartFile file, String md5) {
|
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ if (markPaper == null) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("课程不存在");
|
|
|
|
+ }
|
|
|
|
+ List<MarkPaperFileDto> subjectiveAnswerFileDtoList = new ArrayList<>();
|
|
|
|
+ if (StringUtils.isNotBlank(markPaper.getAnswerFilePath())) {
|
|
|
|
+ subjectiveAnswerFileDtoList = JSON.parseArray(markPaper.getAnswerFilePath(), MarkPaperFileDto.class);
|
|
|
|
+ }
|
|
|
|
+ String answerFilePath = fileStoreUtil.uploadFile(file, md5, UploadFileEnum.PDF);
|
|
|
|
+
|
|
|
|
+ MarkPaperFileDto subjectiveAnswerFileDto = null;
|
|
|
|
+ for (MarkPaperFileDto answerFileDto : subjectiveAnswerFileDtoList) {
|
|
|
|
+ if (paperType.equals(answerFileDto.getPaperType())) {
|
|
|
|
+ answerFileDto.setFilePathVo(JSON.parseObject(answerFilePath, FilePathVo.class));
|
|
|
|
+ subjectiveAnswerFileDto = answerFileDto;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (subjectiveAnswerFileDto == null) {
|
|
|
|
+ subjectiveAnswerFileDto = new MarkPaperFileDto();
|
|
|
|
+ subjectiveAnswerFileDto.setPaperType(paperType);
|
|
|
|
+ subjectiveAnswerFileDto.setFilePathVo(JSON.parseObject(answerFilePath, FilePathVo.class));
|
|
|
|
+ subjectiveAnswerFileDtoList.add(subjectiveAnswerFileDto);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ UpdateWrapper<MarkPaper> updateWrapper = new UpdateWrapper<>();
|
|
|
|
+ updateWrapper.lambda().set(MarkPaper::getAnswerFilePath, JSON.toJSONString(subjectiveAnswerFileDtoList))
|
|
|
|
+ .eq(MarkPaper::getExamId, examId)
|
|
|
|
+ .eq(MarkPaper::getPaperNumber, paperNumber);
|
|
|
|
+ markPaperService.update(updateWrapper);
|
|
|
|
+ return teachcloudCommonService.filePreview(answerFilePath);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<MarkPaperFileDto> previewAnswerFileByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ List<MarkPaperFileDto> markPaperFileDtos = new ArrayList<>();
|
|
|
|
+ if (markPaper != null && StringUtils.isNotBlank(markPaper.getAnswerFilePath())) {
|
|
|
|
+ markPaperFileDtos = JSON.parseArray(markPaper.getAnswerFilePath(), MarkPaperFileDto.class);
|
|
|
|
+ for (MarkPaperFileDto markPaperFileDto : markPaperFileDtos) {
|
|
|
|
+ markPaperFileDto.setUrl(teachcloudCommonService.filePreview(JSON.toJSONString(markPaperFileDto.getFilePathVo())));
|
|
|
|
+ markPaperFileDto.setFilePathVo(null);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return markPaperFileDtos;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<MarkPaperFileDto> previewPaperFileByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ List<MarkPaperFileDto> markPaperFileDtos = new ArrayList<>();
|
|
|
|
+ if (markPaper != null && StringUtils.isNotBlank(markPaper.getPaperFilePath())) {
|
|
|
|
+ markPaperFileDtos = JSON.parseArray(markPaper.getPaperFilePath(), MarkPaperFileDto.class);
|
|
|
|
+ for (MarkPaperFileDto markPaperFileDto : markPaperFileDtos) {
|
|
|
|
+ markPaperFileDto.setUrl(teachcloudCommonService.filePreview(JSON.toJSONString(markPaperFileDto.getFilePathVo())));
|
|
|
|
+ markPaperFileDto.setFilePathVo(null);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return markPaperFileDtos;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<MarkQuestion> listByExamIdAndPaperNumberAndPaperIndexAndPageIndex(Long examId, String paperNumber,
|
|
|
|
+ Integer paperIndex, Integer pageIndex, boolean isObjective) {
|
|
|
|
+ QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
|
|
|
|
+ queryWrapper.lambda().eq(MarkQuestion::getExamId, examId)
|
|
|
|
+ .eq(MarkQuestion::getPaperNumber, paperNumber)
|
|
|
|
+ .eq(MarkQuestion::getPaperIndex, paperIndex)
|
|
|
|
+ .eq(MarkQuestion::getPageIndex, pageIndex)
|
|
|
|
+ .eq(MarkQuestion::getObjective, isObjective)
|
|
|
|
+ .orderByAsc(MarkQuestion::getMainNumber)
|
|
|
|
+ .orderByAsc(MarkQuestion::getSubNumber);
|
|
|
|
+ return this.list(queryWrapper);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public MarkQuestionDto pageQuestionsByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
+ MarkQuestionDto markQuestionDto = new MarkQuestionDto();
|
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ // 试卷结构,默认只取A卷
|
|
|
|
+ List<MarkQuestion> markQuestionList = this.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ markQuestionDto.setQuestionSubmit(markPaper.getQuestionStatus());
|
|
|
|
+ markQuestionDto.setObjectiveSubmit(markQuestionAnswerService.countByExamIdAndPaperNumber(examId, paperNumber) > 0);
|
|
|
|
+ markQuestionDto.setQuestions(markQuestionList);
|
|
|
|
+ return markQuestionDto;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public long countByExamIdAndPaperNumberAndObjectiveAndGroupNumberIsNull(Long examId, String paperNumber, boolean objective) {
|
|
|
|
+ // todo 2025-02-25
|
|
|
|
+// QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
|
|
|
|
+// queryWrapper.lambda().eq(MarkQuestion::getExamId, examId)
|
|
|
|
+// .eq(MarkQuestion::getPaperNumber, paperNumber)
|
|
|
|
+// .eq(MarkQuestion::getObjective, objective)
|
|
|
|
+// .isNull(MarkQuestion::getGroupNumber);
|
|
|
|
+// return this.count(queryWrapper);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<MarkQuestion> listByExamIdAndPaperNumberAndObjective(Long examId, String paperNumber, Boolean objective) {
|
|
|
|
+ QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
|
|
|
|
+ LambdaQueryWrapper<MarkQuestion> lambdaQueryWrapper = queryWrapper.lambda();
|
|
|
|
+ lambdaQueryWrapper.eq(MarkQuestion::getExamId, examId)
|
|
|
|
+ .eq(MarkQuestion::getPaperNumber, paperNumber)
|
|
|
|
+ .eq(MarkQuestion::getObjective, objective);
|
|
|
|
+ lambdaQueryWrapper.orderByAsc(MarkQuestion::getMainNumber)
|
|
|
|
+ .orderByAsc(MarkQuestion::getSubNumber);
|
|
|
|
+ return this.list(queryWrapper);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void deleteByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
+ UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
|
|
|
|
+ updateWrapper.lambda().eq(MarkQuestion::getExamId, examId)
|
|
|
|
+ .eq(MarkQuestion::getPaperNumber, paperNumber);
|
|
|
|
+ this.remove(updateWrapper);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Transactional
|
|
|
|
+ @Override
|
|
|
|
+ public void updateMarkPaperScore(Long examId, String paperNumber) {
|
|
|
|
+ List<MarkQuestion> markQuestions = this.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ Double objectiveScore = markQuestions.stream().filter(MarkQuestion::getObjective)
|
|
|
|
+ .mapToDouble(MarkQuestion::getTotalScore).sum();
|
|
|
|
+ Double subjectiveScore = markQuestions.stream().filter(m -> !m.getObjective())
|
|
|
|
+ .mapToDouble(MarkQuestion::getTotalScore).sum();
|
|
|
|
+ Double totalScore = markQuestions.stream().mapToDouble(MarkQuestion::getTotalScore).sum();
|
|
|
|
+ UpdateWrapper<MarkPaper> updateWrapper = new UpdateWrapper<>();
|
|
|
|
+ updateWrapper.lambda().set(MarkPaper::getObjectiveScore, objectiveScore)
|
|
|
|
+ .set(MarkPaper::getSubjectiveScore, subjectiveScore)
|
|
|
|
+ .set(MarkPaper::getTotalScore, totalScore)
|
|
|
|
+ .eq(MarkPaper::getExamId, examId)
|
|
|
|
+ .eq(MarkPaper::getPaperNumber, paperNumber);
|
|
|
|
+ markPaperService.update(updateWrapper);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<MarkQuestionAnswerVo> listQuestionAnswerByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType, Boolean objective) {
|
|
|
|
+ return this.baseMapper.listQuestionAnswerByExamIdAndPaperNumberAndPaperType(examId, paperNumber, paperType, objective);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<MarkQuestion> listByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
+ QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
|
|
|
|
+ queryWrapper.lambda().eq(MarkQuestion::getExamId, examId)
|
|
|
|
+ .eq(MarkQuestion::getPaperNumber, paperNumber);
|
|
|
|
+ return this.list(queryWrapper);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void deleteByExamIdAndPaperNumberAndObjective(Long examId, String paperNumber, boolean objective) {
|
|
|
|
+ UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
|
|
|
|
+ updateWrapper.lambda().eq(MarkQuestion::getExamId, examId)
|
|
|
|
+ .eq(MarkQuestion::getPaperNumber, paperNumber)
|
|
|
|
+ .eq(MarkQuestion::getObjective, objective);
|
|
|
|
+ this.remove(updateWrapper);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public MarkGroupTaskDto listGroupTaskByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
+ MarkGroupTaskDto markGroupTaskDto = new MarkGroupTaskDto();
|
|
|
|
+ markGroupTaskDto.setExamId(examId);
|
|
|
|
+ markGroupTaskDto.setPaperNumber(paperNumber);
|
|
|
|
+
|
|
|
|
+ // 主观题信息
|
|
|
|
+ List<MarkQuestion> markQuestionList = listByExamIdAndPaperNumberAndObjective(examId, paperNumber, false);
|
|
|
|
+ for (MarkQuestion m : markQuestionList) {
|
|
|
|
+ if (StringUtils.isNotBlank(m.getPicList())) {
|
|
|
|
+ m.setPictureConfigs(JSON.parseArray(m.getPicList(), PictureConfig.class));
|
|
|
|
+ }
|
|
|
|
+ // 评卷员
|
|
|
|
+ List<MarkUser> markUserList = markUserQuestionService.listGroupUserByExamIdAndPaperNumberAndQuestionIdAndClassName(examId, paperNumber, m.getId(), null);
|
|
|
|
+ m.setMarkers(markUserList.stream().filter(MarkUser::getEnable).collect(Collectors.toList()));
|
|
|
|
+ }
|
|
|
|
+ markGroupTaskDto.setQuestions(markQuestionList);
|
|
|
|
+ // 分班阅参数
|
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ markGroupTaskDto.setClassMark(markPaper != null && markPaper.getClassMark());
|
|
|
|
+ markGroupTaskDto.setDoubleMark(markPaper != null && markPaper.getDoubleMark());
|
|
|
|
+ markGroupTaskDto.setMergeMarker(markPaper != null && markPaper.getMergeMarker());
|
|
|
|
+ return markGroupTaskDto;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void updatePicListByQuestionId(QuestionPictureConfigParams questionPictureConfigParams) {
|
|
|
|
+ List<PictureConfig> pictureConfigs = questionPictureConfigParams.getPictureConfigs();
|
|
|
|
+ if (CollectionUtils.isEmpty(pictureConfigs)) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("没有评卷区数据");
|
|
|
|
+ }
|
|
|
|
+ UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
|
|
|
|
+ updateWrapper.lambda().set(MarkQuestion::getPicList, JSON.toJSONString(pictureConfigs))
|
|
|
|
+ .in(MarkQuestion::getId, questionPictureConfigParams.getQuestionIds());
|
|
|
|
+ this.update(updateWrapper);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public Integer countCurrentCountByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
|
+ int total = 0;
|
|
|
|
+ List<MarkQuestion> markQuestionList = this.listByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ if (CollectionUtils.isNotEmpty(markQuestionList)) {
|
|
|
|
+ for (MarkQuestion markQuestion : markQuestionList) {
|
|
|
|
+ total += markService.applyCurrentCount(markQuestion);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return total;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public MarkGroupSummaryProgressDto summaryGroupProgress(Long examId, String paperNumber) {
|
|
|
|
+ MarkGroupSummaryProgressDto markGroupSummaryProgressDto = new MarkGroupSummaryProgressDto();
|
|
|
|
+
|
|
|
|
+ // totalInfo
|
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ if (markPaper == null) {
|
|
|
|
+ return markGroupSummaryProgressDto;
|
|
|
|
+ }
|
|
|
|
+ markGroupSummaryProgressDto.setClassMark(markPaper.getClassMark());
|
|
|
|
+ MarkGroupTotalProgressDto markGroupTotalProgressDto = new MarkGroupTotalProgressDto();
|
|
|
|
+ markGroupTotalProgressDto.setStudentCount(markPaper.getStudentCount());
|
|
|
|
+ markGroupTotalProgressDto.setUploadCount(markStudentService.countUploadedByExamIdAndPaperNumber(examId, paperNumber));
|
|
|
|
+ markGroupTotalProgressDto.setAbsentCount(markStudentService.countAbsentByExamIdAndPaperNumber(examId, paperNumber));
|
|
|
|
+
|
|
|
|
+ int totalCount = markTaskService.countByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ int markedCount = markTaskService.countByExamIdAndPaperNumberAndStatusIn(examId, paperNumber, Arrays.asList(MarkTaskStatus.MARKED, MarkTaskStatus.ARBITRATED));
|
|
|
|
+ markGroupTotalProgressDto.setPercent(Calculator.divide2String(Calculator.multiply(markedCount, 100), Double.valueOf(totalCount), 2));
|
|
|
|
+ markGroupSummaryProgressDto.setTotalInfo(markGroupTotalProgressDto);
|
|
|
|
+
|
|
|
|
+ // groupInfo
|
|
|
|
+ List<MarkGroupProgressDto> markGroupProgressDtoList = new ArrayList<>();
|
|
|
|
+ List<MarkQuestion> markQuestionList = this.listByExamIdAndPaperNumberAndObjective(examId, paperNumber, false);
|
|
|
|
+ for (MarkQuestion markQuestion : markQuestionList) {
|
|
|
|
+ MarkGroupProgressDto markGroupProgressDto = new MarkGroupProgressDto();
|
|
|
|
+ markGroupProgressDto.setQuestionId(markQuestion.getId());
|
|
|
|
+ markGroupProgressDto.setTotalScore(markQuestion.getTotalScore());
|
|
|
|
+ markGroupProgressDto.setQuestionNumber(markQuestion.getQuestionNumber());
|
|
|
|
+ List<MarkUser> markUserList = markUserQuestionService.listGroupUserByExamIdAndPaperNumberAndQuestionIdAndClassName(examId, paperNumber, markQuestion.getId(), null);
|
|
|
|
+ markGroupProgressDto.setMarkerCount(markUserList.size());
|
|
|
|
+ markGroupProgressDto.setTaskCount(markQuestion.getTaskCount());
|
|
|
|
+ markGroupProgressDto.setMarkedCount(markQuestion.getMarkedCount());
|
|
|
|
+ markGroupProgressDto.setLeftCount(markGroupProgressDto.getTaskCount() - markGroupProgressDto.getMarkedCount());
|
|
|
|
+ markGroupProgressDto.setCurrentCount(markService.applyCurrentCount(markQuestion));
|
|
|
|
+ markGroupProgressDto.setPercent(Calculator.divide2String(Calculator.multiply(markGroupProgressDto.getMarkedCount(), 100), Double.valueOf(markGroupProgressDto.getTaskCount()), 2));
|
|
|
|
+ markGroupProgressDto.setArbitrateCount(markArbitrateHistoryService.waitArbitrateCount(examId, paperNumber, markQuestion.getId(), null));
|
|
|
|
+ markGroupProgressDtoList.add(markGroupProgressDto);
|
|
|
|
+ }
|
|
|
|
+ markGroupSummaryProgressDto.setGroupInfo(markGroupProgressDtoList);
|
|
|
|
+ return markGroupSummaryProgressDto;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public IPage<MarkGroupClassProgressDto> summaryGroupClassProgress(Long examId, String paperNumber, String className, Integer pageNumber, Integer pageSize) {
|
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ if (markPaper.getClassMark()) {
|
|
|
|
+ Page<MarkGroupClassProgressDto> page = new Page<>(pageNumber, pageSize);
|
|
|
|
+ IPage<MarkGroupClassProgressDto> markGroupClassProgressDtoIPage = markUserClassService.pageClassByExamIdAndPaperNumber(page, examId, paperNumber, className);
|
|
|
|
+ for (MarkGroupClassProgressDto markGroupClassProgressDto : markGroupClassProgressDtoIPage.getRecords()) {
|
|
|
|
+ Long questionId = markGroupClassProgressDto.getQuestionId();
|
|
|
|
+ List<MarkTask> totalMarkTaskList = new ArrayList<>();
|
|
|
|
+ List<MarkUser> totalMarkUserList = new ArrayList<>();
|
|
|
|
+ totalMarkTaskList.addAll(markTaskService.listByExamIdAndPaperNumberAndQuestionIdAndUserIdAndClassName(examId, paperNumber, questionId, null, markGroupClassProgressDto.getClassName()));
|
|
|
|
+ totalMarkUserList.addAll(markUserQuestionService.listGroupUserByExamIdAndPaperNumberAndQuestionIdAndClassName(examId, paperNumber, questionId, markGroupClassProgressDto.getClassName()));
|
|
|
|
+
|
|
|
|
+ MarkQuestion markQuestion = this.getById(questionId);
|
|
|
|
+ List<MarkUser> markUserList = markUserClassService.listClassMarkerByExamIdAndPaperNumberAndQuestionIdAndClassName(examId, paperNumber, questionId, markGroupClassProgressDto.getClassName());
|
|
|
|
+ int count = 0;
|
|
|
|
+ for (MarkUser markUser : markUserList) {
|
|
|
|
+ MarkUserQuestion markUserQuestion = markUserQuestionService.getByExamIdAndPaperNumberAndQuestionIdAndUserId(examId, paperNumber, questionId, markUser.getUserId());
|
|
|
|
+ if (markUserQuestion != null) {
|
|
|
|
+ int markerCount = markService.applyCurrentCount(markQuestion, markUserQuestion.getId());
|
|
|
|
+ count += markerCount;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 待仲裁数量
|
|
|
|
+ int arbitrateCount = markArbitrateHistoryService.waitArbitrateCount(examId, paperNumber, questionId, markGroupClassProgressDto.getClassName());
|
|
|
|
+ markGroupClassProgressDto.setQuestionNumber(markQuestion.getQuestionNumber());
|
|
|
|
+ markGroupClassProgressDto.setMarkerCount(totalMarkUserList.size());
|
|
|
|
+ markGroupClassProgressDto.setTaskCount(totalMarkTaskList.size());
|
|
|
|
+ markGroupClassProgressDto.setMarkedCount(markTaskService.markedCount(totalMarkTaskList));
|
|
|
|
+ markGroupClassProgressDto.setLeftCount(markGroupClassProgressDto.getTaskCount() - markGroupClassProgressDto.getMarkedCount());
|
|
|
|
+ markGroupClassProgressDto.setCurrentCount(count);
|
|
|
|
+ markGroupClassProgressDto.setPercent(Calculator.divide2String(Calculator.multiply(markGroupClassProgressDto.getMarkedCount(), 100), Double.valueOf(markGroupClassProgressDto.getTaskCount()), 2));
|
|
|
|
+ markGroupClassProgressDto.setArbitrateCount(arbitrateCount);
|
|
|
|
+ }
|
|
|
|
+ return markGroupClassProgressDtoIPage;
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<MarkGroupQuestionsDto> listGroupQuestions(Long examId, String paperNumber) {
|
|
|
|
+ List<MarkQuestion> markQuestionList = this.listByExamIdAndPaperNumberAndObjective(examId, paperNumber, false);
|
|
|
|
+ List<MarkGroupQuestionsDto> markGroupQuestionsDtoList = new ArrayList<>();
|
|
|
|
+ for (MarkQuestion markQuestion : markQuestionList) {
|
|
|
|
+ MarkGroupQuestionsDto markGroupQuestionsDto = new MarkGroupQuestionsDto();
|
|
|
|
+ markGroupQuestionsDto.setQuestionId(markQuestion.getId());
|
|
|
|
+ markGroupQuestionsDto.setQuestionNumber(markQuestion.getQuestionNumber());
|
|
|
|
+ markGroupQuestionsDtoList.add(markGroupQuestionsDto);
|
|
|
|
+ }
|
|
|
|
+ return markGroupQuestionsDtoList;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void updateTaskCount(Long questionId, int taskCount) {
|
|
|
|
+ UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
|
|
|
|
+ updateWrapper.lambda().set(MarkQuestion::getTaskCount, taskCount)
|
|
|
|
+ .eq(MarkQuestion::getId, questionId);
|
|
|
|
+ this.update(updateWrapper);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void updateMarkedCount(Long questionId, int count) {
|
|
|
|
+ UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
|
|
|
|
+ updateWrapper.lambda().set(MarkQuestion::getMarkedCount, count)
|
|
|
|
+ .eq(MarkQuestion::getId, questionId);
|
|
|
|
+ this.update(updateWrapper);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void updateDoubleMarkByQuestionId(DoubleMarkParam doubleMarkParam) {
|
|
|
|
+ Long examId = doubleMarkParam.getExamId();
|
|
|
|
+ String paperNumber = doubleMarkParam.getPaperNumber();
|
|
|
|
+ Long questionId = doubleMarkParam.getQuestionId();
|
|
|
|
+ List<MarkTaskStatus> markTaskStatuses = Arrays.asList(MarkTaskStatus.MARKED, MarkTaskStatus.WAIT_ARBITRATE, MarkTaskStatus.PROBLEM, MarkTaskStatus.REJECTED, MarkTaskStatus.ARBITRATED);
|
|
|
|
+ if (markTaskService.countByExamIdAndPaperNumberAndQuestionIdAndStatusIn(examId, paperNumber, questionId, markTaskStatuses) > 0) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("该题已开始评卷,不允许修改");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ MarkQuestion markQuestion = this.getById(questionId);
|
|
|
|
+
|
|
|
|
+ UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
|
|
|
|
+ updateWrapper.lambda().set(MarkQuestion::getDoubleRate, doubleMarkParam.getDoubleRate())
|
|
|
|
+ .set(MarkQuestion::getArbitrateThreshold, doubleMarkParam.getArbitrateThreshold())
|
|
|
|
+ .set(MarkQuestion::getScorePolicy, doubleMarkParam.getScorePolicy())
|
|
|
|
+ .eq(MarkQuestion::getId, doubleMarkParam.getQuestionId());
|
|
|
|
+ this.update(updateWrapper);
|
|
|
|
+
|
|
|
|
+ // 单、又评切换、双评比例修改,删除任务
|
|
|
|
+ if (!markQuestion.getDoubleRate().equals(doubleMarkParam.getDoubleRate())) {
|
|
|
|
+ this.updateMarkedCount(questionId, 0);
|
|
|
|
+ this.updateTaskCount(questionId, 0);
|
|
|
|
+ if (lockService.trylock(LockType.QUESTION_UPDATE, questionId)) {
|
|
|
|
+ markSyncService.deleteMarkTask(markQuestion);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public MarkQuestionSubjectiveStepStatusDto stepStatus(Long examId, String paperNumber) {
|
|
|
|
+ List<MarkQuestion> markQuestionList = this.listByExamIdAndPaperNumberAndObjective(examId, paperNumber, false);
|
|
|
|
+ Boolean subjectiveStruct = false, subjectiveMarker = false, subjectiveMarkerClass = false, objectiveAnswer = false;
|
|
|
|
+ if (CollectionUtils.isNotEmpty(markQuestionList)) {
|
|
|
|
+ // 主观题结构,小题分是否设置
|
|
|
|
+ long countStruct = markQuestionList.stream().filter(m -> m.getTotalScore() == null || m.getIntervalScore() == null).count();
|
|
|
|
+ subjectiveStruct = countStruct == 0;
|
|
|
|
+
|
|
|
|
+ if (subjectiveStruct) {
|
|
|
|
+ // 主观题设置评卷员
|
|
|
|
+ long countPic = markQuestionList.stream().filter(m -> StringUtils.isBlank(m.getPicList())).count();
|
|
|
|
+ subjectiveMarker = countPic == 0;
|
|
|
|
+ if (subjectiveMarker) {
|
|
|
|
+ for (MarkQuestion markQuestion : markQuestionList) {
|
|
|
|
+ List<MarkUserQuestion> markUserQuestionList = markUserQuestionService.listByExamIdAndPaperNumberAndQuestionId(examId, paperNumber, markQuestion.getId());
|
|
|
|
+ if (CollectionUtils.isEmpty(markUserQuestionList)) {
|
|
|
|
+ subjectiveMarker = false;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (subjectiveMarker) {
|
|
|
|
+ // 分班阅
|
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ subjectiveMarkerClass = markPaper != null && markPaper.getClassMark();
|
|
|
|
+ if (subjectiveMarkerClass) {
|
|
|
|
+ MarkStudentQuery markStudentQuery = new MarkStudentQuery();
|
|
|
|
+ markStudentQuery.setExamId(examId);
|
|
|
|
+ markStudentQuery.setPaperNumber(paperNumber);
|
|
|
|
+ List<MarkStudentVo> markStudentList = markStudentService.listMarkStudentVo(markStudentQuery);
|
|
|
|
+ List<String> teachClasses = markStudentList.stream().filter(m -> StringUtils.isNotBlank(m.getTeachClassName())).map(MarkStudentVo::getTeachClassName).distinct().collect(Collectors.toList());
|
|
|
|
+ for (MarkQuestion markQuestion : markQuestionList) {
|
|
|
|
+ List<String> classNames = markUserQuestionService.countClassByExamIdAndPaperNumberAndQuestionId(examId, paperNumber, markQuestion.getId());
|
|
|
|
+ if (!CollectionUtils.isEqualCollection(teachClasses, classNames)) {
|
|
|
|
+ subjectiveMarkerClass = false;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (subjectiveMarkerClass) {
|
|
|
|
+ // 客观题标答
|
|
|
|
+ List<MarkQuestionAnswer> markQuestionAnswerList = markQuestionAnswerService.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, null);
|
|
|
|
+ long countAnswer = markQuestionAnswerList.stream().filter(m -> StringUtils.isBlank(m.getAnswer()) || m.getObjectivePolicy() == null).count();
|
|
|
|
+ objectiveAnswer = countAnswer == 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return new MarkQuestionSubjectiveStepStatusDto(subjectiveStruct, subjectiveMarker, subjectiveMarkerClass, objectiveAnswer);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void updatePic(String content, List<MarkQuestion> markQuestions) {
|
|
|
|
+ List<SubPictureConfig> pictureConfigs = CardParseUtils.parseCardPic(content, markQuestions);
|
|
|
|
+ List<SubPictureConfig> subPictureConfigList;
|
|
|
|
+ for (MarkQuestion markQuestion : markQuestions) {
|
|
|
|
+ // 填空题区域为一个整体
|
|
|
|
+ if (markQuestion.getQuestionType() == 4) {
|
|
|
|
+ subPictureConfigList = pictureConfigs.stream().filter(m -> m.getMainNumber().equals(markQuestion.getMainNumber())).collect(Collectors.toList());
|
|
|
|
+ } else {
|
|
|
|
+ subPictureConfigList = pictureConfigs.stream().filter(m -> m.getQuestionNumber().equals(markQuestion.getQuestionNumber())).collect(Collectors.toList());
|
|
|
|
+ }
|
|
|
|
+ markQuestion.setPicList(SubPictureConfig.transfer(subPictureConfigList));
|
|
|
|
+ }
|
|
|
|
+ this.updateBatchById(markQuestions);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public long countUnBindMarkerByExamIdAndPaperNumberAndObjective(Long examId, String paperNumber, boolean objective) {
|
|
|
|
+ return this.baseMapper.countUnBindMarkerByExamIdAndPaperNumberAndObjective(examId, paperNumber, objective);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public long countByExamIdAndPaperNumberAndObjective(Long examId, String paperNumber, boolean objective) {
|
|
|
|
+ QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
|
|
|
|
+ queryWrapper.lambda().eq(MarkQuestion::getExamId, examId)
|
|
|
|
+ .eq(MarkQuestion::getPaperNumber, paperNumber)
|
|
|
|
+ .eq(MarkQuestion::getObjective, objective);
|
|
|
|
+ return this.count(queryWrapper);
|
|
|
|
+ }
|
|
|
|
+}
|