12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745 |
- package com.qxgmat.service.extend;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import com.nuliji.tools.Transform;
- import com.nuliji.tools.exception.ParameterException;
- import com.qxgmat.data.constants.enums.*;
- import com.qxgmat.data.constants.enums.module.*;
- import com.qxgmat.data.dao.entity.*;
- import com.qxgmat.data.relation.entity.*;
- import com.qxgmat.service.*;
- import com.qxgmat.service.annotation.*;
- import com.qxgmat.service.inline.*;
- 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 PreviewService previewService;
- @Resource
- private ExaminationPaperService examinationPaperService;
- @Resource
- private ExaminationStructService examinationStructService;
- @Resource
- private QuestionNoService questionNoService;
- @Resource
- private QuestionService questionService;
- @Resource
- private CourseService courseService;
- @Resource
- private SentenceQuestionService sentenceQuestionService;
- @Resource
- private SentencePaperService sentencePaperService;
- @Resource
- private TextbookQuestionService textbookQuestionService;
- @Resource
- private TextbookPaperService textbookPaperService;
- @Resource
- private PreviewPaperService previewPaperService;
- @Resource
- private PreviewAssignService previewAssignService;
- @Resource
- private UsersService usersService;
- @Resource
- private UserReportService userReportService;
- @Resource
- private UserPaperService userPaperService;
- @Resource
- private UserPaperQuestionService userPaperQuestionService;
- @Resource
- private UserQuestionService userQuestionService;
- @Resource
- private UserServiceService userServiceService;
- @Resource
- private UserCourseAppointmentService userCourseAppointmentService;
- @Resource
- private ExaminationService examinationService;
- @Resource
- private CourseExtendService courseExtendService;
- @Resource
- private ToolsService toolsService;
- @Resource
- private MessageExtendService messageExtendService;
- // 自由组卷初始化试卷callback
- private Map<QuestionModule, InitPaper> makePaperCallback = new HashMap<>();
- // 初始化试卷的callback,根据试卷模块进行后续处理
- private Map<PaperModule, InitPaper> initPaperCallback = new HashMap<>();
- // 初始化试卷的callback,根据试卷来源进行后续处理
- private Map<PaperOrigin, InitPaper> initOriginPaperCallback = new HashMap<>();
- // 重置试卷的callback,根据试卷模块进行后续处理
- private Map<PaperOrigin, InitPaper> resetPaperCallback = new HashMap<>();
- // 初始化报告的callback,根据试卷模块进行后续处理
- private Map<PaperModule, InitReport> initReportCallback = new HashMap<>();
- // 初始化题目,根据试卷模块进行选题处理
- private Map<PaperModule, InitQuestion> nextCallback = new HashMap<>();
- // 提交答题的callback,根据试题模块正确判断
- private Map<QuestionModule, SubmitQuestion> submitCallback = new HashMap<>();
- // 提交答题的callback,根据试题模块后续统计,会过滤满足剔除条件
- private Map<QuestionModule, SubmitAfterQuestion> submitAfterCallback = new HashMap<>();
- // 完成试卷的callback,根据试卷模块进行后续处理
- private Map<PaperModule, StatReport> finishCallback = new HashMap<>();
- public QuestionFlowService(){
- makePaperCallback.put(QuestionModule.BASE, (userPaper, id)->{
- // 获取考题时间
- List<QuestionNoRelation> relationList = questionNoService.listWithRelationByIds(userPaper.getQuestionNoIds());
- Integer time = toolsService.computerTime(relationList.toArray(new QuestionNoRelation[0]));
- userPaper.setTime(time);
- return userPaper;
- });
- makePaperCallback.put(QuestionModule.SENTENCE, (userPaper, id)->{
- // 获取考题时间
- List<SentenceQuestionRelation> relationList = sentenceQuestionService.listWithRelationByIds(userPaper.getQuestionNoIds());
- Integer time = toolsService.computerTime(relationList.toArray(new SentenceQuestionRelation[0]));
- userPaper.setTime(time);
- return userPaper;
- });
- makePaperCallback.put(QuestionModule.TEXTBOOK, (userPaper, id)->{
- // 获取考题时间
- List<TextbookQuestionRelation> relationList = textbookQuestionService.listWithRelationByIds(userPaper.getQuestionNoIds());
- Integer time = toolsService.computerTime(relationList.toArray(new TextbookQuestionRelation[0]));
- userPaper.setTime(time);
- return userPaper;
- });
- initOriginPaperCallback.put(PaperOrigin.PREVIEW, (userPaper, id)->{
- // id为分配表,找寻对应的paper
- PreviewAssign assign = previewAssignService.get(id);
- PreviewPaper paper = previewPaperService.get(assign.getPaperId());
- // 根据不同课程处理标题信息
- CourseModule courseModule = CourseModule.ValueOf(assign.getCourseModule());
- switch(courseModule){
- case VIDEO:
- case ONLINE:
- userPaper.setTitle(paper.getTitle());
- case VS:
- userPaper.setTitle(assign.getTitle());
- }
- // 新paper绑定当前记录关系
- if (userPaper.getRecordId() == 0){
- // 获取用户当前课程记录
- Integer recordId = previewService.getRecord(userPaper.getUserId(), id);
- userPaper.setRecordId(recordId);
- }
- userPaper.setQuestionNoIds(paper.getQuestionNoIds());
- // 根据papermodule得到考试时长
- QuestionModule module = QuestionModule.WithPaper(PaperModule.ValueOf(paper.getPaperModule()));
- InitPaper callback = makePaperCallback.get(module);
- return callback.callback(userPaper, id);
- });
- initPaperCallback.put(PaperModule.EXERCISE, (userPaper, id)->{
- ExercisePaper paper = exercisePaperService.get(id);
- userPaper.setTitle(paper.getTitle());
- userPaper.setQuestionNoIds(paper.getQuestionNoIds());
- // 获取考题时间
- List<QuestionNoRelation> relationList = questionNoService.listWithRelationByIds(userPaper.getQuestionNoIds());
- Integer time = toolsService.computerTime(relationList.toArray(new QuestionNoRelation[0]));
- userPaper.setTime(time);
- return userPaper;
- });
- initPaperCallback.put(PaperModule.SENTENCE, (userPaper, id)->{
- SentencePaper paper = sentencePaperService.get(id);
- userPaper.setTitle(paper.getTitle());
- userPaper.setQuestionNoIds(paper.getQuestionNoIds());
- userPaper.setQuestionNumber(paper.getQuestionNumber());
- // 获取考题时间
- List<SentenceQuestionRelation> relationList = sentenceQuestionService.listWithRelationByIds(userPaper.getQuestionNoIds());
- Integer time = toolsService.computerTime(relationList.toArray(new SentenceQuestionRelation[0]));
- userPaper.setTime(time);
- return userPaper;
- });
- initPaperCallback.put(PaperModule.TEXTBOOK, (userPaper, id)->{
- TextbookPaper paper = textbookPaperService.get(id);
- userPaper.setTitle(paper.getTitle());
- userPaper.setQuestionNoIds(paper.getQuestionNoIds());
- userPaper.setQuestionNumber(paper.getQuestionNumber());
- // 获取考题时间
- List<TextbookQuestionRelation> relationList = textbookQuestionService.listWithRelationByIds(userPaper.getQuestionNoIds());
- Integer time = toolsService.computerTime(relationList.toArray(new TextbookQuestionRelation[0]));
- userPaper.setTime(time);
- return userPaper;
- });
- initPaperCallback.put(PaperModule.EXAMINATION, (userPaper, id)->{
- ExaminationPaper paper = examinationPaperService.get(id);
- userPaper.setTitle(paper.getTitle());
- userPaper.setIsAdapt(paper.getIsAdapt());
- ExaminationPaper examinationPaper = examinationPaperService.get(userPaper.getOriginId());
- ExaminationStruct examinationStruct = examinationStructService.get(examinationPaper.getStructThree());
- ServiceKey serviceKey = ServiceKey.ValueOf(examinationStruct.getExtend());
- if (serviceKey == ServiceKey.QX_CAT) {
- User user = usersService.get(userPaper.getUserId());
- userPaper.setPaperNo(user.getQxCat());
- }
- return userPaper;
- });
- initReportCallback.put(PaperModule.EXERCISE, (report, paper)->{
- JSONObject setting = report.getSetting();
- if (setting.getBoolean("disorder")){
- // 随机试题: 选项随机,前端处理
- // report.setQuestionNoIds(this.randomQuestionNoIds(paper.getQuestionNoIds()));
- }
- });
- initReportCallback.put(PaperModule.SENTENCE, (report, paper)->{
- // 无特殊设置
- });
- initReportCallback.put(PaperModule.TEXTBOOK, (report, paper)->{
- // 无特殊设置
- });
- initReportCallback.put(PaperModule.EXAMINATION, (report, paper)->{
- JSONObject setting = report.getSetting();
- if (setting.getBoolean("disorder")){
- // 随机试题: 选项随机,前端处理
- // report.setQuestionNoIds(this.randomQuestionNoIds(paper.getQuestionNoIds()));
- }
- JSONArray order = setting.getJSONArray("order");
- // 初始化第一阶段
- setting.put("stage", order.getString(0));
- // 初始化每阶段时间, 以及做题数
- JSONObject time = new JSONObject();
- JSONObject number = new JSONObject();
- for(String stage : order.toJavaList(String.class)){
- time.put(stage, 0);
- number.put(stage, 0);
- }
- setting.put("time", time);
- setting.put("number", number);
- toolsService.examinationReportInit(report, order);
- });
- resetPaperCallback.put(PaperOrigin.PREVIEW, (userPaper, id)->{
- // 重新初始化
- InitPaper callback = initOriginPaperCallback.get(PaperOrigin.PREVIEW);
- return callback.callback(userPaper, id);
- });
- resetPaperCallback.put(PaperOrigin.EXAMINATION, (userPaper, id)->{
- // 如果是cat模考
- ExaminationPaper examinationPaper = examinationPaperService.get(userPaper.getOriginId());
- ExaminationStruct examinationStruct = examinationStructService.get(examinationPaper.getStructThree());
- ServiceKey serviceKey = ServiceKey.ValueOf(examinationStruct.getExtend());
- if (serviceKey == ServiceKey.QX_CAT){
- User user = usersService.get(userPaper.getUserId());
- // 创建新的paper
- userPaper = userPaperService.newByPaper(userPaper.getUserId(), PaperOrigin.ValueOf(userPaper.getPaperOrigin()), PaperModule.ValueOf(userPaper.getPaperModule()), userPaper.getOriginId());
- userPaper.setIsAdapt(userPaper.getIsAdapt());
- userPaper.setTitle(userPaper.getTitle());
- userPaper.setPaperNo(user.getQxCat());
- }
- return userPaper;
- });
- nextCallback.put(PaperModule.EXERCISE, (question, report, lastQuestion)->{
- Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
- if (questionNoId == 0) return false;
- this.bindQuestionNo(question, questionNoId);
- // 设定最后一次练习记录
- usersService.edit(User.builder().id(question.getUserId()).latestExercise(report.getPaperId()).build());
- // 设定最后一次错题记录
- usersService.edit(User.builder().id(question.getUserId()).latestError(report.getPaperId()).build());
- 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;
- SentenceQuestionRelation relation = sentenceQuestionService.relation(sentenceQuestionService.get(questionNoId));
- question.setQuestionNoId(relation.getId());
- question.setQuestionId(relation.getQuestionId());
- question.setQuestionType(relation.getQuestion().getQuestionType());
- Integer time = toolsService.computerTime(relation);
- question.setTime(time);
- return true;
- });
- nextCallback.put(PaperModule.TEXTBOOK, (question, report, lastQuestion)->{
- Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
- if (questionNoId == 0) return false;
- TextbookQuestionRelation relation = textbookQuestionService.relation(textbookQuestionService.get(questionNoId));
- question.setQuestionNoId(relation.getId());
- question.setQuestionId(relation.getQuestionId());
- question.setQuestionType(relation.getQuestion().getQuestionType());
- Integer time = toolsService.computerTime(relation);
- question.setTime(time);
- return true;
- });
- nextCallback.put(PaperModule.EXAMINATION, (question, report, lastQuestion)->{
- ExaminationPaper paper = examinationPaperService.get(report.getOriginId());
- if (!examinationCompute(paper, report, lastQuestion, question)){
- return false;
- }
- // 保存report: 更新setting
- userReportService.edit(UserReport.builder().id(report.getId()).setting(report.getSetting()).build());
- return true;
- });
- submitCallback.put(QuestionModule.BASE, (userQuestion, userReport)->{
- // 判断答题情况
- JSONObject userAnswer = userQuestion.getUserAnswer();
- Question question = questionService.get(userQuestion.getQuestionId());
- // 作文统计字数
- if (question.getQuestionType().equals(QuestionType.AWA.key)){
- JSONObject detail = new JSONObject();
- String awa = userAnswer.getString("awa");
- String base = awa.replaceAll("/<[^>]+>/g", "")
- .replaceAll("/[,.+-:;']+/g", "");
- detail.put("words", base.split(" ").length);
- userQuestion.setDetail(detail);
- return false;
- }
- JSONObject answer = question.getAnswer();
- return (boolean) this.baseAnswer(userAnswer, answer, question);
- });
- submitCallback.put(QuestionModule.SENTENCE, (userQuestion, userReport)->{
- // 判断答题情况
- JSONObject userAnswer = userQuestion.getUserAnswer();
- Question question = questionService.get(userQuestion.getQuestionId());
- JSONObject answer = question.getAnswer();
- boolean correct = true;
- JSONObject detail = new JSONObject();
- boolean subjectCorrect = this.sentenceAnswer(userAnswer.getJSONArray("subject"), answer.getJSONArray("subject"));
- detail.put("subject", subjectCorrect);
- correct = correct & subjectCorrect;
- boolean predicateCorrect = this.sentenceAnswer(userAnswer.getJSONArray("predicate"), answer.getJSONArray("predicate"));
- detail.put("predicate", predicateCorrect);
- correct = correct & predicateCorrect;
- boolean objectCorrect = this.sentenceAnswer(userAnswer.getJSONArray("object"), answer.getJSONArray("object"));
- detail.put("object", objectCorrect);
- correct = correct & objectCorrect;
- boolean optionsCorrect = this.sentenceAnswerOption(userAnswer.getJSONArray("options"), answer.getJSONArray("options"));
- detail.put("options", optionsCorrect);
- // correct = correct & optionsCorrect;
- userQuestion.setDetail(detail);
- // 主谓宾判断正确,答题正确
- return correct;
- });
- submitCallback.put(QuestionModule.TEXTBOOK, (userQuestion, userReport)->{
- // 判断答题情况
- JSONObject userAnswer = userQuestion.getUserAnswer();
- Question question = questionService.get(userQuestion.getQuestionId());
- JSONObject answer = question.getAnswer();
- return this.baseAnswer(userAnswer, answer, question);
- });
- submitAfterCallback.put(QuestionModule.BASE, (userQuestion, question)->{
- // 作文不统计
- if (question.getQuestionType().equals(QuestionType.AWA.key)){
- return;
- }
- // 更新题目及题目编号统计
- questionNoService.accumulation(userQuestion);
- questionService.accumulation(userQuestion);
- // 统计答案分布
- this.answerDistributed(userQuestion, question);
- });
- submitAfterCallback.put(QuestionModule.SENTENCE, (userQuestion, question)->{
- // 更新题目及长难句统计
- sentenceQuestionService.accumulation(userQuestion);
- questionService.accumulation(userQuestion);
- });
- submitAfterCallback.put(QuestionModule.TEXTBOOK, (userQuestion, question)->{
- // 更新题目及机经统计
- textbookQuestionService.accumulation(userQuestion);
- questionService.accumulation(userQuestion);
- this.answerDistributed(userQuestion, question);
- });
- finishCallback.put(PaperModule.EXERCISE, (report, questionList)->{
- report.setDetail(this.statExerciseReport(report, questionList));
- });
- finishCallback.put(PaperModule.SENTENCE, (report, questionList)->{
- report.setDetail(this.statSentenceReport(report, questionList));
- });
- finishCallback.put(PaperModule.TEXTBOOK, (report, questionList)->{
- report.setDetail(this.statTextbookReport(report, questionList));
- });
- finishCallback.put(PaperModule.EXAMINATION, (report, questionList)->{
- this.statExaminationReport(report, questionList);
- });
- }
- /**
- * 自由组卷:根据题目编号id
- * @param userId
- * @param origin
- * @param questionNoIds
- * @param filterTimes
- * @return
- */
- @Transactional
- public UserPaper makePaper(Integer userId, QuestionModule module, PaperOrigin origin, List<Integer> questionNoIds, Integer filterTimes){
- // PaperOrigin只允许Error和Collect
- if (questionNoIds.size() == 0){
- throw new ParameterException("题目数为空");
- }
- // todo 题目数不能超过50
- // todo 不同类型不能一起组卷
- QuestionOrigin questionOrigin = QuestionOrigin.WithPaper(origin);
- if (filterTimes > 0){
- // 过滤重复多次的题目
- questionNoIds = userPaperQuestionService.filterTimesQuestion(userId, questionOrigin, module, questionNoIds, filterTimes);
- if (questionNoIds.size() == 0){
- throw new ParameterException("题目数为空");
- }
- }
- UserPaper paper = userPaperService.newByPaper(userId, origin, PaperModule.WithQuestion(module), 0);
- paper.setQuestionNumber(questionNoIds.size());
- paper.setQuestionNoIds(questionNoIds.toArray(new Integer[0]));
- InitPaper callback = makePaperCallback.get(module);
- paper = callback.callback(paper, 0);
- paper = userPaperService.add(paper);
- // 绑定关系,用于下次处理过滤
- userPaperQuestionService.addOrigin(userId, paper.getId(), questionOrigin, module, questionNoIds);
- return paper;
- }
- /**
- * 获取做题paper
- * @param userId
- * @param origin
- * @param paperId
- * @return
- */
- @Transactional
- public UserPaper paper(Integer userId, PaperOrigin origin, Integer paperId){
- PaperModule module = PaperModule.WithOrigin(origin);
- UserPaper paper = userPaperService.getByPaper(userId, origin, paperId);
- if (paper == null){
- paper = userPaperService.newByPaper(userId, origin, module, paperId);
- // 先判断来源初始化,如果没有,则根据模块初始化
- InitPaper callback = initOriginPaperCallback.get(origin);
- if (callback == null) {
- callback = initPaperCallback.get(module);
- }
- paper = callback.callback(paper, paperId);
- paper = userPaperService.add(paper);
- }
- return paper;
- }
- /**
- * 开始新一轮做题
- * @param userId
- * @param origin
- * @param paperId
- * @param setting
- * @return
- */
- @Transactional
- public UserReportRelation start(Integer userId, PaperOrigin origin, Integer paperId, JSONObject setting){
- UserPaper paper = paper(userId, origin, paperId);
- // 查找对应的report是否有,如果没有或reset为1,则添加
- UserReport userReport = null;
- if (paper.getIsReset() > 0) {
- paper.setIsReset(0);
- // 是否对重置有特殊处理
- InitPaper callback = resetPaperCallback.get(origin);
- if (callback != null){
- paper = callback.callback(paper, paperId);
- }
- if (paper.getId() != null){
- userPaperService.edit(paper);
- }else{
- paper = userPaperService.add(paper);
- }
- }else if(setting == null){
- // 对于长难句这种没有设置开始页的,读取最后一次
- userReport = userReportService.getLastByPaper(userId, paper.getId());
- }
- if (userReport == null){
- userReport = userReportService.newByPaper(paper, setting);
- InitReport callback = initReportCallback.get(PaperModule.ValueOf(paper.getPaperModule()));
- callback.callback(userReport, paper);
- userReportService.add(userReport);
- }
- return relationReport(userReport);
- }
- /**
- * 继续做题:判断是否可以继续
- * @param userId
- * @param userReportId
- * @return
- */
- public UserReportRelation continueReport(Integer userId, Integer userReportId){
- UserReport userReport = userReportService.get(userReportId);
- if (!userReport.getUserId().equals(userId)){
- throw new ParameterException("试卷不存在");
- }
- if (userReport.getDetail() != null && userReport.getFinishTime() != null){
- throw new ParameterException("做题结束");
- }
- if (userReport.getUserNumber()>=userReport.getQuestionNumber()){
- throw new ParameterException("答题结束,请提交完成");
- }
- return relationReport(userReport);
- }
- /**
- * 获取单个report信息:基础
- * @param userId
- * @param userReportId
- * @return
- */
- public UserReportRelation baseReport(Integer userId, Integer userReportId){
- UserReport userReport = userReportService.get(userReportId);
- if (!userReport.getUserId().equals(userId)){
- throw new ParameterException("试卷不存在");
- }
- return relationReport(userReport);
- }
- /**
- * 获取report的下一道题
- * @param userId
- * @param userReportId
- * @return
- */
- @Transactional
- public UserQuestion next(Integer userId, Integer userReportId){
- UserQuestion userQuestion = userQuestionService.getLastByReport(userId, userReportId);
- // 查找未完成的questionId
- if (userQuestion==null || userQuestion.getUserTime() >0){
- // 创建新的question
- UserReport userReport = userReportService.get(userReportId);
- if (!userReport.getUserId().equals(userId)){
- throw new ParameterException("试卷不存在");
- }
- UserQuestion lastQuestion = userQuestion;
- userQuestion = userQuestionService.newByReport(userReport, lastQuestion);
- InitQuestion callback = nextCallback.get(PaperModule.ValueOf(userReport.getPaperModule()));
- callback.callback(userQuestion, userReport, lastQuestion);
- userQuestion = userQuestionService.add(userQuestion);
- }
- return userQuestion;
- }
- /**
- * 提交试题
- * @param userId
- * @param userQuestion
- * @return
- */
- @Transactional
- public Boolean submit(Integer userId, UserQuestion userQuestion){
- if (!userQuestion.getUserId().equals(userId)){
- throw new ParameterException("题目不存在");
- }
- QuestionModule module = QuestionModule.ValueOf(userQuestion.getQuestionModule());
- UserReport userReport = userReportService.get(userQuestion.getReportId());
- SubmitQuestion callback = submitCallback.get(module);
- Boolean result = callback.callback(userQuestion, userReport);
- userQuestion.setIsCorrect(result ? 1 : 0);
- // 如果做错,从移除错题中移除
- if(!result){
- userPaperQuestionService.removeRemoveError(userId, module, userQuestion.getQuestionNoId());
- }
- userQuestionService.edit(userQuestion);
- // 根据剔除逻辑判断是否统计
- if (toolsService.filterTime(userQuestion)){
- Question question = questionService.get(userQuestion.getQuestionId());
- SubmitAfterQuestion afterCallback = submitAfterCallback.get(module);
- afterCallback.callback(userQuestion, question);
- }
- // 更新对应report记录
- userReportService.accumulation(userQuestion);
- // 自动finish
- if (userReport.getQuestionNumber().equals(userReport.getUserNumber())){
- this.finish(userId, userReport.getId());
- }
- return true;
- }
- /**
- * 模考进入下一阶段:调整出题逻辑,上一阶段都当成未完成
- * @param userId
- * @param userReportId
- * @return
- */
- @Transactional
- public Boolean stage(Integer userId, Integer userReportId){
- UserReport userReport = userReportService.get(userReportId);
- if (!userReport.getUserId().equals(userId)){
- throw new ParameterException("试卷不存在");
- }
- if (userReport.getDetail() != null && userReport.getFinishTime() != null){
- throw new ParameterException("做题结束");
- }
- PaperOrigin origin = PaperOrigin.ValueOf(userReport.getPaperOrigin());
- if (origin != PaperOrigin.EXAMINATION){
- throw new ParameterException("不是模考试卷");
- }
- ExaminationPaper paper = examinationPaperService.get(userReport.getOriginId());
- JSONObject setting = userReport.getSetting();
- // 当前stage,补全所有时间,切换成下一个stage
- JSONArray order = setting.getJSONArray("order");
- String stage = setting.getString("stage");
- JSONObject time = setting.getJSONObject("time");
- JSONObject number = setting.getJSONObject("number");
- Integer useTime = time.getInteger(stage);
- Integer totalTime = toolsService.examinationSubjectTime(stage);
- time.put(stage, totalTime);
- // 自动提交所有该stage的题目
- Integer totalNumber = toolsService.examinationSubjectNumber(stage);
- // 自动提交最后一题
- UserQuestion lastQuestion = userQuestionService.getLastByReport(userId, userReportId);
- UserQuestion question;
- if(lastQuestion != null && lastQuestion.getUserTime() == 0){
- lastQuestion.setUserTime(totalTime - useTime);
- this.submit(userId, lastQuestion);
- }
- // 判断未完成题目数,自动生成
- question = userQuestionService.newByReport(userReport, lastQuestion);
- while(number.getIntValue(stage) < totalNumber){
- examinationCompute(paper, userReport, lastQuestion, question);
- question = userQuestionService.add(question);
- lastQuestion = question;
- question = userQuestionService.newByReport(userReport, lastQuestion);
- }
- // 更新setting
- userReportService.edit(UserReport.builder()
- .id(userReportId)
- .setting(setting).build());
- // 如果是最后阶段。直接完成
- int index = order.indexOf(stage);
- if (index == order.size() - 1){
- // 完成所有阶段,结束考试
- this.finish(userId, userReport.getId());
- }
- return true;
- }
- /**
- * 完成试卷,进行试卷分析
- * @param userId
- * @param userReportId
- * @return
- */
- @Transactional
- public Boolean finish(Integer userId, Integer userReportId){
- UserReport userReport = userReportService.get(userReportId);
- if (!userReport.getUserId().equals(userId)){
- throw new ParameterException("试卷不存在");
- }
- if (userReport.getIsFinish() > 0){
- return true;
- }
- userReport.setFinishTime(new Date());
- userReport.setIsFinish(1);
- List<UserQuestion> userQuestionList = userQuestionService.listByReport(userId, userReportId);
- // 分析做题结果
- StatReport callback = finishCallback.get(PaperModule.ValueOf(userReport.getPaperModule()));
- callback.callback(userReport, userQuestionList);
- userReport.setIsStat(1);
- userReportService.edit(userReport);
- // 统计: 更新对应paper记录
- userPaperService.accumulation(userReport);
- return true;
- }
- /**
- * 重新开始一份试卷:设定试卷reset=1,列表不绑定最后一次考试记录
- * @param userPaperId
- * @param userId
- * @return
- */
- @Transactional
- public Boolean restart(Integer userPaperId, Integer userId){
- // 获取最后一次report,并生成结果
- UserReport userReport = userReportService.getLastByPaper(userId, userPaperId);
- List<UserQuestion> userQuestionList = userQuestionService.listByReport(userId, userReport.getId());
- // 分析做题结果
- StatReport callback = finishCallback.get(PaperModule.ValueOf(userReport.getPaperModule()));
- callback.callback(userReport, userQuestionList);
- userReport.setIsStat(1);
- userReportService.edit(userReport);
- return userPaperService.reset(userPaperId, userId);
- }
- /**
- * 获取提问权限记录
- * @param questionType
- * @return
- */
- public Integer questionRelationCourse(Integer userId, Integer assignId, QuestionType questionType){
- if (assignId != null){
- Integer assignRecordId = previewService.questionCourse(userId, assignId);
- if (assignRecordId != null) return assignRecordId;
- }
- return courseExtendService.questionRelationCourse(userId, questionType);
- }
- /**
- * 累计考试学习时间
- * @param userId
- * @return
- */
- public Integer studyTime(Integer userId, Date startTime, Date endTime){
- UserRecordStatRelation record = userQuestionService.stat(userId, startTime != null? startTime.toString():null, endTime != null ? endTime.toString(): null);
- return record != null ? record.getUserTime() : 0;
- }
- /**
- * 平均考试时间
- * @return
- */
- public Integer studyAvgTime(Date startTime, Date endTime){
- UserRecordStatRelation record = userQuestionService.statAvg(startTime != null? startTime.toString():null, endTime != null ? endTime.toString(): null);
- return record != null ? record.getUserTime() : 0;
- }
- /**
- * 模考完整出题逻辑
- * @param paper
- * @param report
- * @param lastQuestion
- * @param question
- * @return
- */
- public boolean examinationCompute(ExaminationPaper paper, UserReport report, UserQuestion lastQuestion, UserQuestion question){
- JSONObject setting = report.getSetting();
- JSONArray order = setting.getJSONArray("order");
- String stage = setting.getString("stage");
- JSONObject time = setting.getJSONObject("time");
- JSONObject number = setting.getJSONObject("number");
- time.put(stage, time.getIntValue(stage)+ lastQuestion.getUserTime());
- Integer totalNumber = toolsService.examinationSubjectNumber(stage);
- // 判断数量是否已经完成
- if (number.getIntValue(stage) >= totalNumber){
- // 进入下一阶段
- int index = order.indexOf(stage);
- if (index == order.size() - 1){
- // 完成所有阶段,结束考试
- return false;
- }
- stage = order.getString(index + 1);
- setting.put("stage", stage);
- // 重置stage数
- question.setStageNo(1);
- question.setStage(stage);
- }
- // 获取本阶段完成数,剩余题目数
- Integer subnumber = number.getIntValue(stage);
- Integer surplus = totalNumber - subnumber;
- QuestionSubject subject = QuestionSubject.ValueOf(stage);
- List<String> questionTypes = QuestionType.FromSubject(subject);
- List<UserQuestion> userQuestionList = userQuestionService.listByReportAndType(report.getUserId(), report.getId(), questionTypes);
- Collection ids = Transform.getIds(userQuestionList, UserQuestion.class, "questionNoId");
- // 根据设置出题
- Integer questionNoId = 0;
- if (paper.getIsAdapt() > 0 && QuestionSubject.SupportAdapt(subject)){
- switch(subject){
- case VERBAL:
- questionNoId = verbalCompute(paper, setting, subnumber, ids, userQuestionList);
- break;
- case QUANT:
- questionNoId = quantCompute(paper, setting, subnumber, ids, userQuestionList);
- break;
- default:
- throw new ParameterException("模考出题流程错误:"+subject.key+"不支持适应性判断");
- }
- }else{
- questionNoId = randomCompute(subject, paper, questionTypes, setting, subnumber, ids, userQuestionList);
- }
- if (questionNoId == 0) {
- throw new ParameterException("模考出题流程错误:题目生成错误");
- }
- QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
- question.setQuestionNoId(relation.getId());
- question.setQuestionId(relation.getQuestionId());
- question.setQuestionType(relation.getQuestion().getQuestionType());
- question.setTime(toolsService.computerTime(relation));
- // 更新题目数
- number.put(stage, subnumber + 1);
- return true;
- }
- /**
- * 语文出题计算
- * @param setting
- * @param subnumber
- * @param ids
- * @param subQuestionList
- * @return
- */
- public Integer verbalCompute(ExaminationPaper paper, JSONObject setting, Integer subnumber, Collection ids, List<UserQuestion> subQuestionList){
- // 一共分为4个阶段:每个阶段9题,包含一题阅读
- // 其中句改SC有14题,阅读RC有13题(共4篇阅读,每篇题数为3、3、3、4),逻辑CR为9题
- // verbal: { "steps": [{"ids": [], "level": 0}, {}] }
- List questionNoIds = new ArrayList<>();
- JSONObject verbal = setting.getJSONObject("verbal");
- if (verbal == null) {
- verbal = new JSONObject();
- verbal.put("steps", new JSONArray());
- setting.put("verbal", verbal);
- }
- JSONArray steps = verbal.getJSONArray("steps");
- // 判断当前是第几阶段
- Integer step = subnumber / examinationService.verbalPre + 1;
- Integer questionIndex = 0;
- JSONObject info;
- if (subnumber == 0){
- // 初始化
- info = examinationService.initVerbal(paper.getStructThree());
- steps.add(info);
- }else if(subnumber % examinationService.verbalPre == 0){
- info = steps.getJSONObject(step);
- List currentIds = info.getJSONArray("ids").toJavaObject(questionNoIds.getClass());
- // 计算上阶段的做题情况
- long correct = subQuestionList.stream().filter((x)->currentIds.contains(x.getQuestionNoId()) && x.getIsCorrect() > 0).count();
- // 下一阶段
- Integer level = examinationService.verbalNextLevel(info.getInteger("level"), examinationService.verbalPre, correct);
- Map<String, Integer> typeNumber = examinationService.statTypeNumber(subQuestionList);
- info = examinationService.generateVerbal(paper.getStructThree(), level, typeNumber, ids);
- steps.add(info);
- }else{
- info = steps.getJSONObject(step);
- questionIndex = subnumber % examinationService.verbalPre;
- }
- //获取下一题
- questionNoIds = info.getJSONArray("ids").toJavaObject(questionNoIds.getClass());
- return (Integer) questionNoIds.get(questionIndex);
- }
- /**
- * 数学出题计算
- * @param setting
- * @param subnumber
- * @param ids
- * @param subQuestionList
- * @return
- */
- public Integer quantCompute(ExaminationPaper paper, JSONObject setting, Integer subnumber, Collection ids, List<UserQuestion> subQuestionList){
- // 一共分为4个阶段:每个阶段题分别为8、8、8、7题,合计31题
- // 其中数学PS有17题,数学DS有14题
- // quant: { "steps": [{"ids": [], "level": 0}, {}] }
- List questionNoIds = new ArrayList<>();
- JSONObject quant = setting.getJSONObject("quant");
- if (quant == null) {
- quant = new JSONObject();
- quant.put("steps", new JSONArray());
- setting.put("quant", quant);
- }
- JSONArray steps = quant.getJSONArray("steps");
- // 判断当前是第几阶段
- Integer step = examinationService.quantStep(subnumber);
- Integer nextStep = examinationService.quantStep(subnumber+1);
- Integer questionIndex = 0;
- JSONObject info;
- if (subnumber == 0){
- // 初始化
- info = examinationService.initQuant(paper.getStructThree());
- steps.add(info);
- }else if(step < nextStep){
- info = steps.getJSONObject(step);
- List currentIds = info.getJSONArray("ids").toJavaObject(questionNoIds.getClass());
- // 计算上阶段的做题情况
- long correct = subQuestionList.stream().filter((x)->currentIds.contains(x.getQuestionNoId()) && x.getIsCorrect() > 0).count();
- // 下一阶段
- Integer level = examinationService.quantNextLevel(info.getInteger("level"), examinationService.quantBaseLevel[step], correct, step);
- Map<String, Integer> typeNumber = examinationService.statTypeNumber(subQuestionList);
- info = examinationService.generateQuant(paper.getStructThree(), level, typeNumber, ids, nextStep);
- steps.add(info);
- }else{
- info = steps.getJSONObject(step);
- questionIndex = subnumber - examinationService.quantNumber[step];
- }
- //获取下一题
- questionNoIds = info.getJSONArray("ids").toJavaObject(questionNoIds.getClass());
- return (Integer) questionNoIds.get(questionIndex);
- }
- /**
- * 随机出题计算
- * @param subject
- * @param paper
- * @param questionTypes
- * @param setting
- * @param subnumber
- * @param ids
- * @param subQuestionList
- * @return
- */
- public Integer randomCompute(QuestionSubject subject, ExaminationPaper paper, List<String> questionTypes, JSONObject setting, Integer subnumber, Collection ids, List<UserQuestion> subQuestionList){
- // 随机挑题
- switch (subject){
- case VERBAL:
- // 固定顺序抽取阅读题
- if(examinationService.verbalRC(subnumber)){
- // 第一次抽取4题,后面抽取3题,和适应性一致
- JSONObject rc = setting.getJSONObject("rc");
- Integer number = 0;
- if (rc == null) {
- rc = new JSONObject();
- setting.put("rc", rc);
- number = 4;
- }else{
- number = 3;
- }
- Integer[] questions = questionNoService.randomExaminationRc(paper.getStructThree(), number, rc.values());
- // 写入后续题目关系
- Integer position = subnumber;
- for(int q: questions){
- rc.put(position.toString(), q);
- position += 1;
- }
- }
- // 判断是否后续阅读题
- JSONObject rc = setting.getJSONObject("rc");
- if(rc.getInteger(subnumber.toString()) != null){
- return rc.getIntValue(subnumber.toString());
- }
- break;
- }
- Map<String, Integer> typeNumber = examinationService.statTypeNumber(subQuestionList);
- List<String> targetTypes = examinationService.needQuestionTypes(typeNumber, questionTypes);
- // 不主动查询阅读题:targetTypes没有rc
- return questionNoService.randomExamination(paper.getStructThree(), targetTypes, ids);
- }
- /**
- * 获取报告题目列表
- * @param userReportId
- * @param userId
- * @return
- */
- public List<UserQuestion> listByReport(Integer userReportId, Integer userId){
- List<UserQuestion> userQuestionList = userQuestionService.listByReport(userId, userReportId);
- return userQuestionList;
- }
- /**
- * 乱序生成题目列表
- * @param questionNoIds
- * @return
- */
- private Integer[] randomQuestionNoIds(Integer[] questionNoIds){
- Integer[] ran = new Integer[questionNoIds.length];
- List<Integer> 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;
- }
- /**
- * 关联绑定questionNo类型试题
- * @param question
- * @param questionNoId
- */
- private void bindQuestionNo(UserQuestion question, Integer questionNoId){
- QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
- question.setQuestionNoId(relation.getId());
- question.setQuestionId(relation.getQuestionId());
- question.setQuestionType(relation.getQuestion().getQuestionType());
- Integer time = toolsService.computerTime(relation);
- question.setTime(time);
- }
- /**
- * 获取报表关联试卷
- * @param p
- * @return
- */
- private UserReportRelation relationReport(UserReport p){
- UserReportRelation relation = Transform.convert(p, UserReportRelation.class);
- UserPaper paper = userPaperService.get(p.getPaperId());
- relation.setPaper(paper);
- return relation;
- }
- /**
- * 基本题型的答案判断
- * @param userAnswer
- * @param answer
- * @param question
- * @return
- */
- private Boolean baseAnswer(JSONObject userAnswer, JSONObject answer, Question question){
- String type = question.getContent().getString("type");
- QuestionContentType contentType = QuestionContentType.ValueOf(type);
- JSONArray userQuestions = userAnswer.getJSONArray("questions");
- JSONArray questions = answer.getJSONArray("questions");
- for(int i = 0; i< questions.size(); i++){
- JSONObject userOne = userQuestions.getJSONObject(i);
- JSONObject one = questions.getJSONObject(i);
- switch(contentType){
- case DOUBLE:
- JSONArray userDoubleList = userOne.getJSONArray("double");
- JSONArray doubleList = one.getJSONArray("double");
- // if(JSONObject.toJSON(userDoubleList) != JSONObject.toJSON(doubleList)){
- // return false;
- // }
- for(int j = 0; j < doubleList.size(); j++){
- JSONArray singleList = doubleList.getJSONArray(j);
- JSONArray userSingleList = userDoubleList.getJSONArray(i);
- for (int k = 0; k < singleList.size(); k++){
- if (userSingleList.getBoolean(k) != singleList.getBoolean(k)){
- return false;
- }
- }
- }
- break;
- case SINGLE:
- case INLINE:
- default:
- JSONArray userSingleList = userOne.getJSONArray("single");
- JSONArray singleList = one.getJSONArray("single");
- // if(JSONObject.toJSON(userSingleList) != JSONObject.toJSON(singleList)){
- // return false;
- // }
- for(int j = 0; j < singleList.size(); j++){
- if (userSingleList.getBoolean(j) != singleList.getBoolean(j)){
- return false;
- }
- }
- }
- }
- return true;
- }
- /**
- * 长难句单个选项答案判断
- * @param userAnswer
- * @param answer
- * @return
- */
- private Boolean sentenceAnswer(JSONArray userAnswer, JSONArray answer){
- // 数量一致,并且都包含
- for(Object a : answer){
- JSONArray singleArray = (JSONArray) a;
- if (singleArray == null){
- return userAnswer == null;
- }
- if (userAnswer != null && singleArray.size() == userAnswer.size()){
- for (int i = 0; i < singleArray.size(); i++){
- JSONObject single = singleArray.getJSONObject(i);
- JSONObject user = userAnswer.getJSONObject(i);
- // 判断uuid是否一致
- if (!single.getString("uuid").equals(user.getString("uuid"))){
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
- /**
- * 长难句多选答案判断
- * @param userAnswer
- * @param answer
- * @return
- */
- private Boolean sentenceAnswerOption(JSONArray userAnswer, JSONArray answer){
- // 数量一致,并且都包含
- if (userAnswer.size() == answer.size()){
- for(Object s : userAnswer){
- if (!answer.contains(s)){
- return false;
- }
- }
- }else{
- return false;
- }
- return true;
- }
- /**
- * 统计答案分布
- * @param userQuestion
- * @param question
- */
- private void answerDistributed(UserQuestion userQuestion, Question question){
- JSONObject answerDistributed = question.getAnswerDistributed();
- JSONObject answer = question.getAnswer();
- JSONObject userAnswer = userQuestion.getUserAnswer();
- String type = question.getContent().getString("type");
- QuestionContentType contentType = QuestionContentType.ValueOf(type);
- JSONArray userQuestions = userAnswer.getJSONArray("questions");
- JSONArray questions = answer.getJSONArray("questions");
- JSONArray distributed = answerDistributed.getJSONArray("questions");
- if (distributed == null || distributed.isEmpty()){
- distributed = new JSONArray();
- answerDistributed.put("questions", distributed);
- }
- for(int i = 0; i< questions.size(); i++){
- JSONObject userOne = userQuestions.getJSONObject(i);
- JSONObject one = questions.getJSONObject(i);
- JSONObject target = distributed.getJSONObject(i);
- if (target == null || target.isEmpty()){
- target = new JSONObject();
- distributed.add(i, target);
- }
- switch(contentType){
- case DOUBLE:
- JSONArray userDoubleList = userOne.getJSONArray("double");
- JSONArray doubleList = one.getJSONArray("double");
- JSONArray doubleResult = target.getJSONArray("double");
- if (doubleResult == null || doubleResult.isEmpty()){
- doubleResult = new JSONArray();
- target.put("double", doubleResult);
- }
- for(int j = 0; j < doubleList.size(); j++){
- JSONArray singleList = doubleList.getJSONArray(j);
- JSONArray userSingleList = userDoubleList.getJSONArray(i);
- JSONArray singleResult = doubleResult.getJSONArray(j);
- if (singleResult == null){
- singleResult = new JSONArray(0);
- doubleResult.set(j, singleResult);
- }
- for (int k = 0; k < singleList.size(); k++){
- if (singleResult.get(k) == null){
- singleResult.set(k, 0);
- }
- if (userSingleList.getBoolean(k)){
- singleResult.set(k, singleResult.getIntValue(k)+1);
- }
- }
- }
- break;
- case SINGLE:
- case INLINE:
- default:
- JSONArray userSingleList = userOne.getJSONArray("single");
- JSONArray singleList = one.getJSONArray("single");
- JSONArray singleResult = target.getJSONArray("single");
- if (singleResult == null || singleResult.isEmpty()){
- singleResult = new JSONArray();
- target.put("single", singleResult);
- }
- for(int j = 0; j < singleList.size(); j++){
- if (singleResult.get(j) == null){
- singleResult.set(j, 0);
- }
- if (userSingleList.getBoolean(j)){
- singleResult.set(j, singleResult.getIntValue(j)+1);
- }
- }
- }
- }
- questionService.edit(Question.builder().id(question.getId())
- .answerDistributed(answerDistributed)
- .build());
- }
- /**
- * 根据练习报告格式,统计信息
- * @param report
- * @param questionList
- * @return
- */
- private JSONObject statExerciseReport(UserReport report, List<UserQuestion> questionList){
- UserPaper paper = userPaperService.get(report.getPaperId());
- Collection questionNoIds = Transform.getIds(questionList, UserQuestion.class, "questionNoId");
- Map<Number, QuestionNoRelation> relationMap = questionNoService.mapWithRelationByIds((Integer[])questionNoIds.toArray());
- // report
- JSONObject detail = new JSONObject();
- JSONArray pace = new JSONArray();
- JSONObject difficultMap = new JSONObject();
- JSONObject placeMap = new JSONObject();
- for (UserQuestion userQuestion:questionList){
- QuestionNoRelation relation = relationMap.get(userQuestion.getQuestionNoId());
- // 每题用时
- JSONObject one = new JSONObject();
- one.put("time", userQuestion.getTime());
- one.put("userTime", userQuestion.getUserTime());
- one.put("no", userQuestion.getNo());
- pace.add(one);
- // 考点用时,以及正确度
- String placeKey = relation.getQuestion().getPlace();
- JSONObject place = placeMap.getJSONObject(placeKey);
- if (place == null){
- place = new JSONObject();
- place.put("key", placeKey);
- place.put("userNumber", 1);
- place.put("userCorrect", userQuestion.getIsCorrect());
- place.put("userTime", userQuestion.getUserTime());
- placeMap.put(placeKey, place);
- }else{
- place.put("userNumber", place.getInteger("userNumber") + 1);
- place.put("userCorrect", place.getInteger("userCorrect") + userQuestion.getIsCorrect());
- place.put("userTime", place.getInteger("userTime") + userQuestion.getUserTime());
- }
- // 难度正确度
- String difficultKey = relation.getQuestion().getDifficult();
- JSONObject difficult = difficultMap.getJSONObject(difficultKey);
- if (difficult == null){
- difficult = new JSONObject();
- difficult.put("key", difficultKey);
- difficult.put("userNumber", 1);
- difficult.put("userCorrect", userQuestion.getIsCorrect());
- difficult.put("totalNumber", relation.getTotalNumber());
- difficult.put("totalCorrect", relation.getTotalCorrect());
- difficultMap.put(difficultKey, difficult);
- }else{
- difficult.put("userNumber", difficult.getInteger("userNumber") + 1);
- difficult.put("userCorrect", difficult.getInteger("userCorrect") + userQuestion.getIsCorrect());
- difficult.put("totalNumber", difficult.getInteger("totalNumber") + relation.getTotalNumber());
- difficult.put("totalCorrect", difficult.getInteger("totalCorrect") + relation.getTotalCorrect());
- }
- }
- detail.put("pace", pace);
- JSONArray difficult = new JSONArray();
- difficult.addAll(difficultMap.values());
- detail.put("difficult", difficult);
- JSONArray place = new JSONArray();
- place.addAll(placeMap.values());
- detail.put("place", place);
- JSONObject limit = new JSONObject();
- // 限时统计考试正确度
- UserReportLimitRelation relation = userReportService.statLimit(report.getPaperOrigin(), report.getOriginId());
- limit.put("userNumber", relation.getUserNumber());
- limit.put("userCorrect", relation.getUserCorrect());
- detail.put("limit", limit);
- JSONObject info = new JSONObject();
- // 基本信息
- info.put("times", paper.getTimes() + 1); // paper还未计数
- info.put("finishTime", report.getFinishTime());
- info.put("userTime", report.getUserTime());
- info.put("time", report.getTime());
- info.put("questionNumber", report.getQuestionNumber());
- info.put("userNumber", report.getUserNumber());
- info.put("userCorrect", report.getUserCorrect());
- Integer totalNumber = 0;
- Integer totalCorrect = 0;
- Integer totalTime = 0;
- for (QuestionNoRelation questionNoRelation : relationMap.values()){
- totalNumber += questionNoRelation.getTotalNumber();
- totalCorrect += questionNoRelation.getTotalCorrect();
- totalTime += questionNoRelation.getTotalTime();
- }
- Integer correctTime = 0;
- Integer incorrectTime = 0;
- for (UserQuestion userQuestion : questionList){
- if (userQuestion.getIsCorrect() > 0){
- correctTime += userQuestion.getUserTime();
- }else{
- incorrectTime += userQuestion.getUserTime();
- }
- }
- info.put("totalNumber", totalNumber);
- info.put("totalCorrect", totalCorrect);
- info.put("totalTime", totalTime);
- info.put("correctTime", correctTime);
- info.put("incorrectTime", incorrectTime);
- detail.put("info", info);
- return detail;
- }
- /**
- * 根据机经报告格式,统计信息:移除练习中的难度分析
- * @param report
- * @param questionList
- * @return
- */
- private JSONObject statTextbookReport(UserReport report, List<UserQuestion> questionList){
- UserPaper paper = userPaperService.get(report.getPaperId());
- Collection questionNoIds = Transform.getIds(questionList, UserQuestion.class, "questionNoId");
- Map<Number, TextbookQuestionRelation> relationMap = textbookQuestionService.mapWithRelationByIds((Integer[])questionNoIds.toArray());
- // report
- JSONObject detail = new JSONObject();
- JSONArray pace = new JSONArray();
- JSONObject placeMap = new JSONObject();
- for (UserQuestion userQuestion:questionList){
- TextbookQuestionRelation relation = relationMap.get(userQuestion.getQuestionNoId());
- // 每题用时
- JSONObject one = new JSONObject();
- one.put("time", userQuestion.getTime());
- one.put("userTime", userQuestion.getUserTime());
- one.put("no", userQuestion.getNo());
- pace.add(one);
- // 考点用时,以及正确度
- String placeKey = relation.getQuestion().getPlace();
- JSONObject place = placeMap.getJSONObject(placeKey);
- if (place == null){
- place = new JSONObject();
- place.put("key", placeKey);
- place.put("userNumber", 1);
- place.put("userCorrect", userQuestion.getIsCorrect());
- place.put("userTime", userQuestion.getUserTime());
- placeMap.put(placeKey, place);
- }else{
- place.put("userNumber", place.getInteger("userNumber") + 1);
- place.put("userCorrect", place.getInteger("userCorrect") + userQuestion.getIsCorrect());
- place.put("userTime", place.getInteger("userTime") + userQuestion.getUserTime());
- }
- }
- detail.put("pace", pace);
- JSONArray place = new JSONArray();
- place.addAll(placeMap.values());
- detail.put("place", place);
- JSONObject limit = new JSONObject();
- // 限时统计考试正确度
- UserReportLimitRelation relation = userReportService.statLimit(report.getPaperOrigin(), report.getOriginId());
- limit.put("userNumber", relation.getUserNumber());
- limit.put("userCorrect", relation.getUserCorrect());
- detail.put("limit", limit);
- JSONObject info = new JSONObject();
- // 基本信息
- info.put("times", paper.getTimes() + 1); // paper还未计数
- info.put("finishTime", report.getFinishTime());
- info.put("userTime", report.getUserTime());
- info.put("time", report.getTime());
- info.put("questionNumber", report.getQuestionNumber());
- info.put("userNumber", report.getUserNumber());
- info.put("userCorrect", report.getUserCorrect());
- Integer totalNumber = 0;
- Integer totalCorrect = 0;
- Integer totalTime = 0;
- for (TextbookQuestionRelation questionNoRelation : relationMap.values()){
- totalNumber += questionNoRelation.getTotalNumber();
- totalCorrect += questionNoRelation.getTotalCorrect();
- totalTime += questionNoRelation.getTotalTime();
- }
- Integer correctTime = 0;
- Integer incorrectTime = 0;
- for (UserQuestion userQuestion : questionList){
- if (userQuestion.getIsCorrect() > 0){
- correctTime += userQuestion.getUserTime();
- }else{
- incorrectTime += userQuestion.getUserTime();
- }
- }
- info.put("totalNumber", totalNumber);
- info.put("totalCorrect", totalCorrect);
- info.put("totalTime", totalTime);
- info.put("correctTime", correctTime);
- info.put("incorrectTime", incorrectTime);
- detail.put("info", info);
- return detail;
- }
- /**
- * 根据长难句报告格式,统计信息
- * @param report
- * @param questionList
- * @return
- */
- private JSONObject statSentenceReport(UserReport report, List<UserQuestion> questionList){
- UserPaper paper = userPaperService.get(report.getPaperId());
- Collection questionNoIds = Transform.getIds(questionList, UserQuestion.class, "questionNoId");
- Map<Number, SentenceQuestionRelation> relationMap = sentenceQuestionService.mapWithRelationByIds(questionNoIds.toArray());
- // report
- JSONObject detail = new JSONObject();
- JSONObject ability = new JSONObject();
- Integer struct = 0;
- Integer logic = 0;
- Integer speed = 0;
- for (UserQuestion userQuestion:questionList){
- if (userQuestion.getUserTime() < userQuestion.getTime()){
- speed += 1;
- }
- JSONObject questionDetail = userQuestion.getDetail();
- if (questionDetail.getBoolean("subject") && questionDetail.getBoolean("predicate") && questionDetail.getBoolean("object")){
- struct += 1;
- }
- if (questionDetail.getBoolean("options")){
- logic += 1;
- }
- }
- ability.put("struct", struct * 100 / report.getQuestionNumber());
- ability.put("logic", logic * 100 / report.getQuestionNumber());
- ability.put("speed", speed * 100 / report.getQuestionNumber());
- ability.put("score", (struct * 40 + logic * 30 + speed * 30) / report.getQuestionNumber());
- detail.put("ability", ability);
- JSONObject info = new JSONObject();
- // 基本信息
- info.put("times", paper.getTimes() + 1); // paper还未计数
- info.put("finishTime", report.getFinishTime());
- info.put("userTime", report.getUserTime());
- info.put("time", report.getTime());
- info.put("questionNumber", report.getQuestionNumber());
- info.put("userNumber", report.getUserNumber());
- info.put("userCorrect", report.getUserCorrect());
- Integer totalNumber = 0;
- Integer totalCorrect = 0;
- Integer totalTime = 0;
- for (SentenceQuestionRelation questionNoRelation : relationMap.values()){
- totalNumber += questionNoRelation.getTotalNumber();
- totalCorrect += questionNoRelation.getTotalCorrect();
- totalTime += questionNoRelation.getTotalTime();
- }
- Integer correctTime = 0;
- Integer incorrectTime = 0;
- for (UserQuestion userQuestion : questionList){
- if (userQuestion.getIsCorrect() > 0){
- correctTime += userQuestion.getUserTime();
- }else{
- incorrectTime += userQuestion.getUserTime();
- }
- }
- info.put("totalNumber", totalNumber);
- info.put("totalCorrect", totalCorrect);
- info.put("totalTime", totalTime);
- info.put("correctTime", correctTime);
- info.put("incorrectTime", incorrectTime);
- detail.put("info", info);
- return detail;
- }
- /**
- * 根据模考报告格式,统计信息
- * @param report
- * @param questionList
- * @return
- */
- private void statExaminationReport(UserReport report, List<UserQuestion> questionList){
- UserPaper paper = userPaperService.get(report.getPaperId());
- Collection questionNoIds = Transform.getIds(questionList, UserQuestion.class, "questionNoId");
- Map<Number, QuestionNoRelation> relationMap = questionNoService.mapWithRelationByIds((Integer[])questionNoIds.toArray());
- // report
- JSONObject detail = new JSONObject();
- JSONObject score = new JSONObject();
- // 成绩单
- JSONObject subjectMap = new JSONObject();
- JSONObject typeMap = new JSONObject();
- JSONObject tempMap = new JSONObject();
- JSONObject difficult = null;
- JSONObject place = null;
- for (UserQuestion userQuestion : questionList){
- QuestionNoRelation relation = relationMap.get(userQuestion.getQuestionNoId());
- QuestionType questionType = QuestionType.ValueOf(relation.getQuestion().getQuestionType());
- QuestionSubject questionSubject = QuestionSubject.FromType(questionType);
- JSONObject type = typeMap.getJSONObject(questionType.key);
- JSONObject tempType = tempMap.getJSONObject(questionType.key);
- JSONObject subject = subjectMap.getJSONObject(questionSubject.key);
- JSONObject tempSubject = tempMap.getJSONObject(questionSubject.key);
- // 归类
- if (type == null || type.isEmpty()){
- type = new JSONObject();
- type.put("key", questionType.key);
- subject.put("pace", new JSONArray());
- JSONObject initTypeInfo = new JSONObject();
- // 初始化题型基础信息
- initTypeInfo.put("userNumber", 0);
- initTypeInfo.put("userTime", 0);
- initTypeInfo.put("userCorrect", 0);
- initTypeInfo.put("correctTime", 0);
- initTypeInfo.put("incorrectTime", 0);
- initTypeInfo.put("diffCorrect", 0f);
- initTypeInfo.put("diffIncorrect", 0f);
- type.put("info", initTypeInfo);
- typeMap.put(questionType.key, type);
- tempType = new JSONObject();
- tempType.put("place", new JSONObject());
- tempType.put("difficult", new JSONObject());
- tempMap.put(questionType.key, tempType);
- }
- if (subject == null || subject.isEmpty()){
- subject = new JSONObject();
- subject.put("key", questionSubject.key);
- subject.put("pace", new JSONArray());
- JSONObject initSubjectInfo = new JSONObject();
- JSONObject subjectBase = toolsService.examinationSubjectInit(questionSubject);
- // 初始化学科基础信息
- initSubjectInfo.put("questionNumber", subjectBase.getIntValue("number"));
- initSubjectInfo.put("time", subjectBase.getIntValue("time"));
- initSubjectInfo.put("userNumber", 0);
- initSubjectInfo.put("userTime", 0);
- initSubjectInfo.put("userCorrect", 0);
- initSubjectInfo.put("correctTime", 0);
- initSubjectInfo.put("incorrectTime", 0);
- initSubjectInfo.put("diffCorrect", 0f);
- initSubjectInfo.put("diffIncorrect", 0f);
- initSubjectInfo.put("difficultScore", 0);
- subject.put("info", initSubjectInfo);
- subjectMap.put(questionSubject.key, subject);
- tempSubject = new JSONObject();
- tempSubject.put("place", new JSONObject());
- tempSubject.put("difficult", new JSONObject());
- tempMap.put(questionSubject.key, tempType);
- }
- JSONArray paceType = type.getJSONArray("pace");
- JSONObject placeTypeMap = tempType.getJSONObject("place");
- JSONObject difficultTypeMap = tempType.getJSONObject("difficult");
- JSONObject typeInfo = type.getJSONObject("info");
- JSONArray paceSubject = subject.getJSONArray("pace");
- JSONObject placeSubjectMap = tempType.getJSONObject("place");
- JSONObject difficultSubjectMap = tempType.getJSONObject("difficult");
- JSONObject subjectInfo = subject.getJSONObject("info");
- // 每题用时
- JSONObject one = new JSONObject();
- one.put("time", userQuestion.getTime());
- one.put("userTime", userQuestion.getUserTime());
- one.put("no", userQuestion.getNo());
- paceSubject.add(one);
- paceType.add(one);
- // 考点用时,以及正确度
- String placeKey = relation.getQuestion().getPlace();
- place = placeTypeMap.getJSONObject(placeKey);
- if (place == null){
- place = new JSONObject();
- place.put("key", placeKey);
- place.put("userNumber", 1);
- place.put("userCorrect", userQuestion.getIsCorrect());
- place.put("userTime", userQuestion.getUserTime());
- placeTypeMap.put(placeKey, place);
- }else{
- place.put("userNumber", place.getInteger("userNumber") + 1);
- place.put("userCorrect", place.getInteger("userCorrect") + userQuestion.getIsCorrect());
- place.put("userTime", place.getInteger("userTime") + userQuestion.getUserTime());
- }
- place = placeSubjectMap.getJSONObject(placeKey);
- if (place == null){
- place = new JSONObject();
- place.put("key", placeKey);
- place.put("userNumber", 1);
- place.put("userCorrect", userQuestion.getIsCorrect());
- place.put("userTime", userQuestion.getUserTime());
- placeSubjectMap.put(placeKey, place);
- }else{
- place.put("userNumber", place.getInteger("userNumber") + 1);
- place.put("userCorrect", place.getInteger("userCorrect") + userQuestion.getIsCorrect());
- place.put("userTime", place.getInteger("userTime") + userQuestion.getUserTime());
- }
- // 难度正确度
- String difficultKey = relation.getQuestion().getDifficult();
- difficult = difficultTypeMap.getJSONObject(difficultKey);
- if (difficult == null){
- difficult = new JSONObject();
- difficult.put("key", difficultKey);
- difficult.put("userNumber", 1);
- difficult.put("userCorrect", userQuestion.getIsCorrect());
- difficult.put("totalNumber", relation.getTotalNumber());
- difficult.put("totalCorrect", relation.getTotalCorrect());
- difficultTypeMap.put(difficultKey, difficult);
- }else{
- difficult.put("userNumber", difficult.getInteger("userNumber") + 1);
- difficult.put("userCorrect", difficult.getInteger("userCorrect") + userQuestion.getIsCorrect());
- difficult.put("totalNumber", difficult.getInteger("totalNumber") + relation.getTotalNumber());
- difficult.put("totalCorrect", difficult.getInteger("totalCorrect") + relation.getTotalCorrect());
- }
- difficult = difficultSubjectMap.getJSONObject(difficultKey);
- if (difficult == null){
- difficult = new JSONObject();
- difficult.put("key", difficultKey);
- difficult.put("userNumber", 1);
- difficult.put("userCorrect", userQuestion.getIsCorrect());
- difficult.put("totalNumber", relation.getTotalNumber());
- difficult.put("totalCorrect", relation.getTotalCorrect());
- difficultSubjectMap.put(difficultKey, difficult);
- }else{
- difficult.put("userNumber", difficult.getInteger("userNumber") + 1);
- difficult.put("userCorrect", difficult.getInteger("userCorrect") + userQuestion.getIsCorrect());
- difficult.put("totalNumber", difficult.getInteger("totalNumber") + relation.getTotalNumber());
- difficult.put("totalCorrect", difficult.getInteger("totalCorrect") + relation.getTotalCorrect());
- }
- // 基础数据
- typeInfo.put("userNumber", typeInfo.getIntValue("userNumber")+1);
- typeInfo.put("userTime", typeInfo.getIntValue("userTime")+userQuestion.getUserTime());
- typeInfo.put("userCorrect", typeInfo.getIntValue("userCorrect")+userQuestion.getIsCorrect());
- if (userQuestion.getIsCorrect() > 0){
- typeInfo.put("correctTime", typeInfo.getIntValue("correctTime")+userQuestion.getUserTime());
- }else{
- typeInfo.put("incorrectTime", typeInfo.getIntValue("incorrectTime")+userQuestion.getUserTime());
- }
- subjectInfo.put("userNumber", subjectInfo.getIntValue("userNumber")+1);
- subjectInfo.put("userTime", subjectInfo.getIntValue("userTime")+userQuestion.getUserTime());
- subjectInfo.put("userCorrect", subjectInfo.getIntValue("userCorrect")+userQuestion.getIsCorrect());
- if (userQuestion.getIsCorrect() > 0){
- subjectInfo.put("correctTime", subjectInfo.getIntValue("correctTime")+userQuestion.getUserTime());
- }else{
- subjectInfo.put("incorrectTime", subjectInfo.getIntValue("incorrectTime")+userQuestion.getUserTime());
- }
- // 题型难度分计算
- QuestionDifficult questionDifficult = QuestionDifficult.ValueOf(difficultKey);
- if (userQuestion.getIsCorrect() > 0){
- typeInfo.put("diffCorrect", typeInfo.getFloatValue("diffCorrect") + toolsService.diffScore(relation.getTotalNumber(), relation.getTotalCorrect(), questionDifficult));
- subjectInfo.put("diffCorrect", subjectInfo.getFloatValue("diffCorrect") + toolsService.diffScore(relation.getTotalNumber(), relation.getTotalCorrect(), questionDifficult));
- }else{
- typeInfo.put("diffIncorrect", typeInfo.getFloatValue("diffIncorrect") + toolsService.diffScore(relation.getTotalNumber(), relation.getTotalCorrect(), questionDifficult));
- subjectInfo.put("diffIncorrect", subjectInfo.getFloatValue("diffIncorrect") + toolsService.diffScore(relation.getTotalNumber(), relation.getTotalCorrect(), questionDifficult));
- }
- // 获取2级难度得分
- float difficultScore = relation.getQuestion().getDifficultScore();
- subjectInfo.put("difficultScore", subjectInfo.getFloatValue("difficultScore")+difficultScore);
- }
- // 计算难度平均值
- for (String key : typeMap.keySet()) {
- JSONObject type = typeMap.getJSONObject(key);
- JSONObject typeInfo = type.getJSONObject("info");
- typeInfo.put("avgDiffCorrect", toolsService.avgDiffScore(typeInfo.getFloat("diffCorrect"), typeInfo.getIntValue("userCorrect")));
- typeInfo.put("avgDiffIncorrect", toolsService.avgDiffScore(typeInfo.getFloat("diffIncorrect"), typeInfo.getIntValue("userNumber") - typeInfo.getIntValue("userCorrect")));
- }
- for (String key : subjectMap.keySet()) {
- JSONObject subject = subjectMap.getJSONObject(key);
- JSONObject subjectInfo = subject.getJSONObject("info");
- subjectInfo.put("avgDiffCorrect", toolsService.avgDiffScore(subjectInfo.getFloat("diffCorrect"), subjectInfo.getIntValue("userCorrect")));
- subjectInfo.put("avgDiffIncorrect", toolsService.avgDiffScore(subjectInfo.getFloat("diffIncorrect"), subjectInfo.getIntValue("userNumber") - subjectInfo.getIntValue("userCorrect")));
- }
- // 学科得分计算
- JSONObject quantSubject = subjectMap.getJSONObject(QuestionSubject.QUANT.key);
- JSONObject quantInfo = quantSubject.getJSONObject("info");
- Integer quantScore = toolsService.quantScore(quantInfo.getIntValue("number"), quantInfo.getIntValue("userNumber"), quantInfo.getFloatValue("difficultScore"), quantInfo.getInteger("userCorrect"));
- JSONObject verbalSubject = subjectMap.getJSONObject(QuestionSubject.VERBAL.key);
- JSONObject verbalInfo = verbalSubject.getJSONObject("info");
- Integer verbalScore = toolsService.verbalScore(verbalInfo.getIntValue("number"), verbalInfo.getIntValue("userNumber"), verbalInfo.getFloatValue("difficultScore"), verbalInfo.getInteger("userCorrect"));
- JSONObject irSubject = subjectMap.getJSONObject(QuestionSubject.IR.key);
- JSONObject irInfo = irSubject.getJSONObject("info");
- Integer irScore = toolsService.irScore(irInfo.getIntValue("number"), irInfo.getIntValue("userNumber"), irInfo.getInteger("difficultScore"), irInfo.getInteger("userCorrect"));
- Rank rank = toolsService.totalScore(quantScore, verbalScore);
- score.put("totalScore", rank.getTotalScore());
- score.put("totalRank", rank.getTotalRank());
- score.put("quantScore", quantScore);
- score.put("quantRank", rank.getQuantRank());
- score.put("verbalScore", verbalScore);
- score.put("irScore", irScore);
- score.put("irRank", rank.getIrRank());
- detail.put("subject", subjectMap);
- detail.put("type", typeMap);
- JSONObject info = new JSONObject();
- // 基本信息
- info.put("times", paper.getTimes() + 1); // paper还未计数
- info.put("finishTime", report.getFinishTime());
- info.put("userTime", report.getUserTime());
- info.put("time", report.getTime());
- info.put("questionNumber", report.getQuestionNumber());
- info.put("userNumber", report.getUserNumber());
- info.put("userCorrect", report.getUserCorrect());
- detail.put("info", info);
- report.setDetail(detail);
- report.setScore(score);
- // 统计
- UserService userService = null;
- // 判断是否是cat模考:记录到第二次
- ExaminationPaper examinationPaper = examinationPaperService.get(report.getOriginId());
- if(examinationService.isCat(examinationPaper)){
- userService = userServiceService.getService(report.getUserId(), ServiceKey.QX_CAT);
- }
- examinationPaperService.accumulation(report, userService != null && userService.getIsReset() > 0);
- }
- }
|