package com.xhkjedu.sstudy.service.paperstudent;

import com.alibaba.fastjson.JSON;
import com.xhkjedu.constant.PlatformConstant;
import com.xhkjedu.sstudy.mapper.paper.PaperMapper;
import com.xhkjedu.sstudy.mapper.paper.PaperScantronMapper;
import com.xhkjedu.sstudy.mapper.paperstudent.*;
import com.xhkjedu.sstudy.mapper.question.QuestionMapper;
import com.xhkjedu.sstudy.model.paper.TPaper;
import com.xhkjedu.sstudy.model.paper.TPaperScantron;
import com.xhkjedu.sstudy.model.paperstudent.*;
import com.xhkjedu.sstudy.model.question.TQuestion;
import com.xhkjedu.sstudy.service.system.NoticeService;
import com.xhkjedu.sstudy.utils.ArithUtil;
import com.xhkjedu.sstudy.utils.ConvertUtil;
import com.xhkjedu.sstudy.utils.StudyUtil;
import com.xhkjedu.sstudy.vo.paperreport.PaperRQuestionVo;
import com.xhkjedu.sstudy.vo.paperstudent.*;
import com.xhkjedu.utils.N_Utils;
import com.xhkjedu.vo.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

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

/**
 * @author ywx
 * @classname PaperStudentService
 * @description
 * @date 2020/6/10 10:50
 **/
@Service
@Slf4j
public class PaperStudentService {
    @Resource
    private PaperStudentMapper paperStudentMapper;
    @Resource
    private PaperStudentQuestionService paperStudentQuestionService;
    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private PaperClassMapper paperClassMapper;

    @Resource
    private PaperStudentScantronService paperStudentScantronService;
    @Resource
    private PaperScantronMapper paperScantronMapper;
    @Resource
    private PaperStudentQuestionMapper paperStudentQuestionMapper;
    @Resource
    private PaperStudentScantronMapper paperStudentScantronMapper;
    @Resource
    private PaperMapper paperMapper;
    @Resource
    private PaperStudentBackMapper paperStudentBackMapper;
    @Resource
    private NoticeService noticeService;
    @Resource
    private ConvertUtil convertUtil;


    //获取详情
    public TPaperStudent findById(Integer psid) {
        return paperStudentMapper.findById(psid);
    }

    //获取列表
    public List<PaperStudentVo> findAll(PaperSearchVo paperSearch) {
        Integer timestamp = N_Utils.getSecondTimestamp();
        paperSearch.setNowtime(timestamp);
        return paperStudentMapper.findAll(paperSearch);
    }

    /**
     * 学生开始做作业
     * @Param [psid]
     * @Author ywx
     * @Date 2020/6/10 15:56
     * @return java.lang.Integer
     **/
    public synchronized List<PaperStudentQuestionVo> startPaper(Integer psid) {
        StudentPaperVo paper = paperStudentMapper.getStudentPaperTypeAndQuestionIds(psid);
        List<PaperStudentQuestionVo> paperQuestionBeans = getPaperQuestionNoAnswer(psid);
        //2023-04-25
        if (paperQuestionBeans.size() <= 0){
            List<TPaperStudentQuestion> savelist = new ArrayList<>();
            //作业中的所有试题集合
            List<TPaperStudentQuestion> list = paperStudentQuestionMapper.listPaperQuestion(psid);

            if(paper.getPapertype() == 1){
                savelist.addAll(list);
            }else if(paper.getPapertype() == 3){
                //靶向作业中学生试题id集合
                List<String> stuids = JSON.parseArray(paper.getQuestionids(),String.class);

                //学生作业id
                List<TPaperStudentQuestion> stuques = list.stream().filter(
                        (pq) -> stuids.stream().collect(Collectors.toList()).contains(pq.getQuestionpid())).collect(Collectors.toList());

                if(N_Utils.isListNotEmpty(stuques)) savelist.addAll(stuques);
            }

            if(N_Utils.isListNotEmpty(savelist)) paperStudentQuestionMapper.batchSave(savelist);
            paperQuestionBeans = getPaperQuestionNoAnswer(psid);
        }
        updateState(null,null,psid,1);

        return paperQuestionBeans;
    }

    /**
     * 获取学生作业详情
     * @Param [psid]
     * @Author ywx
     * @Date 2020/6/10 15:52
     * @return java.util.List<com.xhkjedu.vo.paperstudent.PaperStudentQuestionVo>
     **/
    public List<PaperStudentQuestionVo> getPaperQuestion(Integer psid) {
        List<PaperStudentQuestionVo> list = paperStudentQuestionMapper.getPaperQuestion(psid);
        for (PaperStudentQuestionVo q : list) {
            String mqstem = q.getMqstem();
            if (N_Utils.isNotEmpty(mqstem)) {
                PaperStudentQuestionVo mt = JSON.parseObject(mqstem, PaperStudentQuestionVo.class);
                q.setMqstem(mt.getQstem());
                q.setMqoption(mt.getQoption());
                q.setMqanswer(mt.getQanswer());
                q.setMqanalyze(mt.getQanalyze());
                q.setMqtypename(mt.getQtypename());
                q.setMhashear(mt.getHashear());
                q.setMhearfile(mt.getHearfile());
                q.setMqlevel(mt.getQlevel());
                q.setMctype(mt.getCtype());
            }
        }
        return list;
    }

