QuestionFlowService.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. package com.qxgmat.service.extend;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.nuliji.tools.exception.ParameterException;
  4. import com.qxgmat.data.constants.enums.SettingKey;
  5. import com.qxgmat.data.constants.enums.module.PaperModule;
  6. import com.qxgmat.data.constants.enums.module.QuestionModule;
  7. import com.qxgmat.data.dao.entity.QuestionNo;
  8. import com.qxgmat.data.dao.entity.UserPaper;
  9. import com.qxgmat.data.dao.entity.UserQuestion;
  10. import com.qxgmat.data.dao.entity.UserReport;
  11. import com.qxgmat.data.relation.entity.QuestionNoRelation;
  12. import com.qxgmat.service.*;
  13. import com.qxgmat.service.annotation.InitPaper;
  14. import com.qxgmat.service.annotation.InitQuestion;
  15. import com.qxgmat.service.annotation.InitReport;
  16. import com.qxgmat.service.inline.QuestionNoService;
  17. import com.qxgmat.service.inline.SentenceQuestionService;
  18. import com.qxgmat.service.inline.UserReportService;
  19. import com.qxgmat.util.annotation.Callback;
  20. import org.springframework.stereotype.Service;
  21. import org.springframework.transaction.annotation.Transactional;
  22. import javax.annotation.Resource;
  23. import java.util.*;
  24. import java.util.stream.Collectors;
  25. @Service
  26. public class QuestionFlowService {
  27. @Resource
  28. private ExercisePaperService exercisePaperService;
  29. @Resource
  30. private HomeworkPreviewService homeworkPreviewService;
  31. @Resource
  32. private ExaminationPaperService examinationPaperService;
  33. @Resource
  34. private QuestionNoService questionNoService;
  35. @Resource
  36. private SentenceQuestionService sentenceQuestionService;
  37. @Resource
  38. private SentencePaperService sentencePaperService;
  39. @Resource
  40. private UserReportService userReportService;
  41. @Resource
  42. private UserPaperService userPaperService;
  43. @Resource
  44. private UserQuestionService userQuestionService;
  45. @Resource
  46. private ToolsService toolsService;
  47. // 初始化试卷的callback,根据试卷模块进行后续处理
  48. private Map<PaperModule, InitPaper> initPaperCallback = new HashMap<>();
  49. // 初始化报告的callback,根据试卷模块进行后续处理
  50. private Map<PaperModule, InitReport> initReportCallback = new HashMap<>();
  51. // 根据
  52. private Map<PaperModule, InitQuestion> nextCallback = new HashMap<>();
  53. // 完成试卷的callback,根据试卷模块进行后续处理
  54. private Map<PaperModule, Callback> finishCallback = new HashMap<>();
  55. // 提交答题的callback,根据试题模块进行后续处理
  56. private Map<QuestionModule, Callback> submitCallback;
  57. public QuestionFlowService(){
  58. initPaperCallback.put(PaperModule.EXERCISE, (paper, id)->{
  59. exercisePaperService.initUserPaper(paper, id);
  60. // 获取考题时间
  61. List<QuestionNoRelation> relationList = questionNoService.listWithRelationByIds(paper.getQuestionNoIds());
  62. Integer time = toolsService.computerTime(SettingKey.EXERCISE_TIME, relationList);
  63. paper.setTime(time);
  64. });
  65. initPaperCallback.put(PaperModule.HOMEWORK_PREVIEW, (paper, id)->{
  66. // 后台主动修改,无需变更
  67. });
  68. initPaperCallback.put(PaperModule.ERROR, (paper, id)->{
  69. // 用户主动添加,无需变更
  70. });
  71. initPaperCallback.put(PaperModule.COLLECT, (paper, id)->{
  72. // 用户主动添加,无需变更
  73. });
  74. initPaperCallback.put(PaperModule.SENTENCE, (paper, id)->{
  75. sentencePaperService.initUserPaper(paper, id);
  76. });
  77. initReportCallback.put(PaperModule.EXERCISE, (report, paper)->{
  78. JSONObject setting = report.getSetting();
  79. if (setting.getBoolean("disorder")){
  80. // 随机试题
  81. report.setQuestionNoIds(this.randomQuestionNoIds(paper.getQuestionNoIds()));
  82. }
  83. });
  84. initReportCallback.put(PaperModule.HOMEWORK_PREVIEW, (report, paper)->{
  85. JSONObject setting = report.getSetting();
  86. if (setting.getBoolean("disorder")){
  87. // 随机试题
  88. report.setQuestionNoIds(this.randomQuestionNoIds(paper.getQuestionNoIds()));
  89. }
  90. });
  91. initReportCallback.put(PaperModule.COLLECT, (report, paper)->{
  92. JSONObject setting = report.getSetting();
  93. if (setting.getBoolean("disorder")){
  94. // 随机试题
  95. report.setQuestionNoIds(this.randomQuestionNoIds(paper.getQuestionNoIds()));
  96. }
  97. });
  98. initReportCallback.put(PaperModule.ERROR, (report, paper)->{
  99. JSONObject setting = report.getSetting();
  100. if (setting.getBoolean("disorder")){
  101. // 随机试题
  102. report.setQuestionNoIds(this.randomQuestionNoIds(paper.getQuestionNoIds()));
  103. }
  104. });
  105. initReportCallback.put(PaperModule.SENTENCE, (paper, report)->{
  106. // 无特殊设置
  107. });
  108. nextCallback.put(PaperModule.EXERCISE, (question, report, lastQuestion)->{
  109. Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
  110. if (questionNoId == 0) return false;
  111. QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
  112. question.setQuestionNoId(relation.getId());
  113. question.setQuestionId(relation.getQuestionId());
  114. Integer time = toolsService.computerTime(SettingKey.EXERCISE_TIME, relation);
  115. question.setTime(time);
  116. return true;
  117. });
  118. nextCallback.put(PaperModule.HOMEWORK_PREVIEW, (question, report, lastQuestion)->{
  119. Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
  120. if (questionNoId == 0) return false;
  121. QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
  122. question.setQuestionNoId(relation.getId());
  123. question.setQuestionId(relation.getQuestionId());
  124. Integer time = toolsService.computerTime(SettingKey.EXERCISE_TIME, relation);
  125. question.setTime(time);
  126. return true;
  127. });
  128. nextCallback.put(PaperModule.COLLECT, (question, report, lastQuestion)->{
  129. Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
  130. if (questionNoId == 0) return false;
  131. QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
  132. question.setQuestionNoId(relation.getId());
  133. question.setQuestionId(relation.getQuestionId());
  134. Integer time = toolsService.computerTime(SettingKey.getTimeByPaperModule(PaperModule.ValueOf(relation.getModule())), relation);
  135. question.setTime(time);
  136. return true;
  137. });
  138. nextCallback.put(PaperModule.ERROR, (question, report, lastQuestion)->{
  139. Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
  140. if (questionNoId == 0) return false;
  141. QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
  142. question.setQuestionNoId(relation.getId());
  143. question.setQuestionId(relation.getQuestionId());
  144. Integer time = toolsService.computerTime(SettingKey.getTimeByPaperModule(PaperModule.ValueOf(relation.getModule())), relation);
  145. question.setTime(time);
  146. return true;
  147. });
  148. nextCallback.put(PaperModule.SENTENCE, (question, report, lastQuestion)->{
  149. Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
  150. if (questionNoId == 0) return false;
  151. QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
  152. question.setQuestionNoId(relation.getId());
  153. question.setQuestionId(relation.getQuestionId());
  154. question.setTime(0);
  155. return true;
  156. });
  157. finishCallback.put(PaperModule.EXERCISE, (obj)->{
  158. return exercisePaperService.finished((UserPaper) obj);
  159. });
  160. finishCallback.put(PaperModule.HOMEWORK_PREVIEW, (obj)->{
  161. return homeworkPreviewService.finished((UserPaper) obj);
  162. });
  163. finishCallback.put(PaperModule.EXAMINATION, (obj)->{
  164. return homeworkPreviewService.finished((UserPaper) obj);
  165. });
  166. submitCallback = new HashMap<>();
  167. submitCallback.put(QuestionModule.BASE, (obj)->{
  168. // 更新题目及题目编号统计
  169. return questionNoService.submit((UserQuestion) obj);
  170. });
  171. submitCallback.put(QuestionModule.SENTENCE, (obj)->{
  172. // 更新题目及题目编号统计
  173. return sentenceQuestionService.submit((UserQuestion) obj);
  174. });
  175. }
  176. /**
  177. * 开始新一轮做题
  178. * @param userId
  179. * @param module
  180. * @param paperId
  181. * @param setting
  182. * @return
  183. */
  184. @Transactional
  185. public UserReport start(Integer userId, PaperModule module, Integer paperId, JSONObject setting){
  186. UserPaper paper = userPaperService.getByPaper(userId, module, paperId, initPaperCallback.get(module));
  187. // 查找对应的report是否有,如果没有或reset为1,则添加
  188. if (paper.getIsReset() > 0) {
  189. paper.setIsReset(0);
  190. userPaperService.edit(paper);
  191. }
  192. // 记录考试设置
  193. UserReport report = userReportService.addByPaper(paper, setting, initReportCallback.get(module));
  194. return report;
  195. }
  196. /**
  197. * 获取report的下一道题
  198. * @param userId
  199. * @param userReportId
  200. * @return
  201. */
  202. public UserQuestion next(Integer userId, Integer userReportId){
  203. UserQuestion userQuestion = userQuestionService.getLastByReport(userId, userReportId);
  204. // 查找未完成的questionId
  205. if (userQuestion==null || userQuestion.getUserTime() >0){
  206. // 创建新的question
  207. UserReport report = userReportService.get(userReportId);
  208. userQuestion = userQuestionService.addByReport(report, userQuestion, nextCallback.get(PaperModule.ValueOf(report.getModule())));
  209. }
  210. return userQuestion;
  211. }
  212. /**
  213. * 提交试题
  214. * @param userId
  215. * @param userQuestionId
  216. * @param answer
  217. * @return
  218. */
  219. @Transactional
  220. public Boolean submit(Integer userId, Integer userQuestionId, JSONObject answer){
  221. UserQuestion userQuestion = userQuestionService.get(userQuestionId);
  222. if (!userQuestion.getUserId().equals(userId)){
  223. throw new ParameterException("题目不存在");
  224. }
  225. UserReport userReport = userReportService.get(userQuestion.getReportId());
  226. // 判断题目是否正确
  227. // 更新做题记录
  228. QuestionModule module = QuestionModule.WithPaper(PaperModule.ValueOf(userReport.getModule()));
  229. Callback callback = submitCallback.get(module);
  230. callback.callback(userQuestion);
  231. return true;
  232. }
  233. /**
  234. * 完成试卷,进行试卷分析
  235. * @param userId
  236. * @param userReportId
  237. * @return
  238. */
  239. @Transactional
  240. public Boolean finish(Integer userId, Integer userReportId){
  241. // 设定paper完成次数加1
  242. // 统计
  243. return true;
  244. }
  245. /**
  246. * 重新开始一份试卷:设定试卷reset=1,列表不绑定最后一次考试记录
  247. * @param paperId
  248. * @param userId
  249. * @return
  250. */
  251. public Boolean restart(Integer paperId, Integer userId){
  252. return userPaperService.reset(paperId, userId);
  253. }
  254. /**
  255. * 乱序生成题目列表
  256. * @param questionNoIds
  257. * @return
  258. */
  259. private Integer[] randomQuestionNoIds(Integer[] questionNoIds){
  260. Integer[] ran = new Integer[questionNoIds.length];
  261. List<Integer> base = Arrays.stream(questionNoIds).collect(Collectors.toList());
  262. int length = base.size();
  263. for(int i = 0; i < ran.length; i++){
  264. ran[i] = base.remove((int)(Math.random()*length));
  265. length -= 1;
  266. }
  267. return ran;
  268. }
  269. /**
  270. * 顺序获取下一题
  271. * @param ids
  272. * @param id
  273. * @return
  274. */
  275. private Integer nextId(Integer[] ids, Integer id){
  276. if (id == null) return ids[0];
  277. boolean flag = false;
  278. for(Integer a : ids){
  279. if (a.equals(id)){
  280. flag = true;
  281. continue;
  282. }
  283. if (flag){
  284. return a;
  285. }
  286. }
  287. return 0;
  288. }
  289. }