package com.xhkjedu.sexam.service.report;

import com.alibaba.fastjson.JSON;
import com.xhkjedu.sexam.mapper.paper.EPaperAnalyzeMapper;
import com.xhkjedu.sexam.mapper.paperstudent.EPaperStudentQuestionMapper;
import com.xhkjedu.sexam.mapper.reportclass.ERclassComplexityMapper;
import com.xhkjedu.sexam.mapper.reportclass.ERclassPointMapper;
import com.xhkjedu.sexam.mapper.reportclass.ERclassQtypeMapper;
import com.xhkjedu.sexam.mapper.reportclass.ERclassQuestionMapper;
import com.xhkjedu.sexam.mapper.reportstu.ERStudentComplexityMapper;
import com.xhkjedu.sexam.mapper.reportstu.ERstudentPointMapper;
import com.xhkjedu.sexam.mapper.reportstu.ERstudentQtypeMapper;
import com.xhkjedu.sexam.model.exam.EBase;
import com.xhkjedu.sexam.model.paperstudent.EPaperStudentQuestion;
import com.xhkjedu.sexam.model.reportclass.ERclassComplexity;
import com.xhkjedu.sexam.model.reportclass.ERclassPoint;
import com.xhkjedu.sexam.model.reportclass.ERclassQtype;
import com.xhkjedu.sexam.model.reportclass.ERclassQuestion;
import com.xhkjedu.sexam.model.reportstu.ERStudentComplexity;
import com.xhkjedu.sexam.model.reportstu.ERStudentQtype;
import com.xhkjedu.sexam.model.reportstu.ERstudentPoint;
import com.xhkjedu.sexam.utils.ExamUtil;
import com.xhkjedu.sexam.vo.paper.QuestionPointVo;
import com.xhkjedu.sexam.vo.report.ERClassScoreVo;
import com.xhkjedu.sexam.vo.report.ERPointStuScoreVo;
import com.xhkjedu.sexam.vo.report.ExamPaperClassVo;
import com.xhkjedu.utils.N_Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

/**
 * @Description：考试生成报告试题相关
 * @Author: WN
 * @Date: 2023/12/26 16:20:02
 **/
@Service
@Slf4j
public class EReportGenerateQuestionService {
    @Resource
    private EPaperStudentQuestionMapper ePaperStudentQuestionMapper;
    @Resource
    private EPaperAnalyzeMapper ePaperAnalyzeMapper;
    @Resource
    private ERclassQtypeMapper eRclassQtypeMapper;
    @Resource
    private ERclassQuestionMapper eRclassQuestionMapper;
    @Resource
    private ERclassPointMapper eRclassPointMapper;
    @Resource
    private ERstudentPointMapper eRstudentPointMapper;
    @Resource
    private ERstudentQtypeMapper eRstudentQtypeMapper;
    @Resource
    private ERclassComplexityMapper eRclassComplexityMapper;
    @Resource
    private ERStudentComplexityMapper erStudentComplexityMapper;

    public void setClassQuestion(Integer examid, List<Map> subjects, List<Map> classes, EBase base) throws Exception {

        try {
            Integer stuzero = base.getStuzero();//0分学生是否参与统计0不统计1统计(默认)
            // 考试所有学生提交试卷作答情况 2023-12-27添加0分学生是否参与统计
            List<EPaperStudentQuestion> stulist = ePaperStudentQuestionMapper.listExamStudentsAnswer(examid);
            if (N_Utils.isListNotEmpty(stulist)) {
                List<ERclassQtype> rtypelist = new ArrayList<>();// 班级题型
                List<ERStudentQtype> stutypelist = new ArrayList<>();// 学生题型
                List<ERclassQuestion> rqueslist = new ArrayList<>();// 班级试题
                List<ERclassPoint> rpointlist = new ArrayList<>();// 班级知识点
                List<ERstudentPoint> stupointlist = new ArrayList<>();// 学生知识点
                List<ERclassComplexity> complist = new ArrayList<>();// 班级难易度
                List<ERStudentComplexity> stucomplist = new ArrayList<>();// 学生难易度

                for (Map map : subjects) {
                    String subjectid = map.get("subjectid").toString();
                    Integer epid = Integer.parseInt(map.get("epid").toString());// 获取试卷id
                    Integer ptype = Integer.parseInt(map.get("ptype").toString());// 试卷类型1题库2附件
                    ExamPaperClassVo examPaperClassVo = new ExamPaperClassVo();
                    examPaperClassVo.setExamid(examid);
                    examPaperClassVo.setEpid(epid);
                    examPaperClassVo.setSubjectid(subjectid);
                    examPaperClassVo.setClasses(classes);

                    // 获取试卷本身的分析
                    Map panalyze = ePaperAnalyzeMapper.getPaperAnalzyeByEpid(epid);
                    // 获取指定试卷学生作答情况
                    List<EPaperStudentQuestion> paperstulist = stulist.stream().filter(s -> s.getEpid().equals(epid)).collect(Collectors.toList());
                    if (N_Utils.isListNotEmpty(paperstulist)) {
                        if (ptype == 1) {
                            // 处理题型下试题：题库显示题号时为母题的题号即order（qn是英语为顺延题号其他学科为母题号和子题排序拼接）
                            String qtypejson = panalyze.get("qnumjson").toString();// 原试卷题型分析
                            List<Map> qtypelist = JSON.parseArray(qtypejson, Map.class);
                            setPaperQuestionTkQtypes(qtypelist, paperstulist, rtypelist, rqueslist, stutypelist, examPaperClassVo, stuzero);

                            // 处理知识点
                            setEPaperQuestionPoints(panalyze, paperstulist, rpointlist, stupointlist, examPaperClassVo, stuzero);

                            // 处理难易度
                            String complexityjson = panalyze.get("complexityjson").toString();
                            List<Map> complexitylist = JSON.parseArray(complexityjson, Map.class);
                            setEPaperQuestionComplexitys(complexitylist, paperstulist, complist, stucomplist, examPaperClassVo, stuzero);

                        } else {
                            // 处理题型及题型下试题：附件显示题号为qn（order）作为排序使用
                            String qtypejson = panalyze.get("qnumjson").toString();// 原试卷题型分析
                            List<Map> qtypelist = JSON.parseArray(qtypejson, Map.class);
                            setPaperQuestionFjQtypes(qtypelist, paperstulist, rtypelist, rqueslist, stutypelist, examPaperClassVo,stuzero);
                        }
                    }
                }

                eRclassQtypeMapper.insertList(rtypelist);
                eRstudentQtypeMapper.insertList(stutypelist);
                eRclassQuestionMapper.insertList(rqueslist);
                if (N_Utils.isListNotEmpty(complist)) eRclassComplexityMapper.insertList(complist);
                if (N_Utils.isListNotEmpty(stucomplist)) erStudentComplexityMapper.insertList(stucomplist);
                if (N_Utils.isListNotEmpty(rpointlist)) eRclassPointMapper.insertList(rpointlist);
                if (N_Utils.isListNotEmpty(stupointlist)) eRstudentPointMapper.insertList(stupointlist);
            }
        }catch (Exception e){
            log.error("生成试题相关报告出错：" + e.getMessage());
            throw new Exception("生成试题相关报告失败");
        }

    }