    /**
     * @Description 获取学生作业详情（无答案）
     * @Param [psid]
     * @Author ywx
     * @Date 2023/6/26 17:37
     * @return java.util.List<com.xhkjedu.sstudy.vo.paperstudent.PaperStudentQuestionVo>
     **/
    public List<PaperStudentQuestionVo> getPaperQuestionNoAnswer(Integer psid) {
        List<PaperStudentQuestionVo> list = paperStudentQuestionMapper.getPaperQuestionNoAnswer(psid);
        for (PaperStudentQuestionVo q : list) {
            String mqstem = q.getMqstem();
            if (N_Utils.isNotEmpty(mqstem)) {
                PaperStudentQuestionVo mt = JSON.parseObject(mqstem, PaperStudentQuestionVo.class);
                q.setMqstem(mt.getQstem());
                q.setMqoption(mt.getQoption());
                q.setMqtypename(mt.getQtypename());
                q.setMhashear(mt.getHashear());
                q.setMhearfile(mt.getHearfile());
                q.setMqlevel(mt.getQlevel());
                q.setMctype(mt.getCtype());
            }
        }
        return list;
    }

    /**
     * 获取学生待批改试题列表
     * @Param [psid]
     * @Author ywx
     * @Date 2020/6/26 13:21
     * @return java.util.List<com.xhkjedu.vo.paperstudent.PaperStudentQuestionVo>
     **/
    public List<PaperStudentQuestionVo> listCorrectQuestion(Integer psid) {
        return paperStudentQuestionService.listCorrectQuestion(psid);
    }

    /**
     * 更新学生作业提交、批改状态
     * @Param [psstate, pschecked, psid, operate]
     * @Author ywx
     * @Date 2020/6/10 15:54
     * @return java.lang.Integer
     **/
    public Integer updateState(Integer psstate, Integer pschecked, Integer psid, Integer operate){
        Integer timestamp = N_Utils.getSecondTimestamp();
        return paperStudentMapper.updateState(psstate, pschecked, psid, operate,timestamp);
    }

    public ResultVo submitQuestion(TPaperStudentQuestion psq) {
        try {
            //获取作业学生试题详情
            TPaperStudentQuestion psq1 = paperStudentQuestionService.findById(psq.getPsqid());
            if (psq1 == null) throw new Exception("该学生作业不存在");
            ResultVo vo = checkPsStateByPsId(psq1.getPsid());//根据学生作业id校验提交状态
            if (vo != null) return vo;
//获取试题详情
            TQuestion questionBean = questionMapper.selectByPrimaryKey(psq1.getQuestionid());
            psq.setChecked(0);
            psq.setAnswertime(N_Utils.getSecondTimestamp());
            //判断是否作答1.提交但未作答设置零分，2.作答设置答题状态为2，3.选择题提交为空判错入错题库
            String useranswer = psq.getUseranswer();
            String useranswertxt = psq.getUseranswertxt();
            List<String> userAnswers = JSON.parseArray(useranswer, String.class);
            String qanswer = questionBean.getQanswer();
            List<String> qanswers = JSON.parseArray(qanswer, String.class);
            //计算用户得分
            Double userScore = 0.0;
            Integer converted = 1;//是否转换0未转换1已转换2转换失败
            if (N_Utils.isEmpty(useranswer) && N_Utils.isListEmpty(userAnswers)
                    && N_Utils.isEmpty(useranswertxt)) {
                psq.setStuscore(userScore);
                psq.setChecked(1);
                psq.setCheckid(0);
                psq.setChecktime(N_Utils.getSecondTimestamp());
                psq.setAnswered(0);
            } else {
                psq.setAnswered(1);
                if(psq.getAnswertype() != 2){
                    //自动批改判断得分
                    Integer ctype = questionBean.getCtype();
                    if (N_Utils.isObjectiveQuestion(ctype)) {
                        if (ctype == 1) {//单选
                            if (useranswer.equalsIgnoreCase(qanswer)) {
                                userScore = psq1.getQscore();
                            }
                        } else if (ctype == 2) {//多选
                            //多选不得分,或者选错不得分，不用处理
                            if (userAnswers.get(0).length() <= questionBean.getQanswer().length()){
                                String[] qanswerList = qanswers.get(0).split("");
                                String[] userAnswerList = userAnswers.get(0).split("");
                                int rightNum = 0;//选对个数
                                for (String userAnswer : userAnswerList){
                                    int right = 0;
                                    for (String answer : qanswerList){
                                        if (answer.equals(userAnswer)){
                                            right = 1;
                                            rightNum += 1;
                                        }
                                    }
                                    if (right == 0){//选错直接0分，结束循环
                                        rightNum = 0;
                                        break;
                                    }
                                }
                                if (rightNum > 0){//选对计算得分
                                    if (qanswerList.length == rightNum) {//1.全选对满分
                                        userScore = psq1.getQscore();
                                    } else if (qanswerList.length > rightNum) {//2.少选得一半分
                                        userScore = ArithUtil.div(psq1.getQscore(), 2, 1);
                                    }
                                }
                            }
                        } else if (ctype == 4 || ctype == 5 || ctype == 6) {
                            //判断题
                            if (useranswer.equalsIgnoreCase(qanswer)) {
                                userScore = psq1.getQscore();
                            }
                        } else if (ctype == 7 || ctype == 8 || ctype == 10) {//完型填空、阅读理解、任务型阅读
                            //计算每小题分数
                            Double qscore = ArithUtil.div(psq1.getQscore(), qanswers.size());
                            Double userScoreDouble = 0D;
                            for (int i = 0; i < qanswers.size(); i++) {
                                if (qanswers.get(i).equalsIgnoreCase(userAnswers.get(i))) {
                                    userScoreDouble = ArithUtil.add(userScoreDouble, qscore);
                                }
                            }
                            userScore = ArithUtil.round(userScoreDouble, 1);
                        }
                        if (userScore.compareTo(psq1.getQscore()) == 1) {
                            userScore = psq1.getQscore();
                        }
                        psq.setStuscore(userScore);
                        psq.setChecked(1);
                        psq.setCheckid(0);
                        psq.setChecktime(N_Utils.getSecondTimestamp());
                    } else{
                        if(userAnswers.size() > 1){
                            converted = 0;//上传的多张图片设为0未转换
                        }
                        psq.setChecked(0);
                    }
                }else{
                    if(N_Utils.isNotEmpty(useranswertxt)){
                        List<String> useranswertxt_list = JSON.parseArray(useranswertxt,String.class);
                        String useranswertxt_txt = useranswertxt_list.get(0);
                        if(N_Utils.isNotEmpty(useranswertxt_txt)){
                            useranswertxt_txt = N_Utils.strTrim(useranswertxt_txt);
                            if(N_Utils.isNotEmpty(useranswertxt_txt)){
                                psq.setChecked(0);
                                List<String> useranswertxt_list_new = new ArrayList<>();
                                useranswertxt_list_new.add(useranswertxt_txt);
                                psq.setUseranswertxt(JSON.toJSONString(useranswertxt_list_new));
                            }else{
                                psq.setChecked(1);
                                psq.setUseranswertxt("[\"\"]");
                            }
                        }else{
                            psq.setChecked(1);
                            psq.setUseranswertxt("[\"\"]");
                        }
                    }else{
                        psq.setChecked(1);
                    }
                }
            }
            Integer costtime = psq1.getCosttime();
            if (costtime == null) costtime = 0;
            psq.setCosttime(psq.getCosttime() + costtime);
            psq.setConverted(converted);
            paperStudentQuestionService.update(psq);
//            return updateStuScore(psq1.getPsid());//自动批改单题提交时修改学生总得分
        } catch (Exception e) {
            log.error("提交试题失败："+e.getMessage());
            return new ResultVo(1, "提交失败！");
        }
        return new ResultVo(0, "提交成功！");
    }

