package com.xhkjedu.smarking.service.scan;

import com.xhkjedu.exception.ServiceException;
import com.xhkjedu.smarking.mapper.exam.MsExamMapper;
import com.xhkjedu.smarking.mapper.paper.MsPaperBlockQuestionMapper;
import com.xhkjedu.smarking.mapper.paper.MsTemplateMapper;
import com.xhkjedu.smarking.mapper.scan.MsScanbatchMapper;
import com.xhkjedu.smarking.mapper.scan.MsScanbatchPaperBlockMapper;
import com.xhkjedu.smarking.mapper.scan.MsScanbatchPaperBlockQuestionMapper;
import com.xhkjedu.smarking.mapper.scan.MsScanbatchPaperMapper;
import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentBlockMapper;
import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentMapper;
import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentQuestionMapper;
import com.xhkjedu.smarking.mapper.system.SchoolMapper;
import com.xhkjedu.smarking.mapper.system.UserMapper;
import com.xhkjedu.smarking.model.paper.MsPaperBlockQuestion;
import com.xhkjedu.smarking.model.paper.MsTemplate;
import com.xhkjedu.smarking.model.scan.MsScanbatch;
import com.xhkjedu.smarking.model.scan.MsScanbatchPaper;
import com.xhkjedu.smarking.model.scan.MsScanbatchPaperBlock;
import com.xhkjedu.smarking.model.scan.MsScanbatchPaperBlockQuestion;
import com.xhkjedu.smarking.model.stupaper.MsPaperStudent;
import com.xhkjedu.smarking.model.stupaper.MsPaperStudentBlock;
import com.xhkjedu.smarking.model.stupaper.MsPaperStudentQuestion;
import com.xhkjedu.smarking.utils.MarkingUtil;
import com.xhkjedu.smarking.vo.scan.ScanParams;
import com.xhkjedu.smarking.vo.stupaper.PaperStudentWebVo;
import com.xhkjedu.smarking.vo.system.SchoolCloudVo;
import com.xhkjedu.utils.N_Utils;
import com.xhkjedu.vo.ResultVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 批阅扫描试卷表 服务实现类
 * @Author auto
 * @Date 2024-10-15
 */
@Service
public class MsScanbatchPaperService {
    @Resource
    private MsScanbatchPaperMapper msScanbatchPaperMapper;
    @Resource
    private MsScanbatchPaperBlockMapper msScanbatchPaperBlockMapper;
    @Resource
    private MsScanbatchPaperBlockQuestionMapper msScanbatchPaperBlockQuestionMapper;
    @Resource
    private MsScanbatchMapper msScanbatchMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private MsPaperStudentMapper msPaperStudentMapper;
    @Resource
    private MsPaperStudentQuestionMapper msPaperStudentQuestionMapper;
    @Resource
    private MsPaperStudentBlockMapper msPaperStudentBlockMapper;
    @Resource
    private MsPaperBlockQuestionMapper msPaperBlockQuestionMapper;
    @Resource
    private SchoolMapper schoolMapper;
    @Resource
    private MsTemplateMapper msTemplateMapper;
    @Resource
    private MsExamMapper msExamMapper;

    /*
     * @Description 扫描记录-查看原卷
     * @Date 2024/10/25 17:22:45
     * @Author WN
     * @Param [mspid]
     * @Return java.util.Map<java.lang.String,java.lang.Object>
     **/
    public Map<String,Object> getScanPaperQuestion(Integer mspid){
        Map<String,Object> map = msScanbatchPaperMapper.getScanPaperByMspid(mspid);

        //获取试卷中所有试题
        List<MsScanbatchPaperBlock> blocks = msScanbatchPaperBlockMapper.listBlockQuestions(mspid);

        //获取试卷中客观题
        List<MsScanbatchPaperBlock> objectives = blocks.stream().filter(b -> b.getMsptype() == 1).collect(Collectors.toList());
        map.put("objectives",objectives);
        //获取试卷中主观题
        List<MsScanbatchPaperBlock> subjectives = blocks.stream().filter(b -> b.getMsptype() == 2).collect(Collectors.toList());
        map.put("subjectives",subjectives);

        return map;
    }

