| | |
| | | package com.mindskip.xzs.service.impl; |
| | | |
| | | import com.mindskip.xzs.configuration.spring.exception.QuestionException; |
| | | import com.mindskip.xzs.domain.*; |
| | | import com.mindskip.xzs.domain.TextContent; |
| | | import com.mindskip.xzs.domain.enums.ExamPaperTypeEnum; |
| | | import com.mindskip.xzs.domain.enums.QuestionTypeEnum; |
| | | import com.mindskip.xzs.domain.exam.ExamPaperQuestionItemObject; |
| | | import com.mindskip.xzs.domain.exam.ExamPaperTitleItemObject; |
| | | import com.mindskip.xzs.domain.other.KeyValue; |
| | | import com.mindskip.xzs.repository.ExamPaperMapper; |
| | | import com.mindskip.xzs.repository.QuestionMapper; |
| | | import com.mindskip.xzs.service.ExamPaperService; |
| | | import com.mindskip.xzs.service.QuestionService; |
| | | import com.mindskip.xzs.service.SubjectService; |
| | | import com.mindskip.xzs.service.TextContentService; |
| | | import com.mindskip.xzs.service.*; |
| | | import com.mindskip.xzs.service.enums.ActionEnum; |
| | | import com.mindskip.xzs.utility.DateTimeUtil; |
| | | import com.mindskip.xzs.utility.JsonUtil; |
| | |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.*; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | private final TextContentService textContentService; |
| | | private final QuestionService questionService; |
| | | private final SubjectService subjectService; |
| | | private final ExamPaperDepartmentService examPaperDepartmentService; |
| | | private final ExamPaperSubjectService examPaperSubjectService; |
| | | private final QuestionSubjectService questionSubjectService; |
| | | |
| | | @Autowired |
| | | public ExamPaperServiceImpl(ExamPaperMapper examPaperMapper, QuestionMapper questionMapper, TextContentService textContentService, QuestionService questionService, SubjectService subjectService) { |
| | | public ExamPaperServiceImpl(ExamPaperMapper examPaperMapper, QuestionMapper questionMapper, TextContentService textContentService, QuestionService questionService, SubjectService subjectService, ExamPaperDepartmentService examPaperDepartmentService, ExamPaperSubjectService examPaperSubjectService, QuestionSubjectService questionSubjectService) { |
| | | super(examPaperMapper); |
| | | this.examPaperMapper = examPaperMapper; |
| | | this.questionMapper = questionMapper; |
| | | this.textContentService = textContentService; |
| | | this.questionService = questionService; |
| | | this.subjectService = subjectService; |
| | | this.examPaperDepartmentService = examPaperDepartmentService; |
| | | this.examPaperSubjectService = examPaperSubjectService; |
| | | this.questionSubjectService = questionSubjectService; |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | @Override |
| | | @Transactional |
| | | public ExamPaper savePaperFromVM(ExamPaperEditRequestVM examPaperEditRequestVM, User user) { |
| | | public ExamPaper savePaperFromVM(ExamPaperEditRequestVM examPaperEditRequestVM, User user) throws QuestionException { |
| | | ActionEnum actionEnum = (examPaperEditRequestVM.getId() == null) ? ActionEnum.ADD : ActionEnum.UPDATE; |
| | | Date now = new Date(); |
| | | List<ExamPaperTitleItemVM> titleItemsVM = examPaperEditRequestVM.getTitleItems(); |
| | | List<ExamPaperTitleItemObject> frameTextContentList = frameTextContentFromVM(titleItemsVM); |
| | | |
| | | List<ExamPaperTitleItemObject> frameTextContentList = new ArrayList<>(); |
| | | List<ExamPaperTitleItemVM> titleItemsVM = new ArrayList<>(); |
| | | //随机试卷 |
| | | if (examPaperEditRequestVM.getSubjectSource().size() != 0) { |
| | | // Map<Integer, Integer> questionList = questionService.getAll().stream().collect(Collectors.toMap(Question::getId, Question::getScore)); |
| | | randomQuestion(examPaperEditRequestVM, frameTextContentList, titleItemsVM); |
| | | } |
| | | if (titleItemsVM.size() == 0) { |
| | | titleItemsVM = examPaperEditRequestVM.getTitleItems(); |
| | | } |
| | | if (frameTextContentList.size() == 0) { |
| | | frameTextContentList = frameTextContentFromVM(titleItemsVM); |
| | | } |
| | | |
| | | String frameTextContentStr = JsonUtil.toJsonStr(frameTextContentList); |
| | | |
| | | ExamPaper examPaper; |
| | |
| | | examPaper.setDeleted(false); |
| | | examPaperFromVM(examPaperEditRequestVM, examPaper, titleItemsVM); |
| | | examPaperMapper.insertSelective(examPaper); |
| | | |
| | | } else { |
| | | examPaper = examPaperMapper.selectByPrimaryKey(examPaperEditRequestVM.getId()); |
| | | TextContent frameTextContent = textContentService.selectById(examPaper.getFrameTextContentId()); |
| | |
| | | modelMapper.map(examPaperEditRequestVM, examPaper); |
| | | examPaperFromVM(examPaperEditRequestVM, examPaper, titleItemsVM); |
| | | examPaperMapper.updateByPrimaryKeySelective(examPaper); |
| | | //批量修改 |
| | | examPaperDepartmentService.removeByExamPaperId(examPaper.getId()); |
| | | examPaperSubjectService.removeByExamPaperId(examPaper.getId()); |
| | | } |
| | | addExamPaperDepartment(examPaperEditRequestVM, examPaper); |
| | | addExamPaperSubject(examPaperEditRequestVM, examPaper); |
| | | return examPaper; |
| | | } |
| | | |
| | |
| | | .map(q -> q.getId())) |
| | | .collect(Collectors.toList()); |
| | | List<Question> questions = questionMapper.selectByIds(questionIds); |
| | | Integer order = 0; |
| | | Set<Integer> generatedNumbers = new HashSet<>(); |
| | | Random random = new Random(); |
| | | List<ExamPaperTitleItemVM> examPaperTitleItemVMS = examPaperTitleItemObjects.stream().map(t -> { |
| | | ExamPaperTitleItemVM tTitleVM = modelMapper.map(t, ExamPaperTitleItemVM.class); |
| | | List<QuestionEditRequestVM> questionItemsVM = t.getQuestionItems().stream().map(i -> { |
| | | Question question = questions.stream().filter(q -> q.getId().equals(i.getId())).findFirst().get(); |
| | | QuestionEditRequestVM questionEditRequestVM = questionService.getQuestionEditRequestVM(question); |
| | | questionEditRequestVM.setItemOrder(i.getItemOrder()); |
| | | return questionEditRequestVM; |
| | | }).collect(Collectors.toList()); |
| | | Question question = questions.stream().filter(q -> q.getId().equals(i.getId())).findFirst().get(); |
| | | QuestionEditRequestVM questionEditRequestVM = questionService.getQuestionEditRequestVM(question); |
| | | questionEditRequestVM.setItemOrder(getRandomNumber(t.getQuestionItems().size() - 1, generatedNumbers, random)); |
| | | return questionEditRequestVM; |
| | | }).sorted(Comparator.comparing(QuestionEditRequestVM::getItemOrder)) |
| | | .collect(Collectors.toList()); |
| | | tTitleVM.setQuestionItems(questionItemsVM); |
| | | return tTitleVM; |
| | | }).collect(Collectors.toList()); |
| | |
| | | List<String> limitDateTime = Arrays.asList(DateTimeUtil.dateFormat(examPaper.getLimitStartTime()), DateTimeUtil.dateFormat(examPaper.getLimitEndTime())); |
| | | vm.setLimitDateTime(limitDateTime); |
| | | } |
| | | |
| | | //查询部门和课目 |
| | | vm.setSubjectId(examPaperSubjectService.getByExamPaperId(examPaper.getId()) |
| | | .stream().map(ExamPaperSubject::getSubjectId).toArray(Integer[]::new)); |
| | | vm.setDepartmentIds(examPaperDepartmentService.getByExamPaperId(examPaper.getId()) |
| | | .stream().map(ExamPaperDepartment::getDepartmentId).toArray(Integer[]::new)); |
| | | return vm; |
| | | } |
| | | |
| | |
| | | }).collect(Collectors.toList()); |
| | | } |
| | | |
| | | @Override |
| | | public Integer removeByIds(Integer[] ids) { |
| | | return examPaperMapper.removeByIds(ids); |
| | | } |
| | | |
| | | @Override |
| | | public List<ExamPaper> gets(Integer[] ids) { |
| | | return examPaperMapper.gets(ids); |
| | | } |
| | | |
| | | private void examPaperFromVM(ExamPaperEditRequestVM examPaperEditRequestVM, ExamPaper examPaper, List<ExamPaperTitleItemVM> titleItemsVM) { |
| | | Integer gradeLevel = subjectService.levelBySubjectId(examPaperEditRequestVM.getSubjectId()); |
| | | // Integer gradeLevel = subjectService.levelBySubjectId(examPaperEditRequestVM.getSubjectId()); |
| | | Integer questionCount = titleItemsVM.stream() |
| | | .mapToInt(t -> t.getQuestionItems().size()).sum(); |
| | | Integer score = titleItemsVM.stream(). |
| | |
| | | ).sum(); |
| | | examPaper.setQuestionCount(questionCount); |
| | | examPaper.setScore(score); |
| | | examPaper.setGradeLevel(gradeLevel); |
| | | examPaper.setGradeLevel(null); |
| | | List<String> dateTimes = examPaperEditRequestVM.getLimitDateTime(); |
| | | if (ExamPaperTypeEnum.TimeLimit == ExamPaperTypeEnum.fromCode(examPaper.getPaperType())) { |
| | | examPaper.setLimitStartTime(DateTimeUtil.parse(dateTimes.get(0), DateTimeUtil.STANDER_FORMAT)); |
| | |
| | | return titleItem; |
| | | }).collect(Collectors.toList()); |
| | | } |
| | | |
| | | private void addExamPaperDepartment(ExamPaperEditRequestVM examPaperEditRequestVM, ExamPaper examPaper) { |
| | | if(examPaperEditRequestVM.getDepartmentIds().length==0){ |
| | | return; |
| | | } |
| | | List<ExamPaperDepartment> list = Arrays.asList(examPaperEditRequestVM.getDepartmentIds()).stream().map(e -> { |
| | | ExamPaperDepartment examPaperDepartment = new ExamPaperDepartment(); |
| | | examPaperDepartment.setExamPaperId(examPaper.getId()); |
| | | examPaperDepartment.setDepartmentId(e); |
| | | examPaperDepartment.setDeleted("0"); |
| | | return examPaperDepartment; |
| | | }).collect(Collectors.toList()); |
| | | examPaperDepartmentService.saves(list); |
| | | } |
| | | |
| | | private void addExamPaperSubject(ExamPaperEditRequestVM examPaperEditRequestVM, ExamPaper examPaper) { |
| | | List<ExamPaperSubject> subjectList = Arrays.asList(examPaperEditRequestVM.getSubjectId()).stream().map(e -> { |
| | | ExamPaperSubject examPaperSubject = new ExamPaperSubject(); |
| | | examPaperSubject.setSubjectId(e); |
| | | examPaperSubject.setExamPaperId(examPaper.getId()); |
| | | examPaperSubject.setDeleted("0"); |
| | | return examPaperSubject; |
| | | }).collect(Collectors.toList()); |
| | | examPaperSubjectService.saves(subjectList); |
| | | } |
| | | |
| | | /** |
| | | * @param result |
| | | * @param scoresMap |
| | | * @param quantity |
| | | * @param totalScore |
| | | */ |
| | | public static void selectRandomScores(Map<Integer, Integer> result, Map<Integer, Integer> scoresMap, int quantity, int totalScore) throws QuestionException { |
| | | // Map<String, Integer> selectedScoresMap = new HashMap<>(); |
| | | |
| | | if (quantity <= 0 || totalScore <= 0 || scoresMap.isEmpty()) { |
| | | return; // 返回空Map |
| | | } |
| | | |
| | | List<Integer> keys = new ArrayList<>(scoresMap.keySet()); |
| | | List<Integer> values = scoresMap.values().stream().map(e -> e = e / 10).collect(Collectors.toList()); |
| | | |
| | | Random random = new Random(); |
| | | int remainingQuantity = quantity; |
| | | int remainingScore = totalScore; |
| | | |
| | | for (int i = 0; i < quantity - 1; i++) { |
| | | if (i >= scoresMap.size()) { |
| | | throw new QuestionException(); |
| | | } |
| | | int index = random.nextInt(values.size()); |
| | | int score = values.get(index); |
| | | |
| | | if (score <= remainingScore) { |
| | | result.put(keys.get(index), score); |
| | | remainingQuantity--; |
| | | remainingScore -= score; |
| | | values.remove(index); |
| | | keys.remove(index); |
| | | } |
| | | } |
| | | |
| | | if (!values.isEmpty()) { |
| | | int index = random.nextInt(values.size()); |
| | | int score = values.get(index); |
| | | result.put(keys.get(index), score); // 最后一个分数为剩余的分数 |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 随机试卷 |
| | | * |
| | | * @param examPaperEditRequestVM 传参 |
| | | * @param frameTextContentList |
| | | * @param titleItemsVM title |
| | | */ |
| | | private void randomQuestion(ExamPaperEditRequestVM examPaperEditRequestVM, List<ExamPaperTitleItemObject> frameTextContentList, List<ExamPaperTitleItemVM> titleItemsVM) throws QuestionException { |
| | | Map<Integer, Integer> subjectSource = examPaperEditRequestVM.getSubjectSource(); |
| | | //总数量 |
| | | Integer sum = subjectSource.values().stream().mapToInt(Integer::intValue).sum(); |
| | | Integer count = 0; |
| | | Integer mark = 0; |
| | | |
| | | ExamPaperTitleItemObject examPaperTitleItemObject = new ExamPaperTitleItemObject(); |
| | | examPaperTitleItemObject.setName(examPaperEditRequestVM.getTitleItems().get(0).getName()); |
| | | |
| | | ExamPaperTitleItemVM examPaperTitleItemVM = new ExamPaperTitleItemVM(); |
| | | //titleItemsVM |
| | | examPaperTitleItemVM.setName(examPaperEditRequestVM.getTitleItems().get(0).getName()); |
| | | |
| | | List<ExamPaperQuestionItemObject> examPaperQuestionItemObjectList = new ArrayList<>(); |
| | | |
| | | List<QuestionEditRequestVM> questionItems = new ArrayList<>(); |
| | | Integer order = 0; |
| | | for (Integer key : subjectSource.keySet()) { // key:数量 |
| | | //该标签对应的分数 多选:3 判断:3 单选:4 |
| | | Integer source = 80 * subjectSource.get(key) / sum - mark; |
| | | // 多选和判断数量 |
| | | Integer multipleNumber = (subjectSource.get(key) + count) * 3 / 10; |
| | | //多选和判断分数 |
| | | Integer multipleSource = source * 3 / 10; |
| | | List<Integer> questions = questionSubjectService.getSubject(key) |
| | | .stream().map(QuestionSubject::getQuestionId).collect(Collectors.toList()); |
| | | List<Question> list = questionService.selectByIds(questions); |
| | | |
| | | Map<Integer, Integer> multiple = new HashMap<>(); |
| | | //多选 |
| | | Map<Integer, Integer> multipleMap = list.stream() |
| | | .filter(e -> e.getQuestionType().equals(QuestionTypeEnum.MultipleChoice.getCode())) |
| | | .collect(Collectors.toMap(Question::getId, Question::getScore)); |
| | | |
| | | selectRandomScores(multiple, multipleMap, multipleNumber < multipleMap.size() ? multipleNumber : multipleMap.size(), multipleSource); |
| | | |
| | | |
| | | //判断 |
| | | Map<Integer, Integer> judgmentMap = list.stream() |
| | | .filter(e -> e.getQuestionType().equals(QuestionTypeEnum.TrueFalse.getCode())) |
| | | .collect(Collectors.toMap(Question::getId, Question::getScore)); |
| | | selectRandomScores(multiple, judgmentMap, multipleNumber < judgmentMap.size() ? multipleNumber : judgmentMap.size(), multipleSource); |
| | | |
| | | //单选数量 |
| | | Integer radioNumber = subjectSource.get(key) - multiple.size(); |
| | | //单选分数 |
| | | Integer radioSource = source - multiple.values().stream().mapToInt(Integer::intValue).sum(); |
| | | //单选 |
| | | Map<Integer, Integer> radioMap = list.stream() |
| | | .filter(e -> e.getQuestionType().equals(QuestionTypeEnum.SingleChoice.getCode())) |
| | | .collect(Collectors.toMap(Question::getId, Question::getScore)); |
| | | selectRandomScores(multiple, radioMap, radioNumber < radioMap.size() ? radioNumber : radioMap.size(), radioSource); |
| | | |
| | | // titleItemsVM.add(examPaperTitleItemVM); |
| | | for (Integer k : multiple.keySet()) { |
| | | ExamPaperQuestionItemObject examPaperQuestionItemObject = new ExamPaperQuestionItemObject(); |
| | | examPaperQuestionItemObject.setId(k); |
| | | examPaperQuestionItemObject.setItemOrder(order++); |
| | | examPaperQuestionItemObjectList.add(examPaperQuestionItemObject); |
| | | //titleItemsVM |
| | | QuestionEditRequestVM questionEditRequestVM = new QuestionEditRequestVM(); |
| | | questionEditRequestVM.setScore(multiple.get(k).toString()); |
| | | questionItems.add(questionEditRequestVM); |
| | | } |
| | | |
| | | examPaperTitleItemObject.setQuestionItems(examPaperQuestionItemObjectList); |
| | | |
| | | //titleItemsVM |
| | | examPaperTitleItemVM.setQuestionItems(questionItems); |
| | | //数量 匹配 |
| | | count = multiple.size() != subjectSource.get(key) ? subjectSource.get(key) - multiple.size() : 0; |
| | | //分数匹配 |
| | | mark = source != multiple.values().stream().mapToInt(Integer::intValue).sum() ? multiple.values().stream().mapToInt(Integer::intValue).sum() - source : 0; |
| | | |
| | | } |
| | | frameTextContentList.add(examPaperTitleItemObject); |
| | | titleItemsVM.add(examPaperTitleItemVM); |
| | | |
| | | if (count != 0 || mark != 0) { |
| | | throw new QuestionException(); |
| | | } |
| | | |
| | | } |
| | | |
| | | public Integer getRandomNumber(Integer a, Set<Integer> generatedNumbers, Random random) { |
| | | if (a <= 0) { |
| | | throw new IllegalArgumentException("a必须为正整数"); |
| | | } |
| | | |
| | | int range = a + 1; |
| | | |
| | | if (generatedNumbers.size() >= range) { |
| | | generatedNumbers.clear(); // 清空已生成的数字集合 |
| | | } |
| | | |
| | | int randomNumber; |
| | | do { |
| | | randomNumber = random.nextInt(range); |
| | | } while (generatedNumbers.contains(randomNumber)); |
| | | |
| | | generatedNumbers.add(randomNumber); |
| | | return randomNumber; |
| | | } |
| | | } |