    // 题型、试题、知识点、难易度--处理学生选项情况和得分情况
    private Map setPaperQuestionsForStuAnswer(List<EPaperStudentQuestion> classStu) {
        EPaperStudentQuestion q = classStu.get(0);// 取第一条数据

        Map<String, List<Map>> answermap = null;
        List<Map> goodlist = new ArrayList<>();
        List<Map> badlist = new ArrayList<>();

        Double score8 = 0.0;
        Double score5 = 0.0;
        String key1 = "";
        String key2 = "";
        String key3 = "";

        Double qscore = q.getQscore();
        int stunum = classStu.size();
        for (int i = 0; i < stunum; i++) {
            EPaperStudentQuestion sq = classStu.get(i);
            String stuanswer = sq.getStuanswer();
            if (q.getCtype() == 1 || q.getCtype() == 2 || q.getCtype() == 4 || q.getCtype() == 5 || q.getCtype() == 6) {
                String answeroption = "未作答";
                if (N_Utils.isNotEmpty(stuanswer)) {
                    List<String> stuanswers = JSON.parseArray(stuanswer, String.class);
                    if (N_Utils.isListNotEmpty(stuanswers)) {
                        String stuansopt = stuanswers.get(0);
                        if (N_Utils.isNotEmpty(stuansopt)) {
                            answeroption = stuansopt;
                        }
                    }
                }

                if (i == 0) {
                    answermap = new TreeMap<>();
                }

                Map stumap = new HashMap();
                stumap.put("studentid", sq.getStudentid());
                stumap.put("stuname", sq.getStuname());
                if (answermap.containsKey(answeroption)) {
                    List<Map> stulist = answermap.get(answeroption);
                    stulist.add(stumap);
                } else {
                    List<Map> stulist = new ArrayList<>();
                    stulist.add(stumap);
                    answermap.put(answeroption, stulist);
                }
            } else {
                // 主观题
                if (i == 0) {
                    answermap = new LinkedHashMap<>();
                    // 处理分数分段对应,用于分数段[0，50%）   [50%，80%）,  [80%，100%]
                    score8 = ExamUtil.getScoreRateScore(qscore, 0.8);
                    score5 = ExamUtil.getScoreRateScore(qscore, 0.5);
                    String str10 = N_Utils.formatDouble(qscore);
                    String str8 = N_Utils.formatDouble(score8);
                    String str5 = N_Utils.formatDouble(score5);
                    key1 = str8 + "-" + str10;
                    key2 = str5 + "-" + str8;
                    key3 = 0 + "-" + str5;
                    answermap.put(key1, new ArrayList<>());
                    answermap.put(key2, new ArrayList<>());
                    answermap.put(key3, new ArrayList<>());
                }

                List<Map> stulist = null;
                if (sq.getStuscore() >= score8) {
                    stulist = answermap.get(key1);
                } else if (sq.getStuscore() >= score5 && sq.getStuscore() < score8) {
                    stulist = answermap.get(key2);
                } else {
                    stulist = answermap.get(key3);
                }

                Map stumap = new HashMap();
                stumap.put("studentid", sq.getStudentid());
                stumap.put("stuname", sq.getStuname());
                stulist.add(stumap);
            }

            if (!N_Utils.isEmptyInteger(sq.getGood()) && sq.getGood() == 1) {
                Map goodmap = new HashMap();
                goodmap.put("studentid", sq.getStudentid());
                goodmap.put("stuname", sq.getStuname());
                goodlist.add(goodmap);
            }
            if (!N_Utils.isEmptyInteger(sq.getBad()) && sq.getBad() == 1) {
                Map badmap = new HashMap();
                badmap.put("studentid", sq.getStudentid());
                badmap.put("stuname", sq.getStuname());
                badlist.add(badmap);
            }
        }

        Map<String, List<Map>> answermapNew = new LinkedHashMap<>();
        if (q.getCtype() == 4 || q.getCtype() == 5 || q.getCtype() == 6) {
            for (Map.Entry<String, List<Map>> entry : answermap.entrySet()) {
                if (!entry.getKey().equals("未作答")) {
                    answermapNew.put(entry.getKey(), entry.getValue());
                }
            }
            // 判断题把“未作答”放最后
            answermapNew.put("未作答", answermap.get("未作答"));
        } else {
            answermapNew.putAll(answermap);
        }

        String erroroption = "";// 高频错误项
        if (q.getCtype() == 1 || q.getCtype() == 2 || q.getCtype() == 4 || q.getCtype() == 5 || q.getCtype() == 6) {
            String answer = q.getAnswer();// 试题正确答案
            List<String> answerlist = JSON.parseArray(answer, String.class);
            int num = 0;
            for (Map.Entry<String, List<Map>> entry : answermap.entrySet()) {
                if (!entry.getKey().equalsIgnoreCase(answerlist.get(0))) {
                    // 当前选项不是正确答案时,数量大的为高频错误选项
                    if (num < entry.getValue().size() && !entry.getKey().equals("未作答")) {
                        num = entry.getValue().size();
                        erroroption = entry.getKey();
                    }
                }
            }
        }

        List<Map> dafblist = new ArrayList<>();// 答案分布
        Map<String, Map> dafbmap = new HashMap<>();// 答案分布
        for (Map.Entry<String, List<Map>> entry : answermapNew.entrySet()) {
            String key = entry.getKey();
            List<Map> students = entry.getValue();
            Map dafb = new HashMap();
            int num = students.size();
            dafb.put("students", students);
            dafb.put("num", num);
            dafb.put("numrate", N_Utils.getIntegerDivideAndMulitiply(num, stunum));
            dafbmap.put(key, dafb);
        }

        Map rtnmap = new HashMap();
        rtnmap.put("answerlist", JSON.toJSONString(dafbmap));
        long fullscorenum = classStu.stream().filter(c -> qscore.equals(c.getStuscore())).count();
        rtnmap.put("fullscorenum", fullscorenum);
        rtnmap.put("dafbjson", JSON.toJSONString(dafblist));
        rtnmap.put("goodlist", JSON.toJSONString(goodlist));
        rtnmap.put("badlist", JSON.toJSONString(badlist));
        rtnmap.put("erroroption", erroroption);
        return rtnmap;
    }