    //获取试卷的所有模版信息
    public List<MsTemplate> listTemplates(Integer mpid){
        return msTemplateMapper.listTemplateBlockQueByMpid(mpid);
    }

    /**
     * @Description 新增
     * @Param [msScanbatchPaper]
     * @Author auto
     * @Date 2024-10-15
     **/
    @Transactional(rollbackFor = Exception.class)
    public void savePaperIdentify(MsScanbatchPaper msScanbatchPaper){

        Integer examstate  = msScanbatchMapper.getExamStateByBatchid(msScanbatchPaper.getBatchid());
        if(examstate == 3){
            throw new ServiceException("考试已统分，禁止扫描");
        }

        //更改扫描出错次数
        if(msScanbatchPaper.getHaserror() == 1){
            msScanbatchMapper.updateScannumAndErrornum(msScanbatchPaper.getBatchid());
        }else{
            //保存一次，扫描次数加1
            msScanbatchMapper.updateScannum(msScanbatchPaper.getBatchid());
        }

        Integer timestamp = N_Utils.getSecondTimestamp();
        msScanbatchPaper.setCreatetime(timestamp);

        //获取考号
        String examno = msScanbatchPaper.getExamno();
        //考号不存在，异常信息2考号有误（异常类型1扫描出错 2考号有误 3考号重复 4缺考异常）
        if(N_Utils.isEmpty(examno)){
            msScanbatchPaper.setErrortype(2);
            savePaperBlockQuestions(msScanbatchPaper);
            return;
        }

        //考号存在，获取对应的试卷信息是否有异常，如果有则该条数据也标识为异常,异常信息3考号重复
        Integer errorNum = msScanbatchPaperMapper.getErrorNumByMpidAndExamno(msScanbatchPaper.getMpid(),examno);
        if(errorNum > 0){
            msScanbatchPaper.setErrortype(3);
            savePaperBlockQuestions(msScanbatchPaper);
            return;
        }

        //根据考号获取学生
        Integer userid = userMapper.getUseridByExamno(examno);
        //用户不存在，异常信息2考号有误
        if(!N_Utils.isTrueInteger(userid)){
            msScanbatchPaper.setErrortype(2);
            savePaperBlockQuestions(msScanbatchPaper);
            return;
        }
        //用户存在，获取用户试卷信息
        MsPaperStudent msPaperStudent = msPaperStudentMapper.getPaperStudentByStudentidAndMpid(userid,msScanbatchPaper.getMpid());
        //试卷不存在，异常信息1扫描出错
        if(msPaperStudent == null){
            msScanbatchPaper.setErrortype(1);
            savePaperBlockQuestions(msScanbatchPaper);
            return;
        }
        //试卷存在，判断学生是否已绑定扫描试卷信息，已有保存扫描信息本次异常，异常信息3考号重复
        if(N_Utils.isTrueInteger(msPaperStudent.getMspid())){
            msScanbatchPaper.setErrortype(3);
            savePaperBlockQuestions(msScanbatchPaper);
            //处理上一次对应扫描试卷为3考号重复，并清空学生试卷试题信息
            msScanbatchPaperMapper.updatePaperErrortype(msPaperStudent.getMspid(),3);
            updatePaperStudentQuestion(msPaperStudent);
            return;
        }

        //保存扫描信息
        savePaperBlockQuestions(msScanbatchPaper);
        //学生试卷信息
        int answernum = saveStudentBlockQuestions(msScanbatchPaper,msPaperStudent.getMpsid());
        if (!N_Utils.isEmptyInteger(msScanbatchPaper.getMissexam()) && msScanbatchPaper.getMissexam() == 1 && answernum>0) {//缺考
            //如果标记考试缺考，且答题数量大于0属于异常,异常信息4缺考异常
            msScanbatchPaper.setErrortype(4);
            //修改扫描信息
            msScanbatchPaperMapper.updatePaperErrortype(msPaperStudent.getMspid(),4);
        }
    }

