xiangpei
2025-05-14 47cd9ecc0eff38ffe6b3b794b2bf197e958f4403
src/main/java/com/mindskip/xzs/service/impl/ExamPaperServiceImpl.java
@@ -1,39 +1,41 @@
package com.mindskip.xzs.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
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.domain.vo.ExamTemplatesVO;
import com.mindskip.xzs.domain.vo.PaperExcelVO;
import com.mindskip.xzs.domain.vo.UserVO;
import com.mindskip.xzs.repository.ExamPaperAnswerMapper;
import com.mindskip.xzs.repository.ExamPaperMapper;
import com.mindskip.xzs.repository.QuestionMapper;
import com.mindskip.xzs.repository.UserDepartmentMapper;
import com.mindskip.xzs.service.*;
import com.mindskip.xzs.service.enums.ActionEnum;
import com.mindskip.xzs.utility.DateTimeUtil;
import com.mindskip.xzs.utility.ExamUtil;
import com.mindskip.xzs.utility.JsonUtil;
import com.mindskip.xzs.utility.ModelMapperSingle;
import com.mindskip.xzs.utility.ExamUtil;
import com.mindskip.xzs.viewmodel.admin.exam.ExamPaperEditRequestVM;
import com.mindskip.xzs.viewmodel.admin.exam.ExamPaperPageRequestVM;
import com.mindskip.xzs.viewmodel.admin.exam.ExamPaperTitleItemVM;
import com.mindskip.xzs.viewmodel.admin.exam.*;
import com.mindskip.xzs.viewmodel.admin.question.ExamQuestionVO;
import com.mindskip.xzs.viewmodel.admin.question.QuestionEditRequestVM;
import com.mindskip.xzs.viewmodel.student.dashboard.PaperFilter;
import com.mindskip.xzs.viewmodel.student.dashboard.PaperInfo;
import com.mindskip.xzs.viewmodel.student.exam.ExamPaperPageVM;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mindskip.xzs.domain.ExamPaper;
import com.mindskip.xzs.domain.Question;
import com.mindskip.xzs.domain.User;
import org.apache.commons.lang3.ObjectUtils;
import org.modelmapper.ModelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
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;
@@ -42,23 +44,37 @@
    protected final static ModelMapper modelMapper = ModelMapperSingle.Instance();
    private final ExamPaperMapper examPaperMapper;
    private final ExamPaperAnswerMapper examPaperAnswerMapper;
    private final QuestionMapper questionMapper;
    private final TextContentService textContentService;
    private final QuestionService questionService;
    private final SubjectService subjectService;
    private final ExamPaperDepartmentService examPaperDepartmentService;
    private final ExamPaperSubjectService examPaperSubjectService;
    private final QuestionSubjectService questionSubjectService;
    private final ExamPaperUserService examPaperUserService;
    private final UserService userService;
    private final UserDepartmentMapper userDepartmentMapper;
    private final DepartmentService departmentService;
    @Autowired
    public ExamPaperServiceImpl(ExamPaperMapper examPaperMapper, QuestionMapper questionMapper, TextContentService textContentService, QuestionService questionService, SubjectService subjectService, ExamPaperDepartmentService examPaperDepartmentService, ExamPaperSubjectService examPaperSubjectService) {
    public ExamPaperServiceImpl(ExamPaperMapper examPaperMapper, ExamPaperAnswerMapper examPaperAnswerMapper, QuestionMapper questionMapper, TextContentService textContentService, QuestionService questionService, SubjectService subjectService, ExamPaperDepartmentService examPaperDepartmentService, ExamPaperSubjectService examPaperSubjectService, QuestionSubjectService questionSubjectService, ExamPaperUserService examPaperUserService, UserService userService, UserDepartmentMapper userDepartmentMapper, DepartmentService departmentService) {
        super(examPaperMapper);
        this.examPaperMapper = examPaperMapper;
        this.examPaperAnswerMapper = examPaperAnswerMapper;
        this.questionMapper = questionMapper;
        this.textContentService = textContentService;
        this.questionService = questionService;
        this.subjectService = subjectService;
        this.examPaperDepartmentService = examPaperDepartmentService;
        this.examPaperSubjectService = examPaperSubjectService;
        this.questionSubjectService = questionSubjectService;
        this.examPaperUserService = examPaperUserService;
        this.userService = userService;
        this.userDepartmentMapper = userDepartmentMapper;
        this.departmentService = departmentService;
    }
@@ -83,14 +99,29 @@
    @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.getQuestionTypeVMS().size() != 0) {
//            Map<Integer, Integer> questionList = questionService.getAll().stream().collect(Collectors.toMap(Question::getId, Question::getScore));
//            randomQuestion(examPaperEditRequestVM, frameTextContentList, titleItemsVM);
            randomQuestionType(examPaperEditRequestVM, frameTextContentList, titleItemsVM);
        }
        if (titleItemsVM.size() == 0) {
            titleItemsVM = examPaperEditRequestVM.getTitleItems();
        }
        if (frameTextContentList.size() == 0) {
            frameTextContentList = frameTextContentFromVM(titleItemsVM);
        }
        String frameTextContentStr = JsonUtil.toJsonStr(frameTextContentList);
        ExamPaper examPaper;
        Integer[] userIds = examPaperEditRequestVM.getUserIds();
        if (actionEnum == ActionEnum.ADD) {
            examPaper = modelMapper.map(examPaperEditRequestVM, ExamPaper.class);
            TextContent frameTextContent = new TextContent(frameTextContentStr, now);
@@ -99,6 +130,7 @@
            examPaper.setCreateTime(now);
            examPaper.setCreateUser(user.getId());
            examPaper.setDeleted(false);
            examPaper.setUserIds(examPaperEditRequestVM.getMenuIds());
            examPaperFromVM(examPaperEditRequestVM, examPaper, titleItemsVM);
            examPaperMapper.insertSelective(examPaper);
@@ -107,38 +139,67 @@
            TextContent frameTextContent = textContentService.selectById(examPaper.getFrameTextContentId());
            frameTextContent.setContent(frameTextContentStr);
            textContentService.updateByIdFilter(frameTextContent);
            examPaperEditRequestVM.setScore(null);
            examPaperEditRequestVM.setUserIds(null);
            modelMapper.map(examPaperEditRequestVM, examPaper);
            examPaperEditRequestVM.setUserIds(userIds);
            examPaperFromVM(examPaperEditRequestVM, examPaper, titleItemsVM);
            examPaperMapper.updateByPrimaryKeySelective(examPaper);
            //批量修改
            examPaperDepartmentService.removeByExamPaperId(examPaper.getId());
            examPaperSubjectService.removeByExamPaperId(examPaper.getId());
        }
        addExamPaperDepartment(examPaperEditRequestVM,examPaper);
        addExamPaperSubject(examPaperEditRequestVM,examPaper);
