package com.qxgmat.task; import com.alibaba.fastjson.JSONObject; import com.nuliji.tools.Transform; import com.qxgmat.data.constants.enums.QuestionDifficult; import com.qxgmat.data.constants.enums.QuestionType; import com.qxgmat.data.constants.enums.ServiceKey; import com.qxgmat.data.constants.enums.SettingKey; import com.qxgmat.data.constants.enums.logic.ExerciseLogic; import com.qxgmat.data.constants.enums.logic.SentenceLogic; import com.qxgmat.data.constants.enums.module.StructModule; import com.qxgmat.data.dao.entity.*; import com.qxgmat.data.relation.entity.QuestionNoRelation; import com.qxgmat.service.UserServiceService; import com.qxgmat.service.UsersService; import com.qxgmat.service.extend.ExerciseService; import com.qxgmat.service.extend.MessageExtendService; import com.qxgmat.service.extend.SentenceService; import com.qxgmat.service.inline.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import java.util.*; import java.util.stream.Collectors; @Component public class AsyncTask { private static final Logger logger = LoggerFactory.getLogger(AsyncTask.class); @Autowired private SentenceQuestionService sentenceQuestionService; @Autowired private SentenceService sentenceService; @Autowired private ExerciseService exerciseService; @Autowired private QuestionNoService questionNoService; @Autowired private ExerciseStructService exerciseStructService; @Autowired private SettingService settingService; @Autowired private TextbookLibraryService textbookLibraryService; @Autowired private CourseDataService courseDataService; @Autowired private CourseDataHistoryService courseDataHistoryService; @Autowired private MessageExtendService messageExtendService; @Autowired private UserServiceService userServiceService; @Autowired private UsersService usersService; @Autowired private UserOrderRecordService userOrderRecordService; @Autowired private UserCourseDataSubscribeService userCourseDataSubscribeService; @Async public void autoExercisePaper() { logger.info("自动练习组卷:顺序,考点,难易度"); long start = System.currentTimeMillis(); Setting setting = settingService.getByKey(SettingKey.EXERCISE_PAPER_STATUS); JSONObject status = setting.getValue(); if (status == null) { status = new JSONObject(); } int progress = 10; status.put("progress", progress); settingService.edit(setting); // 按所有4级结构 List p = exerciseStructService.all(); for(ExerciseStruct struct : p){ if (struct.getLevel()!=4){ continue; } progress += 70 / p.size(); status.put("progress", progress); settingService.edit(setting); String prefixTitle = String.format("%s", struct.getTitleZh()); QuestionType questionType = QuestionType.ValueOf(struct.getExtend()); List list = questionNoService.listWithRelationByStruct(StructModule.EXERCISE, struct.getId()); // 按顺序组卷 logger.debug("{}", exerciseService.getPaperLength()); List noPapers = exerciseService.createPaper(prefixTitle, questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.NO, null, list); Collection noIds = Transform.getIds(noPapers, ExercisePaper.class, "id"); exerciseService.switchPaper(struct.getParentId(), struct.getId(), ExerciseLogic.NO, noIds); // 按难度组卷 List allDifficultIds = new ArrayList<>(); for(QuestionDifficult difficult : QuestionDifficult.all()){ List difficultList = list.stream().filter((question)-> question.getQuestion().getDifficult().equals(difficult.key)).collect(Collectors.toList()); List difficultPapers = exerciseService.createPaper(String.format("%s-%s", prefixTitle, difficult.key), questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.DIFFICULT, difficult.key, difficultList); Collection difficultIds = Transform.getIds(difficultPapers, ExercisePaper.class, "id"); allDifficultIds.addAll(difficultIds); } exerciseService.switchPaper(struct.getParentId(), struct.getId(), ExerciseLogic.DIFFICULT, allDifficultIds); // 按考点组卷 Map> placeMap = new HashMap<>(); for(QuestionNoRelation relation:list){ String place = relation.getQuestion().getPlace(); if (!placeMap.containsKey(place)){ placeMap.put(place, new ArrayList<>()); } List placeList = placeMap.get(place); placeList.add(relation); } List allPlaceIds = new ArrayList<>(); for(String place: placeMap.keySet()){ List placeList = placeMap.get(place); List difficultPapers = exerciseService.createPaper(String.format("%s-%s", prefixTitle, place), questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.PLACE, place, placeList); Collection placeIds = Transform.getIds(difficultPapers, ExercisePaper.class, "id"); allPlaceIds.addAll(placeIds); } exerciseService.switchPaper(struct.getParentId(), struct.getId(), ExerciseLogic.PLACE, allPlaceIds); // 按难易度组卷:保持和下方难易度组卷一致 list.sort((x, y)-> { // 难度从高到低 Integer xScore = x.getTotalNumber() > 0 ? x.getTotalCorrect() * 100/ x.getTotalNumber() : 0; Integer yScore = y.getTotalNumber() > 0 ? y.getTotalCorrect() * 100/ y.getTotalNumber(): 0; return yScore.compareTo(xScore); }); List errorPapers = exerciseService.createPaper(prefixTitle, questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.ERROR, null, list); Collection errorIds = Transform.getIds(errorPapers, ExercisePaper.class, "id"); exerciseService.switchPaper(struct.getParentId(), struct.getId(), ExerciseLogic.ERROR, errorIds); } status.put("progress", 80); settingService.edit(setting); // 作文组卷 for(ExerciseStruct struct : p){ if (struct.getLevel()!=3 || !struct.getExtend().equals(QuestionType.AWA.key)){ continue; } String prefixTitle = String.format("%s", struct.getTitleZh()); QuestionType questionType = QuestionType.ValueOf(struct.getExtend()); List list = questionNoService.listWithRelationByStruct(StructModule.EXERCISE, struct.getId()); // 按顺序组卷 List noPapers = exerciseService.createPaper(prefixTitle, questionType, struct.getId(), 0, exerciseService.getAwaLength(), ExerciseLogic.NO, null, list); Collection noIds = Transform.getIds(noPapers, ExercisePaper.class, "id"); exerciseService.switchPaper(struct.getId(), 0, ExerciseLogic.NO, noIds); } status.put("progress", 80); settingService.edit(setting); // 逻辑组卷 for(ExerciseStruct struct : p){ if (struct.getLevel()!=3 || !struct.getExtend().equals(QuestionType.IR.key)){ continue; } String prefixTitle = String.format("%s", struct.getTitleZh()); QuestionType questionType = QuestionType.ValueOf(struct.getExtend()); List list = questionNoService.listWithRelationByStruct(StructModule.EXERCISE, struct.getId()); // 按顺序组卷 List noPapers = exerciseService.createPaper(prefixTitle, questionType, struct.getId(), 0, exerciseService.getIrLength(), ExerciseLogic.NO, null, list); Collection noIds = Transform.getIds(noPapers, ExercisePaper.class, "id"); exerciseService.switchPaper(struct.getId(), 0, ExerciseLogic.NO, noIds); } status.put("progress", 100); settingService.edit(setting); long end = System.currentTimeMillis(); logger.info("自动练习组卷,耗时:" + (end - start) + "毫秒"); } @Async public void autoExercisePaperError() { logger.info("自动练习:难易度组卷,全局难易度判断"); long start = System.currentTimeMillis(); // 按所有4级结构 List p = exerciseStructService.all(); for(ExerciseStruct struct : p){ if (struct.getLevel()!=4){ continue; } String prefixTitle = String.format("%s%s", struct.getTitleEn(), struct.getTitleZh()); QuestionType questionType = QuestionType.ValueOf(struct.getExtend()); List list = questionNoService.listWithRelationByStruct(StructModule.EXERCISE, struct.getId()); // 按难易度组卷:保持和上方难易度组卷一致 list.sort((x, y)-> { // 难度从高到低 Integer xScore = x.getTotalNumber() > 0 ? x.getTotalCorrect() * 100/ x.getTotalNumber() : 0; Integer yScore = y.getTotalNumber() > 0 ? y.getTotalCorrect() * 100/ y.getTotalNumber(): 0; return yScore.compareTo(xScore); }); List errorPapers = exerciseService.createPaper(prefixTitle, questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.ERROR, null, list); Collection errorIds = Transform.getIds(errorPapers, SentencePaper.class, "id"); exerciseService.switchPaper(struct.getParentId(), struct.getId(), ExerciseLogic.ERROR, errorIds); } long end = System.currentTimeMillis(); logger.info("自动练习难易度组卷,耗时:" + (end - start) + "毫秒"); } @Async public void autoSentencePaper() { logger.info("自动长难句:对于试用卷进行自动生成"); long start = System.currentTimeMillis(); Setting setting = settingService.getByKey(SettingKey.SENTENCE_PAPER_STATUS); JSONObject status = setting.getValue(); if (status == null) { status = new JSONObject(); } status.put("progress", 10); settingService.edit(setting); // 获取所有组卷长难句题目 List list = sentenceQuestionService.allPaper(); status.put("progress", 20); settingService.edit(setting); // 组正常卷 List noPapers = sentenceService.createPaper("长难句", SentenceLogic.NO, list); status.put("progress", 30); settingService.edit(setting); Collection noIds = Transform.getIds(noPapers, SentencePaper.class, "id"); status.put("progress", 40); settingService.edit(setting); sentenceService.switchPaper(SentenceLogic.NO, noIds); status.put("progress", 60); settingService.edit(setting); // 组试用卷 List trailList = list.stream().filter((question)-> question.getIsTrail() > 0).collect(Collectors.toList()); List trailPapers = sentenceService.createPaper("长难句试用", SentenceLogic.TRAIL, trailList); status.put("progress", 70); settingService.edit(setting); Collection trailIds = Transform.getIds(trailPapers, SentencePaper.class, "id"); status.put("progress", 80); settingService.edit(setting); sentenceService.switchPaper(SentenceLogic.TRAIL, trailIds); status.put("progress", 100); settingService.edit(setting); long end = System.currentTimeMillis(); logger.info("自动长难句组卷,耗时:" + (end - start) + "毫秒"); } @Async public void postTextbookLibrary(){ logger.info("换库"); long start = System.currentTimeMillis(); TextbookLibrary latest = textbookLibraryService.getLatest(); TextbookLibrary second = textbookLibraryService.getSecond(); List userList; // 所有用户 int page = 1; int size = 20; do { userList = usersService.select(page, size); for(User user : userList){ messageExtendService.sendTextbookLibrary(user, latest, second); } }while(userList.size() >= size); long end = System.currentTimeMillis(); logger.info("发布机经,耗时:" + (end - start) + "毫秒"); } @Async public void postTextbookUpdate(){ logger.info("发布机经:发送到订阅用户邮箱"); long start = System.currentTimeMillis(); TextbookLibrary textbookLibrary = textbookLibraryService.getLatest(); List userServiceList; // 所有开通机经的用户 int page = 1; int size = 20; do { userServiceList = userServiceService.listByService(page, size, ServiceKey.TEXTBOOK, null); Map userServiceMap = Transform.getMap(userServiceList, UserService.class, "userId"); Collection userIds = Transform.getIds(userServiceList, UserService.class, "userId"); List userList = usersService.select(userIds); for(User user : userList){ UserService userService = (UserService) userServiceMap.get(user.getId()); messageExtendService.sendTextbookUpdate(user, textbookLibrary, userService.getIsSubscribe() > 0); } }while(userServiceList.size() >= size); long end = System.currentTimeMillis(); logger.info("发布机经,耗时:" + (end - start) + "毫秒"); } @Async public void postDataUpdate(Integer dataHistoryId){ logger.info("资料更新"); long start = System.currentTimeMillis(); CourseDataHistory history = courseDataHistoryService.get(dataHistoryId); CourseData courseData = courseDataService.get(history.getDataId()); List subscribeList; // 所有订阅资料的用户 int page = 1; int size = 20; do { subscribeList = userCourseDataSubscribeService.listByData(page, size, courseData.getId()); Collection userIds = Transform.getIds(subscribeList, UserCourseDataSubscribe.class, "userId"); List userList = usersService.select(userIds); List records = userOrderRecordService.listWithDataUser(courseData.getId(), userIds); Map recordMap = Transform.getMap(records, UserOrderRecord.class, "userId"); for(User user : userList){ // 购买并且开通邮箱订阅:才算邮箱订阅 // 纸质没有购买记录,发送也不区分是否订阅状态 messageExtendService.sendDataUpdate(user, courseData, history, user.getDataEmailSubscribe() > 0 && recordMap.get(user.getId())!= null); } }while(subscribeList.size() >= size); long end = System.currentTimeMillis(); logger.info("资料更新,耗时:" + (end - start) + "毫秒"); } }