    // 题型、试题、知识点、难易度--附件题型
    private void setPaperQuestionFjQtypes(List<Map> qtypelist, List<EPaperStudentQuestion> paperstulist, List<ERclassQtype> rtypelist, List<ERclassQuestion> rqueslist,
                                          List<ERStudentQtype> stutypelist, ExamPaperClassVo examPaperClassVo,Integer stuzero) {
        List<Map> classes = examPaperClassVo.getClasses();
        for (int k = 0; k < qtypelist.size(); k++) {
            Map qtypemap = qtypelist.get(k);
            String qtypename = qtypemap.get("qtname").toString();
            String qtypeid = qtypemap.get("qtid").toString();
            Double score = Double.parseDouble(qtypemap.get("score").toString());// 题型下试题总分值
            Double srate = Double.parseDouble(qtypemap.get("srate").toString());// 题型下试题分值占比
            Integer num = Integer.parseInt(qtypemap.get("num").toString());// 题型下试题数量
            Map ques = (Map) qtypemap.get("ques");// 试题相关对象
            List<Integer> eptqids = (List<Integer>) ques.get("eptqids");// 试卷中题型下试题id
            List<String> qns = (List<String>) ques.get("qns");// 试卷中试题题号
            List<Integer> orders = (List<Integer>) ques.get("orders");// 试卷中试题题号
            List<String> qtypenames = (List<String>) ques.get("qtypenames");
            List<Object> scoresObj = (List<Object>) ques.get("scores");
            List<Double> scores = scoresObj.stream().map((d) -> {
                return Double.valueOf(d + "");
            }).collect(Collectors.toList());

            Double tgstuscore = 0.0;// 题型下学生得分
            Double tgscore = 0.0;// 题型下试题总分
            int gstunum = 0;// 题型下学生数量
            Map<Integer, ERClassScoreVo> tclassmap = new HashMap<>();
            Map<Integer, ERStudentQtype> tstumap = new HashMap<>();

            for (int q = 0; q < eptqids.size(); q++) {
                Integer eptqid = eptqids.get(q);
                //所有学生，包含0分的
                List<EPaperStudentQuestion> qgstulistZero = paperstulist.stream().filter(s -> s.getEptqid().equals(eptqid)).collect(Collectors.toList());
                EPaperStudentQuestion ePaperStudentQuestion = qgstulistZero.get(0);//获取第一个对象用于后续生成

                // 获取该题所有学生作答情况
                List<EPaperStudentQuestion> qgstulist = new ArrayList<>();
                if(stuzero == 0){//如果为0：0分学生不参与统计
                    qgstulist = qgstulistZero.stream().filter(s -> s.getStupaperscore() > 0).collect(Collectors.toList());

                }else{
                    //1:0分学生参与统计
                    qgstulist.addAll(qgstulistZero);
                }
                gstunum = qgstulist.size();

                EPaperStudentQuestion qgmaxstu = null;
                Double qgscore = 0D;
                Double qgstuscore = 0D;
                Double qgavgscore = 0D;
                Double qgsrate = 0D;
                if(gstunum > 0){
                    qgmaxstu = qgstulist.stream().max(Comparator.comparing(EPaperStudentQuestion::getStuscore)).get();
                    qgscore = qgstulist.stream().mapToDouble(EPaperStudentQuestion::getQscore).sum();
                    qgscore = N_Utils.formatDouble(qgscore, 1);
                    qgstuscore = qgstulist.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
                    qgstuscore = N_Utils.formatDouble(qgstuscore, 1);

                    qgavgscore = N_Utils.getDoubleDivideForAvg(qgstuscore, gstunum);// 年级平均分

                    qgsrate = N_Utils.getDoubleDivideAndMulitiply(qgstuscore, qgscore);
                    tgscore = ExamUtil.add(tgscore, qgscore);
                    tgstuscore = ExamUtil.add(tgstuscore, qgstuscore);
                }

                // 处理试题班级学生作答
                for (Map classm : classes) {
                    Integer classid = Integer.parseInt(classm.get("classid").toString());
                    List<EPaperStudentQuestion> qcstulist = qgstulist.stream().filter(s -> s.getClassid().equals(classid)).collect(Collectors.toList());
                    List<EPaperStudentQuestion> qcstulistZero = qgstulistZero.stream().filter(s -> s.getClassid().equals(classid)).collect(Collectors.toList());

                    int cstunum = qcstulist.size();//// 班级下试题作答学生数量
                    EPaperStudentQuestion qcmaxstu = null;
                    Double qcscore = 0D;
                    Double qcstuscore = 0D;
                    Double qcavgscore = 0D;
                    Double qcsrate = 0D;
                    if(cstunum>0){
                        qcmaxstu = qcstulist.stream().max(Comparator.comparing(EPaperStudentQuestion::getStuscore)).get();
                        qcscore = qcstulist.stream().mapToDouble(EPaperStudentQuestion::getQscore).sum();
                        qcscore = N_Utils.formatDouble(qcscore, 1);
                        qcstuscore = qcstulist.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
                        qcstuscore = N_Utils.formatDouble(qcstuscore, 1);
                        qcavgscore=N_Utils.getDoubleDivideForAvg(qcstuscore, cstunum);
                        qcsrate = N_Utils.getDoubleDivideAndMulitiply(qcstuscore, qcscore);
                    }

                    // 班级单题情况
                    ERclassQuestion ercq = new ERclassQuestion();
                    ercq.setCtype(ePaperStudentQuestion.getCtype());
                    ercq.setExamid(examPaperClassVo.getExamid());
                    ercq.setClassid(classid);
                    ercq.setSubjectid(examPaperClassVo.getSubjectid());
                    ercq.setEpid(examPaperClassVo.getEpid());
                    ercq.setEptqid(eptqid);
                    ercq.setQn(qns.get(q));
                    ercq.setQorder(orders.get(q));
                    ercq.setScore(scores.get(q));
                    ercq.setQtypename(qtypenames.get(q));
                    ercq.setClassscore(qcstuscore);
                    if(qcmaxstu == null){
                        ercq.setClassmaxscore(0D);
                    }else{
                        ercq.setClassmaxscore(qcmaxstu.getStuscore());
                    }
                    ercq.setClassavgscore(qcavgscore);
                    ercq.setClasssrate(qcsrate);
                    ercq.setClassratetype(ExamUtil.getScoreRateType(qcsrate));
                    ercq.setGradescore(qgstuscore);
                    if(qgmaxstu == null){
                        ercq.setGrademaxscore(0D);
                    }else{
                        ercq.setGrademaxscore(qgmaxstu.getStuscore());
                    }

                    ercq.setGradeavgscore(qgavgscore);
                    ercq.setGradesrate(qgsrate);

                    // 处理单选题选项情况
                    Map stuansmap = setPaperQuestionsForStuAnswer(qcstulistZero);
                    ercq.setFullscorenum(N_Utils.str2Int(stuansmap.get("fullscorenum").toString()));
                    ercq.setAnswerjson(stuansmap.get("answerlist").toString());
                    if (N_Utils.isNotEmpty(stuansmap.get("goodlist"))) {
                        ercq.setGoodstujson(stuansmap.get("goodlist").toString());
                    }
                    if (N_Utils.isNotEmpty(stuansmap.get("badlist"))) {
                        ercq.setBadstujson(stuansmap.get("badlist").toString());
                    }
                    if (N_Utils.isNotEmpty(stuansmap.get("erroroption"))) {
                        ercq.setErroroption(stuansmap.get("erroroption").toString());
                    } else {
                        ercq.setErroroption("");
                    }

                    rqueslist.add(ercq);// 单个试题统计

                    if (tclassmap.containsKey(classid)) {
                        ERClassScoreVo erClassScoreVo = tclassmap.get(classid);
                        erClassScoreVo.setStuscore(ExamUtil.add(erClassScoreVo.getStuscore(), qcstuscore));
                        erClassScoreVo.setCscore(ExamUtil.add(erClassScoreVo.getCscore(), qcscore));
                    } else {
                        ERClassScoreVo erClassScoreVo = new ERClassScoreVo();
                        erClassScoreVo.setStunum(cstunum);
                        erClassScoreVo.setStuscore(qcstuscore);
                        erClassScoreVo.setCscore(qcscore);
                        tclassmap.put(classid, erClassScoreVo);
                    }

                    for (EPaperStudentQuestion psq : qcstulistZero) {
                        if (tstumap.containsKey(psq.getStudentid())) {
                            ERStudentQtype sq = tstumap.get(psq.getStudentid());
                            sq.setStuscore(ExamUtil.add(sq.getStuscore(), psq.getStuscore()));
                        } else {
                            ERStudentQtype sq = new ERStudentQtype();
                            sq.setClassid(psq.getClassid());
                            sq.setStudentid(psq.getStudentid());
                            sq.setStuscore(psq.getStuscore());
                            tstumap.put(psq.getStudentid(), sq);
                        }
                    }
                }
            }

            Double tgavgscore = 0D;
            Double tgsrate = 0D;
            if(gstunum >0){
                tgavgscore = N_Utils.getDoubleDivideForAvg(tgstuscore, gstunum);// 题型下年级平均分
                tgsrate = N_Utils.getDoubleDivideAndMulitiply(tgstuscore, tgscore);// 年级得分率
            }

            // 题型--班级得分
            for (Map.Entry<Integer, ERClassScoreVo> entry : tclassmap.entrySet()) {
                ERClassScoreVo erClassScoreVo = entry.getValue();
                ERclassQtype eRclassQtype = new ERclassQtype();
                eRclassQtype.setExamid(examPaperClassVo.getExamid());
                eRclassQtype.setSubjectid(examPaperClassVo.getSubjectid());
                eRclassQtype.setEpid(examPaperClassVo.getEpid());
                eRclassQtype.setClassid(entry.getKey());
                eRclassQtype.setQtypename(qtypename);
                eRclassQtype.setQtypeid(qtypeid);
                eRclassQtype.setScore(score);
                eRclassQtype.setNum(num);
                eRclassQtype.setSrate(srate);
                eRclassQtype.setGradescore(tgstuscore);
                eRclassQtype.setGradeavgscore(tgavgscore);
                eRclassQtype.setGradesrate(tgsrate);
                eRclassQtype.setClassscore(erClassScoreVo.getStuscore());
                if(erClassScoreVo.getStunum() == 0){
                    eRclassQtype.setClassavgscore(0D);
                }else{
                    eRclassQtype.setClassavgscore(N_Utils.getDoubleDivideForAvg(erClassScoreVo.getStuscore(), erClassScoreVo.getStunum()));
                }

                if(erClassScoreVo.getCscore() == 0){
                    eRclassQtype.setClasssrate(0D);
                }else{
                    eRclassQtype.setClasssrate(N_Utils.getDoubleDivideAndMulitiply(erClassScoreVo.getStuscore(), erClassScoreVo.getCscore()));
                }

                eRclassQtype.setQns(qns.stream().map(String::valueOf).collect(Collectors.joining(",")));
                rtypelist.add(eRclassQtype);
            }
            // 题型--学生得分
            for (Map.Entry<Integer, ERStudentQtype> entry : tstumap.entrySet()) {
                ERStudentQtype erStudentQtype = entry.getValue();
                erStudentQtype.setExamid(examPaperClassVo.getExamid());
                erStudentQtype.setSubjectid(examPaperClassVo.getSubjectid());
                erStudentQtype.setEpid(examPaperClassVo.getEpid());
                erStudentQtype.setQtypename(qtypename);
                erStudentQtype.setQtypeid(qtypeid);
                erStudentQtype.setStusrate(N_Utils.getDoubleDivideAndMulitiply(erStudentQtype.getStuscore(), score));
                stutypelist.add(erStudentQtype);
            }
        }
    }