//        addExamPaperDepartment(examPaperEditRequestVM, examPaper);
        addExamPaperUser(examPaperEditRequestVM, examPaper);    //批量添加试卷关联用户
        addExamPaperSubject(examPaperEditRequestVM, examPaper);
        return examPaper;
    }
    @Override
    public ExamPaperEditRequestVM examPaperToVM(Integer id) {
    public ExamPaperEditRequestVO examPaperToVM(Integer id) {
        ExamPaper examPaper = examPaperMapper.selectByPrimaryKey(id);
        ExamPaperEditRequestVM vm = modelMapper.map(examPaper, ExamPaperEditRequestVM.class);
        if (Objects.isNull(examPaper)) {
            throw new RuntimeException("该考试已被删除,无法查看");
        }
        ExamPaperEditRequestVO vm = modelMapper.map(examPaper, ExamPaperEditRequestVO.class);
        vm.setLevel(examPaper.getGradeLevel());
        vm.setMenuIds(examPaper.getUserIds());
        TextContent frameTextContent = textContentService.selectById(examPaper.getFrameTextContentId());
        List<ExamPaperTitleItemObject> examPaperTitleItemObjects = JsonUtil.toJsonListObject(frameTextContent.getContent(), ExamPaperTitleItemObject.class);
        List<Integer> questionIds = examPaperTitleItemObjects.stream()
                .flatMap(t -> t.getQuestionItems().stream()
                        .map(q -> q.getId()))
                .collect(Collectors.toList());
        if (ObjectUtils.isEmpty(questionIds)) {
            throw new RuntimeException("该试卷没有题目");
        }
        List<Question> questions = questionMapper.selectByIds(questionIds);
        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());
        //单选数量
        Integer singleChoice = questions.stream().filter(e -> e.getQuestionType() == 1).collect(Collectors.toList()).size();
        //多选数量
        Integer multipleChoice = questions.stream().filter(e -> e.getQuestionType() == 2).collect(Collectors.toList()).size();
        //判断数量
        Integer trueFalse = questions.stream().filter(e -> e.getQuestionType() == 3).collect(Collectors.toList()).size();
        Integer order = 0;
        Set<Integer> generatedNumbers = new HashSet<>();
        Random random = new Random();
        List<ExamPaperTitleItemVO> examPaperTitleItemVMS = examPaperTitleItemObjects.stream().map(t -> {
            ExamPaperTitleItemVO tTitleVM = new ExamPaperTitleItemVO();
            BeanUtils.copyProperties(t, tTitleVM);
            List<ExamQuestionVO> questionItemsVM = t.getQuestionItems().stream().map(i -> {
                        Question question = questions.stream().filter(q -> q.getId().equals(i.getId())).findFirst().get();
                        ExamQuestionVO questionEditRequestVM = questionService.getQuestionEditRequestVM(question);
                        questionEditRequestVM.setTitle("(" + QuestionTypeEnum.fromCode(questionEditRequestVM.getQuestionType()).getName() + ") " + questionEditRequestVM.getTitle());
                        questionEditRequestVM.setItemOrder(generateRandomNumber(questionEditRequestVM.getQuestionType() == 1 ? 0 : ((questionEditRequestVM.getQuestionType() == 2 ? singleChoice : multipleChoice + singleChoice)),
                                questionEditRequestVM.getQuestionType() == 1 ? singleChoice : ((questionEditRequestVM.getQuestionType() == 2 ? multipleChoice + singleChoice : trueFalse + multipleChoice + singleChoice)),
                                generatedNumbers, random));
//                        questionEditRequestVM.setItemOrder(getRandomNumber(t.getQuestionItems().size() - 1, generatedNumbers, random));
                        return questionEditRequestVM;
                    }).sorted(Comparator.comparing(ExamQuestionVO::getItemOrder))
                    .collect(Collectors.toList());
            tTitleVM.setQuestionItems(questionItemsVM);
            return tTitleVM;
        }).collect(Collectors.toList());
@@ -154,6 +215,19 @@
                .stream().map(ExamPaperSubject::getSubjectId).toArray(Integer[]::new));
        vm.setDepartmentIds(examPaperDepartmentService.getByExamPaperId(examPaper.getId())
                .stream().map(ExamPaperDepartment::getDepartmentId).toArray(Integer[]::new));
        List<ExamPaperUser> examPaperUsers = examPaperUserService.getByExamPaperId(examPaper.getId());
        List<Integer> userIds = new ArrayList();
        List<String> userNames = new ArrayList();
        for (int i = 0; i < examPaperUsers.size(); i++) {
            User user = userService.getUserById(examPaperUsers.get(i).getUserId());
            if (ObjectUtils.isNotEmpty(user)) {
                Integer userId = examPaperUsers.get(i).getUserId();
                userIds.add(userId);
                userNames.add(user.getRealName());
            }
        }
        vm.setUserIds(userIds);
        vm.setUserNames(userNames);
        return vm;
    }