    //保存扫描试卷-保存扫描题块试题信息
    private void savePaperBlockQuestions(MsScanbatchPaper msScanbatchPaper){
        //获取学校对应区域码，
        SchoolCloudVo schoolCloudVo = schoolMapper.getSchoolCloudcode(msScanbatchPaper.getMpid());
        String saveFloder = schoolCloudVo.getCloudcode() + "/" + schoolCloudVo.getSchoolid() + "/marking/scan";

        String paperfront = MarkingUtil.uploadBase64Img(msScanbatchPaper.getPaperfront(),1,saveFloder);
        if(N_Utils.isNotEmpty(paperfront)){
            msScanbatchPaper.setPaperfront(paperfront);
        }
        String paperback = MarkingUtil.uploadBase64Img(msScanbatchPaper.getPaperback(),1,saveFloder);
        if(N_Utils.isNotEmpty(paperback)){
            msScanbatchPaper.setPaperback(paperback);
        }
        String examnopic = MarkingUtil.uploadBase64Img(msScanbatchPaper.getExamnopic(),1,saveFloder);
        if(N_Utils.isNotEmpty(examnopic)){
            msScanbatchPaper.setExamnopic(examnopic);
        }

        msScanbatchPaperMapper.insertUseGeneratedKeys(msScanbatchPaper);

        Integer mspid = msScanbatchPaper.getId();
        msScanbatchPaper.setMspid(mspid);

        //保存试题
        List<MsScanbatchPaperBlock> spblocks = msScanbatchPaper.getSpblocks();
        for (MsScanbatchPaperBlock spblock : spblocks) {
            spblock.setMspid(mspid);
            spblock.setBatchid(msScanbatchPaper.getBatchid());

            //题块多图片合并比一张图片
            String rtnBlock = MarkingUtil.uploadBase64Img(spblock.getPicpath(),2,saveFloder);
            spblock.setPicpath(rtnBlock);

            //题块多图片合并比一张图片
            String extendBlock = MarkingUtil.uploadBase64Img(spblock.getExtendpath(),2,saveFloder);
            spblock.setExtendpath(extendBlock);
        }

        msScanbatchPaperBlockMapper.insertList(spblocks);
        List<MsScanbatchPaperBlockQuestion> saveQuestions = new ArrayList<>();
        for (MsScanbatchPaperBlock spblock : spblocks) {
            Integer spbid = spblock.getId();

            List<MsScanbatchPaperBlockQuestion> spbquestions = spblock.getSpbquestions();
            if(spbquestions!= null && !spbquestions.isEmpty()){
                for (MsScanbatchPaperBlockQuestion spbquestion : spbquestions) {
                    spbquestion.setMspbid(spbid);
                    saveQuestions.add(spbquestion);
                }
            }
        }
        if(N_Utils.isListNotEmpty(saveQuestions)){
            msScanbatchPaperBlockQuestionMapper.insertList(saveQuestions);
        }
        //更改识别数量
        msScanbatchMapper.updateIdentifynum(msScanbatchPaper.getBatchid());
    }

    //保存扫描试卷-清空学生试卷题块试题信息
    private void updatePaperStudentQuestion(MsPaperStudent msPaperStudent){
        Integer mspid = msPaperStudent.getMspid();
        //清空学生题块、试题 作答信息及批阅信息
        msPaperStudentBlockMapper.updateStudentBlockQuestionByMpsid(mspid);

        //清空学生试卷信息
        MsPaperStudent ps = new MsPaperStudent();
        ps.setBatchid(null);
        ps.setMspid(null);
        ps.setSstate(0);
        ps.setStuscore(0.0);
        ps.setStuscoretype(0);
        ps.setHasbad(0);
        ps.setPaperfront(null);
        ps.setPaperback(null);
        ps.setPagenum(0);
        ps.setMpsid(msPaperStudent.getMpsid());

        msPaperStudentMapper.updateByPrimaryKeySelective(ps);
    }

