package com.xhkjedu.smarking.service.report.generate;

import com.alibaba.fastjson.JSON;
import com.xhkjedu.smarking.mapper.exam.MsClassStudentMapper;
import com.xhkjedu.smarking.mapper.exam.MsSubjectMapper;
import com.xhkjedu.smarking.mapper.paper.MsPaperMapper;
import com.xhkjedu.smarking.mapper.paper.MsPaperQtypeQuestionMapper;
import com.xhkjedu.smarking.mapper.report.reportclass.MsrClassQobjsubMapper;
import com.xhkjedu.smarking.mapper.report.reportclass.MsrClassQtypeMapper;
import com.xhkjedu.smarking.mapper.report.reportclass.MsrClassQuestionMapper;
import com.xhkjedu.smarking.mapper.report.reportclass.MsrClassQuestionObjMapper;
import com.xhkjedu.smarking.mapper.report.reportother.MsrAnalyzeMapper;
import com.xhkjedu.smarking.mapper.report.reportother.MsrReportparamMapper;
import com.xhkjedu.smarking.mapper.report.reportstu.MsrStudentMapper;
import com.xhkjedu.smarking.mapper.report.reportsubject.MsrSubjectPointMapper;
import com.xhkjedu.smarking.mapper.report.reportsubject.MsrSubjectQuestionRankgroupMapper;
import com.xhkjedu.smarking.mapper.report.reportsubject.MsrSubjectQuestionSectionMapper;
import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentQuestionMapper;
import com.xhkjedu.smarking.model.exam.MsClassStudent;
import com.xhkjedu.smarking.model.paper.MsPaper;
import com.xhkjedu.smarking.model.paper.MsPaperQtypeQuestion;
import com.xhkjedu.smarking.model.report.reportclass.MsrClassQobjsub;
import com.xhkjedu.smarking.model.report.reportclass.MsrClassQtype;
import com.xhkjedu.smarking.model.report.reportclass.MsrClassQuestion;
import com.xhkjedu.smarking.model.report.reportclass.MsrClassQuestionObj;
import com.xhkjedu.smarking.model.report.reportother.MsrAnalyze;
import com.xhkjedu.smarking.model.report.reportother.MsrReportparam;
import com.xhkjedu.smarking.model.report.reportstu.MsrStudent;
import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectQuestionRankgroup;
import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectQuestionSection;
import com.xhkjedu.smarking.model.stupaper.MsPaperStudentQuestion;
import com.xhkjedu.smarking.service.paper.MsPaperAnalyzeService;
import com.xhkjedu.smarking.utils.MarkingUtil;
import com.xhkjedu.smarking.vo.report.reportother.RankGroupVo;
import com.xhkjedu.smarking.vo.report.reportother.ReportParams;
import com.xhkjedu.smarking.vo.report.reportother.SzJsonVo;
import com.xhkjedu.smarking.vo.report.reportsubject.SectionScoreVo;
import com.xhkjedu.utils.N_Utils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description：试题对应报告内容
 * @Author: WN
 * @Date: 2024/12/10 10:18:26
 **/
@Service
public class ReportGenerateQuestionService {
    @Resource
    private MsPaperStudentQuestionMapper msPaperStudentQuestionMapper;
    @Resource
    private MsClassStudentMapper msClassStudentMapper;
    @Resource
    private MsSubjectMapper msSubjectMapper;
    @Resource
    private MsPaperQtypeQuestionMapper msPaperQtypeQuestionMapper;
    @Resource
    private MsrReportparamMapper msrReportparamMapper;
    @Resource
    private MsrStudentMapper msrStudentMapper;
    @Resource
    private MsrClassQuestionMapper msrClassQuestionMapper;
    @Resource
    private MsrClassQuestionObjMapper msrClassQuestionObjMapper;
    @Resource
    private MsrClassQobjsubMapper msrClassQobjsubMapper;
    @Resource
    private MsrClassQtypeMapper msrClassQtypeMapper;
    @Resource
    private MsrSubjectQuestionRankgroupMapper msrSubjectQuestionRankgroupMapper;
    @Resource
    private MsrSubjectQuestionSectionMapper msrSubjectQuestionSectionMapper;
    @Resource
    private ReportGeneratePointService reportGeneratePointService;
    @Resource
    private MsPaperAnalyzeService msPaperAnalyzeService;
    @Resource
    private MsPaperMapper msPaperMapper;
    @Resource
    private MsrSubjectPointMapper msrSubjectPointMapper;
    @Resource
    private MsrAnalyzeMapper msrAnalyzeMapper;

    @Transactional(rollbackFor = Exception.class)
    public void generateQuestion(Integer examid, Integer raid,List<MsPaper> subjects,List<MsClassStudent> classStudents) {
        // 获取考试参数
        List<MsrReportparam> params = msrReportparamMapper.listReportparamByRpbelong(examid, "quesummary", null);

        // 根据科目进行区分
        for (MsPaper subject : subjects) {
            String subjectid = subject.getSubjectid();

            // 获取科目下所有学生试题
            List<MsPaperStudentQuestion> subjectStuQuestions = msPaperStudentQuestionMapper.listAllStuQuesByExamid(examid,subjectid);

            // 科目下所有班级学生
            List<MsClassStudent> subjectClassStudents = classStudents.stream().filter(classStudent -> classStudent.getSubjectid().equals(subjectid)).collect(Collectors.toList());
            // 获取试卷中所有小题基础信息包含大题信息
            List<MsPaperQtypeQuestion> questions = msPaperQtypeQuestionMapper.listQuestionsForReport(subject.getMpid());
            // 获取科目参数
            List<MsrReportparam> subjectParams = params.stream().filter(p -> p.getSubjectid().equals(subjectid)).collect(Collectors.toList());
            // 获取学生科目得分及排名
            List<MsrStudent> subjectStuPapers = msrStudentMapper.listStuScoreAndRankByExamid(examid,subjectid);

            // 处理学生客观题、主观题得分
            handleStudentObjSub(subjectStuQuestions, subjectStuPapers, questions);
            // 处理小题
            handleQuestion(subjectStuQuestions, subjectClassStudents, questions, subjectParams, subjectStuPapers, examid, subjectid,subject.getPscore(),raid);
            //处理题型
            handleQtype(subjectStuQuestions, subjectClassStudents, questions, subjectParams, examid, subjectid,raid);
            //客观题、主观题
            handleObjSub(subjectStuQuestions, subjectClassStudents, questions, subjectStuPapers, examid, subjectid,subject.getPscore(),raid);
            //知识点相关分析
            reportGeneratePointService.generatePoint(subjectStuQuestions,questions,subjectClassStudents,subjectStuPapers,examid,subjectid,subject.getMpid(),subject.getPscore(),raid);
        }
    }