@@ -164,8 +238,8 @@
    @Override
    public Integer selectAllCount() {
        return examPaperMapper.selectAllCount();
    public Integer selectAllCount(List<Integer> deptIds) {
        return examPaperMapper.selectAllCount(deptIds);
    }
    @Override
@@ -178,6 +252,58 @@
            KeyValue keyValue = mouthCount.stream().filter(kv -> kv.getName().equals(md)).findAny().orElse(null);
            return null == keyValue ? 0 : keyValue.getValue();
        }).collect(Collectors.toList());
    }
    @Override
    public Integer removeByIds(Integer[] ids) {
        return examPaperMapper.removeByIds(ids);
    }
    @Override
    public List<ExamPaper> gets(Integer[] ids) {
        return examPaperMapper.gets(ids);
    }
    @Override
    public List<PaperExcelVO> getPaperExcelById(Integer id) {
        List<PaperExcelVO> paperExcel = examPaperMapper.getPaperExcelById(id);
        paperExcel = paperExcel.stream().map(e->{
            e.setPaperScore(ExamUtil.scoreToVM(Integer.parseInt(e.getPaperScore())));
            e.setUserScore(ExamUtil.scoreToVM(Integer.parseInt(e.getUserScore())));
            List<UserDepartment> userDepartments = userDepartmentMapper.selectByUserId(Integer.parseInt(e.getUserId()));
            if(userDepartments.size() != 0){
                Department byId = departmentService.getById(userDepartments.get(0).getDepartmentId());
                e.setDepartmentName(byId.getName());
                e.setDeptId(byId.getId());
            }
            return e;
        }).collect(Collectors.toList());
        return paperExcel;
    }
    @Override
    public List<PaperExcelVO> getRandomPaperExcelById(Integer id) {
        List<PaperExcelVO> paperExcel = examPaperMapper.getRandomPaperExcelById(id);
        // 如果某考生存在多个部门,每个部门都加一遍数据
        List<PaperExcelVO> needAdd = new ArrayList<>();
        List<PaperExcelVO> needRemove = new ArrayList<>();
        paperExcel = paperExcel.stream().map(e->{
            e.setPaperScore(ExamUtil.scoreToVM(Integer.parseInt(e.getPaperScore())));
            e.setUserScore(ExamUtil.scoreToVM(Integer.parseInt(e.getUserScore())));
            List<Department> userDepartments = userDepartmentMapper.selectDeptByUserId(Integer.parseInt(e.getUserId()));
            for (Department dept : userDepartments) {
                PaperExcelVO vo = new PaperExcelVO();
                BeanUtils.copyProperties(e, vo);
                vo.setDepartmentName(dept.getName());
                vo.setDeptId(dept.getId());
                needAdd.add(vo);
                needRemove.add(e);
            }
            return e;
        }).collect(Collectors.toList());
        paperExcel.removeAll(needRemove);
        paperExcel.addAll(needAdd);
        return paperExcel.stream().filter(e -> Objects.nonNull(e.getDeptId())).collect(Collectors.toList());
    }
    private void examPaperFromVM(ExamPaperEditRequestVM examPaperEditRequestVM, ExamPaper examPaper, List<ExamPaperTitleItemVM> titleItemsVM) {
@@ -214,8 +340,11 @@
        }).collect(Collectors.toList());
    }
    private void addExamPaperDepartment(ExamPaperEditRequestVM examPaperEditRequestVM, ExamPaper examPaper){
        List<ExamPaperDepartment> list = Arrays.asList(examPaperEditRequestVM.getDepartmentIds()).stream().map(e->{
    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);
@@ -225,8 +354,28 @@
        examPaperDepartmentService.saves(list);
    }
    private void addExamPaperSubject(ExamPaperEditRequestVM examPaperEditRequestVM, ExamPaper examPaper){
        List<ExamPaperSubject> subjectList = Arrays.asList(examPaperEditRequestVM.getSubjectId()).stream().map(e->{
    private void addExamPaperUser(ExamPaperEditRequestVM examPaperEditRequestVM, ExamPaper examPaper) {
        if (examPaperEditRequestVM.getUserIds().length == 0) {
            return;
        }
        if (examPaperUserService.getByExamPaperId(examPaper.getId()).size() > 0) {
            examPaperUserService.removeByExamPaperId(examPaper.getId());
        }
        List<ExamPaperUser> list = Arrays.asList(examPaperEditRequestVM.getUserIds()).stream().map(e -> {
            ExamPaperUser examPaperUser = new ExamPaperUser();
            examPaperUser.setUserId(e);
            examPaperUser.setExamPaperId(examPaper.getId());
            examPaperUser.setDeleted("0");
            return examPaperUser;
        }).collect(Collectors.toList());
        examPaperUserService.saves(list);
    }
    private void addExamPaperSubject(ExamPaperEditRequestVM examPaperEditRequestVM, ExamPaper examPaper) {
        if (examPaperSubjectService.getByExamPaperId(examPaper.getId()).size() > 0) {
            examPaperSubjectService.removeByExamPaperId(examPaper.getId());
        }
        List<ExamPaperSubject> subjectList = Arrays.asList(examPaperEditRequestVM.getSubjectId()).stream().map(e -> {
            ExamPaperSubject examPaperSubject = new ExamPaperSubject();
            examPaperSubject.setSubjectId(e);
            examPaperSubject.setExamPaperId(examPaper.getId());
@@ -235,4 +384,316 @@
        }).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 randomQuesrandomQuestiontion(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 = 100 * 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();
        }
    }
    /**
     * 随机试卷
     *
     * @param examPaperEditRequestVM 传参
     * @param frameTextContentList
     * @param titleItemsVM           title
     */
    private void randomQuestionType(ExamPaperEditRequestVM examPaperEditRequestVM, List<ExamPaperTitleItemObject> frameTextContentList, List<ExamPaperTitleItemVM> titleItemsVM) throws QuestionException {
        //单选
        Integer singleChoice = examPaperEditRequestVM.getQuestionTypeVMS().stream().mapToInt(QuestionTypeVM::getSingleChoice).sum();
        //多选
        Integer multipleChoice = examPaperEditRequestVM.getQuestionTypeVMS().stream().mapToInt(QuestionTypeVM::getMultipleChoice).sum();
        //判断
        Integer judgment = examPaperEditRequestVM.getQuestionTypeVMS().stream().mapToInt(QuestionTypeVM::getTrueFalse).sum();
        if ((singleChoice * 2 + multipleChoice * 2 + judgment * 2) != new Integer(100)) {
            throw new QuestionException();
        }
        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<>();
        List<QuestionTypeVM> questionTypeVMList = examPaperEditRequestVM.getQuestionTypeVMS();
        Integer order = 0;
        for (QuestionTypeVM questionTypeVM : questionTypeVMList) {
            List<Integer> questions = questionSubjectService.getSubjectBySubjectIds(examPaperEditRequestVM.getSubjectId())
                    .stream().map(QuestionSubject::getQuestionId).collect(Collectors.toList());
            List<Question> list = questionService.selectByIds(questions);
            // List<Question> list = questionService.getAll();
            Map<Integer, Integer> multiple = new HashMap<>();
            //多选
            Map<Integer, Integer> multipleMap = list.stream()
                    .filter(e -> Objects.equals(QuestionTypeEnum.MultipleChoice.getCode(), e.getQuestionType()))
                    .collect(Collectors.toMap(Question::getId, Question::getScore));
            Integer multipleSource = questionTypeVM.getMultipleChoice() * 2;
            selectRandomScores(multiple, multipleMap, questionTypeVM.getMultipleChoice(), multipleSource);
            //判断
            List<Question> collect1 = list.stream().filter(e -> Objects.equals(e.getQuestionType(), QuestionTypeEnum.TrueFalse.getCode())).collect(Collectors.toList());
            Map<Integer, Integer> judgmentMap = collect1.stream().collect(Collectors.toMap(Question::getId, Question::getScore));
            Integer trueFalse1 = questionTypeVM.getTrueFalse();
            Integer trueFalse = trueFalse1 * 2;
            selectRandomScores(multiple, judgmentMap, questionTypeVM.getTrueFalse(), trueFalse);
            //单选分数
            Integer radioSource = questionTypeVM.getSingleChoice() * 4;
            //单选
            Map<Integer, Integer> radioMap = list.stream()
                    .filter(e -> Objects.equals(e.getQuestionType(), QuestionTypeEnum.SingleChoice.getCode()))
                    .collect(Collectors.toMap(Question::getId, Question::getScore));
            selectRandomScores(multiple, radioMap, questionTypeVM.getSingleChoice(), 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);
        }
        frameTextContentList.add(examPaperTitleItemObject);
        titleItemsVM.add(examPaperTitleItemVM);
    }
    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;
    }
    /**
     * 两个数之前的随机数(不重复)
     *
     * @param a
     * @param b
     * @return
     */
    public static int generateRandomNumber(Integer a, Integer b, Set<Integer> generatedNumbers, Random random) {
        int randomNumber = random.nextInt(b - a) + a;
        while (generatedNumbers.contains(randomNumber)) {
            randomNumber = random.nextInt(b - a) + a;
        }
        generatedNumbers.add(randomNumber);
        return randomNumber;
    }
    @Override
    @Transactional
    public void missExam(ExamPaperEditRequestVM model) {
        // 修改原来的试卷时间
        if (ObjectUtils.isNotEmpty(model.getLimitDateTime())) {
            ExamPaper examPaper = new ExamPaper();
            examPaper.setId(model.getExamPaperId());
            examPaper.setLimitStartTime(DateTimeUtil.parse(model.getLimitDateTime().get(0), DateTimeUtil.STANDER_FORMAT));
            examPaper.setLimitEndTime(DateTimeUtil.parse(model.getLimitDateTime().get(1), DateTimeUtil.STANDER_FORMAT));
            examPaperMapper.updateByPrimaryKeySelective(examPaper);
        }
        // 根据考试id将选择的补考考生的考试成绩设置为无效
        examPaperAnswerMapper.setMissExam(model);
        // 补考时将没有选择的并且没有参加过考试的考生增加一条零分考试记录,否则没有参加过考试的即使不被选择也可以参加补考
        examPaperAnswerMapper.insertDefault(model);
    }
    @Override
    @Transactional
    public void missExamByTemplateId(ExamTemplatesVO model) {
        List<Integer> id = examPaperMapper.getExamPaperByTemplateId(model);
        model.setPaperIds(id);
        // 根据考试id将选择的补考考生的考试成绩设置为无效
        examPaperAnswerMapper.setMissExamByTemplate(model);
    }
    @Override
    public List<ExamPaper> list(List<Integer> deptIds) {
        List<ExamPaper> list = examPaperMapper.list(deptIds);
        List<ExamPaper> template = examPaperMapper.template(deptIds);
        list.addAll(template);
        return list.stream().sorted(Comparator.comparing(ExamPaper::getCreateTime).reversed()).collect(Collectors.toList());
    }
    @Override
    public PageInfo<UserVO> selectStudent(UserVO userVO, List<Integer> adminDeptIds) {
        userVO.setDeptIds(ObjectUtils.isNotEmpty(userVO.getDeptIds()) ? userVO.getDeptIds() : adminDeptIds);
        return PageHelper.startPage(userVO.getPageIndex(), userVO.getPageSize()).doSelectPageInfo(() ->
                examPaperMapper.selectStudent(userVO));
    }
    @Override
    public List<ExamPaper> queryCondition() {
        List<ExamPaper> examPaperList = examPaperMapper.getExamPaper();
        List<ExamPaper> templateList = examPaperMapper.getTemplate();
        examPaperList.addAll(templateList);
        return examPaperList.stream().sorted(Comparator.comparing(ExamPaper::getCreateTime).reversed()).collect(Collectors.toList());
    }
}