AsyncTask.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. package com.qxgmat.task;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.nuliji.tools.Transform;
  4. import com.qxgmat.data.constants.enums.QuestionDifficult;
  5. import com.qxgmat.data.constants.enums.QuestionType;
  6. import com.qxgmat.data.constants.enums.ServiceKey;
  7. import com.qxgmat.data.constants.enums.SettingKey;
  8. import com.qxgmat.data.constants.enums.logic.ExerciseLogic;
  9. import com.qxgmat.data.constants.enums.logic.SentenceLogic;
  10. import com.qxgmat.data.constants.enums.module.StructModule;
  11. import com.qxgmat.data.dao.entity.*;
  12. import com.qxgmat.data.relation.entity.QuestionNoRelation;
  13. import com.qxgmat.service.UserServiceService;
  14. import com.qxgmat.service.UsersService;
  15. import com.qxgmat.service.extend.ExerciseService;
  16. import com.qxgmat.service.extend.MessageExtendService;
  17. import com.qxgmat.service.extend.SentenceService;
  18. import com.qxgmat.service.inline.*;
  19. import org.slf4j.Logger;
  20. import org.slf4j.LoggerFactory;
  21. import org.springframework.beans.factory.annotation.Autowired;
  22. import org.springframework.scheduling.annotation.Async;
  23. import org.springframework.stereotype.Component;
  24. import java.util.*;
  25. import java.util.stream.Collectors;
  26. @Component
  27. public class AsyncTask {
  28. private static final Logger logger = LoggerFactory.getLogger(AsyncTask.class);
  29. @Autowired
  30. private SentenceQuestionService sentenceQuestionService;
  31. @Autowired
  32. private SentenceService sentenceService;
  33. @Autowired
  34. private ExerciseService exerciseService;
  35. @Autowired
  36. private QuestionNoService questionNoService;
  37. @Autowired
  38. private ExerciseStructService exerciseStructService;
  39. @Autowired
  40. private SettingService settingService;
  41. @Autowired
  42. private TextbookLibraryService textbookLibraryService;
  43. @Autowired
  44. private CourseDataService courseDataService;
  45. @Autowired
  46. private CourseDataHistoryService courseDataHistoryService;
  47. @Autowired
  48. private MessageExtendService messageExtendService;
  49. @Autowired
  50. private UserServiceService userServiceService;
  51. @Autowired
  52. private UsersService usersService;
  53. @Autowired
  54. private UserOrderRecordService userOrderRecordService;
  55. @Autowired
  56. private UserCourseDataSubscribeService userCourseDataSubscribeService;
  57. @Async
  58. public void autoExercisePaper() {
  59. logger.info("自动练习组卷:顺序,考点,难易度");
  60. long start = System.currentTimeMillis();
  61. Setting setting = settingService.getByKey(SettingKey.EXERCISE_PAPER_STATUS);
  62. JSONObject status = setting.getValue();
  63. if (status == null) {
  64. status = new JSONObject();
  65. }
  66. int progress = 10;
  67. status.put("progress", progress);
  68. settingService.edit(setting);
  69. // 按所有4级结构
  70. List<ExerciseStruct> p = exerciseStructService.all();
  71. for(ExerciseStruct struct : p){
  72. if (struct.getLevel()!=4){
  73. continue;
  74. }
  75. progress += 70 / p.size();
  76. status.put("progress", progress);
  77. settingService.edit(setting);
  78. String prefixTitle = String.format("%s", struct.getTitleZh());
  79. QuestionType questionType = QuestionType.ValueOf(struct.getExtend());
  80. List<QuestionNoRelation> list = questionNoService.listWithRelationByStruct(StructModule.EXERCISE, struct.getId());
  81. // 按顺序组卷
  82. logger.debug("{}", exerciseService.getPaperLength());
  83. List<ExercisePaper> noPapers = exerciseService.createPaper(prefixTitle, questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.NO, null, list);
  84. Collection noIds = Transform.getIds(noPapers, ExercisePaper.class, "id");
  85. exerciseService.switchPaper(struct.getParentId(), struct.getId(), ExerciseLogic.NO, noIds);
  86. // 按难度组卷
  87. List<Integer> allDifficultIds = new ArrayList<>();
  88. for(QuestionDifficult difficult : QuestionDifficult.all()){
  89. List<QuestionNoRelation> difficultList = list.stream().filter((question)-> question.getQuestion().getDifficult().equals(difficult.key)).collect(Collectors.toList());
  90. List<ExercisePaper> difficultPapers = exerciseService.createPaper(String.format("%s-%s", prefixTitle, difficult.key), questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.DIFFICULT, difficult.key, difficultList);
  91. Collection difficultIds = Transform.getIds(difficultPapers, ExercisePaper.class, "id");
  92. allDifficultIds.addAll(difficultIds);
  93. }
  94. exerciseService.switchPaper(struct.getParentId(), struct.getId(), ExerciseLogic.DIFFICULT, allDifficultIds);
  95. // 按考点组卷
  96. Map<String, List<QuestionNoRelation>> placeMap = new HashMap<>();
  97. for(QuestionNoRelation relation:list){
  98. String place = relation.getQuestion().getPlace();
  99. if (!placeMap.containsKey(place)){
  100. placeMap.put(place, new ArrayList<>());
  101. }
  102. List<QuestionNoRelation> placeList = placeMap.get(place);
  103. placeList.add(relation);
  104. }
  105. List<Integer> allPlaceIds = new ArrayList<>();
  106. for(String place: placeMap.keySet()){
  107. List<QuestionNoRelation> placeList = placeMap.get(place);
  108. List<ExercisePaper> difficultPapers = exerciseService.createPaper(String.format("%s-%s", prefixTitle, place), questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.PLACE, place, placeList);
  109. Collection placeIds = Transform.getIds(difficultPapers, ExercisePaper.class, "id");
  110. allPlaceIds.addAll(placeIds);
  111. }
  112. exerciseService.switchPaper(struct.getParentId(), struct.getId(), ExerciseLogic.PLACE, allPlaceIds);
  113. // 按难易度组卷:保持和下方难易度组卷一致
  114. list.sort((x, y)-> {
  115. // 难度从高到低
  116. Integer xScore = x.getTotalNumber() > 0 ? x.getTotalCorrect() * 100/ x.getTotalNumber() : 0;
  117. Integer yScore = y.getTotalNumber() > 0 ? y.getTotalCorrect() * 100/ y.getTotalNumber(): 0;
  118. return yScore.compareTo(xScore);
  119. });
  120. List<ExercisePaper> errorPapers = exerciseService.createPaper(prefixTitle, questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.ERROR, null, list);
  121. Collection errorIds = Transform.getIds(errorPapers, ExercisePaper.class, "id");
  122. exerciseService.switchPaper(struct.getParentId(), struct.getId(), ExerciseLogic.ERROR, errorIds);
  123. }
  124. status.put("progress", 80);
  125. settingService.edit(setting);
  126. // 作文组卷
  127. for(ExerciseStruct struct : p){
  128. if (struct.getLevel()!=3 || !struct.getExtend().equals(QuestionType.AWA.key)){
  129. continue;
  130. }
  131. String prefixTitle = String.format("%s", struct.getTitleZh());
  132. QuestionType questionType = QuestionType.ValueOf(struct.getExtend());
  133. List<QuestionNoRelation> list = questionNoService.listWithRelationByStruct(StructModule.EXERCISE, struct.getId());
  134. // 按顺序组卷
  135. List<ExercisePaper> noPapers = exerciseService.createPaper(prefixTitle, questionType, struct.getId(), 0, exerciseService.getAwaLength(), ExerciseLogic.NO, null, list);
  136. Collection noIds = Transform.getIds(noPapers, ExercisePaper.class, "id");
  137. exerciseService.switchPaper(struct.getId(), 0, ExerciseLogic.NO, noIds);
  138. }
  139. status.put("progress", 80);
  140. settingService.edit(setting);
  141. // 逻辑组卷
  142. for(ExerciseStruct struct : p){
  143. if (struct.getLevel()!=3 || !struct.getExtend().equals(QuestionType.IR.key)){
  144. continue;
  145. }
  146. String prefixTitle = String.format("%s", struct.getTitleZh());
  147. QuestionType questionType = QuestionType.ValueOf(struct.getExtend());
  148. List<QuestionNoRelation> list = questionNoService.listWithRelationByStruct(StructModule.EXERCISE, struct.getId());
  149. // 按顺序组卷
  150. List<ExercisePaper> noPapers = exerciseService.createPaper(prefixTitle, questionType, struct.getId(), 0, exerciseService.getIrLength(), ExerciseLogic.NO, null, list);
  151. Collection noIds = Transform.getIds(noPapers, ExercisePaper.class, "id");
  152. exerciseService.switchPaper(struct.getId(), 0, ExerciseLogic.NO, noIds);
  153. }
  154. status.put("progress", 100);
  155. settingService.edit(setting);
  156. long end = System.currentTimeMillis();
  157. logger.info("自动练习组卷,耗时:" + (end - start) + "毫秒");
  158. }
  159. @Async
  160. public void autoExercisePaperError() {
  161. logger.info("自动练习:难易度组卷,全局难易度判断");
  162. long start = System.currentTimeMillis();
  163. // 按所有4级结构
  164. List<ExerciseStruct> p = exerciseStructService.all();
  165. for(ExerciseStruct struct : p){
  166. if (struct.getLevel()!=4){
  167. continue;
  168. }
  169. String prefixTitle = String.format("%s%s", struct.getTitleEn(), struct.getTitleZh());
  170. QuestionType questionType = QuestionType.ValueOf(struct.getExtend());
  171. List<QuestionNoRelation> list = questionNoService.listWithRelationByStruct(StructModule.EXERCISE, struct.getId());
  172. // 按难易度组卷:保持和上方难易度组卷一致
  173. list.sort((x, y)-> {
  174. // 难度从高到低
  175. Integer xScore = x.getTotalNumber() > 0 ? x.getTotalCorrect() * 100/ x.getTotalNumber() : 0;
  176. Integer yScore = y.getTotalNumber() > 0 ? y.getTotalCorrect() * 100/ y.getTotalNumber(): 0;
  177. return yScore.compareTo(xScore);
  178. });
  179. List<ExercisePaper> errorPapers = exerciseService.createPaper(prefixTitle, questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.ERROR, null, list);
  180. Collection errorIds = Transform.getIds(errorPapers, SentencePaper.class, "id");
  181. exerciseService.switchPaper(struct.getParentId(), struct.getId(), ExerciseLogic.ERROR, errorIds);
  182. }
  183. long end = System.currentTimeMillis();
  184. logger.info("自动练习难易度组卷,耗时:" + (end - start) + "毫秒");
  185. }
  186. @Async
  187. public void autoSentencePaper() {
  188. logger.info("自动长难句:对于试用卷进行自动生成");
  189. long start = System.currentTimeMillis();
  190. Setting setting = settingService.getByKey(SettingKey.SENTENCE_PAPER_STATUS);
  191. JSONObject status = setting.getValue();
  192. if (status == null) {
  193. status = new JSONObject();
  194. }
  195. status.put("progress", 10);
  196. settingService.edit(setting);
  197. // 获取所有组卷长难句题目
  198. List<SentenceQuestion> list = sentenceQuestionService.allPaper();
  199. status.put("progress", 20);
  200. settingService.edit(setting);
  201. // 组正常卷
  202. List<SentencePaper> noPapers = sentenceService.createPaper("长难句", SentenceLogic.NO, list);
  203. status.put("progress", 30);
  204. settingService.edit(setting);
  205. Collection noIds = Transform.getIds(noPapers, SentencePaper.class, "id");
  206. status.put("progress", 40);
  207. settingService.edit(setting);
  208. sentenceService.switchPaper(SentenceLogic.NO, noIds);
  209. status.put("progress", 60);
  210. settingService.edit(setting);
  211. // 组试用卷
  212. List<SentenceQuestion> trailList = list.stream().filter((question)-> question.getIsTrail() > 0).collect(Collectors.toList());
  213. List<SentencePaper> trailPapers = sentenceService.createPaper("长难句试用", SentenceLogic.TRAIL, trailList);
  214. status.put("progress", 70);
  215. settingService.edit(setting);
  216. Collection trailIds = Transform.getIds(trailPapers, SentencePaper.class, "id");
  217. status.put("progress", 80);
  218. settingService.edit(setting);
  219. sentenceService.switchPaper(SentenceLogic.TRAIL, trailIds);
  220. status.put("progress", 100);
  221. settingService.edit(setting);
  222. long end = System.currentTimeMillis();
  223. logger.info("自动长难句组卷,耗时:" + (end - start) + "毫秒");
  224. }
  225. @Async
  226. public void postTextbookLibrary(){
  227. logger.info("换库");
  228. long start = System.currentTimeMillis();
  229. TextbookLibrary latest = textbookLibraryService.getLatest();
  230. TextbookLibrary second = textbookLibraryService.getSecond();
  231. List<User> userList;
  232. // 所有用户
  233. int page = 1;
  234. int size = 20;
  235. do {
  236. userList = usersService.select(page, size);
  237. for(User user : userList){
  238. messageExtendService.sendTextbookLibrary(user, latest, second);
  239. }
  240. }while(userList.size() >= size);
  241. long end = System.currentTimeMillis();
  242. logger.info("发布机经,耗时:" + (end - start) + "毫秒");
  243. }
  244. @Async
  245. public void postTextbookUpdate(){
  246. logger.info("发布机经:发送到订阅用户邮箱");
  247. long start = System.currentTimeMillis();
  248. TextbookLibrary textbookLibrary = textbookLibraryService.getLatest();
  249. List<UserService> userServiceList;
  250. // 所有开通机经的用户
  251. int page = 1;
  252. int size = 20;
  253. do {
  254. userServiceList = userServiceService.listByService(page, size, ServiceKey.TEXTBOOK, null);
  255. Map userServiceMap = Transform.getMap(userServiceList, UserService.class, "userId");
  256. Collection userIds = Transform.getIds(userServiceList, UserService.class, "userId");
  257. List<User> userList = usersService.select(userIds);
  258. for(User user : userList){
  259. UserService userService = (UserService) userServiceMap.get(user.getId());
  260. messageExtendService.sendTextbookUpdate(user, textbookLibrary, userService.getIsSubscribe() > 0);
  261. }
  262. }while(userServiceList.size() >= size);
  263. long end = System.currentTimeMillis();
  264. logger.info("发布机经,耗时:" + (end - start) + "毫秒");
  265. }
  266. @Async
  267. public void postDataUpdate(Integer dataHistoryId){
  268. logger.info("资料更新");
  269. long start = System.currentTimeMillis();
  270. CourseDataHistory history = courseDataHistoryService.get(dataHistoryId);
  271. CourseData courseData = courseDataService.get(history.getDataId());
  272. List<UserCourseDataSubscribe> subscribeList;
  273. // 所有订阅资料的用户
  274. int page = 1;
  275. int size = 20;
  276. do {
  277. subscribeList = userCourseDataSubscribeService.listByData(page, size, courseData.getId());
  278. Collection userIds = Transform.getIds(subscribeList, UserCourseDataSubscribe.class, "userId");
  279. List<User> userList = usersService.select(userIds);
  280. List<UserOrderRecord> records = userOrderRecordService.listWithDataUser(courseData.getId(), userIds);
  281. Map recordMap = Transform.getMap(records, UserOrderRecord.class, "userId");
  282. for(User user : userList){
  283. // 购买并且开通邮箱订阅:才算邮箱订阅
  284. // 纸质没有购买记录,发送也不区分是否订阅状态
  285. messageExtendService.sendDataUpdate(user, courseData, history, user.getDataEmailSubscribe() > 0 && recordMap.get(user.getId())!= null);
  286. }
  287. }while(subscribeList.size() >= size);
  288. long end = System.currentTimeMillis();
  289. logger.info("资料更新,耗时:" + (end - start) + "毫秒");
  290. }
  291. }