    //学生客观题、主观题得分
    private void handleStudentObjSub(List<MsPaperStudentQuestion> subjectStuQuestions, List<MsrStudent> stus, List<MsPaperQtypeQuestion> questions){
        //获取试卷中所有主观题、客观题
        List<Integer> objMptqids = questions.stream().filter(q -> q.getQtype()==1).map(MsPaperQtypeQuestion::getMptqid).distinct().collect(Collectors.toList());
        List<Integer> subMptqids = questions.stream().filter(q -> q.getQtype()==2).map(MsPaperQtypeQuestion::getMptqid).distinct().collect(Collectors.toList());
        //学生试题按学生分组
        Map<Integer,List<MsPaperStudentQuestion>> stuQuestionMap = subjectStuQuestions.stream().collect(Collectors.groupingBy(MsPaperStudentQuestion::getStudentid));

        for(MsrStudent stu:stus){
            Integer studentid = stu.getStudentid();
            if(stuQuestionMap.containsKey(studentid)){
                List<MsPaperStudentQuestion> stuQuestions = stuQuestionMap.get(studentid);
                List<MsPaperStudentQuestion> objStuQues = stuQuestions.stream().filter(q -> objMptqids.contains(q.getMptqid())).collect(Collectors.toList());
                List<MsPaperStudentQuestion> subStuQues = stuQuestions.stream().filter(q -> subMptqids.contains(q.getMptqid())).collect(Collectors.toList());
                //学生客观题得分
                double objScore = objStuQues.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
                //学生主观题得分
                double subScore = subStuQues.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
                stu.setObjscore(N_Utils.formatDouble(objScore,1));
                stu.setSubscore(N_Utils.formatDouble(subScore,1));
            }else{
                stu.setObjscore(0.0);
                stu.setSubscore(0.0);
            }
        }
        msrStudentMapper.updateBatchObjSubScore(stus);
    }

    // 单个试题分析
    private void handleQuestion(List<MsPaperStudentQuestion> subjectStuQuestions, List<MsClassStudent> subjectClassStudents, List<MsPaperQtypeQuestion> questions,
                                List<MsrReportparam> params, List<MsrStudent> subjectStuPapers, Integer examid, String subjectid,Double pscore,Integer raid) {

        List<MsrClassQuestion> saveQuestions = new ArrayList<>();// 小题分析
        List<MsrClassQuestionObj> saveQuestionObjs = new ArrayList<>();// 小题-客观题选项分析
        List<MsrSubjectQuestionSection> saveSectionQuestions = new ArrayList<>();// 学科分段之间学生在该题的整体得分率
        List<MsrSubjectQuestionRankgroup> saveRankGroupQuestions = new ArrayList<>();//分组分数分布

        // 获取学生科目得分-科目默认分段学生
        List<MsrSubjectQuestionSection> subjectSectionQuestions = subjectSectionForQuestion(subjectStuPapers, pscore);

        // 处理小题信息
        for (MsPaperQtypeQuestion question : questions) {
            // 获取第一小题所有作答情况，全校作答情况
            List<MsPaperStudentQuestion> stuQuestions = subjectStuQuestions.stream().filter(q -> q.getMptqid().equals(question.getMptqid())).collect(Collectors.toList());
            int stunum = stuQuestions.size();// 学生数量
            Double sumQScore = question.getQscore() * stunum;// 小题得分
            List<Double> stuScores = stuQuestions.stream().map(MsPaperStudentQuestion::getStuscore).collect(Collectors.toList());// 所有学生得分

            Double maxScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).max().orElse(0.0);// 最高分
            Double minScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).min().orElse(0.0);// 最低分
            Double avgScore = MarkingUtil.calculateAverage(stuScores);// 平均分
            Double avgScoreRate = MarkingUtil.div(avgScore, sumQScore);// 平均得分率

            MsrClassQuestion schoolQ = new MsrClassQuestion();
            schoolQ.setClassid(0);// 全体班级
            schoolQ.setExamid(examid);
            schoolQ.setSubjectid(subjectid);
            schoolQ.setSchoolmaxscore(maxScore);
            schoolQ.setSchoolminscore(minScore);
            schoolQ.setSchoolavgscore(avgScore);
            schoolQ.setSchoolavgrate(avgScoreRate);
            schoolQ.setMptqid(question.getMptqid());
            schoolQ.setQorder(question.getQorder());
            schoolQ.setZqda(question.getQanswer());
            schoolQ.setQn(question.getQnstr());
            schoolQ.setRaid(raid);
            // 全校班级试题情况
            MsrClassQuestion schoolQue = questionClass(stuQuestions, question, params, schoolQ);
            saveQuestions.add(schoolQue);

            // 班级试题--客观题选项情况
            MsrClassQuestionObj qobj = new MsrClassQuestionObj();
            if (question.getQtype() == 1) {
                qobj.setRaid(raid);
                qobj.setExamid(examid);
                qobj.setSubjectid(subjectid);
                qobj.setClassid(0);
                qobj.setMptqid(question.getMptqid());
                List<MsrClassQuestionObj> qobjList = questionXuanxiang(stuQuestions, qobj);
                saveQuestionObjs.addAll(qobjList);
            }

            // 学科分段之间学生在该题的整体得分率
            List<MsrSubjectQuestionSection> sectionQuestions = subjectSectionQuestion(stuQuestions, subjectSectionQuestions, 1,question.getQscore(),question.getMptqid(),raid);
            saveSectionQuestions.addAll(sectionQuestions);
            //试题分组分数分布、客观题选项分组
            List<MsrSubjectQuestionRankgroup> rankGroupQuestions = questionScoreRankGroup(stuQuestions, subjectStuPapers,examid,subjectid,question.getQtype(),question.getQscore(),question.getMptqid(),raid);
            saveRankGroupQuestions.addAll(rankGroupQuestions);