    //保存扫描试卷-保存学生试卷题块信息
    private int saveStudentBlockQuestions(MsScanbatchPaper msScanbatchPaper,Integer mpsid){
        int rtnanswernum;//试题数量

        //扫描试卷中切割题块
        List<MsScanbatchPaperBlock> spblocks = msScanbatchPaper.getSpblocks();

        //学生题块试题信息
        List<MsPaperStudentBlock> paperQuestions =msPaperStudentBlockMapper.listPaperStuBlockQuestions(mpsid);
        //扫描的题块数量和学生试题题块数量不一致
        if(spblocks.size() != paperQuestions.size()){
            return -1;
        }

        double stuPaperScore = 0.0;//学生试卷得分
        List<MsPaperStudentBlock>  saveBlockList = new ArrayList<>();// 保存学生题块信息
        List<MsPaperStudentQuestion> saveQuesList = new ArrayList<>();//保存学生提交试题
        Integer timestamp = N_Utils.getSecondTimestamp();

        //获取原试卷题块下所有试题
        List<MsPaperBlockQuestion> blockQuestions = msPaperBlockQuestionMapper.listQuestionsByMpid(mpsid);

        for(MsScanbatchPaperBlock spblock : spblocks){
            String picPath = spblock.getPicpath();
            MsPaperStudentBlock studentBlock = paperQuestions.stream().filter(b -> b.getMblockid().equals(spblock.getMblockid())).findFirst().orElse(null);
            assert studentBlock != null;
            studentBlock.setStuanswer(picPath);

            List<MsPaperStudentQuestion> stuQuestions = studentBlock.getQuestions();//学生试题
            List<MsScanbatchPaperBlockQuestion> spbquestions = spblock.getSpbquestions();//扫描题块下试题
            if(studentBlock.getBlocktype() == 1){
                //说明是客观题题块,需要自动批改
                for(MsScanbatchPaperBlockQuestion spbquestion : spbquestions) {
                    //获取试题对应题块下试题值（为了获取题块下试题对应的原试卷试题ID）
                    MsPaperBlockQuestion blockQuestion = blockQuestions.stream().filter(q -> q.getMptqid().equals(spbquestion.getMptqid())).findFirst().orElse(null);
                    //试题答案
                    MsPaperStudentQuestion queAnswer = stuQuestions.stream().filter(q -> {
                        assert blockQuestion != null;
                        return q.getMptqid().equals(blockQuestion.getMptqid());
                    }).findFirst().orElse(null);
                    if(queAnswer == null){
                        throw new RuntimeException("学生试题信息有误");
                    }

                    String identifycont = spbquestion.getIdentifycont();

                    //扫描结果
                    MsPaperStudentQuestion stuQuestion = new MsPaperStudentQuestion();
                    stuQuestion.setStuanswer(identifycont);
                    stuQuestion.setMpsid(mpsid);
                    stuQuestion.setMblockid(spblock.getMblockid());
                    stuQuestion.setAnswertime(timestamp);
                    stuQuestion.setAnswertype(1);
                    stuQuestion.setMptqid(spbquestion.getMptqid());
                    queAnswer.setStuanswer(identifycont);
                    checkObjectiveQuestion(queAnswer);//客观题自动批阅
                    stuQuestion.setStuscore(queAnswer.getStuscore());
                    stuQuestion.setAnswered(queAnswer.getAnswered());
                    stuQuestion.setChecked(3);//客观题自动批阅
                    stuQuestion.setFirstccore(queAnswer.getStuscore());
                    stuQuestion.setFirstcime(queAnswer.getFirstcime());
                    stuPaperScore = MarkingUtil.add(stuPaperScore, stuQuestion.getStuscore());

                    saveQuesList.add(stuQuestion);
                }
                studentBlock.setChecked(3);
            }else{
                //主观题
                for(MsPaperStudentQuestion stuQuestion : stuQuestions){
                    stuQuestion.setMpsid(mpsid);
                    stuQuestion.setMblockid(spblock.getMblockid());
                    stuQuestion.setStuanswer(picPath);
                    stuQuestion.setAnswertype(2);
                    stuQuestion.setAnswered(1);
                    stuQuestion.setChecked(1);
                    stuQuestion.setAnswertime(timestamp);
                    saveQuesList.add(stuQuestion);
                }
                studentBlock.setChecked(1);
            }
            saveBlockList.add(studentBlock);
        }

        //处理试卷信息
        MsPaperStudent msPaperStudent = new MsPaperStudent();
        msPaperStudent.setMpsid(mpsid);
        msPaperStudent.setEndtime(timestamp);
        msPaperStudent.setBatchid(msScanbatchPaper.getBatchid());
        msPaperStudent.setMspid(msScanbatchPaper.getMspid());
        msPaperStudent.setCosttime(0);
        msPaperStudent.setPaperfront(msScanbatchPaper.getPaperfront());
        msPaperStudent.setPaperback(msScanbatchPaper.getPaperback());
        msPaperStudent.setPagenum(msScanbatchPaper.getBatchorder());
        msPaperStudent.setStuscore(stuPaperScore);
        msPaperStudent.setStuscoretype(1);
        if(msScanbatchPaper.getMissexam() == 1){
            //缺考
            msPaperStudent.setSstate(3);//状态0未进场1已进场2已交卷3缺考
        }else{
            msPaperStudent.setSstate(2);//状态0未进场1已进场2已交卷3缺考
        }
        if(msScanbatchPaper.getViolated() == 1){
            msPaperStudent.setHasbad(1);
        }

        //批量修改试卷题块、试题信息
        msPaperStudentBlockMapper.updateBatchStuBlock(saveBlockList);
        msPaperStudentQuestionMapper.updateBatchStuAnswerForScan(saveQuesList);
        msPaperStudentMapper.updateByPrimaryKeySelective(msPaperStudent);

        if(msScanbatchPaper.getMissexam() == 1){
            msScanbatchMapper.updateQknum(msScanbatchPaper.getBatchid());//更改缺考数量
        }
        if(msScanbatchPaper.getViolated() == 1){
            msScanbatchMapper.updateWgnum(msScanbatchPaper.getBatchid());//更改违规数量
        }

        rtnanswernum = saveQuesList.size();

        return rtnanswernum;
    }