    // 题型、试题、知识点、难易度--题库题型
    private void setPaperQuestionTkQtypes(List<Map> qtypelist, List<EPaperStudentQuestion> paperstulist, List<ERclassQtype> rtypelist, List<ERclassQuestion> rqueslist,
                                          List<ERStudentQtype> stutypelist, ExamPaperClassVo examPaperClassVo,Integer stuzero) {
        List<Map> classes = examPaperClassVo.getClasses();
        for (int k = 0; k < qtypelist.size(); k++) {
            Map qtypemap = qtypelist.get(k);
            String qtypename = qtypemap.get("qtname").toString();
            String qtypeid = qtypemap.get("qtid").toString();
            Double score = Double.parseDouble(qtypemap.get("score").toString());// 题型下试题总分值
            Double srate = Double.parseDouble(qtypemap.get("srate").toString());// 题型下试题分值占比
            Integer num = Integer.parseInt(qtypemap.get("num").toString());// 题型下试题数量
            List<Map> queslist = (List<Map>) qtypemap.get("ques");// 试题相关对象（数量为几个代表几个母题）
            String qns = "";

            Double tgstuscore = 0.0;// 题型下学生得分
            Double tgscore = 0.0;// 题型下试题总分
            int gstunum = 0;// 题型下学生数量

            Map<Integer, ERClassScoreVo> tclassmap = new HashMap<>();
            Map<Integer, ERStudentQtype> tstumap = new HashMap<>();

            for (Map quesmap : queslist) {
                List<Integer> eptqids = (List<Integer>) quesmap.get("eptqids");
                Integer qlevel = Integer.parseInt(quesmap.get("qlevel").toString());
                String order = quesmap.get("order").toString();// 试题母题题号
                String questionid = quesmap.get("questionid").toString();
                List<String> qnslist = (List<String>) quesmap.get("qns");
                String quesname = quesmap.get("name").toString();
                Integer complexity = Integer.parseInt(quesmap.get("complexity").toString());
                Double quesscore = Double.parseDouble(quesmap.get("score").toString());
                qns = qns + order + ",";

                // 获取集合中对应子题集合的数据
                List<EPaperStudentQuestion> qgstulistZero = null;
                Integer eptqid = null;
                if (qlevel == 1) {
                    // 单题时直接为试题id
                    eptqid = eptqids.get(0);
                    Integer teptqid = eptqid;
                    qgstulistZero = paperstulist.stream().filter(s -> teptqid.equals(s.getEptqid())).collect(Collectors.toList());
                } else {
                    qgstulistZero = new ArrayList<>();
                    List<EPaperStudentQuestion> stuqlist = paperstulist.stream().filter(s -> eptqids.contains(s.getEptqid())).collect(Collectors.toList());
                    // 母子题情况，计算所有子题的和即为母题。把试题按照学生分组，分组为一组的即为
                    Map<Integer, List<EPaperStudentQuestion>> stuQuesMap = stuqlist.stream().collect(Collectors.groupingBy(EPaperStudentQuestion::getStudentid));
                    for (Map.Entry<Integer, List<EPaperStudentQuestion>> entry : stuQuesMap.entrySet()) {
                        List<EPaperStudentQuestion> stuqueslist = entry.getValue();
                        EPaperStudentQuestion pfist = stuqueslist.get(0);
                        EPaperStudentQuestion pstq = new EPaperStudentQuestion();
                        pstq.setStupaperscore(pfist.getStupaperscore());
                        pstq.setClassid(pfist.getClassid());
                        pstq.setStudentid(entry.getKey());
                        pstq.setStuname(pfist.getStuname());

                        Double qstuscore = stuqueslist.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
                        qstuscore = N_Utils.formatDouble(qstuscore, 1);
                        Double qscore = stuqueslist.stream().mapToDouble(EPaperStudentQuestion::getQscore).sum();
                        qscore = N_Utils.formatDouble(qscore, 1);
                        pstq.setQscore(qscore);
                        pstq.setStuscore(qstuscore);
                        pstq.setCtype(11);// 母子题关系的均设置为复合题，不再进行选项区分
                        int bad = 0;
                        int good = 0;
                        for (EPaperStudentQuestion sq : stuqueslist) {
                            if (sq.getBad() == 1) {
                                bad++;
                            }
                            if (sq.getGood() == 1) {
                                good++;
                            }
                        }
                        if (bad > 0) {
                            pstq.setBad(1);
                        }
                        if (good > 0) {
                            pstq.setGood(1);
                        }
                        qgstulistZero.add(pstq);
                    }
                }

                EPaperStudentQuestion ePaperStudentQuestion = qgstulistZero.get(0);
                List<EPaperStudentQuestion> qgstulist = new ArrayList<>();
                if(stuzero == 0){//如果为0：0分学生不参与统计
                    qgstulist = qgstulistZero.stream().filter(s -> s.getStupaperscore() > 0).collect(Collectors.toList());
                }else{
                    //1:0分学生参与统计
                    qgstulist.addAll(qgstulistZero);
                }

                gstunum = qgstulist.size();
                Double qgscore = 0D;
                Double qgstuscore = 0D;
                EPaperStudentQuestion qgmaxscore = null;
                Double qgavgscore = 0D;
                Double qgsrate = 0D;
                if(gstunum > 0){
                    qgscore = qgstulist.stream().mapToDouble(EPaperStudentQuestion::getQscore).sum();
                    qgscore = N_Utils.formatDouble(qgscore, 1);
                    qgstuscore = qgstulist.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
                    qgstuscore = N_Utils.formatDouble(qgstuscore, 1);
                    qgmaxscore = qgstulist.stream().max(Comparator.comparing(EPaperStudentQuestion::getStuscore)).get();
                    tgscore = ExamUtil.add(tgscore, qgscore);
                    tgstuscore = ExamUtil.add(tgstuscore, qgstuscore);
                    qgavgscore= N_Utils.getDoubleDivideForAvg(qgstuscore, gstunum);
                    qgsrate = N_Utils.getDoubleDivideAndMulitiply(qgstuscore, qgscore);
                }

                for (Map classm : classes) {
                    Integer classid = Integer.parseInt(classm.get("classid").toString());
                    List<EPaperStudentQuestion> qcstulist = qgstulist.stream().filter(s -> s.getClassid().equals(classid)).collect(Collectors.toList());
                    List<EPaperStudentQuestion> qcstulistZero = qgstulistZero.stream().filter(s -> s.getClassid().equals(classid)).collect(Collectors.toList());

                    int cstunum = qcstulist.size();// 班级下试题作答学生数量
                    Double qcscore = 0D;
                    Double qcstuscore = 0D;
                    Double qcavgscore = 0D;
                    EPaperStudentQuestion maxscore = null;
                    Double qcsrate = 0D;
                    if(cstunum > 0){
                        qcscore = qcstulist.stream().mapToDouble(EPaperStudentQuestion::getQscore).sum();
                        qcscore = N_Utils.formatDouble(qcscore, 1);
                        qcstuscore = qcstulist.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
                        qcstuscore = N_Utils.formatDouble(qcstuscore, 1);
                        qcavgscore = N_Utils.getDoubleDivideForAvg(qcstuscore, cstunum);
                        maxscore = qcstulist.stream().max(Comparator.comparing(EPaperStudentQuestion::getStuscore)).get();
                        qcsrate = N_Utils.getDoubleDivideAndMulitiply(qcstuscore, qcscore);
                    }

                    if (tclassmap.containsKey(classid)) {
                        ERClassScoreVo erClassScoreVo = tclassmap.get(classid);
                        erClassScoreVo.setStuscore(ExamUtil.add(erClassScoreVo.getStuscore(), qcstuscore));
                        erClassScoreVo.setCscore(ExamUtil.add(erClassScoreVo.getCscore(), qcscore));
                    } else {
                        ERClassScoreVo erClassScoreVo = new ERClassScoreVo();
                        erClassScoreVo.setStunum(cstunum);
                        erClassScoreVo.setStuscore(qcstuscore);
                        erClassScoreVo.setCscore(qcscore);
                        tclassmap.put(classid, erClassScoreVo);
                    }
                    for (EPaperStudentQuestion psq : qcstulistZero) {
                        if (tstumap.containsKey(psq.getStudentid())) {
                            ERStudentQtype sq = tstumap.get(psq.getStudentid());
                            sq.setStuscore(ExamUtil.add(sq.getStuscore(), psq.getStuscore()));
                        } else {
                            ERStudentQtype sq = new ERStudentQtype();
                            sq.setClassid(psq.getClassid());
                            sq.setStudentid(psq.getStudentid());
                            sq.setStuscore(psq.getStuscore());
                            tstumap.put(psq.getStudentid(), sq);
                        }
                    }

                    // 班级单题情况
                    ERclassQuestion ercq = new ERclassQuestion();
                    ercq.setCtype(ePaperStudentQuestion.getCtype());
                    ercq.setExamid(examPaperClassVo.getExamid());
                    ercq.setClassid(classid);
                    ercq.setSubjectid(examPaperClassVo.getSubjectid());
                    ercq.setEpid(examPaperClassVo.getEpid());
                    ercq.setEptqid(eptqid);
                    ercq.setQuestionid(questionid);
                    ercq.setQtypename(quesname);
                    ercq.setComplexity(complexity);
                    ercq.setScore(quesscore);
                    ercq.setQn(String.join(",", qnslist));
                    ercq.setQorder(Integer.parseInt(order));
                    ercq.setClassscore(qcstuscore);
                    if(maxscore == null){
                        ercq.setClassmaxscore(0D);
                    }else {
                        ercq.setClassmaxscore(maxscore.getStuscore());
                    }
                    ercq.setClassavgscore(qcavgscore);
                    ercq.setClasssrate(qcsrate);
                    ercq.setClassratetype(ExamUtil.getScoreRateType(qcsrate));
                    if(qgmaxscore == null){
                        ercq.setGrademaxscore(0D);
                    }else {
                        ercq.setGrademaxscore(qgmaxscore.getStuscore());
                    }
                    ercq.setGradescore(qgstuscore);
                    ercq.setGradeavgscore(qgavgscore);
                    ercq.setGradesrate(qgsrate);
                    // 处理单选题选项情况
                    Map stuansmap = setPaperQuestionsForStuAnswer(qcstulistZero);
                    ercq.setFullscorenum(N_Utils.str2Int(stuansmap.get("fullscorenum").toString()));
                    ercq.setAnswerjson(stuansmap.get("answerlist").toString());
                    if (N_Utils.isNotEmpty(stuansmap.get("goodlist"))) {
                        ercq.setGoodstujson(stuansmap.get("goodlist").toString());
                    }
                    if (N_Utils.isNotEmpty(stuansmap.get("badlist"))) {
                        ercq.setBadstujson(stuansmap.get("badlist").toString());
                    }
                    if (N_Utils.isNotEmpty(stuansmap.get("erroroption"))) {
                        ercq.setErroroption(stuansmap.get("erroroption").toString());
                    } else {
                        ercq.setErroroption("");
                    }
                    rqueslist.add(ercq);// 单个试题统计
                }
            }
            Double tgavgscore = 0D;
            Double tgsrate = 0D;
            if(gstunum > 0){
                tgavgscore = N_Utils.getDoubleDivideForAvg(tgstuscore, gstunum);// 题型下年级平均分
                tgsrate = N_Utils.getDoubleDivideAndMulitiply(tgstuscore, tgscore);// 年级得分率
            }

            // 题型--班级得分
            for (Map.Entry<Integer, ERClassScoreVo> entry : tclassmap.entrySet()) {
                ERClassScoreVo erClassScoreVo = entry.getValue();
                ERclassQtype eRclassQtype = new ERclassQtype();
                eRclassQtype.setExamid(examPaperClassVo.getExamid());
                eRclassQtype.setSubjectid(examPaperClassVo.getSubjectid());
                eRclassQtype.setEpid(examPaperClassVo.getEpid());
                eRclassQtype.setClassid(entry.getKey());
                eRclassQtype.setQtypename(qtypename);
                eRclassQtype.setQtypeid(qtypeid);
                eRclassQtype.setScore(score);
                eRclassQtype.setNum(num);
                eRclassQtype.setSrate(srate);
                eRclassQtype.setGradescore(tgstuscore);
                eRclassQtype.setGradeavgscore(tgavgscore);
                eRclassQtype.setGradesrate(tgsrate);
                eRclassQtype.setClassscore(erClassScoreVo.getStuscore());
                if(erClassScoreVo.getStunum() == 0){
                    eRclassQtype.setClassavgscore(0D);
                }else{
                    eRclassQtype.setClassavgscore(N_Utils.getDoubleDivideForAvg(erClassScoreVo.getStuscore(), erClassScoreVo.getStunum()));
                }
                if(erClassScoreVo.getCscore() == 0){
                    eRclassQtype.setClasssrate(0D);
                }else{
                    eRclassQtype.setClasssrate(N_Utils.getDoubleDivideAndMulitiply(erClassScoreVo.getStuscore(), erClassScoreVo.getCscore()));
                }

                eRclassQtype.setQns(qns.substring(0, qns.lastIndexOf(",")));
                rtypelist.add(eRclassQtype);
            }

            // 题型--学生得分
            for (Map.Entry<Integer, ERStudentQtype> entry : tstumap.entrySet()) {
                ERStudentQtype erStudentQtype = entry.getValue();
                erStudentQtype.setExamid(examPaperClassVo.getExamid());
                erStudentQtype.setSubjectid(examPaperClassVo.getSubjectid());
                erStudentQtype.setEpid(examPaperClassVo.getEpid());
                erStudentQtype.setQtypename(qtypename);
                erStudentQtype.setQtypeid(qtypeid);
                erStudentQtype.setStusrate(N_Utils.getDoubleDivideAndMulitiply(erStudentQtype.getStuscore(), score));
                stutypelist.add(erStudentQtype);
            }
        }
    }

