package com.qxgmat.service.extend; import com.alibaba.fastjson.JSONObject; import com.nuliji.tools.exception.ParameterException; import com.qxgmat.data.constants.enums.SettingKey; import com.qxgmat.data.constants.enums.module.PaperModule; import com.qxgmat.data.constants.enums.module.QuestionModule; import com.qxgmat.data.dao.entity.QuestionNo; import com.qxgmat.data.dao.entity.UserPaper; import com.qxgmat.data.dao.entity.UserQuestion; import com.qxgmat.data.dao.entity.UserReport; import com.qxgmat.data.relation.entity.QuestionNoRelation; import com.qxgmat.service.*; import com.qxgmat.service.annotation.InitPaper; import com.qxgmat.service.annotation.InitQuestion; import com.qxgmat.service.annotation.InitReport; import com.qxgmat.service.inline.QuestionNoService; import com.qxgmat.service.inline.SentenceQuestionService; import com.qxgmat.service.inline.UserReportService; import com.qxgmat.util.annotation.Callback; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; @Service public class QuestionFlowService { @Resource private ExercisePaperService exercisePaperService; @Resource private HomeworkPreviewService homeworkPreviewService; @Resource private ExaminationPaperService examinationPaperService; @Resource private QuestionNoService questionNoService; @Resource private SentenceQuestionService sentenceQuestionService; @Resource private SentencePaperService sentencePaperService; @Resource private UserReportService userReportService; @Resource private UserPaperService userPaperService; @Resource private UserQuestionService userQuestionService; @Resource private ToolsService toolsService; // 初始化试卷的callback,根据试卷模块进行后续处理 private Map initPaperCallback = new HashMap<>(); // 初始化报告的callback,根据试卷模块进行后续处理 private Map initReportCallback = new HashMap<>(); // 根据 private Map nextCallback = new HashMap<>(); // 完成试卷的callback,根据试卷模块进行后续处理 private Map finishCallback = new HashMap<>(); // 提交答题的callback,根据试题模块进行后续处理 private Map submitCallback; public QuestionFlowService(){ initPaperCallback.put(PaperModule.EXERCISE, (paper, id)->{ exercisePaperService.initUserPaper(paper, id); // 获取考题时间 List relationList = questionNoService.listWithRelationByIds(paper.getQuestionNoIds()); Integer time = toolsService.computerTime(SettingKey.EXERCISE_TIME, relationList); paper.setTime(time); }); initPaperCallback.put(PaperModule.HOMEWORK_PREVIEW, (paper, id)->{ // 后台主动修改,无需变更 }); initPaperCallback.put(PaperModule.ERROR, (paper, id)->{ // 用户主动添加,无需变更 }); initPaperCallback.put(PaperModule.COLLECT, (paper, id)->{ // 用户主动添加,无需变更 }); initPaperCallback.put(PaperModule.SENTENCE, (paper, id)->{ sentencePaperService.initUserPaper(paper, id); }); initReportCallback.put(PaperModule.EXERCISE, (report, paper)->{ JSONObject setting = report.getSetting(); if (setting.getBoolean("disorder")){ // 随机试题 report.setQuestionNoIds(this.randomQuestionNoIds(paper.getQuestionNoIds())); } }); initReportCallback.put(PaperModule.HOMEWORK_PREVIEW, (report, paper)->{ JSONObject setting = report.getSetting(); if (setting.getBoolean("disorder")){ // 随机试题 report.setQuestionNoIds(this.randomQuestionNoIds(paper.getQuestionNoIds())); } }); initReportCallback.put(PaperModule.COLLECT, (report, paper)->{ JSONObject setting = report.getSetting(); if (setting.getBoolean("disorder")){ // 随机试题 report.setQuestionNoIds(this.randomQuestionNoIds(paper.getQuestionNoIds())); } }); initReportCallback.put(PaperModule.ERROR, (report, paper)->{ JSONObject setting = report.getSetting(); if (setting.getBoolean("disorder")){ // 随机试题 report.setQuestionNoIds(this.randomQuestionNoIds(paper.getQuestionNoIds())); } }); initReportCallback.put(PaperModule.SENTENCE, (paper, report)->{ // 无特殊设置 }); nextCallback.put(PaperModule.EXERCISE, (question, report, lastQuestion)->{ Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null); if (questionNoId == 0) return false; QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId); question.setQuestionNoId(relation.getId()); question.setQuestionId(relation.getQuestionId()); Integer time = toolsService.computerTime(SettingKey.EXERCISE_TIME, relation); question.setTime(time); return true; }); nextCallback.put(PaperModule.HOMEWORK_PREVIEW, (question, report, lastQuestion)->{ Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null); if (questionNoId == 0) return false; QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId); question.setQuestionNoId(relation.getId()); question.setQuestionId(relation.getQuestionId()); Integer time = toolsService.computerTime(SettingKey.EXERCISE_TIME, relation); question.setTime(time); return true; }); nextCallback.put(PaperModule.COLLECT, (question, report, lastQuestion)->{ Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null); if (questionNoId == 0) return false; QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId); question.setQuestionNoId(relation.getId()); question.setQuestionId(relation.getQuestionId()); Integer time = toolsService.computerTime(SettingKey.getTimeByPaperModule(PaperModule.ValueOf(relation.getModule())), relation); question.setTime(time); return true; }); nextCallback.put(PaperModule.ERROR, (question, report, lastQuestion)->{ Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null); if (questionNoId == 0) return false; QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId); question.setQuestionNoId(relation.getId()); question.setQuestionId(relation.getQuestionId()); Integer time = toolsService.computerTime(SettingKey.getTimeByPaperModule(PaperModule.ValueOf(relation.getModule())), relation); question.setTime(time); return true; }); nextCallback.put(PaperModule.SENTENCE, (question, report, lastQuestion)->{ Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null); if (questionNoId == 0) return false; QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId); question.setQuestionNoId(relation.getId()); question.setQuestionId(relation.getQuestionId()); question.setTime(0); return true; }); finishCallback.put(PaperModule.EXERCISE, (obj)->{ return exercisePaperService.finished((UserPaper) obj); }); finishCallback.put(PaperModule.HOMEWORK_PREVIEW, (obj)->{ return homeworkPreviewService.finished((UserPaper) obj); }); finishCallback.put(PaperModule.EXAMINATION, (obj)->{ return homeworkPreviewService.finished((UserPaper) obj); }); submitCallback = new HashMap<>(); submitCallback.put(QuestionModule.BASE, (obj)->{ // 更新题目及题目编号统计 return questionNoService.submit((UserQuestion) obj); }); submitCallback.put(QuestionModule.SENTENCE, (obj)->{ // 更新题目及题目编号统计 return sentenceQuestionService.submit((UserQuestion) obj); }); } /** * 开始新一轮做题 * @param userId * @param module * @param paperId * @param setting * @return */ @Transactional public UserReport start(Integer userId, PaperModule module, Integer paperId, JSONObject setting){ UserPaper paper = userPaperService.getByPaper(userId, module, paperId, initPaperCallback.get(module)); // 查找对应的report是否有,如果没有或reset为1,则添加 if (paper.getIsReset() > 0) { paper.setIsReset(0); userPaperService.edit(paper); } // 记录考试设置 UserReport report = userReportService.addByPaper(paper, setting, initReportCallback.get(module)); return report; } /** * 获取report的下一道题 * @param userId * @param userReportId * @return */ public UserQuestion next(Integer userId, Integer userReportId){ UserQuestion userQuestion = userQuestionService.getLastByReport(userId, userReportId); // 查找未完成的questionId if (userQuestion==null || userQuestion.getUserTime() >0){ // 创建新的question UserReport report = userReportService.get(userReportId); userQuestion = userQuestionService.addByReport(report, userQuestion, nextCallback.get(PaperModule.ValueOf(report.getModule()))); } return userQuestion; } /** * 提交试题 * @param userId * @param userQuestionId * @param answer * @return */ @Transactional public Boolean submit(Integer userId, Integer userQuestionId, JSONObject answer){ UserQuestion userQuestion = userQuestionService.get(userQuestionId); if (!userQuestion.getUserId().equals(userId)){ throw new ParameterException("题目不存在"); } UserReport userReport = userReportService.get(userQuestion.getReportId()); // 判断题目是否正确 // 更新做题记录 QuestionModule module = QuestionModule.WithPaper(PaperModule.ValueOf(userReport.getModule())); Callback callback = submitCallback.get(module); callback.callback(userQuestion); return true; } /** * 完成试卷,进行试卷分析 * @param userId * @param userReportId * @return */ @Transactional public Boolean finish(Integer userId, Integer userReportId){ // 设定paper完成次数加1 // 统计 return true; } /** * 重新开始一份试卷:设定试卷reset=1,列表不绑定最后一次考试记录 * @param paperId * @param userId * @return */ public Boolean restart(Integer paperId, Integer userId){ return userPaperService.reset(paperId, userId); } /** * 乱序生成题目列表 * @param questionNoIds * @return */ private Integer[] randomQuestionNoIds(Integer[] questionNoIds){ Integer[] ran = new Integer[questionNoIds.length]; List base = Arrays.stream(questionNoIds).collect(Collectors.toList()); int length = base.size(); for(int i = 0; i < ran.length; i++){ ran[i] = base.remove((int)(Math.random()*length)); length -= 1; } return ran; } /** * 顺序获取下一题 * @param ids * @param id * @return */ private Integer nextId(Integer[] ids, Integer id){ if (id == null) return ids[0]; boolean flag = false; for(Integer a : ids){ if (a.equals(id)){ flag = true; continue; } if (flag){ return a; } } return 0; } }