|
@@ -1,545 +1,564 @@
|
|
-package cn.com.qmth.examcloud.core.questions.service.impl;
|
|
|
|
-
|
|
|
|
-import java.math.BigDecimal;
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
-import java.util.List;
|
|
|
|
-
|
|
|
|
-import org.apache.commons.collections4.CollectionUtils;
|
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
|
-import org.bson.types.ObjectId;
|
|
|
|
-import org.jsoup.Jsoup;
|
|
|
|
-import org.jsoup.nodes.Document;
|
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
-import org.springframework.data.domain.Sort;
|
|
|
|
-import org.springframework.data.domain.Sort.Direction;
|
|
|
|
-import org.springframework.data.domain.Sort.Order;
|
|
|
|
-import org.springframework.data.mongodb.core.MongoTemplate;
|
|
|
|
-import org.springframework.data.mongodb.core.query.Criteria;
|
|
|
|
-import org.springframework.data.mongodb.core.query.Query;
|
|
|
|
-import org.springframework.data.redis.core.RedisTemplate;
|
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
|
-
|
|
|
|
-import cn.com.qmth.examcloud.api.commons.enums.AdminOperateType;
|
|
|
|
-import cn.com.qmth.examcloud.api.commons.security.bean.User;
|
|
|
|
-import cn.com.qmth.examcloud.commons.exception.StatusException;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.base.Model;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.base.enums.PaperType;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.base.question.enums.QuesStructType;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.PaperDetailUnitRepo;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.PaperRepo;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.Paper;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetail;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetailUnit;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.Question;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.PaperDetailUnitService;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.PaperService;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.QuesService;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.RandomPaperQuestionService;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.bean.dto.PaperDetailUnitDto;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.bean.dto.PaperDetailUnitExp;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.cache.BasePaperCache;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.cache.ExtractConfigPaperCache;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.cache.QuestionAnswerCache;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.cache.QuestionCache;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.util.PaperUtil;
|
|
|
|
-import cn.com.qmth.examcloud.reports.commons.bean.AdminOperateReport;
|
|
|
|
-import cn.com.qmth.examcloud.reports.commons.util.ReportsUtil;
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * @author chenken
|
|
|
|
- * @date 2017年9月13日 上午11:29:56
|
|
|
|
- * @company QMTH
|
|
|
|
- */
|
|
|
|
-@Service("paperDetailUnitService")
|
|
|
|
-public class PaperDetailUnitServiceImpl implements PaperDetailUnitService {
|
|
|
|
- @Autowired
|
|
|
|
- PaperRepo paperRepo;
|
|
|
|
- @Autowired
|
|
|
|
- private ExtractConfigPaperCache extractConfigPaperCache;
|
|
|
|
- @Autowired
|
|
|
|
- private BasePaperCache basePaperCache;
|
|
|
|
- @Autowired
|
|
|
|
- private QuestionCache questionCache;
|
|
|
|
- @Autowired
|
|
|
|
- private QuestionAnswerCache questionAnswerCache;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- PaperDetailUnitRepo paperDetailUnitRepo;
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- QuesService quesService;
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- PaperService paperService;
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- MongoTemplate mongoTemplate;
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- RedisTemplate<String, Object> redisTemplate;
|
|
|
|
- @Autowired
|
|
|
|
- private RandomPaperQuestionService randomPaperQuestionService;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 根据Id获得对应的试题对象
|
|
|
|
- *
|
|
|
|
- * @param id
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- public Question getQuestionByPaperDetailUnitId(String id) {
|
|
|
|
- return Model.of(paperDetailUnitRepo.findById(id)).getQuestion();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 按ID查询小题
|
|
|
|
- *
|
|
|
|
- * @param id
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- public PaperDetailUnit findById(String id) {
|
|
|
|
- return Model.of(paperDetailUnitRepo.findById(id));
|
|
|
|
- }
|
|
|
|
- private void checkFillBlankQuestion(Question question) {
|
|
|
|
- if(question.getQuestionType() == QuesStructType.FILL_BLANK_QUESTION) {
|
|
|
|
- String body=question.getQuesBody();
|
|
|
|
- Document bodyDoc = Jsoup.parse(body);
|
|
|
|
- if(bodyDoc.body().childrenSize()==0) {
|
|
|
|
- throw new StatusException("1000", "题干不能为空");
|
|
|
|
- }
|
|
|
|
- String bodyText=bodyDoc.body().html();
|
|
|
|
- if(StringUtils.isBlank(bodyText)) {
|
|
|
|
- throw new StatusException("1001", "题干不能为空");
|
|
|
|
- }
|
|
|
|
- if(bodyText.indexOf("###")==-1) {
|
|
|
|
- throw new StatusException("1002", "题干不能没有空格(###)");
|
|
|
|
- }
|
|
|
|
- String answer=question.getQuesAnswer();
|
|
|
|
- Document answerDoc = Jsoup.parse(answer);
|
|
|
|
- if(answerDoc.body().childrenSize()!=0) {
|
|
|
|
- String answerText=answerDoc.body().html();
|
|
|
|
- if(StringUtils.isNotBlank(answerText)) {
|
|
|
|
- if(getSubStringCount(bodyText, "###")!=answerText.split("##").length) {
|
|
|
|
- throw new StatusException("1003", "题干空格(###)数量和答案数量不一致");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- private int getSubStringCount(String src,String find){
|
|
|
|
- int o = 0;
|
|
|
|
- int index=-1;
|
|
|
|
- while((index=src.indexOf(find,index))>-1){
|
|
|
|
- ++index;
|
|
|
|
- ++o;
|
|
|
|
- }
|
|
|
|
- return o;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public boolean paperInUse(String questionId) {
|
|
|
|
- Query query = new Query();
|
|
|
|
- query.addCriteria(Criteria.where("question.$id").is(new ObjectId(questionId)));
|
|
|
|
- query.addCriteria(Criteria.where("paperType").is(PaperType.GENERATE.name()));
|
|
|
|
- List<PaperDetailUnitDto> units=this.mongoTemplate.find(query, PaperDetailUnitDto.class,"paperDetailUnit");
|
|
|
|
- if(CollectionUtils.isEmpty(units)) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- for(PaperDetailUnitDto dto:units) {
|
|
|
|
- if(dto.getPaper().getInUse()!=null&&dto.getPaper().getInUse()==1) {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- /**
|
|
|
|
- * 保存小题
|
|
|
|
- */
|
|
|
|
- public PaperDetailUnit savePaperDetailUnit(PaperDetailUnitExp updateUnit, User user) {
|
|
|
|
- StringBuilder sb=new StringBuilder();
|
|
|
|
- PaperDetailUnit baseUnit = Model.of(paperDetailUnitRepo.findById(updateUnit.getId()));
|
|
|
|
- if(paperInUse(baseUnit.getQuestion().getId())) {
|
|
|
|
- PaperUtil.checkUpdate(updateUnit, baseUnit,"试卷已调用,");
|
|
|
|
- }
|
|
|
|
- if(randomPaperQuestionService.existQuestion(baseUnit.getQuestion().getId())) {
|
|
|
|
- PaperUtil.checkUpdateOption(updateUnit, baseUnit,"小题已被抽题模板使用,");
|
|
|
|
- }
|
|
|
|
- Question baseQuestion = baseUnit.getQuestion();
|
|
|
|
- Question updateQuestion = updateUnit.getQuestion();
|
|
|
|
- checkFillBlankQuestion(updateQuestion);
|
|
|
|
- if (baseUnit.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
|
|
|
|
- if (updateQuestion.getId().equals(baseQuestion.getId())) {
|
|
|
|
-
|
|
|
|
- if(!StringUtils.equals(baseQuestion.getQuesBody(), updateQuestion.getQuesBody())) {
|
|
|
|
- sb.append(" 第"+baseUnit.getNumber()+"小题(套题)题干变动");
|
|
|
|
- }
|
|
|
|
- // 更新对象为套题本身
|
|
|
|
- quesService.saveQues(updateQuestion);
|
|
|
|
- baseUnit.setQuestion(updateQuestion);
|
|
|
|
- } else {
|
|
|
|
- if(updateQuestion.getQuesOptions()!=null&&updateQuestion.getQuesOptions().size()>26) {
|
|
|
|
- throw new StatusException("选项数量不能超过26");
|
|
|
|
- }
|
|
|
|
- List<Double> subScoreList = baseUnit.getSubScoreList();
|
|
|
|
- int size = baseQuestion.getSubQuestions().size();
|
|
|
|
- boolean match = false;
|
|
|
|
-
|
|
|
|
- // 判断更新的对象是哪个子题
|
|
|
|
- for (int index = 1; index <= size; index++) {
|
|
|
|
- // 检查子题分数,确保没有错误数据
|
|
|
|
- if (subScoreList.size() < index) {
|
|
|
|
- subScoreList.add(0d);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- Question sub = baseQuestion.getSubQuestions().get(index - 1);
|
|
|
|
- if (updateQuestion.getId().equals(sub.getId())) {
|
|
|
|
- String changInfo=getQuestionChangeInfo(sub, updateQuestion);
|
|
|
|
- if(changInfo!=null) {
|
|
|
|
- sb.append("第"+baseUnit.getNumber()+"小题第"+index+"子题变动:"+changInfo);
|
|
|
|
- }
|
|
|
|
- // 匹配到子题
|
|
|
|
- subScoreList.set(index - 1, updateUnit.getScore());
|
|
|
|
- baseQuestion.getSubQuestions().set(index - 1, updateQuestion);
|
|
|
|
-
|
|
|
|
- //重新计算套题的难度,公开度
|
|
|
|
- boolean publicity = false;
|
|
|
|
- double totalSum = 0d;
|
|
|
|
- double totalDou = 0d;
|
|
|
|
- for (int i = 0; i < baseQuestion.getSubQuestions().size(); i++) {
|
|
|
|
- Question subQuestion = baseQuestion.getSubQuestions().get(i);
|
|
|
|
- //设置公开度
|
|
|
|
- if (subQuestion.getPublicity()) {
|
|
|
|
- publicity = true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (subQuestion.getDifficultyDegree() == null) {
|
|
|
|
- subQuestion.setDifficultyDegree(0.5);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- totalSum = subQuestion.getDifficultyDegree() * subScoreList.get(i) + totalSum;
|
|
|
|
- totalDou = subScoreList.get(i) + totalDou;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- BigDecimal b;
|
|
|
|
- if (totalDou != 0d) {
|
|
|
|
- b = BigDecimal.valueOf(totalSum / totalDou);
|
|
|
|
- } else {
|
|
|
|
- b = BigDecimal.valueOf(0d);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- Double difficulty = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
|
|
|
- baseQuestion.setDifficultyDegree(difficulty);
|
|
|
|
- baseQuestion.setPublicity(publicity);
|
|
|
|
- match = true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (match) {
|
|
|
|
- quesService.saveQues(baseQuestion);
|
|
|
|
- baseUnit.setQuestion(baseQuestion);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 更新套题unit当前总分与子题分数
|
|
|
|
- baseUnit.setSubScoreList(subScoreList);
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- if(updateQuestion.getQuesOptions()!=null&&updateQuestion.getQuesOptions().size()>26) {
|
|
|
|
- throw new StatusException("选项数量不能超过26");
|
|
|
|
- }
|
|
|
|
- String changInfo=getQuestionChangeInfo(baseQuestion, updateQuestion);
|
|
|
|
- if(changInfo!=null) {
|
|
|
|
- sb.append("第"+baseUnit.getNumber()+"小题变动:"+changInfo);
|
|
|
|
- }
|
|
|
|
- quesService.saveQues(updateQuestion);
|
|
|
|
- baseUnit.setQuestion(updateQuestion);
|
|
|
|
- baseUnit.setScore(updateUnit.getScore());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 同时要跟新小题里面的Question对象
|
|
|
|
- paperDetailUnitRepo.save(baseUnit);
|
|
|
|
-
|
|
|
|
- Paper paper = baseUnit.getPaper();
|
|
|
|
- Double total=paper.getTotalScore();
|
|
|
|
- Integer dc=paper.getPaperDetailCount();
|
|
|
|
- Integer uc=paper.getUnitCount();
|
|
|
|
- if(PaperType.GENERATE.equals(paper.getPaperType())) {
|
|
|
|
- paper.setAuditStatus(false);
|
|
|
|
- }
|
|
|
|
- paperService.formatPaper(paper, user);
|
|
|
|
-
|
|
|
|
- String changInfo=PaperUtil.getPaperChangeInfo(total, dc, uc, paper);
|
|
|
|
- if(changInfo!=null) {
|
|
|
|
- sb.append(changInfo);
|
|
|
|
- }
|
|
|
|
- if(sb.length()!=0) {
|
|
|
|
- StringBuilder paperInfo=new StringBuilder();
|
|
|
|
- paperInfo.append(" 课程:"+paper.getCourse().getName()+"("+paper.getCourse().getCode()+")");
|
|
|
|
- paperInfo.append(" 试卷名称:"+paper.getName());
|
|
|
|
- sb.append(paperInfo);
|
|
|
|
- if(PaperType.IMPORT.equals(paper.getPaperType())) {
|
|
|
|
- ReportsUtil.report(new AdminOperateReport(user.getRootOrgId(), user.getUserId(), AdminOperateType.TYPE43.getDesc(),sb.toString()));
|
|
|
|
- }else {
|
|
|
|
- ReportsUtil.report(new AdminOperateReport(user.getRootOrgId(), user.getUserId(), AdminOperateType.TYPE44.getDesc(),sb.toString()));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (baseUnit.getQuestion() != null) {
|
|
|
|
- //清除缓存
|
|
|
|
- this.clearQuestionCache(baseUnit.getQuestion().getId());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return baseUnit;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- private String getQuestionChangeInfo(Question old,Question now) {
|
|
|
|
- StringBuilder sb=new StringBuilder();
|
|
|
|
- if(old.getScore().doubleValue() !=now.getScore().doubleValue()) {
|
|
|
|
- sb.append(" 分数变动("+old.getScore()+"变为"+now.getScore()+")");
|
|
|
|
- }
|
|
|
|
- if(!StringUtils.equals(old.getQuesBody(), now.getQuesBody())) {
|
|
|
|
- sb.append(" 题干变动");
|
|
|
|
- }
|
|
|
|
- if(optionChange(old, now)) {
|
|
|
|
- sb.append(" 选项变动");
|
|
|
|
- }
|
|
|
|
- if(!StringUtils.equals(old.getQuesAnswer(), now.getQuesAnswer())) {
|
|
|
|
- sb.append(" 答案变动");
|
|
|
|
- }
|
|
|
|
- if(sb.length()==0) {
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
- return sb.toString();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private boolean optionChange(Question old,Question now) {
|
|
|
|
- if(now.getQuesOptions()==null) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- if(old.getQuesOptions().size()!=now.getQuesOptions().size()) {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- for(int i=0;i<now.getQuesOptions().size();i++) {
|
|
|
|
- if(!StringUtils.equals(old.getQuesOptions().get(i).getOptionBody(), now.getQuesOptions().get(i).getOptionBody())) {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- /**
|
|
|
|
- * 删除小题
|
|
|
|
- *
|
|
|
|
- * @param id
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- public void deletePaperDetailUnit(String id, User user) {
|
|
|
|
- String changInfo=null;
|
|
|
|
- PaperDetailUnit detailUnit = Model.of(paperDetailUnitRepo.findById(id));
|
|
|
|
- Paper paper = detailUnit.getPaper();
|
|
|
|
- if(paper.getInUse()!=null&&paper.getInUse()==1) {
|
|
|
|
- throw new StatusException("500", "试卷已调用");
|
|
|
|
- }
|
|
|
|
- paperDetailUnitRepo.deleteById(id);
|
|
|
|
-
|
|
|
|
- if (detailUnit.getQuestion() != null) {
|
|
|
|
- //清除缓存
|
|
|
|
- this.clearQuestionCache(detailUnit.getQuestion().getId());
|
|
|
|
- }
|
|
|
|
- Double total=paper.getTotalScore();
|
|
|
|
- Integer dc=paper.getPaperDetailCount();
|
|
|
|
- Integer uc=paper.getUnitCount();
|
|
|
|
- paper.setAuditStatus(false);
|
|
|
|
- paperService.formatPaper(paper, user);
|
|
|
|
- changInfo=PaperUtil.getPaperChangeInfo(total, dc, uc, paper);
|
|
|
|
- if(detailUnit!=null) {
|
|
|
|
- StringBuilder sb=new StringBuilder();
|
|
|
|
- sb.append("课程:"+detailUnit.getPaper().getCourse().getName()+"("+detailUnit.getPaper().getCourse().getCode()+")");
|
|
|
|
- sb.append(" 试卷名称:"+detailUnit.getPaper().getName());
|
|
|
|
- sb.append(" 第"+detailUnit.getNumber()+"小题 ");
|
|
|
|
- sb.append(changInfo);
|
|
|
|
- ReportsUtil.report(new AdminOperateReport(user.getRootOrgId(), user.getUserId(), AdminOperateType.TYPE45.getDesc(),sb.toString()));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 根据大题查小题
|
|
|
|
- *
|
|
|
|
- * @param paperDetail
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- public List<PaperDetailUnit> getUnitsByPaperDetail(PaperDetail paperDetail) {
|
|
|
|
- return paperDetailUnitRepo.findByPaperDetailOrderByNumber(paperDetail);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 根据大题集合删除小题
|
|
|
|
- *
|
|
|
|
- * @param paperDetails
|
|
|
|
- */
|
|
|
|
- public void deleteUnitsByPaperDetails(List<PaperDetail> paperDetails) {
|
|
|
|
- List<PaperDetailUnit> units = new ArrayList<>();
|
|
|
|
- for (PaperDetail pd : paperDetails) {
|
|
|
|
- units.addAll(getUnitsByPaperDetail(pd));
|
|
|
|
- }
|
|
|
|
- paperDetailUnitRepo.deleteAll(units);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public List<PaperDetailUnit> findByQuestionAndPaperTypes(Question question, List<PaperType> paperTypes) {
|
|
|
|
- Query query = new Query();
|
|
|
|
- query.addCriteria(Criteria.where("paperType").in(paperTypes));
|
|
|
|
- query.addCriteria(Criteria.where("question").is(question));
|
|
|
|
- return this.mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 查询大题下的小题
|
|
|
|
- * 按number升序或降序排列,取第一个
|
|
|
|
- *
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- public PaperDetailUnit findTopOrderByNumber(PaperDetail paperDetail, String orderType) {
|
|
|
|
- if ("ASC".equals(orderType)) {
|
|
|
|
- return paperDetailUnitRepo.findTopByPaperDetailOrderByNumberAsc(paperDetail);
|
|
|
|
- } else if ("DESC".equals(orderType)) {
|
|
|
|
- return paperDetailUnitRepo.findTopByPaperDetailOrderByNumberDesc(paperDetail);
|
|
|
|
- }
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 按试卷 查询 小题,并将小题按number,createTime排序
|
|
|
|
- *
|
|
|
|
- * @param paper
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- public List<PaperDetailUnit> findByPaperAndSort(Paper paper) {
|
|
|
|
- Query query = new Query();
|
|
|
|
- query.addCriteria(Criteria.where("paper").is(paper));
|
|
|
|
- query.with(Sort.by(new Order(Direction.ASC, "number")));
|
|
|
|
- query.with(Sort.by(new Order(Direction.ASC, "createTime")));
|
|
|
|
- return this.mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- public List<PaperDetailUnit> findByQuestionsAndPaperTypeOnline(List<String> ids, PaperType paperType) {
|
|
|
|
- Query query = new Query();
|
|
|
|
- query.addCriteria(Criteria.where("question.id").in(ids));
|
|
|
|
- query.addCriteria(Criteria.where("paperType").is(paperType));
|
|
|
|
- List<PaperDetailUnit> paperDetailUnits = this.mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
- return paperDetailUnits;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<PaperDetailUnit> findByQuestionsAndPaperType(List<String> ids, PaperType paperType) {
|
|
|
|
- List<ObjectId> objectIds = new ArrayList<>();
|
|
|
|
- for (String id : ids) {
|
|
|
|
- objectIds.add(new ObjectId(id));
|
|
|
|
- }
|
|
|
|
- Query query = new Query();
|
|
|
|
- query.addCriteria(Criteria.where("question.$id").in(objectIds));
|
|
|
|
- query.addCriteria(Criteria.where("paperType").is(paperType));
|
|
|
|
- List<PaperDetailUnit> paperDetailUnits = this.mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
- return paperDetailUnits;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<PaperDetailUnit> findByDDQuestionsAndPaperType(List<String> ids, PaperType paperType, List<Question> questionList) {
|
|
|
|
- List<ObjectId> objectIds = new ArrayList<>();
|
|
|
|
- for (String id : ids) {
|
|
|
|
- objectIds.add(new ObjectId(id));
|
|
|
|
- }
|
|
|
|
- Query query = new Query();
|
|
|
|
- query.addCriteria(Criteria.where("question.$id").in(objectIds));
|
|
|
|
- query.addCriteria(Criteria.where("paperType").is("IMPORT"));
|
|
|
|
- List<PaperDetailUnit> paperDetailUnits = mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
- return paperDetailUnits;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /*@Override
|
|
|
|
- public List<PaperDetailUnit> testFind(List<String> ids,PaperType paperType, List<Question> questionList) {
|
|
|
|
- //第一种查询,quesion.id id
|
|
|
|
- DBObject query1 = new BasicDBObject();
|
|
|
|
- BasicDBList values = new BasicDBList();
|
|
|
|
- for(String id:ids){
|
|
|
|
- values.add(id);
|
|
|
|
- }
|
|
|
|
- query1.put("quesion.id", new BasicDBObject("$in", values));
|
|
|
|
- DBCursor dbCursor = mongoTemplate.getCollection("paperDetailUnit").find(query1);
|
|
|
|
- while (dbCursor.hasNext()){
|
|
|
|
- DBObject object=dbCursor.next();
|
|
|
|
- log.debug("打印游标---------------"+object);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //第二种查询,quesion.$id id
|
|
|
|
- //DBObject query2 = new BasicDBObject();
|
|
|
|
- BasicDBList values2 = new BasicDBList();
|
|
|
|
- for(String id:ids){
|
|
|
|
- values2.add(id);
|
|
|
|
- }
|
|
|
|
- query1.put("quesion.$id", new BasicDBObject("$in", values2));
|
|
|
|
- DBCursor dbCursor2 = mongoTemplate.getCollection("paperDetailUnit").find(query1);
|
|
|
|
- while (dbCursor2.hasNext()){
|
|
|
|
- DBObject object=dbCursor2.next();
|
|
|
|
- log.debug("打印游标2---------------"+object);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //第三种查询,quesion.$id ObjectId
|
|
|
|
- //DBObject query3 = new BasicDBObject();
|
|
|
|
- BasicDBList values3 = new BasicDBList();
|
|
|
|
- for(String id:ids){
|
|
|
|
- values3.add(new ObjectId(id));
|
|
|
|
- }
|
|
|
|
- query1.put("quesion.$id", new BasicDBObject("$in", values3));
|
|
|
|
- DBCursor dbCursor3 = mongoTemplate.getCollection("paperDetailUnit").find(query1);
|
|
|
|
- while (dbCursor3.hasNext()){
|
|
|
|
- DBObject object=dbCursor3.next();
|
|
|
|
- log.debug("打印游标3---------------"+object);
|
|
|
|
- }
|
|
|
|
- return null;
|
|
|
|
- }*/
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<PaperDetailUnit> findByPaperIds(List<String> ids) {
|
|
|
|
- List<ObjectId> objectIds = new ArrayList<>();
|
|
|
|
- for (String id : ids) {
|
|
|
|
- objectIds.add(new ObjectId(id));
|
|
|
|
- }
|
|
|
|
- Query query = new Query();
|
|
|
|
- query.addCriteria(Criteria.where("paper.$id").in(objectIds));
|
|
|
|
- List<PaperDetailUnit> paperDetailUnits = mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
- return paperDetailUnits;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public void clearQuestionCache(String questionId) {
|
|
|
|
- //清理与当前试题相关的缓存
|
|
|
|
-// final String patternKey = CACHE_KEY_QUESTION + "*" + questionId;
|
|
|
|
-// Set<String> keys = redisTemplate.keys(patternKey);
|
|
|
|
-// if (CollectionUtils.isNotEmpty(keys)) {
|
|
|
|
-// redisTemplate.delete(keys);
|
|
|
|
-// }
|
|
|
|
- questionCache.remove(questionId);
|
|
|
|
- questionAnswerCache.remove(questionId);
|
|
|
|
- //根据questionId清空相关联的paper缓存
|
|
|
|
- List<PaperDetailUnit> list=findByQuestionId(questionId);
|
|
|
|
- if(list!=null&&list.size()>0) {
|
|
|
|
- for(PaperDetailUnit pd:list) {
|
|
|
|
-// String paperKey = CACHE_KEY_PAPER + "*" + pd.getPaper().getId();
|
|
|
|
-// Set<String> paperKeys = redisTemplate.keys(paperKey);
|
|
|
|
-// if (CollectionUtils.isNotEmpty(paperKeys)) {
|
|
|
|
-// redisTemplate.delete(paperKeys);
|
|
|
|
-// }
|
|
|
|
- extractConfigPaperCache.remove(pd.getPaper().getId());
|
|
|
|
- basePaperCache.remove(pd.getPaper().getId());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private List<PaperDetailUnit> findByQuestionId(String questionId) {
|
|
|
|
- Query query = new Query();
|
|
|
|
- query.addCriteria(Criteria.where("question.id").is(questionId));
|
|
|
|
- List<PaperDetailUnit> paperDetailUnits = this.mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
- return paperDetailUnits;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+package cn.com.qmth.examcloud.core.questions.service.impl;
|
|
|
|
+
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.Collections;
|
|
|
|
+import java.util.Comparator;
|
|
|
|
+import java.util.List;
|
|
|
|
+
|
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
+import org.bson.types.ObjectId;
|
|
|
|
+import org.jsoup.Jsoup;
|
|
|
|
+import org.jsoup.nodes.Document;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.data.domain.Sort;
|
|
|
|
+import org.springframework.data.domain.Sort.Direction;
|
|
|
|
+import org.springframework.data.domain.Sort.Order;
|
|
|
|
+import org.springframework.data.mongodb.core.MongoTemplate;
|
|
|
|
+import org.springframework.data.mongodb.core.query.Criteria;
|
|
|
|
+import org.springframework.data.mongodb.core.query.Query;
|
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+
|
|
|
|
+import cn.com.qmth.examcloud.api.commons.enums.AdminOperateType;
|
|
|
|
+import cn.com.qmth.examcloud.api.commons.security.bean.User;
|
|
|
|
+import cn.com.qmth.examcloud.commons.exception.StatusException;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.base.Model;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.base.enums.PaperType;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.base.question.enums.QuesStructType;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.PaperDetailUnitRepo;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.PaperRepo;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.Paper;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetail;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetailUnit;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.Question;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.PaperDetailUnitService;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.PaperService;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.QuesService;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.RandomPaperQuestionService;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.bean.dto.PaperDetailUnitDto;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.bean.dto.PaperDetailUnitExp;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.cache.BasePaperCache;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.cache.ExtractConfigPaperCache;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.cache.QuestionAnswerCache;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.cache.QuestionCache;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.util.PaperUtil;
|
|
|
|
+import cn.com.qmth.examcloud.reports.commons.bean.AdminOperateReport;
|
|
|
|
+import cn.com.qmth.examcloud.reports.commons.util.ReportsUtil;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @author chenken
|
|
|
|
+ * @date 2017年9月13日 上午11:29:56
|
|
|
|
+ * @company QMTH
|
|
|
|
+ */
|
|
|
|
+@Service("paperDetailUnitService")
|
|
|
|
+public class PaperDetailUnitServiceImpl implements PaperDetailUnitService {
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ PaperRepo paperRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private ExtractConfigPaperCache extractConfigPaperCache;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private BasePaperCache basePaperCache;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private QuestionCache questionCache;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private QuestionAnswerCache questionAnswerCache;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ PaperDetailUnitRepo paperDetailUnitRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ QuesService quesService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ PaperService paperService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ MongoTemplate mongoTemplate;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ RedisTemplate<String, Object> redisTemplate;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private RandomPaperQuestionService randomPaperQuestionService;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 根据Id获得对应的试题对象
|
|
|
|
+ *
|
|
|
|
+ * @param id
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public Question getQuestionByPaperDetailUnitId(String id) {
|
|
|
|
+ return Model.of(paperDetailUnitRepo.findById(id)).getQuestion();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 按ID查询小题
|
|
|
|
+ *
|
|
|
|
+ * @param id
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public PaperDetailUnit findById(String id) {
|
|
|
|
+ return Model.of(paperDetailUnitRepo.findById(id));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void checkFillBlankQuestion(Question question) {
|
|
|
|
+ if (question.getQuestionType() == QuesStructType.FILL_BLANK_QUESTION) {
|
|
|
|
+ String body = question.getQuesBody();
|
|
|
|
+ Document bodyDoc = Jsoup.parse(body);
|
|
|
|
+ if (bodyDoc.body().childrenSize() == 0) {
|
|
|
|
+ throw new StatusException("1000", "题干不能为空");
|
|
|
|
+ }
|
|
|
|
+ String bodyText = bodyDoc.body().html();
|
|
|
|
+ if (StringUtils.isBlank(bodyText)) {
|
|
|
|
+ throw new StatusException("1001", "题干不能为空");
|
|
|
|
+ }
|
|
|
|
+ if (bodyText.indexOf("###") == -1) {
|
|
|
|
+ throw new StatusException("1002", "题干不能没有空格(###)");
|
|
|
|
+ }
|
|
|
|
+ String answer = question.getQuesAnswer();
|
|
|
|
+ Document answerDoc = Jsoup.parse(answer);
|
|
|
|
+ if (answerDoc.body().childrenSize() != 0) {
|
|
|
|
+ String answerText = answerDoc.body().html();
|
|
|
|
+ if (StringUtils.isNotBlank(answerText)) {
|
|
|
|
+ if (getSubStringCount(bodyText, "###") != answerText.split("##").length) {
|
|
|
|
+ throw new StatusException("1003", "题干空格(###)数量和答案数量不一致");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int getSubStringCount(String src, String find) {
|
|
|
|
+ int o = 0;
|
|
|
|
+ int index = -1;
|
|
|
|
+ while ((index = src.indexOf(find, index)) > -1) {
|
|
|
|
+ ++index;
|
|
|
|
+ ++o;
|
|
|
|
+ }
|
|
|
|
+ return o;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public boolean paperInUse(String questionId) {
|
|
|
|
+ Query query = new Query();
|
|
|
|
+ query.addCriteria(Criteria.where("question.$id").is(new ObjectId(questionId)));
|
|
|
|
+ query.addCriteria(Criteria.where("paperType").is(PaperType.GENERATE.name()));
|
|
|
|
+ List<PaperDetailUnitDto> units = this.mongoTemplate.find(query, PaperDetailUnitDto.class, "paperDetailUnit");
|
|
|
|
+ if (CollectionUtils.isEmpty(units)) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ for (PaperDetailUnitDto dto : units) {
|
|
|
|
+ if (dto.getPaper().getInUse() != null && dto.getPaper().getInUse() == 1) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 保存小题
|
|
|
|
+ */
|
|
|
|
+ public PaperDetailUnit savePaperDetailUnit(PaperDetailUnitExp updateUnit, User user) {
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
+ PaperDetailUnit baseUnit = Model.of(paperDetailUnitRepo.findById(updateUnit.getId()));
|
|
|
|
+ if (paperInUse(baseUnit.getQuestion().getId())) {
|
|
|
|
+ PaperUtil.checkUpdate(updateUnit, baseUnit, "试卷已调用,");
|
|
|
|
+ }
|
|
|
|
+ if (randomPaperQuestionService.existQuestion(baseUnit.getQuestion().getId())) {
|
|
|
|
+ PaperUtil.checkUpdateOption(updateUnit, baseUnit, "小题已被抽题模板使用,");
|
|
|
|
+ }
|
|
|
|
+ Question baseQuestion = baseUnit.getQuestion();
|
|
|
|
+ Question updateQuestion = updateUnit.getQuestion();
|
|
|
|
+ checkFillBlankQuestion(updateQuestion);
|
|
|
|
+ if (baseUnit.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
|
|
|
|
+ if (updateQuestion.getId().equals(baseQuestion.getId())) {
|
|
|
|
+
|
|
|
|
+ if (!StringUtils.equals(baseQuestion.getQuesBody(), updateQuestion.getQuesBody())) {
|
|
|
|
+ sb.append(" 第" + baseUnit.getNumber() + "小题(套题)题干变动");
|
|
|
|
+ }
|
|
|
|
+ // 更新对象为套题本身
|
|
|
|
+ quesService.saveQues(updateQuestion);
|
|
|
|
+ baseUnit.setQuestion(updateQuestion);
|
|
|
|
+ } else {
|
|
|
|
+ if (updateQuestion.getQuesOptions() != null && updateQuestion.getQuesOptions().size() > 26) {
|
|
|
|
+ throw new StatusException("选项数量不能超过26");
|
|
|
|
+ }
|
|
|
|
+ List<Double> subScoreList = baseUnit.getSubScoreList();
|
|
|
|
+ int size = baseQuestion.getSubQuestions().size();
|
|
|
|
+ boolean match = false;
|
|
|
|
+
|
|
|
|
+ // 判断更新的对象是哪个子题
|
|
|
|
+ for (int index = 1; index <= size; index++) {
|
|
|
|
+ // 检查子题分数,确保没有错误数据
|
|
|
|
+ if (subScoreList.size() < index) {
|
|
|
|
+ subScoreList.add(0d);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Question sub = baseQuestion.getSubQuestions().get(index - 1);
|
|
|
|
+ if (updateQuestion.getId().equals(sub.getId())) {
|
|
|
|
+ String changInfo = getQuestionChangeInfo(sub, updateQuestion);
|
|
|
|
+ if (changInfo != null) {
|
|
|
|
+ sb.append("第" + baseUnit.getNumber() + "小题第" + index + "子题变动:" + changInfo);
|
|
|
|
+ }
|
|
|
|
+ // 匹配到子题
|
|
|
|
+ subScoreList.set(index - 1, updateUnit.getScore());
|
|
|
|
+ baseQuestion.getSubQuestions().set(index - 1, updateQuestion);
|
|
|
|
+
|
|
|
|
+ // 重新计算套题的难度,公开度
|
|
|
|
+ boolean publicity = false;
|
|
|
|
+ double totalSum = 0d;
|
|
|
|
+ double totalDou = 0d;
|
|
|
|
+ for (int i = 0; i < baseQuestion.getSubQuestions().size(); i++) {
|
|
|
|
+ Question subQuestion = baseQuestion.getSubQuestions().get(i);
|
|
|
|
+ // 设置公开度
|
|
|
|
+ if (subQuestion.getPublicity()) {
|
|
|
|
+ publicity = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (subQuestion.getDifficultyDegree() == null) {
|
|
|
|
+ subQuestion.setDifficultyDegree(0.5);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ totalSum = subQuestion.getDifficultyDegree() * subScoreList.get(i) + totalSum;
|
|
|
|
+ totalDou = subScoreList.get(i) + totalDou;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ BigDecimal b;
|
|
|
|
+ if (totalDou != 0d) {
|
|
|
|
+ b = BigDecimal.valueOf(totalSum / totalDou);
|
|
|
|
+ } else {
|
|
|
|
+ b = BigDecimal.valueOf(0d);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Double difficulty = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
|
|
|
+ baseQuestion.setDifficultyDegree(difficulty);
|
|
|
|
+ baseQuestion.setPublicity(publicity);
|
|
|
|
+ match = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (match) {
|
|
|
|
+ quesService.saveQues(baseQuestion);
|
|
|
|
+ baseUnit.setQuestion(baseQuestion);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 更新套题unit当前总分与子题分数
|
|
|
|
+ baseUnit.setSubScoreList(subScoreList);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if (updateQuestion.getQuesOptions() != null && updateQuestion.getQuesOptions().size() > 26) {
|
|
|
|
+ throw new StatusException("选项数量不能超过26");
|
|
|
|
+ }
|
|
|
|
+ String changInfo = getQuestionChangeInfo(baseQuestion, updateQuestion);
|
|
|
|
+ if (changInfo != null) {
|
|
|
|
+ sb.append("第" + baseUnit.getNumber() + "小题变动:" + changInfo);
|
|
|
|
+ }
|
|
|
|
+ quesService.saveQues(updateQuestion);
|
|
|
|
+ baseUnit.setQuestion(updateQuestion);
|
|
|
|
+ baseUnit.setScore(updateUnit.getScore());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 同时要跟新小题里面的Question对象
|
|
|
|
+ paperDetailUnitRepo.save(baseUnit);
|
|
|
|
+
|
|
|
|
+ Paper paper = baseUnit.getPaper();
|
|
|
|
+ Double total = paper.getTotalScore();
|
|
|
|
+ Integer dc = paper.getPaperDetailCount();
|
|
|
|
+ Integer uc = paper.getUnitCount();
|
|
|
|
+ if (PaperType.GENERATE.equals(paper.getPaperType())) {
|
|
|
|
+ paper.setAuditStatus(false);
|
|
|
|
+ }
|
|
|
|
+ paperService.formatPaper(paper, user);
|
|
|
|
+
|
|
|
|
+ String changInfo = PaperUtil.getPaperChangeInfo(total, dc, uc, paper);
|
|
|
|
+ if (changInfo != null) {
|
|
|
|
+ sb.append(changInfo);
|
|
|
|
+ }
|
|
|
|
+ if (sb.length() != 0) {
|
|
|
|
+ StringBuilder paperInfo = new StringBuilder();
|
|
|
|
+ paperInfo.append(" 课程:" + paper.getCourse().getName() + "(" + paper.getCourse().getCode() + ")");
|
|
|
|
+ paperInfo.append(" 试卷名称:" + paper.getName());
|
|
|
|
+ sb.append(paperInfo);
|
|
|
|
+ if (PaperType.IMPORT.equals(paper.getPaperType())) {
|
|
|
|
+ ReportsUtil.report(new AdminOperateReport(user.getRootOrgId(), user.getUserId(),
|
|
|
|
+ AdminOperateType.TYPE43.getDesc(), sb.toString()));
|
|
|
|
+ } else {
|
|
|
|
+ ReportsUtil.report(new AdminOperateReport(user.getRootOrgId(), user.getUserId(),
|
|
|
|
+ AdminOperateType.TYPE44.getDesc(), sb.toString()));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (baseUnit.getQuestion() != null) {
|
|
|
|
+ // 清除缓存
|
|
|
|
+ this.clearQuestionCache(baseUnit.getQuestion().getId());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return baseUnit;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private String getQuestionChangeInfo(Question old, Question now) {
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
+ if (old.getScore().doubleValue() != now.getScore().doubleValue()) {
|
|
|
|
+ sb.append(" 分数变动(" + old.getScore() + "变为" + now.getScore() + ")");
|
|
|
|
+ }
|
|
|
|
+ if (!StringUtils.equals(old.getQuesBody(), now.getQuesBody())) {
|
|
|
|
+ sb.append(" 题干变动");
|
|
|
|
+ }
|
|
|
|
+ if (optionChange(old, now)) {
|
|
|
|
+ sb.append(" 选项变动");
|
|
|
|
+ }
|
|
|
|
+ if (!StringUtils.equals(old.getQuesAnswer(), now.getQuesAnswer())) {
|
|
|
|
+ sb.append(" 答案变动");
|
|
|
|
+ }
|
|
|
|
+ if (sb.length() == 0) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ return sb.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private boolean optionChange(Question old, Question now) {
|
|
|
|
+ if (now.getQuesOptions() == null) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (old.getQuesOptions().size() != now.getQuesOptions().size()) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ for (int i = 0; i < now.getQuesOptions().size(); i++) {
|
|
|
|
+ if (!StringUtils.equals(old.getQuesOptions().get(i).getOptionBody(),
|
|
|
|
+ now.getQuesOptions().get(i).getOptionBody())) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 删除小题
|
|
|
|
+ *
|
|
|
|
+ * @param id
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public void deletePaperDetailUnit(String id, User user) {
|
|
|
|
+ String changInfo = null;
|
|
|
|
+ PaperDetailUnit detailUnit = Model.of(paperDetailUnitRepo.findById(id));
|
|
|
|
+ Paper paper = detailUnit.getPaper();
|
|
|
|
+ if (paper.getInUse() != null && paper.getInUse() == 1) {
|
|
|
|
+ throw new StatusException("500", "试卷已调用");
|
|
|
|
+ }
|
|
|
|
+ paperDetailUnitRepo.deleteById(id);
|
|
|
|
+
|
|
|
|
+ if (detailUnit.getQuestion() != null) {
|
|
|
|
+ // 清除缓存
|
|
|
|
+ this.clearQuestionCache(detailUnit.getQuestion().getId());
|
|
|
|
+ }
|
|
|
|
+ Double total = paper.getTotalScore();
|
|
|
|
+ Integer dc = paper.getPaperDetailCount();
|
|
|
|
+ Integer uc = paper.getUnitCount();
|
|
|
|
+ paper.setAuditStatus(false);
|
|
|
|
+ paperService.formatPaper(paper, user);
|
|
|
|
+ changInfo = PaperUtil.getPaperChangeInfo(total, dc, uc, paper);
|
|
|
|
+ if (detailUnit != null) {
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
+ sb.append("课程:" + detailUnit.getPaper().getCourse().getName() + "("
|
|
|
|
+ + detailUnit.getPaper().getCourse().getCode() + ")");
|
|
|
|
+ sb.append(" 试卷名称:" + detailUnit.getPaper().getName());
|
|
|
|
+ sb.append(" 第" + detailUnit.getNumber() + "小题 ");
|
|
|
|
+ sb.append(changInfo);
|
|
|
|
+ ReportsUtil.report(new AdminOperateReport(user.getRootOrgId(), user.getUserId(),
|
|
|
|
+ AdminOperateType.TYPE45.getDesc(), sb.toString()));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 根据大题查小题
|
|
|
|
+ *
|
|
|
|
+ * @param paperDetail
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public List<PaperDetailUnit> getUnitsByPaperDetail(PaperDetail paperDetail) {
|
|
|
|
+ return paperDetailUnitRepo.findByPaperDetailOrderByNumber(paperDetail);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 根据大题集合删除小题
|
|
|
|
+ *
|
|
|
|
+ * @param paperDetails
|
|
|
|
+ */
|
|
|
|
+ public void deleteUnitsByPaperDetails(List<PaperDetail> paperDetails) {
|
|
|
|
+ List<PaperDetailUnit> units = new ArrayList<>();
|
|
|
|
+ for (PaperDetail pd : paperDetails) {
|
|
|
|
+ units.addAll(getUnitsByPaperDetail(pd));
|
|
|
|
+ }
|
|
|
|
+ paperDetailUnitRepo.deleteAll(units);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public List<PaperDetailUnit> findByQuestionAndPaperTypes(Question question, List<PaperType> paperTypes) {
|
|
|
|
+ Query query = new Query();
|
|
|
|
+ query.addCriteria(Criteria.where("paperType").in(paperTypes));
|
|
|
|
+ query.addCriteria(Criteria.where("question").is(question));
|
|
|
|
+ return this.mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 查询大题下的小题 按number升序或降序排列,取第一个
|
|
|
|
+ *
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public PaperDetailUnit findTopOrderByNumber(PaperDetail paperDetail, String orderType) {
|
|
|
|
+ if ("ASC".equals(orderType)) {
|
|
|
|
+ return paperDetailUnitRepo.findTopByPaperDetailOrderByNumberAsc(paperDetail);
|
|
|
|
+ } else if ("DESC".equals(orderType)) {
|
|
|
|
+ return paperDetailUnitRepo.findTopByPaperDetailOrderByNumberDesc(paperDetail);
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 按试卷 查询 小题,并将小题按number,createTime排序
|
|
|
|
+ *
|
|
|
|
+ * @param paper
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public List<PaperDetailUnit> findByPaperAndSort(Paper paper) {
|
|
|
|
+ Query query = new Query();
|
|
|
|
+ query.addCriteria(Criteria.where("paper").is(paper));
|
|
|
|
+ // query.with(Sort.by(new Order(Direction.ASC, "number")));
|
|
|
|
+ // query.with(Sort.by(new Order(Direction.ASC, "createTime")));
|
|
|
|
+ List<PaperDetailUnit> list = this.mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
+ Collections.sort(list, new Comparator<PaperDetailUnit>() {
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public int compare(PaperDetailUnit o1, PaperDetailUnit o2) {
|
|
|
|
+ if (o1.getPaperDetail().getNumber() > o2.getPaperDetail().getNumber()) {
|
|
|
|
+ return 1;
|
|
|
|
+ } else if (o1.getPaperDetail().getNumber() < o2.getPaperDetail().getNumber()) {
|
|
|
|
+ return -1;
|
|
|
|
+ } else {
|
|
|
|
+ if (o1.getNumber() > o2.getNumber()) {
|
|
|
|
+ return 1;
|
|
|
|
+ } else if (o1.getNumber() < o2.getNumber()) {
|
|
|
|
+ return -1;
|
|
|
|
+ } else {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+ return list;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public List<PaperDetailUnit> findByQuestionsAndPaperTypeOnline(List<String> ids, PaperType paperType) {
|
|
|
|
+ Query query = new Query();
|
|
|
|
+ query.addCriteria(Criteria.where("question.id").in(ids));
|
|
|
|
+ query.addCriteria(Criteria.where("paperType").is(paperType));
|
|
|
|
+ List<PaperDetailUnit> paperDetailUnits = this.mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
+ return paperDetailUnits;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<PaperDetailUnit> findByQuestionsAndPaperType(List<String> ids, PaperType paperType) {
|
|
|
|
+ List<ObjectId> objectIds = new ArrayList<>();
|
|
|
|
+ for (String id : ids) {
|
|
|
|
+ objectIds.add(new ObjectId(id));
|
|
|
|
+ }
|
|
|
|
+ Query query = new Query();
|
|
|
|
+ query.addCriteria(Criteria.where("question.$id").in(objectIds));
|
|
|
|
+ query.addCriteria(Criteria.where("paperType").is(paperType));
|
|
|
|
+ List<PaperDetailUnit> paperDetailUnits = this.mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
+ return paperDetailUnits;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<PaperDetailUnit> findByDDQuestionsAndPaperType(List<String> ids, PaperType paperType,
|
|
|
|
+ List<Question> questionList) {
|
|
|
|
+ List<ObjectId> objectIds = new ArrayList<>();
|
|
|
|
+ for (String id : ids) {
|
|
|
|
+ objectIds.add(new ObjectId(id));
|
|
|
|
+ }
|
|
|
|
+ Query query = new Query();
|
|
|
|
+ query.addCriteria(Criteria.where("question.$id").in(objectIds));
|
|
|
|
+ query.addCriteria(Criteria.where("paperType").is("IMPORT"));
|
|
|
|
+ List<PaperDetailUnit> paperDetailUnits = mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
+ return paperDetailUnits;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @Override public List<PaperDetailUnit> testFind(List<String>
|
|
|
|
+ * ids,PaperType paperType, List<Question> questionList) {
|
|
|
|
+ * //第一种查询,quesion.id id DBObject query1 = new BasicDBObject(); BasicDBList
|
|
|
|
+ * values = new BasicDBList(); for(String id:ids){ values.add(id); }
|
|
|
|
+ * query1.put("quesion.id", new BasicDBObject("$in", values)); DBCursor
|
|
|
|
+ * dbCursor = mongoTemplate.getCollection("paperDetailUnit").find(query1);
|
|
|
|
+ * while (dbCursor.hasNext()){ DBObject object=dbCursor.next();
|
|
|
|
+ * log.debug("打印游标---------------"+object); }
|
|
|
|
+ *
|
|
|
|
+ * //第二种查询,quesion.$id id //DBObject query2 = new BasicDBObject();
|
|
|
|
+ * BasicDBList values2 = new BasicDBList(); for(String id:ids){
|
|
|
|
+ * values2.add(id); } query1.put("quesion.$id", new BasicDBObject("$in",
|
|
|
|
+ * values2)); DBCursor dbCursor2 =
|
|
|
|
+ * mongoTemplate.getCollection("paperDetailUnit").find(query1); while
|
|
|
|
+ * (dbCursor2.hasNext()){ DBObject object=dbCursor2.next();
|
|
|
|
+ * log.debug("打印游标2---------------"+object); }
|
|
|
|
+ *
|
|
|
|
+ * //第三种查询,quesion.$id ObjectId //DBObject query3 = new BasicDBObject();
|
|
|
|
+ * BasicDBList values3 = new BasicDBList(); for(String id:ids){
|
|
|
|
+ * values3.add(new ObjectId(id)); } query1.put("quesion.$id", new
|
|
|
|
+ * BasicDBObject("$in", values3)); DBCursor dbCursor3 =
|
|
|
|
+ * mongoTemplate.getCollection("paperDetailUnit").find(query1); while
|
|
|
|
+ * (dbCursor3.hasNext()){ DBObject object=dbCursor3.next();
|
|
|
|
+ * log.debug("打印游标3---------------"+object); } return null; }
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<PaperDetailUnit> findByPaperIds(List<String> ids) {
|
|
|
|
+ List<ObjectId> objectIds = new ArrayList<>();
|
|
|
|
+ for (String id : ids) {
|
|
|
|
+ objectIds.add(new ObjectId(id));
|
|
|
|
+ }
|
|
|
|
+ Query query = new Query();
|
|
|
|
+ query.addCriteria(Criteria.where("paper.$id").in(objectIds));
|
|
|
|
+ List<PaperDetailUnit> paperDetailUnits = mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
+ return paperDetailUnits;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void clearQuestionCache(String questionId) {
|
|
|
|
+ // 清理与当前试题相关的缓存
|
|
|
|
+ // final String patternKey = CACHE_KEY_QUESTION + "*" + questionId;
|
|
|
|
+ // Set<String> keys = redisTemplate.keys(patternKey);
|
|
|
|
+ // if (CollectionUtils.isNotEmpty(keys)) {
|
|
|
|
+ // redisTemplate.delete(keys);
|
|
|
|
+ // }
|
|
|
|
+ questionCache.remove(questionId);
|
|
|
|
+ questionAnswerCache.remove(questionId);
|
|
|
|
+ // 根据questionId清空相关联的paper缓存
|
|
|
|
+ List<PaperDetailUnit> list = findByQuestionId(questionId);
|
|
|
|
+ if (list != null && list.size() > 0) {
|
|
|
|
+ for (PaperDetailUnit pd : list) {
|
|
|
|
+ // String paperKey = CACHE_KEY_PAPER + "*" +
|
|
|
|
+ // pd.getPaper().getId();
|
|
|
|
+ // Set<String> paperKeys = redisTemplate.keys(paperKey);
|
|
|
|
+ // if (CollectionUtils.isNotEmpty(paperKeys)) {
|
|
|
|
+ // redisTemplate.delete(paperKeys);
|
|
|
|
+ // }
|
|
|
|
+ extractConfigPaperCache.remove(pd.getPaper().getId());
|
|
|
|
+ basePaperCache.remove(pd.getPaper().getId());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private List<PaperDetailUnit> findByQuestionId(String questionId) {
|
|
|
|
+ Query query = new Query();
|
|
|
|
+ query.addCriteria(Criteria.where("question.id").is(questionId));
|
|
|
|
+ List<PaperDetailUnit> paperDetailUnits = this.mongoTemplate.find(query, PaperDetailUnit.class);
|
|
|
|
+ return paperDetailUnits;
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|