    // 题型、试题、知识点、难易度--知识点
    private void setEPaperQuestionPoints(Map panalyze, List<EPaperStudentQuestion> paperstulist, List<ERclassPoint> cpointlist, List<ERstudentPoint> stupointlist,
                                         ExamPaperClassVo examPaperClassVo,Integer stuzero) {
        // 原试卷知识点分析
        String pointjson = panalyze.get("pointjson").toString();
        List<Map> pointlist = JSON.parseArray(pointjson, Map.class);

        // 试题对应知识点关系
        String quespointjson = panalyze.get("quespointjson").toString();
        List<QuestionPointVo> quepointlist = JSON.parseArray(quespointjson, QuestionPointVo.class);

        List<ERPointStuScoreVo> gradestulist = new ArrayList<>();// 每个知识点每个学生的得分
        for (int i = 0; i < quepointlist.size(); i++) {
            QuestionPointVo qpoint = quepointlist.get(i);
            List<Map> points = qpoint.getPointids();
            if (N_Utils.isListNotEmpty(points)) {
                if (qpoint.getQlevel() == 1 || !N_Utils.isEmptyInteger(qpoint.getEptqid())) {
                    // 说明本题为单题,获取该题下所有学生的得分情况
                    List<EPaperStudentQuestion> stuqueslist = paperstulist.stream().filter(s -> s.getEptqid().equals(qpoint.getEptqid())).collect(Collectors.toList());
                    for (EPaperStudentQuestion sq : stuqueslist) {
                        setEPaperQuestionPointsForStuQues(gradestulist, sq, points, qpoint.getEptqid().toString());
                    }
                } else {
                    // 说明该题为复合题，获取所有子题
                    List<Integer> eptqids = qpoint.getEptqids();
                    String eptqidsStr = eptqids.stream().map(String::valueOf).collect(Collectors.joining(","));
                    List<EPaperStudentQuestion> stuqueslist = paperstulist.stream().filter(s -> eptqids.contains(s.getEptqid())).collect(Collectors.toList());
                    // 根据每个学生分组获取每个学生该题分值
                    Map<Integer, List<EPaperStudentQuestion>> stuquesmap = stuqueslist.stream().collect(Collectors.groupingBy(EPaperStudentQuestion::getStudentid));
                    for (Map.Entry<Integer, List<EPaperStudentQuestion>> entry : stuquesmap.entrySet()) {
                        List<EPaperStudentQuestion> stuques = entry.getValue();
                        Double stuscore = stuques.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
                        stuscore = N_Utils.formatDouble(stuscore, 1);
                        EPaperStudentQuestion sqfirst = stuques.get(0);
                        EPaperStudentQuestion sq = new EPaperStudentQuestion();
                        sq.setStudentid(entry.getKey());
                        sq.setClassid(sqfirst.getClassid());
                        sq.setStuscore(stuscore);
                        setEPaperQuestionPointsForStuQues(gradestulist, sq, points, eptqidsStr);
                    }
                }
            }
        }

        List<Map> classes = examPaperClassVo.getClasses();
        // 根据试卷知识点分析进行生成学生、班级、年级知识点分析
        for (Map map : pointlist) {
            String pointid = map.get("pointid").toString();
            String pointname = map.get("pointname").toString();
            Double pointscore = Double.parseDouble(map.get("score").toString());
            Double pointrate = Double.parseDouble(map.get("srate").toString());
            List<Map> qorders = (List<Map>) map.get("ques");
            List<Integer> orders = qorders.stream().map(s -> Integer.parseInt(s.get("order").toString())).collect(Collectors.toList());
            String orderstr = orders.stream().map(String::valueOf).collect(Collectors.joining(","));// 试题
            // 单个知识点学生得分情况:一个知识对应一个或多个试题，
            List<ERPointStuScoreVo> gradepointstulist = gradestulist.stream().filter(s -> s.getPointid().equals(pointid)).collect(Collectors.toList());

            List<ERPointStuScoreVo> pointstuscorelistZero = new ArrayList<>(); // 知识点下多个试题，处理成单个学生总分值情况
            Map<Integer, List<ERPointStuScoreVo>> pointstuscoremap = gradepointstulist.stream().collect(Collectors.groupingBy(ERPointStuScoreVo::getStudentid));
            for (Map.Entry<Integer, List<ERPointStuScoreVo>> entry : pointstuscoremap.entrySet()) {
                List<ERPointStuScoreVo> stuscorelist = entry.getValue();
                Double stuscore = stuscorelist.stream().mapToDouble(ERPointStuScoreVo::getStuscore).sum();
                stuscore = N_Utils.formatDouble(stuscore, 1);
                ERPointStuScoreVo sscorevofirst = stuscorelist.get(0);
                ERPointStuScoreVo sscorevo = new ERPointStuScoreVo();
                sscorevo.setStupaperscore(sscorevofirst.getStupaperscore());
                sscorevo.setStudentid(sscorevofirst.getStudentid());
                sscorevo.setClassid(sscorevofirst.getClassid());
                sscorevo.setStuscore(stuscore);
                pointstuscorelistZero.add(sscorevo);
            }

            List<ERPointStuScoreVo> pointstuscorelist = new ArrayList<>();
            if(stuzero == 0){
                //如果为0：0分学生不参与统计
                pointstuscorelist = pointstuscorelistZero.stream().filter(s -> s.getStupaperscore() > 0).collect(Collectors.toList());
            }else {
                pointstuscorelist.addAll(pointstuscorelistZero);
            }

            Double gstuscore = 0D;
            Double gavgscore = 0D;
            Double gsrate = 0D;
            if(pointstuscorelist.size() > 0){
                gstuscore = pointstuscorelist.stream().mapToDouble(ERPointStuScoreVo::getStuscore).sum();
                gstuscore = N_Utils.formatDouble(gstuscore, 1);
                gavgscore = N_Utils.getDoubleDivideForAvg(gstuscore, pointstuscorelist.size());
                gsrate = N_Utils.getDoubleDivideAndMulitiply(gstuscore, pointscore * pointstuscorelist.size());
            }


            for (Map classm : classes) {
                Integer classid = Integer.parseInt(classm.get("classid").toString());
                List<ERPointStuScoreVo> classpointstulist = pointstuscorelist.stream().filter(s -> s.getClassid().equals(classid)).collect(Collectors.toList());
                List<ERPointStuScoreVo> classpointstulistZero = pointstuscorelistZero.stream().filter(s -> s.getClassid().equals(classid)).collect(Collectors.toList());

                Double cstuscore = 0D;
                Double cavgscore = 0D;
                Double csrate = 0D;
                if (N_Utils.isListNotEmpty(classpointstulist) && classpointstulist.size() > 0) {
                    cstuscore = classpointstulist.stream().mapToDouble(ERPointStuScoreVo::getStuscore).sum();
                    cstuscore = N_Utils.formatDouble(cstuscore, 1);
                    cavgscore = N_Utils.getDoubleDivideForAvg(cstuscore, classpointstulist.size());
                    csrate = N_Utils.getDoubleDivideAndMulitiply(cstuscore, pointscore * classpointstulist.size());
                }

                ERclassPoint eRclassPoint = new ERclassPoint();
                eRclassPoint.setExamid(examPaperClassVo.getExamid());
                eRclassPoint.setClassid(classid);
                eRclassPoint.setEpid(examPaperClassVo.getEpid());
                eRclassPoint.setSubjectid(examPaperClassVo.getSubjectid());
                eRclassPoint.setPointid(pointid);
                eRclassPoint.setPointname(pointname);
                eRclassPoint.setScore(pointscore);
                eRclassPoint.setSrate(pointrate);
                eRclassPoint.setGradescore(gstuscore);
                eRclassPoint.setGradeavgscore(gavgscore);
                eRclassPoint.setGradesrate(gsrate);
                eRclassPoint.setClassscore(cstuscore);
                eRclassPoint.setClassavgscore(cavgscore);
                eRclassPoint.setClasssrate(csrate);
                eRclassPoint.setQns(orderstr);
                cpointlist.add(eRclassPoint);

                // 遍历单个学生
                for (ERPointStuScoreVo stu : classpointstulistZero) {
                    ERstudentPoint erstupoint = new ERstudentPoint();
                    erstupoint.setExamid(examPaperClassVo.getExamid());
                    erstupoint.setSubjectid(examPaperClassVo.getSubjectid());
                    erstupoint.setEpid(examPaperClassVo.getEpid());
                    erstupoint.setStudentid(stu.getStudentid());
                    erstupoint.setClassid(classid);
                    erstupoint.setPointid(pointid);
                    erstupoint.setPointname(pointname);
                    erstupoint.setStuscore(stu.getStuscore());
                    erstupoint.setStusrate(N_Utils.getDoubleDivideAndMulitiply(stu.getStuscore(), pointscore));
                    stupointlist.add(erstupoint);
                }
            }
        }
    }