    /*
     * @Description 客观题自动批阅（扫描）
     * @Date 2024/10/29 10:34:54
     * @Author WN
     * @Param [stuQuestion 学生作答, queAnswer 试题答案]
     * @Return void
     **/
    private void checkObjectiveQuestion(MsPaperStudentQuestion stuQuestion){
        String stuAnswer = stuQuestion.getStuanswer();
        Double stuScore = 0D;
        Integer timestamp = N_Utils.getSecondTimestamp();

        //学生答案为空时
        if(N_Utils.isEmpty(stuAnswer)){
            stuQuestion.setAnswered(0);
            stuQuestion.setStuanswer(null);
            stuQuestion.setStuscore(stuScore);
            stuQuestion.setFirstcime(timestamp);
        }else{
            int ctype = stuQuestion.getCtype();
            //试卷设置了正确答案
            if(stuQuestion.getHasanswer()!=null && stuQuestion.getHasanswer() == 1){
                //如果试题进行了得分设置，则直接进行分值处理(分值设置0默认1送分题 20分题)
                Integer scoreset = stuQuestion.getScoreset();
                if(N_Utils.isTrueInteger(scoreset)){
                    if(scoreset == 1){
                        stuScore = stuQuestion.getQscore();
                    }
                }else{
                    stuScore = MarkingUtil.checkObjectiveStuAnswer(stuAnswer, ctype,stuQuestion.getQanswer(),stuQuestion.getLoseoption(),stuQuestion.getQscore());
                }

                stuQuestion.setFirstcime(timestamp);
            }

            stuQuestion.setStuscore(stuScore);
            stuQuestion.setAnswered(1);
        }
        stuQuestion.setChecked(3);//批阅状态0默认1待批阅2批阅中3已批阅
    }