    /**
     * 批改完修改学生总得分和批改状态 (结构性试题)
     * @Param [psid]
     * @Author ywx
     * @Date 2020/6/10 16:28
     * @return java.lang.Integer
     **/
    public Integer updateStuScore(Integer psid, Integer checkid){
        return paperStudentMapper.updateStuScore(psid,checkid);
    }

    /**
     * 提交作业
     * @Param [psid]
     * @Author ywx
     * @Date 2020/6/11 10:44
     * @return int
     **/
    public ResultVo submitPaper(Integer psid) {
        try {
            TPaperStudent ps = findById(psid);
            //如果学生作业不存在或是已提交，直接返回1提交成功
            ResultVo vo = StudyUtil.checkPsState(ps);//校验学生作业提交状态
            if (vo != null) return vo;
            Integer paperid = ps.getPaperid();
            Integer classid = ps.getClassid();
            TPaperStudent paperStudentBean = new TPaperStudent();
            paperStudentBean.setPsid(psid);
            int nowTime = N_Utils.getSecondTimestamp();
            TPaperClass pg = paperClassMapper.selectByPaperAndClassId(paperid, classid);
            if (pg.getStoptime() < nowTime) paperStudentBean.setPsstate(2);
            else paperStudentBean.setPsstate(1);

            paperStudentBean.setStoptime(nowTime);
            int costtime = paperStudentQuestionService.getSumQuesitonsCosttime(psid);
            paperStudentBean.setCosttime(costtime);

            //答案显示方式：1作业截至时间，2提交后显示
            Integer showanswer = 0;
            if (pg.getShowtype() == 2 || paperStudentBean.getPsstate() == 2) {
                showanswer = 1;
            }
            paperStudentBean.setShowanswer(showanswer);
            Integer result = updatePaper(psid, paperStudentBean, pg);

            //获取未合并的学生答案
            List<TPaperStudentQuestion> list = paperStudentQuestionService.listNoMergeUserAnswer(psid);
            if (N_Utils.isListNotEmpty(list)) {
                for (TPaperStudentQuestion psq : list) {
                    List<String> userAnswers = JSON.parseArray(psq.getUseranswer(), String.class);
                    if (N_Utils.isListNotEmpty(userAnswers) && userAnswers.size() > 1) {
                        convertUtil.imgMerge(psq.getPsqid(), userAnswers, 1);
                    }
                }
            }

        } catch (Exception e) {
            log.error("提交作业失败："+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new ResultVo(1, "提交失败！");
        }
        return new ResultVo(0, "提交成功！");
    }

    //根据学生作业id校验提交状态
    public ResultVo checkPsStateByPsId(Integer psid) {
        Integer psstate = paperStudentMapper.getPsStateByPsId(psid);
        if (psstate.equals(4)) return PlatformConstant.AFTER_COMMIT;
        if (psstate == null || StudyUtil.tjlist.contains(psstate)) return PlatformConstant.PAPER_COMMIT;
        return null;
    }

    /**
     * 题库作业提交更新操作
     * @Param [psid, paperStudentBean, pg]
     * @Author ywx
     * @Date 2020/11/7 10:00
     * @return java.lang.Integer
     **/
    @Transactional(rollbackFor = Exception.class)
    public Integer updatePaper(Integer psid, TPaperStudent paperStudentBean, TPaperClass pg) throws Exception {
        Integer result = null;
        try {
            //把学生未做的题设置分值为0，状态为已批改
            paperStudentQuestionService.updatePSQByNotDo(psid);
            int psqStudentCount = paperStudentQuestionService.getNotCorrect(psid);
            Integer pschecked = 0;
            if (psqStudentCount <= 0) {//该学生作业已经全部批改完成
                //作业学生关联表，学生批改状态置为已批改
                pschecked = 1;
                paperStudentBean.setAutocheck(1);
            }
            paperStudentBean.setPschecked(pschecked);
            result = paperStudentMapper.updatePaper(paperStudentBean);
            //questionClassService.submitPaper(pg);//自动批改的作业全部批改完调用批阅结束方法
        } catch (Exception e) {
            log.error("提交作业失败："+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException("提交失败");
        }
        return result;
    }

    //题库作业--批阅单人作业
    public void correct(Integer psid, Integer checkid, String questionResult) throws Exception {
        try {
            List<TPaperStudentQuestion> psqs = JSON.parseArray(questionResult, TPaperStudentQuestion.class);
            if (N_Utils.isListEmpty(psqs)) return;
            for (TPaperStudentQuestion psq : psqs) {
                //设置批改状态为已批改
                psq.setCheckid(checkid);
                psq.setChecked(1);
                psq.setChecktime(N_Utils.getSecondTimestamp());
            }
            updateCorrect(psid, checkid, psqs);
            /*TPaperStudent ps = findById(psid);
            Integer paperid = ps.getPaperid();
            Integer classid = ps.getClassid();
            //判断该作业该班级时候已经批改完成
            //查询如果为0，则证明本作业本班级截止当前时间已经提交作业学生全部批改完成
            //Integer notCorrect = paperStudentMapper.getNotCorrect(paperid, classid);
            return notCorrect;*/
        } catch (Exception e) {
            log.error("批改作业失败："+e.getMessage());
            throw new Exception("批改失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateCorrect(Integer psid, Integer checkid, List<TPaperStudentQuestion> psqs) throws Exception {
        try {
            //批量更新试题批改信息
            paperStudentMapper.updatePsQuestionBatch(psqs);
            //批改完修改学生总得分和批改状态 (结构性试题)
            updateStuScore(psid,checkid);
        } catch (Exception e) {
            log.error("批改作业失败："+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException("批改作业失败");
        }
    }

    /**
     * 作业批改完成之后一系列操作
     * @Param [psid]
     * @Author ywx
     * @Date 2020/6/11 11:08
     * @return void
     **/
    /*private void checkedOverDone(Integer psid) {
        //查询该作业该学生是否还存在未批改的题
        int psqStudentCount = paperStudentQuestionService.getNotCorrect(psid);
        if (psqStudentCount <= 0) {//该学生作业已经全部批改完成
            //作业学生关联表，学生批改状态置为已批改
            updateState(null, 1, psid, 3);
        }
    }*/

    /**
     * 批阅列表
     * @Param [ps]
     * @Author ywx
     * @Date 2020/6/18 14:34
     * @return java.util.List<com.xhkjedu.vo.paperstudent.PaperStudentVo>
     **/
    public List<Map> correctList(TPaperStudent ps) {
        return paperStudentMapper.correctList(ps);
    }

    //题库作业--按题批阅列表
    public List<Map> qcorrectList(Integer paperid, Integer classid) {
        List<Map> questions = paperStudentQuestionService.qcorrectList(paperid, classid);
        return questions;
    }

    //题库作业--按题批阅
    public void qcorrect(TPaperStudentQuestion psq) throws Exception {
        try {
            psq.setChecked(1);
            psq.setChecktime(N_Utils.getSecondTimestamp());
            paperStudentQuestionService.update(psq);

            //获取学生作业未批改试题数量
            Integer noCheckNum = paperStudentQuestionService.getNoCheckNumByPsId(psq.getPsid());
            if (noCheckNum.equals(0)) {
                //批改完修改学生总得分和批改状态 (结构性试题)
                updateStuScore(psq.getPsid(), psq.getCheckid());
            }
        } catch (Exception e) {
            log.error("批改作业失败："+e.getMessage());
            throw new Exception("批改失败");
        }
    }

    /**
     * 作业说明
     * @Param [psid]
     * @Author ywx
     * @Date 2020/6/18 17:10
     * @return com.xhkjedu.vo.paperstudent.PaperCommVo
     **/
    public PaperCommVo getPaperComm(Integer psid){
        return paperStudentMapper.getPaperComm(psid);
    }

    /**
     *功能描述 修改学生作答记录（教师添加批注）
     * @author WN
     * @date 2020/8/24
     * @param  * @param useranswer
     * @param psqid
     * @return void
     */
    public void updateUseranswer(String useranswer,Integer psqid){
        paperStudentQuestionService.updateUseranswer(useranswer,psqid);
    }

    //////////////////////////////////////////////图片作业 start//////////////////////////////////////////////////////////////////////

    /**
     *功能描述 图片作业-学生开始做作业
     * @author WN
     * @date 2020/6/12
     * @param  * @param psid
     * @return java.lang.Integer
     */
    public synchronized List<Map> scantronStartPaper(Integer psid){
        List<Map> psscanlst = paperStudentScantronMapper.listPaperStudentScantronsNoAnswer(psid);
        if(psscanlst.size()<=0){
            //保存学生关联答题卡信息
            paperStudentScantronService.saveBatchStudentScantron(psid);
            psscanlst = paperStudentScantronMapper.listPaperStudentScantronsNoAnswer(psid);
        }
        //更改开始状态
        updateState(null,null,psid,1);
        return psscanlst;
    }

    /**
     *功能描述 图片作业--学生作业答题卡
     * @author WN
     * @date 2020/6/12
     * @param  * @param psid
     * @return java.util.List<com.xhkjedu.vo.paperstudent.PaperStudentScantronVo>
     */
    public List<PaperStudentScantronVo> listPaperStudentScantrons(Integer psid) {
        return paperStudentScantronService.listPaperStudentScantrons(psid);
    }

    /**
     * 获取学生答题卡待批改试题列表
     * @Param [psid]
     * @Author ywx
     * @Date 2020/6/26 14:52
     * @return java.util.List<com.xhkjedu.vo.paperstudent.PaperStudentScantronVo>
     **/
    public List<PaperStudentScantronVo> sListCorrectQuestion(Integer psid) {
        return paperStudentScantronService.sListCorrectQuestion(psid);
    }

    /**
     *功能描述  图片作业--学生提交单题
     * @author WN
     * @date 2020/6/12
     * @param  * @param pss
     * @return int
     */
    public ResultVo scantronSubmitQuestion(TPaperStudentScantron pss) {
        try {
            //学生作业试题
            TPaperStudentScantron pss1 = paperStudentScantronService.getObjById(pss.getPssid());
            if (pss1 == null) throw new Exception("该学生作业不存在");
            ResultVo vo = checkPsStateByPsId(pss1.getPsid());//根据学生作业id校验提交状态
            if (vo != null) return vo;
            //获取原试题情况
            TPaperScantron scantronBean = paperScantronMapper.findById(pss1.getPscaid());
            pss.setChecked(0);
            pss.setAnswertime(N_Utils.getSecondTimestamp());
            //判断是否作答1.提交但未作答设置零分，2.作答设置答题状态为2，3.选择题提交为空判错
            String useranswer = pss.getUseranswer();
            String useranswertxt = pss.getUseranswertxt();
            List<String> userAnswers = JSON.parseArray(useranswer, String.class);
            String psanswer = scantronBean.getPsanswer();
            List<String> psanswers = JSON.parseArray(psanswer, String.class);
            //计算用户得分
            Double userScore = 0.0;
            Integer converted = 1;//是否转换0未转换1已转换2转换失败
            if (N_Utils.isEmpty(pss.getUseranswer()) && N_Utils.isListEmpty(userAnswers)
                    && N_Utils.isEmpty(pss.getUseranswertxt())) {
                pss.setStuscore(userScore);
                pss.setChecked(1);
                pss.setCheckid(0);
                pss.setChecktime(N_Utils.getSecondTimestamp());
                pss.setAnswered(0);
            } else {
                pss.setAnswered(1);
                if(pss.getAnswertype() != 2){
                    //自动批改判断得分
                    Integer ctype = scantronBean.getCtype();
                    if (N_Utils.isObjectiveQuestion(ctype)) {
                        if (ctype == 1) {//单选
                            if (useranswer.equalsIgnoreCase(psanswer)) {
                                userScore = pss1.getQscore();
                            }
                        } else if (ctype == 2) {//多选
                            //多选不得分,或者选错不得分，不用处理
                            if (useranswer.length() <= psanswer.length()){
                                String[] qanswerList = psanswers.get(0).split("");
                                String[] userAnswerList = userAnswers.get(0).split("");
                                int rightNum = 0;//选对个数
                                for (String userAnswer : userAnswerList){
                                    int right = 0;
                                    for (String qanswer : qanswerList){
                                        if (qanswer.equals(userAnswer)){
                                            right = 1;
                                            rightNum += 1;
                                        }
                                    }
                                    if (right == 0){//选错直接0分，结束循环
                                        rightNum = 0;
                                        break;
                                    }
                                }
                                if (rightNum > 0){//选对计算得分
                                    if (qanswerList.length == rightNum) {//1.全选对满分
                                        userScore = pss1.getQscore();
                                    } else if (qanswerList.length > rightNum) {//2.少选得一半分
                                        userScore = ArithUtil.div(pss1.getQscore(), 2 ,1);
                                    }
                                }
                            }
                        } else if (ctype == 4 || ctype == 5 || ctype == 6) {
                            //判断题
                            if (useranswer.equalsIgnoreCase(psanswer)) {
                                userScore = pss1.getQscore();
                            }
                        } else if (ctype == 7 || ctype == 8 || ctype == 10) {//完型填空、阅读理解、任务型阅读
                            //计算每小题分数
                            Double qscore = ArithUtil.div(pss1.getQscore(), psanswers.size());
                            Double userScoreDouble = 0D;
                            for (int i = 0; i < psanswers.size(); i++) {
                                if (psanswers.get(i).equalsIgnoreCase(userAnswers.get(i))) {
                                    userScoreDouble = ArithUtil.add(userScoreDouble, qscore);
                                }
                            }
                            userScore = ArithUtil.round(userScoreDouble, 1);
                        }
                        if (userScore.compareTo(pss1.getQscore()) == 1) {
                            userScore = pss1.getQscore();
                        }
                        pss.setStuscore(userScore);
                        pss.setChecked(1);
                        pss.setCheckid(0);
                        pss.setChecktime(N_Utils.getSecondTimestamp());
                    } else {
                        if(userAnswers.size() > 1){
                            converted = 0;//上传的多张图片设为0未转换
                        }
                        pss.setChecked(0);
                    }
                }else{
                    if(N_Utils.isNotEmpty(useranswertxt)){
                        List<String> useranswertxt_list = JSON.parseArray(useranswertxt,String.class);
                        String useranswertxt_txt = useranswertxt_list.get(0);
                        if(N_Utils.isNotEmpty(useranswertxt_txt)){
                            useranswertxt_txt = N_Utils.strTrim(useranswertxt_txt);
                            if(N_Utils.isNotEmpty(useranswertxt_txt)){
                                pss.setChecked(0);
                                List<String> useranswertxt_list_new = new ArrayList<>();
                                useranswertxt_list_new.add(useranswertxt_txt);
                                pss.setUseranswertxt(JSON.toJSONString(useranswertxt_list_new));
                            }else{
                                pss.setChecked(1);
                                pss.setUseranswertxt("[\"\"]");
                            }
                        }else{
                            pss.setChecked(1);
                            pss.setUseranswertxt("[\"\"]");
                        }
                    }else{
                        pss.setChecked(1);
                    }
                }
            }

            Integer costtime = pss1.getCosttime();
            if (costtime == null) costtime = 0;
            pss.setCosttime(pss.getCosttime() + costtime);
            pss.setConverted(converted);
            paperStudentScantronService.updateStudentScantron(pss);
//            updateScantronStuScore(pss1.getPsid());//自动批改单题提交时修改学生总得分
        } catch (Exception e) {
            log.error("图片作业提交单题失败："+e.getMessage());
            return new ResultVo(1, "提交失败！");
        }
        return new ResultVo(0, "提交成功！");
    }

    /**
     *功能描述 图片作业--提交作业
     * @author WN
     * @date 2020/6/12
     * @param  * @param psid
     * @return int
     */
    public ResultVo scantronSubmitPaper(Integer psid) {
        try {
            TPaperStudent ps = findById(psid);
            ResultVo vo = StudyUtil.checkPsState(ps);//校验学生作业提交状态
            if (vo != null) return vo;
            Integer paperid = ps.getPaperid();
            Integer classid = ps.getClassid();
            TPaperStudent paperStudentBean = new TPaperStudent();
            paperStudentBean.setPsid(psid);
            int nowTime = N_Utils.getSecondTimestamp();
            TPaperClass pg = paperClassMapper.selectByPaperAndClassId(paperid, classid);
            if (pg.getStoptime() < nowTime) paperStudentBean.setPsstate(2);
            else paperStudentBean.setPsstate(1);
            paperStudentBean.setStoptime(nowTime);
            int consttime = paperStudentScantronService.getSumScantronsCosttime(psid);
            paperStudentBean.setCosttime(consttime);

            //答案显示方式：1作业截至时间，2提交后显示
            Integer showanswer = 0;
            if (pg.getShowtype() == 2 || paperStudentBean.getPsstate() == 2) {
                showanswer = 1;
            }
            paperStudentBean.setShowanswer(showanswer);
            updateSPaper(psid, paperStudentBean, pg);
            //获取未合并的学生答案
            List<TPaperStudentScantron> list = paperStudentScantronService.listNoMergeUserAnswer(psid);
            if (N_Utils.isListNotEmpty(list)) {
                for (TPaperStudentScantron pss : list) {
                    List<String> userAnswers = JSON.parseArray(pss.getUseranswer(), String.class);
                    if (N_Utils.isListNotEmpty(userAnswers) && userAnswers.size() > 1) {
                        convertUtil.imgMerge(pss.getPssid(), userAnswers, 2);
                    }
                }
            }
        } catch (Exception e) {
            log.error("图片作业提交作业失败："+e.getMessage());
            return new ResultVo(1, "提交失败！");
        }
        return new ResultVo(0, "提交成功！");
    }

    /**
     * 附件作业提交更新操作
     * @Param [psid, paperStudentBean, pg]
     * @Author ywx
     * @Date 2020/11/7 9:56
     * @return java.lang.Integer
     **/
    @Transactional(rollbackFor = Exception.class)
    public Integer updateSPaper(Integer psid, TPaperStudent paperStudentBean, TPaperClass pg) throws Exception {
        Integer result = null;
        try {
            //把学生未做的题设置分值为0，状态为已批改
            paperStudentScantronService.updateScantronPSQByNotDo(psid);
            int psqStudentCount = paperStudentScantronService.getScantronNotCorrect(psid);
            Integer pschecked = 0;
            if (psqStudentCount <= 0) {//该学生作业已经全部批改完成
                //作业学生关联表，学生批改状态置为已批改
                pschecked = 1;
                paperStudentBean.setAutocheck(1);
            }
            paperStudentBean.setPschecked(pschecked);
            result = paperStudentMapper.updateSPaper(paperStudentBean);
            //questionClassService.submitPaper(pg);//自动批改的作业全部批改完调用批阅结束方法
        } catch (Exception e) {
            log.error("图片作业提交作业失败："+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException("提交失败");
        }
        return result;
    }

    //学生作业处理
    /*private void sacntronCheckedOverDone(Integer psid) {
        //查询该作业该学生是否还存在未批改的题
        int psqStudentCount = paperStudentScantronService.getScantronNotCorrect(psid);
        if (psqStudentCount <= 0) {//该学生作业已经全部批改完成
            //作业学生关联表，学生批改状态置为已批改
            updateState(null, 1, psid, 3);
        }
    }*/

    /**
     * 批改完修改学生总得分和批改状态 (答题卡试题)
     * @author WN
     * @date 2020/6/12
     * @param psid
     * @param checkid
     * @return java.lang.Integer
     */
    public Integer updateScantronStuScore(Integer psid, Integer checkid){
        return paperStudentMapper.updateScantronStuScore(psid, checkid);
    }

    /**
     *功能描述 图片作业--单人批改
     * @author WN
     * @date 2020/6/12
     * @param  * @param psid
     * @param checkid
     * @param questionResult
     * @return int
     */
    public void scantronCorrect(Integer psid, Integer checkid, String questionResult) throws Exception {
        try {
            List<TPaperStudentScantron> psslist = JSON.parseArray(questionResult,TPaperStudentScantron.class);
            if (N_Utils.isListEmpty(psslist)) return;
            for (TPaperStudentScantron pss : psslist) {
                //设置批改状态为已批改
                pss.setCheckid(checkid);
                pss.setChecked(1);
                pss.setChecktime(N_Utils.getSecondTimestamp());
            }
            updateSCorrect(psid, checkid, psslist);
        } catch (Exception e) {
            log.error("图片作业批改失败："+e.getMessage());
            throw new Exception("批改失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateSCorrect(Integer psid, Integer checkid, List<TPaperStudentScantron> psslist) throws Exception {
        try {
            //批量更新试题批改信息
            paperStudentScantronService.updateScantronQuestionBatch(psslist);
            //批改完修改学生总得分和批改状态 (答题卡试题)
            updateScantronStuScore(psid, checkid);
        } catch (Exception e) {
            log.error("图片作业批改失败："+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException("图片作业批改失败");
        }
    }

    /**
     *功能描述 修改学生作答记录（教师添加批注）
     * @author WN
     * @date 2020/8/24
     * @param  * @param useranswer
     * @param psqid
     * @return void
     */
    public void updateScantronUseranswer(String useranswer,Integer psqid){
        paperStudentScantronService.updateUseranswer(useranswer,psqid);
    }

    /**
     *功能描述  修改作业答案是否显示
     * @author WN
     * @date 2020/10/13
     * @param  * @param
     * @return void
     */
    public void updateShowanswer(){
        int timestamp = N_Utils.getSecondTimestamp();
        paperStudentMapper.updateShowanswer(timestamp);
    }

    /**
     * @Description 作业自动收卷
     * @Date 2024/4/1 14:39
     * @Author YWX
     * @Param []
     * @Return void
     **/
    public void updatePaperRollUp() {
        int timestamp = N_Utils.getSecondTimestamp();
        //要自动收卷的作业班级列表
        List<Map> list = paperStudentMapper.listRollUpPaper(timestamp);
        if (N_Utils.isListEmpty(list)) return;
        List<Map> tkList = list.stream().filter(p -> !p.get("papertype").equals(2)).collect(Collectors.toList());
        List<Map> fjList = list.stream().filter(p -> p.get("papertype").equals(2)).collect(Collectors.toList());
        if (N_Utils.isListNotEmpty(tkList)) {//题库作业
            paperStudentMapper.updateStuQuestion(tkList, timestamp);
            paperStudentMapper.updatePaperStu(tkList, timestamp);
        }
        if (N_Utils.isListNotEmpty(fjList)) {//附件作业
            paperStudentMapper.updateStuScantron(fjList, timestamp);
            paperStudentMapper.updatePaperScan(fjList, timestamp);
        }
        paperStudentMapper.updatePaperRollUp(list);
    }



    //////////////////////////////////////////////图片作业 end//////////////////////////////////////////////////////////////////////

    /**
     * 根据学生作业id获取作业是否完成批阅
     * @Param [psid]
     * @Author ywx
     * @Date 2020/8/26 14:56
     * @return java.lang.Integer
     **/
    public Integer getCheckedByPsId(Integer psid){
        return paperClassMapper.getCheckedByPsId(psid);
    }

    //学生作业退回
    @Transactional(rollbackFor = Exception.class)
    public ResultVo backPaper(TPaperStudentBack psb) {
        //修改作业状态
        TPaperStudent ps2 = new TPaperStudent();
        ps2.setPsid(psb.getPsid());
        ps2.setPsstate(3);
        ps2.setPschecked(0);
        paperStudentMapper.updateByPrimaryKeySelective(ps2);

        //添加退回记录
        psb.setCreatetime(N_Utils.getSecondTimestamp());
        paperStudentBackMapper.insertUseGeneratedKeys(psb);

        //清空学生学业设置的试题优秀，先获取作业类型
        Map pmap = paperStudentMapper.listPapersByPsid(psb.getPsid());
        Integer papertype = Integer.parseInt(pmap.get("papertype").toString());
        if(papertype == 2){
            paperStudentScantronMapper.updatePaperStudentGoodByPsid(psb.getPsid());
        }else{
            paperStudentQuestionMapper.updatePaperStudentGoodByPsid(psb.getPsid());
        }

        //发送通知
        noticeService.save(pmap,psb);

        return new ResultVo(0, "退回成功");
    }

    //获取学生作业状态
    public Map getPaperState(Integer psid) {
        return paperStudentMapper.getPaperState(psid);
    }

    public List<Map> sqcorrectList(Integer paperid, Integer classid) {
        return paperStudentScantronService.sqcorrectList(paperid, classid);
    }

    //图片作业--按题批改
    public void sqcorrect(TPaperStudentScantron pss) throws Exception {
        try {
            pss.setChecked(1);
            pss.setChecktime(N_Utils.getSecondTimestamp());
            paperStudentScantronService.updateStudentScantron(pss);

            //获取学生作业未批改试题数量
            Integer noCheckNum = paperStudentScantronService.getNoCheckNumByPsId(pss.getPsid());
            if (noCheckNum.equals(0)) {
                //批改完修改学生总得分和批改状态 (答题卡试题)
                updateScantronStuScore(pss.getPsid(), pss.getCheckid());
            }
        } catch (Exception e) {
            log.error("图片作业批改失败：" + e.getMessage());
            throw new Exception("批改失败");
        }
    }

    /**
     * 合并学生答案-题库作业
     *
     * @param []
     * @return void
     * @author ywx
     * @date 2022/5/9 16:30
     */
    public void paperStuQuestionAnswerMerge() {
        //获取未合并的学生答案
        List<TPaperStudentQuestion> list = paperStudentQuestionService.listNoMergeUserAnswer(0);
        if (N_Utils.isListNotEmpty(list)) {
            for (TPaperStudentQuestion psq : list) {
                List<String> userAnswers = JSON.parseArray(psq.getUseranswer(), String.class);
                if (N_Utils.isListNotEmpty(userAnswers) && userAnswers.size() > 1) {
                    convertUtil.imgMerge(psq.getPsqid(), userAnswers, 1);
                }
            }
        }
    }

    /**
     * 合并学生答案-题库作业
     *
     * @param []
     * @return void
     * @author ywx
     * @date 2022/5/9 16:32
     */
    public void paperStuScantronAnswerMerge() {
        //获取未合并的学生答案
        List<TPaperStudentScantron> list = paperStudentScantronService.listNoMergeUserAnswer(0);
        if (N_Utils.isListNotEmpty(list)) {
            for (TPaperStudentScantron pss : list) {
                List<String> userAnswers = JSON.parseArray(pss.getUseranswer(), String.class);
                if (N_Utils.isListNotEmpty(userAnswers) && userAnswers.size() > 1) {
                    convertUtil.imgMerge(pss.getPssid(), userAnswers, 2);
                }
            }
        }
    }

    public void chandlePaperStuQues(){
        //获取已发布的所有作业
        List<TPaper> paperList = paperMapper.listPapersForAllFb();
        for(TPaper paper : paperList){
            int paperid = paper.getPaperid();
            int papertype = paper.getPapertype();
            //获取作业没有关联试题的学生
            List<TPaperStudent> psList = new ArrayList<>();
            if(papertype == 2){
                psList = paperStudentMapper.listPaperStuForScanQues(paperid);
            }else{
                psList = paperStudentMapper.listPaperStuForQueQues(paperid);
            }
            //说明作业有学生未关联试题
            if(N_Utils.isListNotEmpty(psList)){
                //后去试卷中试题
                List<PaperRQuestionVo> quesList = new ArrayList<>();
                if(papertype == 2){
                    quesList = paperStudentScantronMapper.listAllQuesByPaperid(paperid);
                    saveScanPaperStuQues(psList,quesList);
                }else{
                    quesList = paperStudentQuestionMapper.listAllQuesByPaperid(paperid);
                    if(papertype == 1){
                        saveQuesPaperStuQues(psList,quesList);
                    }else{
                        saveQuesPaperStuQuesBx(psList,quesList);
                    }

                }
            }
        }
    }

    private void saveScanPaperStuQues(List<TPaperStudent> psList,List<PaperRQuestionVo> quesList){
        List<TPaperStudentScantron> pssList = new ArrayList<>();
        for(TPaperStudent pstu : psList){
            //遍历试题
            for(PaperRQuestionVo q : quesList){
                TPaperStudentScantron pss = new TPaperStudentScantron();
                pss.setPaperid(pstu.getPaperid());
                pss.setClassid(pstu.getClassid());
                pss.setStudentid(pstu.getStudentid());
                pss.setPscaid(q.getPtqid());
                pss.setPsid(pstu.getPsid());
                pss.setQn(q.getQn());
                pss.setQorder(q.getQorder());
                pss.setAnswered(0);
                pss.setAnswertype(0);
                pss.setConverted(1);
                pss.setCosttime(0);
                pss.setChecked(0);
                pss.setStuscore(0.0);
                pss.setQscore(q.getQscore());
                pss.setSchoolid(pstu.getSchoolid());
                pssList.add(pss);
            }
        }
        if(N_Utils.isListNotEmpty(pssList)){
            paperStudentScantronMapper.insertList(pssList);
        }
    }
    private void saveQuesPaperStuQues(List<TPaperStudent> psList,List<PaperRQuestionVo> quesList){
        List<TPaperStudentQuestion> pssList = new ArrayList<>();
        for(TPaperStudent pstu : psList){
            //遍历试题
            for(PaperRQuestionVo q : quesList){
                TPaperStudentQuestion pss = new TPaperStudentQuestion();
                pss.setPaperid(pstu.getPaperid());
                pss.setClassid(pstu.getClassid());
                pss.setStudentid(pstu.getStudentid());
                pss.setPsid(pstu.getPsid());
                pss.setQuestionpid(q.getQuestionpid());
                pss.setQuestionid(q.getQuestionid());
                pss.setQn(q.getQn());
                pss.setQorder(q.getQorder());
                pss.setAnswered(0);
                pss.setAnswertype(0);
                pss.setConverted(1);
                pss.setCosttime(0);
                pss.setChecked(0);
                pss.setStuscore(0.0);
                pss.setQscore(q.getQscore());
                pss.setSchoolid(pstu.getSchoolid());
                pssList.add(pss);
            }
        }
        if(N_Utils.isListNotEmpty(pssList)){
            paperStudentQuestionMapper.insertList(pssList);
        }
    }

    private void saveQuesPaperStuQuesBx(List<TPaperStudent> psList,List<PaperRQuestionVo> quesList){
        List<TPaperStudentQuestion> pssList = new ArrayList<>();
        for(TPaperStudent pstu : psList){
            //靶向作业
            String questionids = pstu.getQuestionids();
            List<String> qidList = JSON.parseArray(questionids,String.class);

            //学生符合的试题
            List<PaperRQuestionVo> stuQuesList = quesList.stream().filter(s -> qidList.contains(s.getQuestionpid())).collect(Collectors.toList());
            if(N_Utils.isListNotEmpty(stuQuesList)){
                //遍历试题
                for(PaperRQuestionVo q : stuQuesList){
                    TPaperStudentQuestion pss = new TPaperStudentQuestion();
                    pss.setPaperid(pstu.getPaperid());
                    pss.setClassid(pstu.getClassid());
                    pss.setStudentid(pstu.getStudentid());
                    pss.setPsid(pstu.getPsid());
                    pss.setQuestionpid(q.getQuestionpid());
                    pss.setQuestionid(q.getQuestionid());
                    pss.setQn(q.getQn());
                    pss.setQorder(q.getQorder());
                    pss.setAnswered(0);
                    pss.setAnswertype(0);
                    pss.setConverted(1);
                    pss.setCosttime(0);
                    pss.setChecked(0);
                    pss.setStuscore(0.0);
                    pss.setQscore(q.getQscore());
                    pss.setSchoolid(pstu.getSchoolid());
                    pssList.add(pss);
                }
            }
        }
        if(N_Utils.isListNotEmpty(pssList)){
            paperStudentQuestionMapper.insertList(pssList);
        }
    }

    /*
    * @Description 取消单个学生单题优秀作答
    * @Author WN
    * @Date 2023/6/8 17:37:40
    */
    public void updatePaperStudentQuesGood(PaperStudentQuestionVo psq){
        if(psq.getPapertype() == 2){
            //附件作业
            paperStudentScantronMapper.updatePaperStudentGoodByPsqid(0,psq.getPsqid());
        }else{
            paperStudentQuestionMapper.updatePaperStudentGoodByPsqid(0, psq.getPsid(), psq.getQuestionpid());
        }
    }

    /**
     * @Description 是否是批阅人
     * @Param [psq]
     * @Author ywx
     * @Date 2023/6/26 15:18
     * @return java.lang.Integer
     **/
    public Integer isChecker(PaperStudentQuestionVo psq) {
        return paperStudentMapper.isChecker(psq);
    }

    /**
     * @Description 批阅学生列表
     * @Date 2023/12/19 16:14
     * @Author YWX
     * @Param [ps]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listCorrectStu(TPaperStudent ps) {
        return paperStudentMapper.listCorrectStu(ps);
    }
}