    // 题型、试题、知识点、难易度--知识点:设置每个学生每个试题知识点得分
    private void setEPaperQuestionPointsForStuQues(List<ERPointStuScoreVo> gradestulist, EPaperStudentQuestion sq, List<Map> points, String eptqids) {
        if (points.size() == 1) {
            Map pointmap = points.get(0);
            // 说明该试题仅有一个知识点得分直接为改知识点分值
            ERPointStuScoreVo pscvo = new ERPointStuScoreVo();
            pscvo.setStupaperscore(sq.getStupaperscore());
            pscvo.setClassid(sq.getClassid());
            pscvo.setStudentid(sq.getStudentid());
            pscvo.setStuscore(sq.getStuscore());
            String pointid = pointmap.get("pointid").toString();
            pscvo.setPointid(pointid);
            pscvo.setEptqids(eptqids);
            gradestulist.add(pscvo);
        } else {
            // 计算每个知识点所占分值（平均分配）
            Double[] avgps = N_Utils.getPointAvgScore(points.size(), sq.getStuscore());
            for (int j = 0; j < points.size(); j++) {
                Map pointmap = points.get(j);
                ERPointStuScoreVo pscvo = new ERPointStuScoreVo();
                pscvo.setStupaperscore(sq.getStupaperscore());
                pscvo.setClassid(sq.getClassid());
                pscvo.setStudentid(sq.getStudentid());
                String pointid = pointmap.get("pointid").toString();
                pscvo.setPointid(pointid);
                pscvo.setEptqids(eptqids);
                if (avgps.length == 2 && (j + 1) == points.size()) {
                    pscvo.setStuscore(avgps[1]);
                } else {
                    pscvo.setStuscore(avgps[0]);
                }

                gradestulist.add(pscvo);
            }
        }
    }