    /*
     * @Description 扫码记录-查看原卷-客观题-保存答案
     * @Date 2024/11/7 17:08:20
     * @Author WN
     * @Param [msScanbatchPaperBlock]
     * @Return com.xhkjedu.vo.ResultVo
     **/
    @Transactional(rollbackFor = Exception.class)
    public ResultVo updateObjectiveQuestionAnswer(MsScanbatchPaperBlock msScanbatchPaperBlock){
        String identifycont = msScanbatchPaperBlock.getIdentifycont();//识别结果
        List<String> identifycontList = MarkingUtil.extractCharacters(identifycont);
        //获取该题块下所有单题
        Integer mspid = msScanbatchPaperBlock.getMspid();
        Integer mblockid = msScanbatchPaperBlock.getMblockid();
        List<MsScanbatchPaperBlockQuestion> spbquestions = msScanbatchPaperBlockQuestionMapper.listBlockQuestionsByMspid(mspid,mblockid);

        if(identifycontList.size() != spbquestions.size()){
            return new ResultVo(1,"识别结果和试题数量不一致");
        }

        //获取试卷题块对应已保存学生答案
        List<MsPaperStudentQuestion> stuQuestions = msPaperStudentQuestionMapper.listStuQuestionsByMspidAnbBlockid(mspid,mblockid);
        boolean hasstu = stuQuestions != null && !stuQuestions.isEmpty();

        List<MsPaperStudentQuestion> upStuQuestions = new ArrayList<>();//需要更改正确答案的学生试题
        Integer timestamp = N_Utils.getSecondTimestamp();
        for (int i = 0; i < spbquestions.size(); i++) {
            MsScanbatchPaperBlockQuestion spbquestion = spbquestions.get(i);
            String qidentify = identifycontList.get(i);
            if ("-".equals(qidentify)) {
                qidentify = null;
            }
            spbquestion.setIdentifycont(qidentify);

            if(hasstu){
                //获取答案
                MsPaperStudentQuestion stuQuestion = stuQuestions.stream().filter(q -> q.getMptqid().equals(spbquestion.getMptqid())).findFirst().orElse(null);
                if(stuQuestion!=null &&N_Utils.isNotEmpty(qidentify) && N_Utils.isNotEmpty(stuQuestion.getStuanswer()) && !qidentify.equals(stuQuestion.getStuanswer())){
                    //如果识别结果和学生答案都不为空且不相等，则更改学生答案
                    stuQuestion.setStuanswer(qidentify);
                    checkObjectiveQuestion(stuQuestion);
                    stuQuestion.setFirstccore(stuQuestion.getStuscore());
                    stuQuestion.setFirstcime(timestamp);
                    upStuQuestions.add(stuQuestion);
                }
            }
        }

        msScanbatchPaperBlockMapper.updateByPrimaryKeySelective(msScanbatchPaperBlock);
        msScanbatchPaperBlockQuestionMapper.updateBatchQuestionIdentify(spbquestions);
        if(!upStuQuestions.isEmpty()){
            msPaperStudentQuestionMapper.updateBatchStuAnswerForScan(upStuQuestions);
        }

        return new ResultVo(0,"保存成功");
    }

    /*
     * @Description 扫描异常-异常数量
     * @Date 2024/11/8 15:59:23
     * @Author WN
     * @Param [mpid, batchid]
     * @Return java.util.Map<java.lang.String,java.lang.Object>
     **/
    public Map<String,Object> getScanErrorNum(Integer mpid,Integer batchid){
        Map<String,Object> map = new HashMap<>();

        List<MsScanbatch> batchList = msScanbatchPaperMapper.getScanErrorNum(mpid);
        MsScanbatch msScanbatch = batchList.stream().filter(b -> b.getBatchid().equals(batchid)).findFirst().orElse(null);
        Integer batchnum = 0;
        if(msScanbatch!= null){
            batchnum = msScanbatch.getScannum();
        }
        map.put("batchnum",batchnum);
        int totalnum = batchList.stream().mapToInt(MsScanbatch::getScannum).sum();
        map.put("totalnum",totalnum);
        return map;
    }