            // 班级试题分析
            // 获取所有班级
            List<Integer> classIds = subjectClassStudents.stream().map(MsClassStudent::getClassid).distinct().collect(Collectors.toList());
            for (Integer classid : classIds) {
                // 获取班级下学生id
                List<Integer> classStuIds =
                        subjectClassStudents.stream().filter(c -> c.getClassid().equals(classid)).map(MsClassStudent::getStudentid).collect(Collectors.toList());
                // 获取班级下学生试题
                List<MsPaperStudentQuestion> classStuQuestions = stuQuestions.stream().filter(q -> classStuIds.contains(q.getStudentid())).collect(Collectors.toList());
                schoolQ.setClassid(classid);
                MsrClassQuestion classQue = questionClass(classStuQuestions, question, params, schoolQ);
                saveQuestions.add(classQue);

                // 班级试题--客观题选项情况
                if (question.getQtype() == 1) {
                    qobj.setClassid(classid);
                    List<MsrClassQuestionObj> qobjList = questionXuanxiang(classStuQuestions, qobj);
                    saveQuestionObjs.addAll(qobjList);
                }
            }
        }

        if(!saveQuestions.isEmpty()) msrClassQuestionMapper.insertList(saveQuestions);
        if(!saveQuestionObjs.isEmpty()) msrClassQuestionObjMapper.insertList(saveQuestionObjs);
        if(!saveSectionQuestions.isEmpty()) msrSubjectQuestionSectionMapper.insertList(saveSectionQuestions);
        if(!saveRankGroupQuestions.isEmpty()) msrSubjectQuestionRankgroupMapper.insertList(saveRankGroupQuestions);

    }

    // 单个试题分析-学校、班级分析
    private MsrClassQuestion questionClass(List<MsPaperStudentQuestion> stuQuestions, MsPaperQtypeQuestion question, List<MsrReportparam> params, MsrClassQuestion schoolQ) {
        int stunum = stuQuestions.size();// 学生数量
        Double qScore = question.getQscore();// 试题分值
        Double sumQScore = question.getQscore() * stunum;// 小题得分
        List<Double> stuScores = stuQuestions.stream().map(MsPaperStudentQuestion::getStuscore).collect(Collectors.toList());// 所有学生得分
        Double sumStuScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();// 综合

        Double maxScore;// 最高分
        Double minScore;// 最低分
        Double avgScore;// 平均分
        Double avgScoreRate;// 平均得分率
        if (schoolQ.getClassid() == 0) {
            // 代表是校级
            maxScore = schoolQ.getSchoolmaxscore();
            minScore = schoolQ.getSchoolminscore();
            avgScore = schoolQ.getSchoolavgscore();
            avgScoreRate = schoolQ.getSchoolavgrate();
        } else {
            // 指定班级
            maxScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).max().orElse(0.0);// 最高分
            minScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).min().orElse(0.0);// 最低分
            avgScore = MarkingUtil.calculateAverage(stuScores);// 平均分
            avgScoreRate = MarkingUtil.div(avgScore, sumQScore);// 平均得分率
        }
        Double stuScoreRate = MarkingUtil.div(sumStuScore, sumQScore);// 学生得分率
        MsrClassQuestion classQ = new MsrClassQuestion();
        classQ.setRaid(schoolQ.getRaid());
        classQ.setExamid(schoolQ.getExamid());
        classQ.setSubjectid(schoolQ.getSubjectid());
        classQ.setClassid(schoolQ.getClassid());// 班级id
        classQ.setMptqid(question.getMptqid());
        classQ.setQtype(question.getQtype());
        classQ.setQn(question.getQnstr());
        classQ.setQorder(question.getQorder());
        classQ.setFullscore(question.getQscore());
        classQ.setStunum(stunum);
        classQ.setClassmaxscore(maxScore);
        classQ.setClassminscore(minScore);
        classQ.setClassavgscore(avgScore);
        classQ.setClassavgrate(avgScoreRate);

        classQ.setSchoolmaxscore(schoolQ.getSchoolmaxscore());
        classQ.setSchoolminscore(schoolQ.getSchoolminscore());
        classQ.setSchoolavgscore(schoolQ.getSchoolavgscore());
        classQ.setSchoolavgrate(schoolQ.getSchoolavgrate());

        classQ.setScorerate(stuScoreRate);
        classQ.setScoreratec(MarkingUtil.sub(MarkingUtil.div(maxScore, qScore), MarkingUtil.div(minScore, qScore)));// 得分率差=最高得分率-最低得分率
        classQ.setNd(MarkingUtil.div(avgScore, qScore));// 难度
        String[] ndStr = questionNdAndQfd(params, 1, classQ.getNd());
        classQ.setNdms(ndStr[0]);// 难度描述
        classQ.setNdfw(ndStr[1]);// 难度范围
        classQ.setQfd(MarkingUtil.qfd(stuScores));// 区分度
        String[] qfdStr = questionNdAndQfd(params, 2, classQ.getQfd());
        classQ.setQfdms(qfdStr[0]);// 区分度描述
        classQ.setQfdfw(qfdStr[1]);// 区分度范围
        classQ.setBzc(MarkingUtil.bzc(stuScores));// 标准差
        classQ.setCyxs(MarkingUtil.div(classQ.getBzc(), avgScore));// 差异系数
        classQ.setJbzs(MarkingUtil.jbzs(stuScores, question.getQscore()));// 鉴别指数
        classQ.setZqda(schoolQ.getZqda());
        // 获取所有满分学生
        List<MsPaperStudentQuestion> fullStuQuestions = stuQuestions.stream().filter(q -> q.getStuscore().equals(q.getQscore())).collect(Collectors.toList());
        if(!fullStuQuestions.isEmpty()){
            String mfids = fullStuQuestions.stream().map(p -> p.getStudentid().toString()).collect(Collectors.joining(","));// 满分学生id
            classQ.setMfnum(fullStuQuestions.size());
            classQ.setMfrate(MarkingUtil.calculateRate(classQ.getMfnum(), stunum));////正确率、满分人数占比
            classQ.setMfids(mfids);
        }else{
            classQ.setMfnum(0);
            classQ.setMfrate(0.0);////正确率、满分人数占比
        }
        classQ.setZqrate(classQ.getMfrate());

        // 获取零分学生
        List<MsPaperStudentQuestion> lfStuQuestions = stuQuestions.stream().filter(q -> q.getStuscore() == 0).collect(Collectors.toList());
        if (!lfStuQuestions.isEmpty()) {
            String lfids = lfStuQuestions.stream().map(p -> p.getStudentid().toString()).collect(Collectors.joining(","));// 零分学生id
            classQ.setLfnum(lfStuQuestions.size());
            classQ.setLfrate(MarkingUtil.calculateRate(lfStuQuestions.size(), stunum));////零分人数占比
            classQ.setLfids(lfids);
        } else {
            classQ.setLfnum(0);
            classQ.setLfrate(0.0);////零分人数占比
        }
        return classQ;
    }

    // 单个试题分析-试题难度、区分度
    private String[] questionNdAndQfd(List<MsrReportparam> params, Integer rptype, Double nd) {
        // 获取难度或者区分度
        MsrReportparam ndParam = params.stream().filter(p -> p.getRptype().equals(rptype)).findFirst().orElse(null);// 难度
        if (ndParam != null) {
            return questionNdAndQfdComm(ndParam.getSzjson(),nd);
        }
        return new String[]{null, null};
    }
    // 单个试题分析-试题难度、区分度判断值-通用
    private String[] questionNdAndQfdComm(String szjson,Double nd){
        List<SzJsonVo> szList = JSON.parseArray(szjson, SzJsonVo.class);
        String ndms = "";
        String ndfw = "";
        if(szList.isEmpty()){
            return new String[]{null, null};
        }else{
            for (SzJsonVo sz : szList) {
                if (nd == 1 && sz.getMaxvalue() == 1) {
                    ndms = sz.getDjkey();
                    ndfw = "[" + sz.getMinvalue() + "~" + "1]";
                    break;
                } else if (nd == 0 && sz.getMinvalue() == 0) {
                    ndms = sz.getDjkey();
                    ndfw = "[0" + "~" + sz.getMaxvalue() + ")";
                    break;
                } else if (nd >= sz.getMinvalue() && nd < sz.getMaxvalue()) {
                    ndms = sz.getDjkey();
                    ndfw = "[" + sz.getMinvalue() + "~" + sz.getMaxvalue() + ")";
                    break;
                }
            }
            return new String[]{ndms, ndfw};
        }
    }

    // 单个试题分析-客观题选项情况
    private List<MsrClassQuestionObj> questionXuanxiang(List<MsPaperStudentQuestion> stuQuestions, MsrClassQuestionObj questionObj) {
        Map<String, List<MsPaperStudentQuestion>> optionMap = stuQuestions.stream().collect(Collectors.groupingBy(MsPaperStudentQuestion::getStuanswer));
        int totalNum = stuQuestions.size();
        List<MsrClassQuestionObj> qobjList = new ArrayList<>();
        for (Map.Entry<String, List<MsPaperStudentQuestion>> entry : optionMap.entrySet()) {
            String option = entry.getKey();
            List<MsPaperStudentQuestion> optionStuQuestions = entry.getValue();

            MsrClassQuestionObj qobj = new MsrClassQuestionObj();
            qobj.setRaid(questionObj.getRaid());
            qobj.setExamid(questionObj.getExamid());
            qobj.setSubjectid(questionObj.getSubjectid());
            qobj.setClassid(questionObj.getClassid());
            qobj.setMptqid(questionObj.getMptqid());
            if (N_Utils.isNotEmpty(option)) {
                qobj.setXxda(option);
            } else {
                qobj.setXxda("未选");
            }
            qobj.setXxnum(optionStuQuestions.size());
            qobj.setXxrate(MarkingUtil.calculateRate(optionStuQuestions.size(), totalNum));
            String stuids = optionStuQuestions.stream().map(q -> q.getStudentid().toString()).collect(Collectors.joining(","));
            qobj.setStuids(stuids);
            qobjList.add(qobj);
        }
        return qobjList;
    }
    // 单个试题分析-小题分组分布、客观题选项分组分布
    private List<MsrSubjectQuestionRankgroup> questionScoreRankGroup(List<MsPaperStudentQuestion> stuQuestions,List<MsrStudent> stuPapers,Integer examid,String subjectid,Integer qtype,Double fullScore,Integer mptqid,Integer raid){
        //获取学生排名最大名次的树
        Integer totalRank = stuPapers.stream().mapToInt(MsrStudent::getSchoolrank).max().orElse(0);
        //获取排名分组,默认分为7组
        List<RankGroupVo> rankGroups = MarkingUtil.rankGroup(totalRank,7);
        //获取试题分段,1分1段
        List<SectionScoreVo> sectionScores = MarkingUtil.fdScoreForOne(fullScore);

        //获取所有客观题选项内容
        List<String> options = new ArrayList<>();
        if(qtype == 1){
            options = stuQuestions.stream().map(MsPaperStudentQuestion::getStuanswer).distinct().collect(Collectors.toList());
        }

        List<MsrSubjectQuestionRankgroup> rtnList = new ArrayList<>();
        for (RankGroupVo rankGroup : rankGroups) {
            //名次下学生信息
            List<MsrStudent> groupStus = stuPapers.stream().filter(s -> s.getSchoolrank() >= rankGroup.getMinvalue() && s.getSchoolrank() <= rankGroup.getMaxvalue()).collect(Collectors.toList());
            MsrSubjectQuestionRankgroup sqr = new MsrSubjectQuestionRankgroup();
            sqr.setRaid(raid);
            sqr.setExamid(examid);
            sqr.setSubjectid(subjectid);
            if(qtype == 1){
                sqr.setQntype(1);//类型1小题2客观题3主观题
            }else{
                //类型1小题2客观题3主观题
                if(qtype == 2){
                    sqr.setQntype(1);
                }else if(qtype == 11){
                    sqr.setQntype(2);
                }else{
                    sqr.setQntype(3);
                }
            }
            sqr.setRgtype(2);//类型1客观题选项 2客/主分值 (代表所有分值，分值不进行分段)
            sqr.setMptqid(mptqid);
            sqr.setRgroup(rankGroup.getGroupname());
            sqr.setRgroupname(rankGroup.getGroupv());

            List<Integer> groupStuids;
            List<MsPaperStudentQuestion> groupStuQuestions = null;
            if(!groupStus.isEmpty()){
                groupStuids = groupStus.stream().map(MsrStudent::getStudentid).collect(Collectors.toList());
                //名次下学生试题作答情况
                groupStuQuestions = stuQuestions.stream().filter(q -> groupStuids.contains(q.getStudentid())).collect(Collectors.toList());
                double sumScore = groupStuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
                double avgScore = MarkingUtil.div(sumScore, groupStuQuestions.size());
                sqr.setStunum(groupStuQuestions.size());
                sqr.setStuids(groupStuQuestions.stream().map(q -> q.getStudentid().toString()).collect(Collectors.joining(",")));
                sqr.setScorerate(MarkingUtil.div(sumScore, groupStuQuestions.size() * fullScore));
                sqr.setAvgrate(MarkingUtil.div(avgScore, fullScore));
            } else {
                groupStuids = null;
                sqr.setStunum(0);
                sqr.setScorerate(0.0);
                sqr.setAvgrate(0.0);
            }

            //试题分段区间
            for(SectionScoreVo sectionScore : sectionScores){
                MsrSubjectQuestionRankgroup sqrg = new MsrSubjectQuestionRankgroup();
                sqrg.setRaid(raid);
                sqrg.setExamid(examid);
                sqrg.setSubjectid(subjectid);
                sqrg.setQntype(1);
                sqrg.setMptqid(mptqid);
                sqrg.setRgroup(rankGroup.getGroupname());
                sqrg.setRgroupname(rankGroup.getGroupv());
                sqrg.setRgtype(2);
                sqrg.setRsection(sectionScore.getSectionname());

                if(groupStuids != null && !groupStuids.isEmpty()){
                    //名次分组下有学生，进行学生分数段计算
                    List<MsPaperStudentQuestion> sectionStuQuestions;
                    if(sectionScore.getMinvalue() == fullScore){
                        //最小值为满分时分段形式为[qscore,qscore)
                        sectionStuQuestions = groupStuQuestions.stream().filter(q -> q.getStuscore() >= sectionScore.getMinvalue()).collect(Collectors.toList());
                    }else{
                        sectionStuQuestions = groupStuQuestions.stream().filter(q -> q.getStuscore() >= sectionScore.getMinvalue() && q.getStuscore() < sectionScore.getMaxvalue()).collect(Collectors.toList());
                    }
                    if(!sectionStuQuestions.isEmpty()){
                        double sectionStuSumScore = sectionStuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
                        double sectionStuAvgScore = MarkingUtil.div(sectionStuSumScore, sectionStuQuestions.size());
                        sqrg.setStunum(sectionStuQuestions.size());
                        sqrg.setStuids(sectionStuQuestions.stream().map(q -> q.getStudentid().toString()).collect(Collectors.joining(",")));
                        sqrg.setScorerate(MarkingUtil.div(sectionStuSumScore, sectionStuQuestions.size() * fullScore));
                        sqrg.setAvgrate(MarkingUtil.div(sectionStuAvgScore, fullScore));
                    }else{
                        sqrg.setStunum(0);
                        sqrg.setScorerate(0.0);
                        sqrg.setAvgrate(0.0);
                    }
                }else{
                    sqrg.setStunum(0);
                    sqrg.setScorerate(0.0);
                    sqrg.setAvgrate(0.0);
                }
                rtnList.add(sqrg);
            }
            rtnList.add(sqr);

            //客观题选项
            if(qtype == 1){
                if(options.isEmpty()){
                    options = new ArrayList<>();
                    options.add("");
                }
                List<String> newOptions = options.stream().map(s -> s != null && !s.isEmpty() ? s : "未作答").sorted().collect(Collectors.toList());
                for(String optionStr : newOptions){
                    MsrSubjectQuestionRankgroup optionObj = new MsrSubjectQuestionRankgroup();
                    optionObj.setRaid(raid);
                    optionObj.setExamid(examid);
                    optionObj.setSubjectid(subjectid);
                    optionObj.setMptqid(mptqid);
                    optionObj.setQntype(1);
                    optionObj.setRgroup(rankGroup.getGroupname());
                    optionObj.setRgroupname(rankGroup.getGroupv());
                    optionObj.setRgtype(1);
                    optionObj.setRsection(optionStr);

                    List<MsPaperStudentQuestion> optionStuQuestions;
                    if(groupStuQuestions != null && !groupStuQuestions.isEmpty()){
                        if("未作答".equals(optionStr)){
                            optionStuQuestions = groupStuQuestions.stream().filter(q -> q.getStuanswer() == null || q.getStuanswer().isEmpty()).collect(Collectors.toList());
                        }else{
                            optionStuQuestions = groupStuQuestions.stream().filter(q -> optionStr.equals(q.getStuanswer())).collect(Collectors.toList());
                        }

                        if(!optionStuQuestions.isEmpty()){
                            double optionStuSumScore = optionStuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
                            double optionStuAvgScore = MarkingUtil.div(optionStuSumScore, optionStuQuestions.size());

                            optionObj.setStunum(optionStuQuestions.size());
                            optionObj.setStuids(optionStuQuestions.stream().map(q -> q.getStudentid().toString()).collect(Collectors.joining(",")));
                            optionObj.setScorerate(MarkingUtil.calculateRate(optionStuSumScore, optionStuQuestions.size() * fullScore));
                            optionObj.setAvgrate(MarkingUtil.calculateRate(optionStuAvgScore, fullScore));
                        }else{
                            optionObj.setStunum(0);
                            optionObj.setScorerate(0.0);
                            optionObj.setAvgrate(0.0);
                        }

                    }else{
                        optionObj.setStunum(0);
                        optionObj.setScorerate(0.0);
                        optionObj.setAvgrate(0.0);
                    }
                    rtnList.add(optionObj);
                }
            }
        }
        return rtnList;
    }

    // 单个试题-科目分段-默认5分一段为后续试题在段上学生得分率做准备
    private List<MsrSubjectQuestionSection> subjectSectionForQuestion(List<MsrStudent> StuPapers, Double pscore) {
        // 把科目总分分段，默认5分一段
        List<RankGroupVo> fdList = MarkingUtil.fdScore(pscore, 5);
        List<MsrSubjectQuestionSection> sections = new ArrayList<>();
        MsrStudent fdStuPaper = StuPapers.get(0);
        for (RankGroupVo fd : fdList) {
            // 获取学生得分在指定区间的学生
            List<MsrStudent> fdStuPapers;
            if (fd.getMaxvalue() == pscore) {
                fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd.getMinvalue()).collect(Collectors.toList());
            } else {
                fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd.getMinvalue() && s.getStuscore() < fd.getMaxvalue()).collect(Collectors.toList());
            }

            MsrSubjectQuestionSection question = new MsrSubjectQuestionSection();
            question.setExamid(fdStuPaper.getExamid());
            question.setSubjectid(fdStuPaper.getSubjectid());
            question.setFdfw(fd.getGroupname());
            question.setFdnum(fdStuPapers.size());
            question.setFdids(fdStuPapers.stream().map(s -> s.getStudentid().toString()).collect(Collectors.joining(",")));
            sections.add(question);
        }
        return sections;
    }

    // 单个试题分析-科目分段区间平均得分率
    private List<MsrSubjectQuestionSection> subjectSectionQuestion(List<MsPaperStudentQuestion> stuQuestions, List<MsrSubjectQuestionSection> sections,
                            Integer qtype,Double fullScore,Integer mptqid,Integer raid) {
        List<MsrSubjectQuestionSection> rtnList = new ArrayList<>();
        for (MsrSubjectQuestionSection section : sections) {
            String[] userids = section.getFdids().split(",");
            List<String> useridList = Arrays.asList(userids);
            List<MsPaperStudentQuestion> sectionStuQuestions = stuQuestions.stream().filter(q -> useridList.contains(q.getStudentid().toString())).collect(Collectors.toList());

            MsrSubjectQuestionSection sqs = new MsrSubjectQuestionSection();
            sqs.setRaid(raid);
            sqs.setExamid(section.getExamid());
            sqs.setSubjectid(section.getSubjectid());
            sqs.setMptqid(mptqid);
            sqs.setFdfw(section.getFdfw());
            sqs.setFdnum(section.getFdnum());
            sqs.setFdids(section.getFdids());
            // 获取总分
            if(!sectionStuQuestions.isEmpty()){
                int stuNum = sectionStuQuestions.size();
                // 获取总分
                double sumScore = sectionStuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
                // 获取平均分
                double avgScore = MarkingUtil.div(sumScore, stuNum);
                // 获取平均得分率
                double avgScoreRate = MarkingUtil.div(avgScore, fullScore);
                sqs.setAvgscore(avgScore);
                sqs.setAvgrate(avgScoreRate);
            }else{
                sqs.setAvgscore(0.0);
                sqs.setAvgrate(0.0);
            }

            if(qtype == 1){
                sqs.setQntype(qtype);//类型1小题2客观题3主观题
            }else{
                sqs.setQntype(qtype+1);
            }
            rtnList.add(sqs);
        }
        return rtnList;
    }

    // 题型分析
    private void handleQtype(List<MsPaperStudentQuestion> subjectStuQuestions,List<MsClassStudent> subjectClassStudents, List<MsPaperQtypeQuestion> questions,
                            List<MsrReportparam> params,Integer examid, String subjectid,Integer raid) {
        List<MsrClassQtype> saveQtypes = new ArrayList<>();//班级题型分析
        // 处理大题
        Map<Integer, List<MsPaperQtypeQuestion>> qtypeMap = questions.stream().collect(Collectors.groupingBy(MsPaperQtypeQuestion::getMptid));
        for (Map.Entry<Integer, List<MsPaperQtypeQuestion>> entry : qtypeMap.entrySet()) {
            List<MsPaperQtypeQuestion> qtypeQuestions = entry.getValue();
            Double fullScore = qtypeQuestions.stream().mapToDouble(MsPaperQtypeQuestion::getQscore).sum();// 题型满分

            // 获取所有题型下试题id集合
            List<Integer> mptqids = qtypeQuestions.stream().map(MsPaperQtypeQuestion::getMptqid).distinct().collect(Collectors.toList());
            // 获取题型下所有学生试题情况
            List<MsPaperStudentQuestion> stuQuestions = subjectStuQuestions.stream().filter(q -> mptqids.contains(q.getMptqid())).collect(Collectors.toList());
            //初始化信息
            MsrClassQtype schoolQtype = new MsrClassQtype();
            schoolQtype.setRaid(raid);
            schoolQtype.setExamid(examid);
            schoolQtype.setSubjectid(subjectid);
            schoolQtype.setClassid(0);
            schoolQtype.setMptid(entry.getKey());
            schoolQtype.setMptqn(qtypeQuestions.get(0).getMptqn());
            schoolQtype.setFullscore(fullScore);

            //全校班级题型情况
            MsrClassQtype qtypeSchool = qtypeClass(stuQuestions, params, schoolQtype);
            saveQtypes.add(qtypeSchool);

            // 班级题型分析
            // 获取所有班级
            List<Integer> classIds = subjectClassStudents.stream().map(MsClassStudent::getClassid).distinct().collect(Collectors.toList());
            for (Integer classid : classIds) {
                schoolQtype.setClassid(classid);
                // 获取班级下学生id
                List<Integer> classStuIds =
                        subjectClassStudents.stream().filter(c -> c.getClassid().equals(classid)).map(MsClassStudent::getStudentid).collect(Collectors.toList());
                // 获取班级下学生试题
                List<MsPaperStudentQuestion> classStuQuestions = stuQuestions.stream().filter(q -> classStuIds.contains(q.getStudentid())).collect(Collectors.toList());
                 // 班级题型分析
                MsrClassQtype qtypeClass = qtypeClass(classStuQuestions, params, schoolQtype);
                saveQtypes.add(qtypeClass);
            }
        }
        if(!saveQtypes.isEmpty()) msrClassQtypeMapper.insertList(saveQtypes);
    }
    // 题型分析-学校、班级分析
    private MsrClassQtype qtypeClass(List<MsPaperStudentQuestion> stuQuestions, List<MsrReportparam> params,MsrClassQtype schoolQtype){
        // 获取所有学生id
        List<Integer> studentIds = stuQuestions.stream().map(MsPaperStudentQuestion::getStudentid).distinct().collect(Collectors.toList());
        int stuNum = stuQuestions.size();
        List<Double> stuScores = new ArrayList<>();
        int mfnum = 0;
        StringBuilder mfids = new StringBuilder();
        int lfnum = 0;
        StringBuilder lfids = new StringBuilder();
        for (Integer studentId : studentIds) {
            List<MsPaperStudentQuestion> stuQtype = stuQuestions.stream().filter(q -> studentId.equals(q.getStudentid())).collect(Collectors.toList());
            Double stuQtypeScore = stuQtype.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
            stuScores.add(stuQtypeScore);
            if(Objects.equals(schoolQtype.getFullscore(), stuQtypeScore)){
                mfnum++;
                mfids.append(studentId).append(",");
            }
            if(stuQtypeScore == 0){
                lfnum++;
                lfids.append(studentId).append(",");
            }
        }

        Double stuSumScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();// 学生总分
        Double avgScore = MarkingUtil.div(stuSumScore, stuNum);// 平均分

        MsrClassQtype classQtype = new MsrClassQtype();
        classQtype.setRaid(schoolQtype.getRaid());
        classQtype.setExamid(schoolQtype.getExamid());
        classQtype.setSubjectid(schoolQtype.getSubjectid());
        classQtype.setClassid(schoolQtype.getClassid());
        classQtype.setMptid(schoolQtype.getMptid());
        classQtype.setMptqn(schoolQtype.getMptqn());
        classQtype.setFullscore(schoolQtype.getFullscore());
        classQtype.setAvgscore(avgScore);
        classQtype.setBzc(MarkingUtil.bzc(stuScores));
        classQtype.setNd(MarkingUtil.div(avgScore, schoolQtype.getFullscore()));
        classQtype.setNdms(questionNdAndQfd(params, 1, classQtype.getNd())[0]);
        classQtype.setQfd(MarkingUtil.qfd(stuScores));
        classQtype.setQfdms(questionNdAndQfd(params, 2, classQtype.getQfd())[0]);
        classQtype.setMfnum(mfnum);
        classQtype.setMfrate(MarkingUtil.calculateRate(mfnum, stuNum));
        if(mfnum > 0){
            schoolQtype.setMfids(mfids.substring(0,mfids.length()-1));
        }
        classQtype.setMfids(mfids.toString());
        classQtype.setLfnum(lfnum);
        classQtype.setLfrate(MarkingUtil.calculateRate(lfnum, stuNum));
        if(lfnum > 0){
            classQtype.setMfids(lfids.substring(0,lfids.length()-1));
        }

        return classQtype;
    }

    //客观题/主观题分析
    private void handleObjSub(List<MsPaperStudentQuestion> subjectStuQuestions,List<MsClassStudent> subjectClassStudents, List<MsPaperQtypeQuestion> questions,
                                List<MsrStudent> subjectStuPapers,Integer examid, String subjectid,Double pscore,Integer raid){

        List<MsrClassQobjsub> saveObjSubs = new ArrayList<>();//客观题/主观题分析
        List<MsrSubjectQuestionSection> saveSectionQuestions = new ArrayList<>();// 学科分段之间学生在该题的整体得分率
        List<MsrSubjectQuestionRankgroup> saveRankGroupQuestions = new ArrayList<>();//分组分数分布

        // 获取学生科目得分-科目默认分段学生
        List<MsrSubjectQuestionSection> subjectSectionQuestions = subjectSectionForQuestion(subjectStuPapers, pscore);

        //根据试题类型分组
        Map<Integer,List<MsPaperQtypeQuestion>> objSubMap = questions.stream().collect(Collectors.groupingBy(MsPaperQtypeQuestion::getQtype));
        for (Map.Entry<Integer, List<MsPaperQtypeQuestion>> entry : objSubMap.entrySet()){
            List<MsPaperQtypeQuestion> objSubQuestions = entry.getValue();
            Double fullScore = objSubQuestions.stream().mapToDouble(MsPaperQtypeQuestion::getQscore).sum();// 客/主观题满分
            List<Integer> mptqids = objSubQuestions.stream().map(MsPaperQtypeQuestion::getMptqid).distinct().collect(Collectors.toList());
            //类型下学生试题
            List<MsPaperStudentQuestion> stuQuestions = subjectStuQuestions.stream().filter(q -> mptqids.contains(q.getMptqid())).collect(Collectors.toList());
            //初始化信息
            MsrClassQobjsub schoolObjSub = new MsrClassQobjsub();
            schoolObjSub.setRaid(raid);
            schoolObjSub.setExamid(examid);
            schoolObjSub.setSubjectid(subjectid);
            schoolObjSub.setClassid(0);
            schoolObjSub.setQtype(entry.getKey());
            schoolObjSub.setFullscore(fullScore);

            MsrClassQobjsub objSubSchool = qobjsubClass(stuQuestions, schoolObjSub);
            saveObjSubs.add(objSubSchool);

            // 学科分段之间学生在该题的整体得分率,qntype=1小题2客观题3主观题
            List<MsrSubjectQuestionSection> sectionQuestions = subjectSectionQuestion(stuQuestions, subjectSectionQuestions,entry.getKey(), fullScore,null,raid);
            saveSectionQuestions.addAll(sectionQuestions);

            int qobjsubtype;//为了区分表中存放值
            if(entry.getKey() == 1){
                qobjsubtype = 11;
            }else{
                qobjsubtype = 12;
            }
            //试题分组分数分布、客观题选项分组、客观题主观题分组分数分布
            List<MsrSubjectQuestionRankgroup> rankGroupQuestions = questionScoreRankGroup(stuQuestions, subjectStuPapers,examid,subjectid, qobjsubtype, fullScore,null,raid);
            saveRankGroupQuestions.addAll(rankGroupQuestions);

            List<Integer> classIds = subjectClassStudents.stream().map(MsClassStudent::getClassid).distinct().collect(Collectors.toList());
            for (Integer classid : classIds) {
                schoolObjSub.setClassid(classid);
                // 获取班级下学生id
                List<Integer> classStuIds =
                        subjectClassStudents.stream().filter(c -> c.getClassid().equals(classid)).map(MsClassStudent::getStudentid).collect(Collectors.toList());
                // 获取班级下学生试题
                List<MsPaperStudentQuestion> classStuQuestions = stuQuestions.stream().filter(q -> classStuIds.contains(q.getStudentid())).collect(Collectors.toList());
                // 班级题型分析
                MsrClassQobjsub objSubClass = qobjsubClass(classStuQuestions, schoolObjSub);
                saveObjSubs.add(objSubClass);
            }
        }

        if(!saveObjSubs.isEmpty()) msrClassQobjsubMapper.insertList(saveObjSubs);
        if(!saveSectionQuestions.isEmpty()) msrSubjectQuestionSectionMapper.insertList(saveSectionQuestions);
        if(!saveRankGroupQuestions.isEmpty()) msrSubjectQuestionRankgroupMapper.insertList(saveRankGroupQuestions);
    }
    //客观题/主观题分析--学校、班级分析
    private MsrClassQobjsub qobjsubClass(List<MsPaperStudentQuestion> stuQuestions, MsrClassQobjsub schoolObjsub){
        //获取学生集合
        List<Integer> studentIds = stuQuestions.stream().map(MsPaperStudentQuestion::getStudentid).distinct().collect(Collectors.toList());
        int stuNum = studentIds.size();

        List<Double> stuScores = new ArrayList<>();
        int mfnum = 0;
        StringBuilder mfids = new StringBuilder();
        int lfnum = 0;
        StringBuilder lfids = new StringBuilder();
        for (Integer studentId : studentIds) {
            List<MsPaperStudentQuestion> stuObjQuesitons = stuQuestions.stream().filter(q -> studentId.equals(q.getStudentid())).collect(Collectors.toList());
            Double stuObjScore = stuObjQuesitons.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
            stuScores.add(stuObjScore);
            if(Objects.equals(schoolObjsub.getFullscore(), stuObjScore)){
                mfnum++;
                mfids.append(studentId).append(",");
            }
            if(stuObjScore == 0){
                lfnum++;
                lfids.append(studentId).append(",");
            }
        }

        Double stuSumScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();// 学生总分
        Double avgScore = MarkingUtil.div(stuSumScore, stuNum);// 平均分

        MsrClassQobjsub objSub = new MsrClassQobjsub();
        objSub.setRaid(schoolObjsub.getRaid());
        objSub.setExamid(schoolObjsub.getExamid());
        objSub.setSubjectid(schoolObjsub.getSubjectid());
        objSub.setClassid(schoolObjsub.getClassid());
        objSub.setStunum(stuNum);
        objSub.setQtype(schoolObjsub.getQtype());
        objSub.setFullscore(schoolObjsub.getFullscore());
        objSub.setMaxscore(stuScores.stream().max(Double::compareTo).orElse(0.0));
        objSub.setMinscore(stuScores.stream().min(Double::compareTo).orElse(0.0));
        objSub.setAvgscore(avgScore);
        objSub.setAvgrate(MarkingUtil.div(avgScore, schoolObjsub.getFullscore()));
        objSub.setNd(MarkingUtil.div(avgScore, schoolObjsub.getFullscore()));
        objSub.setQfd(MarkingUtil.qfd(stuScores));
        objSub.setBzc(MarkingUtil.bzc(stuScores));
        objSub.setCyxs(MarkingUtil.div(objSub.getBzc(), avgScore));
        objSub.setJbzs(MarkingUtil.jbzs(stuScores, schoolObjsub.getFullscore()));
        objSub.setMfnum(mfnum);
        objSub.setMfrate(MarkingUtil.calculateRate(mfnum, stuNum));
        if(mfnum > 0){
            objSub.setMfids(mfids.substring(0,mfids.length()-1));
        }
        objSub.setLfnum(lfnum);
        objSub.setLfrate(MarkingUtil.calculateRate(lfnum, stuNum));
        if(lfnum > 0){
            objSub.setLfids(lfids.substring(0,lfids.length()-1));
        }

        return objSub;
    }

    //设置难度/区分度描述
    @Transactional(rollbackFor = Exception.class)
    public void saveNdAndQfd(ReportParams reportParams){
        List<MsrReportparam> params = reportParams.getParams();
        if(params == null || params.isEmpty()){
            return;
        }

        int rptype = reportParams.getRptype();//1难度 2区别度
        //删除已存在试题汇总参数
        msrReportparamMapper.deleteByExamidAndRpbelong(reportParams.getExamid(), reportParams.getRpbelong(),rptype);
        //保存试题汇总参数
        List<MsrReportparam> saveParams = new ArrayList<>();

        //获取考试分析试题难易度数据
        List<MsrClassQuestion> questions = msrClassQuestionMapper.listQuestionClassForNdByExamid(reportParams.getExamid());
        List<MsrClassQuestion> saveQuestions = new ArrayList<>();

        Integer timestamp = N_Utils.getSecondTimestamp();
        for(MsrReportparam param : params){
            String subjectid = param.getSubjectid();
            MsrReportparam rp = new MsrReportparam();
            rp.setExamid(reportParams.getExamid());
            rp.setSubjectid(subjectid);
            rp.setRpbelong(reportParams.getRpbelong());
            rp.setRptype(rptype);
            rp.setHandleid(param.getHandleid());
            rp.setHandletime(timestamp);
            rp.setSzjson(param.getSzjson());
            saveParams.add(rp);

            List<MsrClassQuestion> subQuestions = questions.stream().filter(q -> q.getSubjectid().equals(subjectid)).collect(Collectors.toList());
            for(MsrClassQuestion question : subQuestions){
                MsrClassQuestion saveQue = new MsrClassQuestion();
                saveQue.setCqid(question.getCqid());
                String[] ndvalues = questionNdAndQfdComm(param.getSzjson(),question.getNd());
                if(rptype == 1){
                    saveQue.setNdms(ndvalues[0]);
                    saveQue.setNdfw(ndvalues[1]);
                }else{
                    saveQue.setQfdms(ndvalues[0]);
                    saveQue.setQfdfw(ndvalues[1]);
                }
                saveQuestions.add(saveQue);
            }
        }

        //保存参数
        msrReportparamMapper.insertList(saveParams);
        if(rptype == 1){
            msrClassQuestionMapper.updateBatchNdById(saveQuestions);
        }else {
            msrClassQuestionMapper.updateBatchQfdById(saveQuestions);
        }
    }

    //学科素养-标定知识点-保存加重新生成报告
    @Transactional(rollbackFor = Exception.class)
    public void handleQuestionPointAndAnalyze(Integer mpid) {
        //保存新标定的知识点

        //获取试卷基础信息
        MsPaper paper = msPaperMapper.selectByPrimaryKey(mpid);
        //先生产学生报告
        if(paper.getPtype() == 1){
            msPaperAnalyzeService.savePaperAnalyzeForQuestion(paper);
        }else{
            msPaperAnalyzeService.savePaperAnalyzeForFj(paper);
        }

        //删除试卷试题信息
        msrSubjectPointMapper.deletePointAnalyze(paper.getExamid(),paper.getSubjectid());
        //获取试卷关联学生试题
        List<MsPaperStudentQuestion> stuQuestions = msPaperStudentQuestionMapper.listAllStuQuesByExamid(paper.getExamid(),paper.getSubjectid());
        List<MsPaperQtypeQuestion> qtypeQuestions = msPaperQtypeQuestionMapper.listQuestionsForReport(paper.getMpid());
        List<MsClassStudent> classStus = msClassStudentMapper.listStudentByExamId(paper.getExamid(),paper.getSubjectid());
        List<MsrStudent> stuPapers = msrStudentMapper.listStuScoreAndRankByExamid(paper.getExamid(),paper.getSubjectid());

        //获取考试关联的报告
        MsrAnalyze report = msrAnalyzeMapper.getAnalyzeByExamid(paper.getExamid());
        reportGeneratePointService.generatePoint(stuQuestions,qtypeQuestions,classStus,stuPapers,paper.getExamid(),paper.getSubjectid(),paper.getMpid(),paper.getPscore(),report.getRaid());
    }
}