    // 题型、试题、知识点、难易度--难易度
    private void setEPaperQuestionComplexitys(List<Map> complexitylist, List<EPaperStudentQuestion> paperstulist, List<ERclassComplexity> complist,
                                              List<ERStudentComplexity> stucomplist, ExamPaperClassVo examPaperClassVo,Integer stuzero) {
        List<Map> classes = examPaperClassVo.getClasses();
        for (Map compmap : complexitylist) {
            Integer complexity = Integer.parseInt(compmap.get("level").toString());
            Double score = Double.parseDouble(compmap.get("score").toString());// 难易度下试题总分值
            Double srate = Double.parseDouble(compmap.get("srate").toString());// 难易度下试题分值占比
            List<Map> queslist = (List<Map>) compmap.get("ques");// 试题相关对象（数量为几个代表几个母题）

            String qns = "";
            List<Integer> leveleptqids = new ArrayList<>();// 所有试题id
            for (Map quesmap : queslist) {
                List<Integer> eptqids = (List<Integer>) quesmap.get("eptqids");
                String order = quesmap.get("order").toString();// 试题母题题号
                qns = qns + order + ",";
                leveleptqids.addAll(eptqids);
            }

            List<EPaperStudentQuestion> levelstuquelist = new ArrayList<>();// 难易度下所有试题
            for (Integer eptqid : leveleptqids) {
                List<EPaperStudentQuestion> petqqueslit = paperstulist.stream().filter(s -> eptqid.equals(s.getEptqid())).collect(Collectors.toList());
                levelstuquelist.addAll(petqqueslit);
            }

            List<EPaperStudentQuestion> qgstulistZero = new ArrayList<>();// 每个学生难易度下得分
            Map<Integer, List<EPaperStudentQuestion>> stuQuesMap = levelstuquelist.stream().collect(Collectors.groupingBy(EPaperStudentQuestion::getStudentid));
            for (Map.Entry<Integer, List<EPaperStudentQuestion>> entry : stuQuesMap.entrySet()) {
                List<EPaperStudentQuestion> stuqueslist = entry.getValue();
                EPaperStudentQuestion pfirst = stuqueslist.get(0);
                EPaperStudentQuestion pstq = new EPaperStudentQuestion();
                pstq.setStupaperscore(pfirst.getStupaperscore());
                pstq.setStudentid(entry.getKey());
                pstq.setClassid(pfirst.getClassid());
                Double qstuscore = stuqueslist.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
                qstuscore = N_Utils.formatDouble(qstuscore, 1);
                Double qscore = stuqueslist.stream().mapToDouble(EPaperStudentQuestion::getQscore).sum();
                qscore = N_Utils.formatDouble(qscore, 1);
                pstq.setQscore(qscore);
                pstq.setStuscore(qstuscore);
                qgstulistZero.add(pstq);

                ERStudentComplexity stucomp = new ERStudentComplexity();
                stucomp.setStudentid(entry.getKey());
                stucomp.setClassid(pstq.getClassid());
                stucomp.setExamid(examPaperClassVo.getExamid());
                stucomp.setSubjectid(examPaperClassVo.getSubjectid());
                stucomp.setEpid(examPaperClassVo.getEpid());
                stucomp.setComplexity(complexity);
                stucomp.setStuscore(qstuscore);
                stucomp.setStusrate(N_Utils.getDoubleDivideAndMulitiply(qstuscore, qscore));
                stucomplist.add(stucomp);
            }

            List<EPaperStudentQuestion> qgstulist = new ArrayList<>();
            if(stuzero == 0){
                //如果为0：0分学生不参与统计
                qgstulist = qgstulistZero.stream().filter(s -> s.getStupaperscore() > 0).collect(Collectors.toList());
            }else{
                qgstulist.addAll(qgstulistZero);
            }

            Double tgstuscore = 0D;
            Double tgscore = 0D;
            Double tgsrate = 0D;
            Double tgavgscore = 0D;
            if(qgstulist.size() > 0){
                tgstuscore = qgstulist.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();// 难易度下学生得分
                tgstuscore = N_Utils.formatDouble(tgstuscore, 1);
                tgscore = qgstulist.stream().mapToDouble(EPaperStudentQuestion::getQscore).sum();// 难易度下试题总分
                tgscore = N_Utils.formatDouble(tgscore, 1);
                tgsrate = N_Utils.getDoubleDivideAndMulitiply(tgstuscore, tgscore);// 年级得分率
                tgavgscore = N_Utils.getDoubleDivideForAvg(tgstuscore, qgstulist.size());
            }

            for (Map classm : classes) {
                Integer classid = Integer.parseInt(classm.get("classid").toString());
                List<EPaperStudentQuestion> qcstulist = qgstulist.stream().filter(s -> s.getClassid().equals(classid)).collect(Collectors.toList());
                // List<EPaperStudentQuestion> qcstulistZero = qgstulistZero.stream().filter(s -> s.getClassid().equals(classid)).collect(Collectors.toList());
                Double qcscore = 0D;
                Double qcstuscore = 0D;
                Double qcavgscore = 0D;
                Double qcrate = 0D;
                if (N_Utils.isListNotEmpty(qcstulist) && qcstulist.size() > 0) {
                    qcscore = qcstulist.stream().mapToDouble(EPaperStudentQuestion::getQscore).sum();
                    qcscore = N_Utils.formatDouble(qcscore, 1);
                    qcstuscore = qcstulist.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
                    qcstuscore = N_Utils.formatDouble(qcstuscore, 1);
                    qcavgscore = N_Utils.getDoubleDivideForAvg(qcstuscore, qcstulist.size());
                    qcrate = N_Utils.getDoubleDivideAndMulitiply(qcstuscore, qcscore);
                }
                ERclassComplexity erc = new ERclassComplexity();
                erc.setExamid(examPaperClassVo.getExamid());
                erc.setSubjectid(examPaperClassVo.getSubjectid());
                erc.setEpid(examPaperClassVo.getEpid());
                erc.setClassid(classid);
                erc.setComplexity(complexity);
                erc.setScore(score);
                erc.setSrate(srate);
                erc.setGradescore(tgstuscore);
                erc.setGradeavgscore(tgavgscore);
                erc.setGradesrate(tgsrate);
                erc.setClassscore(qcstuscore);
                erc.setClasssrate(qcrate);
                erc.setClassavgscore(qcavgscore);
                erc.setQns(qns.substring(0, qns.lastIndexOf(",")));
                complist.add(erc);
            }
        }
    }

}