    /*
     * @Description 扫描异常-异常列表
     * @Date 2024/11/8 15:09:39
     * @Author WN
     * @Param [msScanbatchPaper]
     * @Return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     **/
    public List<Map<String,Object>> listScanPaperErrors(MsScanbatchPaper msScanbatchPaper){
        return msScanbatchPaperMapper.listScanPaperErrors(msScanbatchPaper);
    }

    /*
     * @Description 扫描异常-异常列表-数量
     * @Date 2024/11/11 10:29:09
     * @Author WN
     * @Param [mpid]
     * @Return java.util.Map<java.lang.String,java.lang.Object>
     **/
    public Map<String,Object> listScanPaperErrorNum(Integer mpid){
        return msScanbatchPaperMapper.listScanPaperErrorsNum(mpid);
    }

    /*
     * @Description 扫描异常-更改状态
     * @Date 2024/11/8 15:28:47
     * @Author WN
     * @Param [mspid, msstate]
     * @Return void
     **/
    public void updateScanPaperMsstate(Integer mspid,Integer msstate){
        msScanbatchPaperMapper.updateScanPaperMsstate(mspid,msstate);
    }

    /*
     * @Description 扫描异常-已删除数量
     * @Date 2024/11/8 15:37:45
     * @Author WN
     * @Param [mpid]
     * @Return int
     **/
    public int getDelScanPaperCount(Integer mpid){
        return msScanbatchPaperMapper.getDeleteScanPaperCount(mpid);
    }

