package com.mindskip.xzs.service.impl; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.mindskip.xzs.domain.*; import com.mindskip.xzs.domain.enums.ExamPaperAnswerStatusEnum; import com.mindskip.xzs.domain.enums.ExamPaperTypeEnum; import com.mindskip.xzs.domain.enums.QuestionTypeEnum; import com.mindskip.xzs.domain.exam.ExamPaperTitleItemObject; import com.mindskip.xzs.domain.other.ExamPaperAnswerUpdate; import com.mindskip.xzs.domain.other.KeyValue; import com.mindskip.xzs.domain.task.TaskItemAnswerObject; import com.mindskip.xzs.domain.vo.ExamPaperDataExportVO; import com.mindskip.xzs.domain.vo.ExamPaperDataVO; import com.mindskip.xzs.domain.vo.ExamPaperStatisticVO; import com.mindskip.xzs.repository.ExamPaperAnswerMapper; import com.mindskip.xzs.repository.ExamPaperMapper; import com.mindskip.xzs.repository.QuestionMapper; import com.mindskip.xzs.repository.TaskExamCustomerAnswerMapper; import com.mindskip.xzs.service.ExamPaperAnswerService; import com.mindskip.xzs.service.ExamPaperQuestionCustomerAnswerService; import com.mindskip.xzs.service.TextContentService; import com.mindskip.xzs.utility.DateTimeUtil; import com.mindskip.xzs.utility.ExamUtil; import com.mindskip.xzs.utility.JsonUtil; import com.mindskip.xzs.viewmodel.admin.paper.ExamPaperGradePageRequestVM; import com.mindskip.xzs.viewmodel.admin.paper.ExamPaperGradeQuery; import com.mindskip.xzs.viewmodel.student.exam.ExamPaperSubmitItemVM; import com.mindskip.xzs.viewmodel.student.exam.ExamPaperSubmitVM; import com.mindskip.xzs.viewmodel.student.exampaper.ExamPaperAnswerPageVM; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; @Service public class ExamPaperAnswerServiceImpl extends BaseServiceImpl implements ExamPaperAnswerService { private final ExamPaperAnswerMapper examPaperAnswerMapper; private final ExamPaperMapper examPaperMapper; private final TextContentService textContentService; private final QuestionMapper questionMapper; private final ExamPaperQuestionCustomerAnswerService examPaperQuestionCustomerAnswerService; private final TaskExamCustomerAnswerMapper taskExamCustomerAnswerMapper; @Autowired public ExamPaperAnswerServiceImpl(ExamPaperAnswerMapper examPaperAnswerMapper, ExamPaperMapper examPaperMapper, TextContentService textContentService, QuestionMapper questionMapper, ExamPaperQuestionCustomerAnswerService examPaperQuestionCustomerAnswerService, TaskExamCustomerAnswerMapper taskExamCustomerAnswerMapper) { super(examPaperAnswerMapper); this.examPaperAnswerMapper = examPaperAnswerMapper; this.examPaperMapper = examPaperMapper; this.textContentService = textContentService; this.questionMapper = questionMapper; this.examPaperQuestionCustomerAnswerService = examPaperQuestionCustomerAnswerService; this.taskExamCustomerAnswerMapper = taskExamCustomerAnswerMapper; } @Override public PageInfo studentPage(ExamPaperAnswerPageVM requestVM) { return PageHelper.startPage(requestVM.getPageIndex(), requestVM.getPageSize(), "id desc").doSelectPageInfo(() -> examPaperAnswerMapper.studentPage(requestVM)); } @Override public ExamPaperAnswerInfo calculateExamPaperAnswer(ExamPaperSubmitVM examPaperSubmitVM, User user) { ExamPaperAnswerInfo examPaperAnswerInfo = new ExamPaperAnswerInfo(); Date now = new Date(); ExamPaper examPaper = examPaperMapper.selectByPrimaryKey(examPaperSubmitVM.getId()); ExamPaperTypeEnum paperTypeEnum = ExamPaperTypeEnum.fromCode(examPaper.getPaperType()); //任务试卷只能做一次 if (paperTypeEnum == ExamPaperTypeEnum.Task) { ExamPaperAnswer examPaperAnswer = examPaperAnswerMapper.getByPidUid(examPaperSubmitVM.getId(), user.getId()); if (null != examPaperAnswer) return null; } String frameTextContent = textContentService.selectById(examPaper.getFrameTextContentId()).getContent(); List examPaperTitleItemObjects = JsonUtil.toJsonListObject(frameTextContent, ExamPaperTitleItemObject.class); List questionIds = examPaperTitleItemObjects.stream().flatMap(t -> t.getQuestionItems().stream().map(q -> q.getId())).collect(Collectors.toList()); List questions = questionMapper.selectByIds(questionIds); //将题目结构的转化为题目答案 List examPaperQuestionCustomerAnswers = examPaperTitleItemObjects.stream() .flatMap(t -> t.getQuestionItems().stream() .map(q -> { Question question = questions.stream().filter(tq -> tq.getId().equals(q.getId())).findFirst().get(); ExamPaperSubmitItemVM customerQuestionAnswer = examPaperSubmitVM.getAnswerItems().stream() .filter(tq -> tq.getQuestionId().equals(q.getId())) .findFirst() .orElse(null); return ExamPaperQuestionCustomerAnswerFromVM(question, customerQuestionAnswer, examPaper, q.getItemOrder(), user, now); }) ).collect(Collectors.toList()); ExamPaperAnswer examPaperAnswer = ExamPaperAnswerFromVM(examPaperSubmitVM, examPaper, examPaperQuestionCustomerAnswers, user, now); examPaperAnswerInfo.setExamPaper(examPaper); examPaperAnswerInfo.setExamPaperAnswer(examPaperAnswer); examPaperAnswerInfo.setExamPaperQuestionCustomerAnswers(examPaperQuestionCustomerAnswers); return examPaperAnswerInfo; } @Override @Transactional public String judge(ExamPaperSubmitVM examPaperSubmitVM) { ExamPaperAnswer examPaperAnswer = examPaperAnswerMapper.selectByPrimaryKey(examPaperSubmitVM.getId()); List judgeItems = examPaperSubmitVM.getAnswerItems().stream().filter(d -> d.getDoRight() == null).collect(Collectors.toList()); List examPaperAnswerUpdates = new ArrayList<>(judgeItems.size()); Integer customerScore = examPaperAnswer.getUserScore(); Integer questionCorrect = examPaperAnswer.getQuestionCorrect(); for (ExamPaperSubmitItemVM d : judgeItems) { ExamPaperAnswerUpdate examPaperAnswerUpdate = new ExamPaperAnswerUpdate(); examPaperAnswerUpdate.setId(d.getId()); examPaperAnswerUpdate.setCustomerScore(ExamUtil.scoreFromVM(d.getScore())); boolean doRight = examPaperAnswerUpdate.getCustomerScore().equals(ExamUtil.scoreFromVM(d.getQuestionScore())); examPaperAnswerUpdate.setDoRight(doRight); examPaperAnswerUpdates.add(examPaperAnswerUpdate); customerScore += examPaperAnswerUpdate.getCustomerScore(); if (examPaperAnswerUpdate.getDoRight()) { ++questionCorrect; } } examPaperAnswer.setUserScore(customerScore); examPaperAnswer.setQuestionCorrect(questionCorrect); examPaperAnswer.setStatus(ExamPaperAnswerStatusEnum.Complete.getCode()); examPaperAnswerMapper.updateByPrimaryKeySelective(examPaperAnswer); examPaperQuestionCustomerAnswerService.updateScore(examPaperAnswerUpdates); ExamPaperTypeEnum examPaperTypeEnum = ExamPaperTypeEnum.fromCode(examPaperAnswer.getPaperType()); switch (examPaperTypeEnum) { case Task: //任务试卷批改完成后,需要更新任务的状态 ExamPaper examPaper = examPaperMapper.selectByPrimaryKey(examPaperAnswer.getExamPaperId()); Integer taskId = examPaper.getTaskExamId(); Integer userId = examPaperAnswer.getCreateUser(); TaskExamCustomerAnswer taskExamCustomerAnswer = taskExamCustomerAnswerMapper.getByTUid(taskId, userId); TextContent textContent = textContentService.selectById(taskExamCustomerAnswer.getTextContentId()); List taskItemAnswerObjects = JsonUtil.toJsonListObject(textContent.getContent(), TaskItemAnswerObject.class); taskItemAnswerObjects.stream() .filter(d -> d.getExamPaperAnswerId().equals(examPaperAnswer.getId())) .findFirst().ifPresent(taskItemAnswerObject -> taskItemAnswerObject.setStatus(examPaperAnswer.getStatus())); textContentService.jsonConvertUpdate(textContent, taskItemAnswerObjects, null); textContentService.updateByIdFilter(textContent); break; default: break; } return ExamUtil.scoreToVM(customerScore); } @Override public ExamPaperSubmitVM examPaperAnswerToVM(Integer id) { ExamPaperSubmitVM examPaperSubmitVM = new ExamPaperSubmitVM(); ExamPaperAnswer examPaperAnswer = examPaperAnswerMapper.selectByPrimaryKey(id); examPaperSubmitVM.setId(examPaperAnswer.getId()); examPaperSubmitVM.setDoTime(examPaperAnswer.getDoTime()); examPaperSubmitVM.setScore(ExamUtil.scoreToVM(examPaperAnswer.getUserScore())); List examPaperQuestionCustomerAnswers = examPaperQuestionCustomerAnswerService.selectListByPaperAnswerId(examPaperAnswer.getId()); List examPaperSubmitItemVMS = examPaperQuestionCustomerAnswers.stream() .map(a -> examPaperQuestionCustomerAnswerService.examPaperQuestionCustomerAnswerToVM(a)) .collect(Collectors.toList()); examPaperSubmitVM.setAnswerItems(examPaperSubmitItemVMS); return examPaperSubmitVM; } @Override public Integer selectAllCount(List deptIds) { return examPaperAnswerMapper.selectAllCount(deptIds); } @Override public List selectMothCount() { Date startTime = DateTimeUtil.getMonthStartDay(); Date endTime = DateTimeUtil.getMonthEndDay(); List mouthCount = examPaperAnswerMapper.selectCountByDate(startTime, endTime); List mothStartToNowFormat = DateTimeUtil.MothStartToNowFormat(); return mothStartToNowFormat.stream().map(md -> { KeyValue keyValue = mouthCount.stream().filter(kv -> kv.getName().equals(md)).findAny().orElse(null); return null == keyValue ? 0 : keyValue.getValue(); }).collect(Collectors.toList()); } /** * 用户提交答案的转化存储对象 * * @param question question * @param customerQuestionAnswer customerQuestionAnswer * @param examPaper examPaper * @param itemOrder itemOrder * @param user user * @param now now * @return ExamPaperQuestionCustomerAnswer */ private ExamPaperQuestionCustomerAnswer ExamPaperQuestionCustomerAnswerFromVM(Question question, ExamPaperSubmitItemVM customerQuestionAnswer, ExamPaper examPaper, Integer itemOrder, User user, Date now) { ExamPaperQuestionCustomerAnswer examPaperQuestionCustomerAnswer = new ExamPaperQuestionCustomerAnswer(); examPaperQuestionCustomerAnswer.setQuestionId(question.getId()); examPaperQuestionCustomerAnswer.setExamPaperId(examPaper.getId()); examPaperQuestionCustomerAnswer.setQuestionScore(question.getScore()); examPaperQuestionCustomerAnswer.setSubjectId(examPaper.getSubjectId()); examPaperQuestionCustomerAnswer.setItemOrder(itemOrder); examPaperQuestionCustomerAnswer.setCreateTime(now); examPaperQuestionCustomerAnswer.setCreateUser(user.getId()); examPaperQuestionCustomerAnswer.setQuestionType(question.getQuestionType()); examPaperQuestionCustomerAnswer.setQuestionTextContentId(question.getInfoTextContentId()); if (null == customerQuestionAnswer) { examPaperQuestionCustomerAnswer.setCustomerScore(0); } else { setSpecialFromVM(examPaperQuestionCustomerAnswer, question, customerQuestionAnswer); } return examPaperQuestionCustomerAnswer; } /** * 判断提交答案是否正确,保留用户提交的答案 * * @param examPaperQuestionCustomerAnswer examPaperQuestionCustomerAnswer * @param question question * @param customerQuestionAnswer customerQuestionAnswer */ private void setSpecialFromVM(ExamPaperQuestionCustomerAnswer examPaperQuestionCustomerAnswer, Question question, ExamPaperSubmitItemVM customerQuestionAnswer) { QuestionTypeEnum questionTypeEnum = QuestionTypeEnum.fromCode(examPaperQuestionCustomerAnswer.getQuestionType()); switch (questionTypeEnum) { case SingleChoice: examPaperQuestionCustomerAnswer.setAnswer(customerQuestionAnswer.getContent()); examPaperQuestionCustomerAnswer.setDoRight(question.getCorrect().equals(customerQuestionAnswer.getContent())); examPaperQuestionCustomerAnswer.setCustomerScore(examPaperQuestionCustomerAnswer.getDoRight() ? question.getScore() : 0); break; case TrueFalse: examPaperQuestionCustomerAnswer.setAnswer(customerQuestionAnswer.getContent()); examPaperQuestionCustomerAnswer.setDoRight(question.getCorrect().equals(customerQuestionAnswer.getContent())); examPaperQuestionCustomerAnswer.setCustomerScore(examPaperQuestionCustomerAnswer.getDoRight() ? question.getScore() : 0); break; case MultipleChoice: String customerAnswer = customerQuestionAnswer.getContent() ==null ? ExamUtil.contentToString(customerQuestionAnswer.getContentArray()) : customerQuestionAnswer.getContent(); examPaperQuestionCustomerAnswer.setAnswer(customerAnswer); examPaperQuestionCustomerAnswer.setDoRight(customerAnswer.equals(question.getCorrect())); examPaperQuestionCustomerAnswer.setCustomerScore(examPaperQuestionCustomerAnswer.getDoRight() ? question.getScore() : 0); break; case GapFilling: String correctAnswer = JsonUtil.toJsonStr(customerQuestionAnswer.getContentArray()); examPaperQuestionCustomerAnswer.setAnswer(correctAnswer); examPaperQuestionCustomerAnswer.setCustomerScore(0); break; default: examPaperQuestionCustomerAnswer.setAnswer(customerQuestionAnswer.getContent()); examPaperQuestionCustomerAnswer.setCustomerScore(0); break; } } private ExamPaperAnswer ExamPaperAnswerFromVM(ExamPaperSubmitVM examPaperSubmitVM, ExamPaper examPaper, List examPaperQuestionCustomerAnswers, User user, Date now) { Integer systemScore = examPaperQuestionCustomerAnswers.stream().mapToInt(a -> a.getCustomerScore()).sum(); long questionCorrect = examPaperQuestionCustomerAnswers.stream().filter(a -> a.getCustomerScore().equals(a.getQuestionScore())).count(); ExamPaperAnswer examPaperAnswer = new ExamPaperAnswer(); examPaperAnswer.setPaperName(examPaper.getName()); examPaperAnswer.setDoTime(examPaperSubmitVM.getDoTime()); examPaperAnswer.setExamPaperId(examPaper.getId()); examPaperAnswer.setCreateUser(user.getId()); examPaperAnswer.setCreateTime(now); examPaperAnswer.setSubjectId(examPaper.getSubjectId()); examPaperAnswer.setQuestionCount(examPaper.getQuestionCount()); examPaperAnswer.setPaperScore(examPaper.getScore()); examPaperAnswer.setPaperType(examPaper.getPaperType()); examPaperAnswer.setSystemScore(systemScore); examPaperAnswer.setUserScore(systemScore); examPaperAnswer.setTaskExamId(examPaper.getTaskExamId()); examPaperAnswer.setQuestionCorrect((int) questionCorrect); boolean needJudge = examPaperQuestionCustomerAnswers.stream().anyMatch(d -> QuestionTypeEnum.needSaveTextContent(d.getQuestionType())); if (needJudge) { examPaperAnswer.setStatus(ExamPaperAnswerStatusEnum.WaitJudge.getCode()); } else { examPaperAnswer.setStatus(ExamPaperAnswerStatusEnum.Complete.getCode()); } return examPaperAnswer; } @Override public PageInfo adminPage(com.mindskip.xzs.viewmodel.admin.paper.ExamPaperAnswerPageRequestVM requestVM) { return PageHelper.startPage(requestVM.getPageIndex(), requestVM.getPageSize(), "user_score desc").doSelectPageInfo(() -> examPaperAnswerMapper.adminPage(requestVM)); } @Override public ExamPaperAnswer getById(Integer id) { return examPaperAnswerMapper.getById(id); } @Override public List selectByPaperName(String paperName) { return examPaperAnswerMapper.selectByPaperName(paperName); } @Override public List getByExamPaperIdAndUserId(List examTemplatesUserCount) { return examPaperAnswerMapper.getByExamPaperIdAndUserId(examTemplatesUserCount); } @Override public PageInfo adminPageByGrade(ExamPaperGradePageRequestVM grade) { return PageHelper.startPage(grade.getPageIndex(), grade.getPageSize(), "id desc").doSelectPageInfo(() -> examPaperAnswerMapper.adminPageByGrade(grade)); } @Override public List getByScorePaperIdAndUserId(List scoreTemplatesUserCounts) { return examPaperAnswerMapper.getByScorePaperIdAndUserId(scoreTemplatesUserCounts); } @Override public PageInfo getByCreatUser(ExamPaperGradeQuery query) { query.setFullTime(); return PageHelper.startPage(query.getPageIndex(), query.getPageSize(), "id desc").doSelectPageInfo(() -> examPaperAnswerMapper.getByCreatUser(query)); } @Override public Map statistic(ExamPaperStatisticVO examPaperStatisticVO) { // 获取原始数据 Map histogram; ExamPaperDataExportVO examPaperDataExportVO; if (Objects.equals(examPaperStatisticVO.getExamPaperType(), 7)) { histogram = examPaperAnswerMapper.histogramByTemplate(examPaperStatisticVO); examPaperDataExportVO = examPaperAnswerMapper.totalByTemplate(new ExamPaperDataVO().setId(examPaperStatisticVO.getExamPaperId()).setDeptIds(examPaperStatisticVO.getDepartmentId())); } else { histogram = examPaperAnswerMapper.histogram(examPaperStatisticVO); examPaperDataExportVO = examPaperAnswerMapper.totalByPaper(new ExamPaperDataVO().setId(examPaperStatisticVO.getExamPaperId()).setDeptIds(examPaperStatisticVO.getDepartmentId())); } // 不存在时填充0 if (Objects.isNull(examPaperDataExportVO)) { examPaperDataExportVO = new ExamPaperDataExportVO() .setExamTotal(examPaperAnswerMapper.getExamTotal(examPaperStatisticVO)) .setFactPeopleTotal(0) .setAverageScore(BigDecimal.ZERO) .setReferencePercentage(BigDecimal.ZERO); } Map pieChart = examPaperAnswerMapper.pieChart(examPaperStatisticVO); // 初始化结果容器 HashMap map = new HashMap<>(); List> score = new ArrayList<>(); List> age = new ArrayList<>(); List> examPeopleNum = new ArrayList<>(); // 处理成绩与年龄分布 histogram.forEach((k, v) -> { Map hashMap = new HashMap<>(); hashMap.put(k, v); if (k.contains("score")) { score.add(hashMap); } if (k.contains("age")) { age.add(hashMap); } }); // 处理参考人数(出席与缺席) pieChart.forEach((k, v) -> { Map hashMap = new HashMap<>(); hashMap.put(k, v); if ("totalAttended".equals(k)) { examPeopleNum.add(hashMap); } if ("totalAbsent".equals(k)) { examPeopleNum.add(hashMap); } }); map.put("score", score); map.put("age", age); map.put("examPeopleNum", examPeopleNum); map.put("total", examPaperDataExportVO); return map; } @Override public Map data(ExamPaperDataVO examPaperDataVO) { Map map = new HashMap<>(); // 随机试卷 if (Objects.equals(examPaperDataVO.getType(), 7)) { map.put("data", examPaperAnswerMapper.dataByTemplate(examPaperDataVO)); map.put("total", examPaperAnswerMapper.totalByTemplate(examPaperDataVO)); } else { map.put("data", examPaperAnswerMapper.dataByPaper(examPaperDataVO)); map.put("total", examPaperAnswerMapper.totalByPaper(examPaperDataVO)); } return map; } @Override public List dataExport(ExamPaperDataVO examPaperDataVO) { // 随机试卷 if (Objects.equals(examPaperDataVO.getType(), 7)) { List dataByTemplate = examPaperAnswerMapper.dataByTemplate(examPaperDataVO); ExamPaperDataExportVO totalByTemplate = examPaperAnswerMapper.totalByTemplate(examPaperDataVO); dataByTemplate.add(0, totalByTemplate.setName("所有部门")); return dataByTemplate; } else { List dataByPaper = examPaperAnswerMapper.dataByPaper(examPaperDataVO); ExamPaperDataExportVO totalByPaper = examPaperAnswerMapper.totalByPaper(examPaperDataVO); dataByPaper.add(0, totalByPaper.setName("所有部门")); return dataByPaper; } } }