AsyncTask.java 16 KB

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