    /*
     * @Description 扫描异常--考号异常确认
     * @Date 2024/11/8 17:35:12
     * @Author WN
     * @Param [psWebVo]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void updateExamnoConfirm(PaperStudentWebVo psWebVo) throws Exception{
        //判断新考号情况
        chandleExamnoConfirm(psWebVo);
        //标记要确认的信息为已处理
        msScanbatchPaperMapper.updateScanPaperMsstateAndExamno(psWebVo.getMspid(),2,psWebVo.getExamno());
    }

    //扫描异常-考确认新考号
    private void chandleExamnoConfirm(PaperStudentWebVo psWebVo) throws Exception{
        //根据考号获取用户id
        Integer userid = userMapper.getUseridByExamno(psWebVo.getExamno());
        if(!N_Utils.isTrueInteger(userid)){
            throw new Exception("考号对应学生不存在");
        }

        //获取学生试卷
        MsPaperStudent msPaperStudent = msPaperStudentMapper.getPaperStudentByStudentidAndMpid(userid,psWebVo.getMpid());
        //如果新考号对应学生已有扫描信息，标记要处理的扫描试卷和新考号学生都为考号重复；异常类型1扫描出错 2考号有误 3考号重复 4缺考异常
        if(N_Utils.isTrueInteger(msPaperStudent.getMspid())){
            msScanbatchPaperMapper.updatePaperErrortype(psWebVo.getMspid(),3);//更改要处理的数据为3考号重复

            //标记确认考号对应学生扫描试卷信息为3考号重复
            msScanbatchPaperMapper.updatePaperErrortype(msPaperStudent.getMspid(),3);
            Integer mpsid = msPaperStudent.getMpsid();
            //清空试卷信息
            msPaperStudentMapper.updateStuPaperForScanErrorClear(mpsid);
            //清空试卷题块、试题
            msPaperStudentBlockMapper.updateStudentBlockQuestionByMpsid(mpsid);
        }else{
            MsScanbatchPaper msScanbatchPaper = msScanbatchPaperMapper.selectByPrimaryKey(psWebVo.getMspid());
            List<MsScanbatchPaperBlock> blocks = msScanbatchPaperBlockMapper.listBlockQuestions(psWebVo.getMspid());
            msScanbatchPaper.setSpblocks(blocks);

            //学生试卷信息
            int answernum = saveStudentBlockQuestions(msScanbatchPaper,msPaperStudent.getMpsid());
            if (!N_Utils.isEmptyInteger(msScanbatchPaper.getMissexam()) && msScanbatchPaper.getMissexam() == 1 && answernum>0) {//缺考
                //如果标记考试缺考，且答题数量大于0属于异常,异常信息4缺考异常
                msScanbatchPaper.setErrortype(4);
                //修改扫描信息
                msScanbatchPaperMapper.updatePaperErrortype(msPaperStudent.getMspid(),4);
            }
        }
    }

    /*
     * @Description 扫描异常--考号重复确认
     * @Date 2024/11/11 9:35:46
     * @Author WN
     * @Param [psWebVo]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void updateExamnoRepeatConfirm(PaperStudentWebVo psWebVo) throws Exception{
        chandleExamnoConfirm(psWebVo);
        //标记要确认的信息为已处理
        msScanbatchPaperMapper.updateScanPaperMsstate(psWebVo.getMspid(),2);
    }

    /*
     * @Description 扫描异常--缺考异常
     * @Date 2024/11/11 10:10:10
     * @Author WN
     * @Param [list]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void updateMissExamConfirm(List<PaperStudentWebVo> list){
        List<MsPaperStudent> pslist = new ArrayList<>();//保存需要设置为非缺考学生
        for(PaperStudentWebVo psWebVo : list){
            MsPaperStudent msPaperStudent = new MsPaperStudent();
            msPaperStudent.setMspid(psWebVo.getMspid());
            msPaperStudent.setSstate(2);
            msPaperStudent.setMpid(psWebVo.getMpid());
            pslist.add(msPaperStudent);
            psWebVo.setMspstate(2);
        }

        //更改缺考学生为正常考试
        msPaperStudentMapper.updateBatchStuPaperSstate(pslist);
        //更改扫描信息里异常为已处理
        msScanbatchPaperMapper.updateBatchScanPaperMspstate(list);
    }

    @Transactional(rollbackFor = Exception.class)
    public void reIdentifyPaper(ScanParams param) {
        Integer examstate  = msExamMapper.getExamstate(param.getExamid());
        if(examstate >= 3){
            throw new ServiceException("考试已统分，禁止重新识别");
        }

        Integer mpid = param.getMpid();
        //获取符合条件的需要重新识别的试卷
        List<MsScanbatchPaper> scanbatchPapers = msScanbatchPaperMapper.listScanPapersForReidentify(param);
        if(scanbatchPapers.isEmpty()) return;

        //获取考试对应的试卷模板及坐标信息
        List<MsTemplate> templates = msTemplateMapper.listTemplateBlockQueByMpid(mpid);
        if(templates.isEmpty()) throw new ServiceException("该考试未设置试卷模板");

        //清空学生题块试题信息和学生试卷扫描识别信息
        msPaperStudentMapper.updateStudentBlockQuestionForReIdentify(param);
        //清空符合条件的需要从新识别的试卷的识别信息
        msScanbatchPaperMapper.deleteScanPaperForReidentify(param);
    }

    private void chandleIdentifyPaper(List<MsScanbatchPaper> scanbatchPapers,List<MsTemplate> templates){
        MsTemplate template = getPaperTemplate(scanbatchPapers,templates);//试卷模板
        for(MsScanbatchPaper scanbatchPaper : scanbatchPapers){

        }
    }
    //重新识别-试卷模板
    private MsTemplate getPaperTemplate(List<MsScanbatchPaper> scanbatchPapers,List<MsTemplate> templates){
        MsTemplate template = null;//试卷模板
        if(templates.size() == 1){
            template = templates.get(0);
        }else{
            MsScanbatchPaper firstPaper = scanbatchPapers.get(0);
            Integer maxWidth = firstPaper.getTwidth() + 30;
            Integer minWidth = firstPaper.getTwidth() - 30;
            for(MsTemplate t : templates){
                if(t.getTwidth() >= minWidth && t.getTwidth() <= maxWidth){
                    template = t;
                    break;
                }
            }
        }
        return template;
    }



}
