欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(二十)整理维护

程序员文章站 2022-07-03 18:22:34
目录解决方案JavaScript脚本// ==UserScript==// @name 易班优课YOOC浙理助手// @namespace http://tampermonkey.net/// @version 0.2.5// @description 浙江理工大学易班优课YOOC测试、刷题// @author STZG// @match *://*.yooc.me/*// @grant uns.....

目录

Web安全——易班优课YOOC课群在线测试自动答题解决方案

解决方案

JavaScript脚本 

// ==UserScript==
// @name         易班优课YOOC浙理助手
// @namespace    http://tampermonkey.net/
// @version      0.2.5
// @description  浙江理工大学易班优课YOOC测试、刷题
// @author       STZG
// @match        *://*.yooc.me/*
// @grant        unsafeWindow
// @grant        GM_xmlhttpRequest
// @grant        GM_setClipboard
// @require      https://code.jquery.com/jquery-3.5.1.js#sha256=QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=
// @updateURL    https://*/*/yooc/yooc_helper.js
// @license      MIT
// ==/UserScript==


(function() {
    // 设置修改后,需要刷新或重新打开网课页面才会生效
    const setting = {
            id:[[${ID}]],
            baseURL:"https://*/*",
            yoocURL:"https://www.yooc.me",
            model:"debug"
        };
    let url;
    let _self,top;
    let parent,Ext,UE,vjs;
    if(typeof unsafeWindow!=="undefined"){
        _self = unsafeWindow;
        top = _self;
        $ = _self.jQuery || top.jQuery;
        parent = _self === top ? self : _self.parent;
        Ext = _self.Ext || parent.Ext || {};
        UE = _self.UE;
        vjs = _self.videojs;
    }
    const log={
        LEVEL:{info:0,debug:1},
        logMessage:(msg,level)=> {
            if (log.LEVEL[setting.model]>=log.LEVEL[level]){
                console.log(msg)
            }
        },
        info:(msg)=> log.logMessage(msg, "info"),
        debug: (msg)=> log.logMessage(msg, "debug")
    };
    const ajaxUsualErrorMessage=(e) =>{
        if(e.status === 500){
            //页面函数
            xAlert('失败','网络请求失败')
        }else if(e.status === 404){
            //页面函数
            xAlert('失败','找不到网页')
        }
    };
    const htmlToQuestionObj=(id,questionHTML)=>{
        return {id:id,question:questionHTML
                .replace(/the-ans fls/g,"the-ans crt")
                .replace(/<li class="crt"/g,'<li class=""')
                .replace(/<li class="fls"/g,'<li class=""')}
    };
    let analysisDetailAnswerPage=(pagehtml)=>{
        log.debug(pagehtml);
        //创建DOM
        let pageDOM=document.createElement("html");
        pageDOM.innerHTML=pagehtml;
        let page=$(pageDOM);
        log.debug(page);
        //获取考试信息
        let groupData=page.find('#group-data');
        let groupId=groupData.attr("data-group-id");
        let examId=groupData.attr("data-exam-id");
        //获取问题信息
        let question=page.find('.question-board');
        log.debug(question);
        //数据封装
        let question_arr=[];
        question.each((index,q)=>{
            question_arr.push(htmlToQuestionObj(q.id,q.outerHTML));
            let aq=$("#"+q.id).find('.the-ans');
            if(aq.length === 1){
                aq.html($(q).find('.the-ans').html())
            }
        })
        return {group:groupId,
            exam:examId,
            questions:question_arr}
    }
    let getDetailPage=(groupId,examId)=>{
        return $.ajax({
            //请求方式
            type : "GET",
            //请求地址
            url :setting.yoocURL + '/group/'+groupId+'/exam/'+examId+'/detail'
        });
    }
    let uploadAnswer=(groupId,examId,question_arr)=>{
        return $.ajax({
            //请求方式
            type : "POST",
            //请求的媒体类型
            contentType: "application/json;charset=UTF-8",
            headers:{'JS-ID':setting.id},
            //请求地址
            url : setting.baseURL + "/yooc/group/"+groupId+"/exam/"+examId+"/upload",
            //数据,json字符串
            data : JSON.stringify(question_arr)
        });
    }
    let getAnswer=(groupId,examId,question_arr)=>{
        return $.ajax({
            //请求方式
            type : "GET",
            headers:{'JS-ID':setting.id},
            //请求地址
            url : setting.baseURL + "/yooc/group/"+groupId+"/exam/"+examId+"/answer?question="+question_arr,
        });
    }
    let unblock=()=>{
        //选择
        document.onselectstart= function(e){
            e = e || window.event;
            e.returnValue = true;
            return true;
        }

        //鼠标按下
        document.onmousedown = function(e) {
            e = e || window.event;
            e.returnValue = true;
            return true;
        }
        //鼠标右键菜单
        document.oncontextmenu = function(e) {
            e = e || window.event;
            e.returnValue = true;
            return true;
        }

        window.onkeydown = function(e) {
            //Ctrl+S 保存
            if (e.ctrlKey && e.keyCode == 83) {
                e.returnValue = true;
                return true;
            }
            //Ctrl+P 打印
            if (e.ctrlKey && e.keyCode == 80) {
                e.returnValue = true;
                return true;
            }
            //Ctrl+C 复制
            if (e.ctrlKey && e.keyCode == 67) {
                e.returnValue = true;
                return true;
            }
        }
    }
    let examsPage=()=>{
        //获取考试信息
        let group=document.getElementById('group-data')
        let groupId=group.getAttribute("data-group-id")
        let csrf=group.getAttribute("data-csrf")
        let auth=group.getAttribute("data-auth")
        let seeExam=(exam)=>{
            let a_score=exam.getElementsByClassName('score')[0]
            if(a_score&&a_score.innerHTML==='禁止查卷'){
                let t_bgc=document.getElementsByClassName('t-bgc fl')[7]
                let edit_history_url=t_bgc.getElementsByTagName('a')[0].href
                a_score.href=edit_history_url.replace('edit_history','detail')
                a_score.innerHTML='查看详情'
            }
        }
        let autoPractice=(exam)=>{
            let search=exam.getElementsByClassName('board-bottom')[0]
            if(search){
                return
            }
            let examId=exam.getAttribute("data-exam-id")
            let sum=Number(/(.*)\u9898/.exec(exam.getElementsByClassName('board-det')[0].childNodes[1]
                .getElementsByTagName('span')[0]
                .innerText.trim())[1])
            let is_repeat=exam.getElementsByClassName('board-left')[0].childNodes[25].innerText.trim()==='允许'
            let template='<div class="fl board-bottom robot" style="width: 770px;"><div class="fl board-left" style="    height: 40px!important;line-height: 40px;font-size: 14px;padding: 0 10px;"><div class="progress-tar" style="width:70%;display: inline-block;"><span style="line-height:  20px;height:  20px;">刷题进度:</span><progress class="progress" value="30" max="100" style="width: 60%;border-radius: 2px;border-left: 1px #ccc solid;border-right: 1px #ccc solid;border-top: 1px #aaa solid;background-color: #eee;margin-bottom: 1px;">您的浏览器不支持progress元素</progress><span style="margin: 10px;    line-height: 20px;"><span class="count-practice">0</span>/<span  class="sum-practice"></span></span></div><div style="width: 25%;text-align: center;display: inline-block;"><span class="status-practice" style="margin: 10px;">正在xxxx</span></div><div style="width: 5%;display:  inline-block;text-align:  center;"><a href="https://www.shentuzhigang.top:8443/MyZSTU/favicon.ico"><svg t="1591623102863" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2609" width="32" height="32" style="width: 16px;height: 16px;"><path d="M859.990016 634.09664l0 139.674624c0 39.171072-30.993408 70.9376-69.229568 70.9376L236.429312 844.708864c-38.23616 0-69.229568-31.766528-69.229568-70.9376L167.199744 634.09664l-101.376 0 0 173.45024c0 78.331904 68.68992 141.860864 145.16224 141.860864l617.2416 0c76.473344 0 138.464256-63.52896 138.464256-141.860864L966.69184 634.09664 859.990016 634.09664zM754.766848 383.643648l-135.146496 1.11104L618.540032 66.707456 409.6256 66.707456l0 318.047232L274.47296 384.754688l240.146432 319.127552L754.766848 383.643648z" p-id="2610"></path></svg><a></div></div><div class="fl board-right" style="height: 40px!important;line-height:40px;font-size:14px;background-color: #fe8333;cursor: pointer;color: white;"><div class="button-practice"></div></div></div>'
            //添加伪元素CSS
            document.styleSheets[0].addRule('progress::-webkit-progress-bar','background-color: #d7d7d7;'); // 支持IE
            document.styleSheets[0].addRule('progress::-webkit-progress-value','background-color: #aadd6a;'); // 支持IE
            let board_bottom=document.createElement('div')
            board_bottom.innerHTML=template
            board_bottom=board_bottom.childNodes[0]
            exam.appendChild(board_bottom)
            let button_practice=board_bottom.getElementsByClassName('button-practice')[0]
            let count_practice=board_bottom.getElementsByClassName('count-practice')[0]
            let sum_practice=board_bottom.getElementsByClassName('sum-practice')[0]
            let status_practice=board_bottom.getElementsByClassName('status-practice')[0]
            let progress=board_bottom.getElementsByClassName('progress')[0]
            sum_practice.innerHTML=sum
            progress.value=0/sum*100
            count_practice.innerHTML=0
            let updateFlag=false;
            let now_sum=0;
            let updateStatus=(o)=>{
                now_sum=o
                if(updateFlag){
                    return
                }else{
                    let timer=setInterval(()=>{
                        let now_num=Math.round(Number(count_practice.innerHTML))
                        let cmp=now_sum-now_num
                        if(cmp===0){
                            updateFlag=false;
                            clearInterval(timer);
                        }else{
                            if(now_num===0){
                                now_num=1;
                            }else{
                                now_num=now_num+Math.round(cmp/Math.abs(cmp))
                            }
                            count_practice.innerHTML=now_num
                            progress.value=now_num/sum*100
                        }
                    },50)
                }
            }
            let refreshStatusSum=()=>{
                updateStatus(0)
                return $.ajax({
                    url:setting.baseURL + '/yooc/group/'+groupId+'/exam/'+examId+'/answer/total',
                    type:'get',
                    headers:{'JS-ID':setting.id},
                    success:(res)=>{
                        log.debug(res)
                        updateStatus(res.data)
                    }
                })
            }
            if(is_repeat){
                button_practice.innerHTML="开始自动刷题"
                let autoPracticeStatus=false
                button_practice.onclick=e=>{
                    let exam_status=0
                    let repeat=exam.getElementsByClassName('repeat')[0]
                    if(repeat){
                        if(autoPracticeStatus){
                            autoPracticeStatus=false
                            button_practice.innerHTML="开始自动刷题"
                            window.location.href=document.URL
                        }else{
                            if(now_sum === sum){
                                //页面方法
                                xAlert('提示','刷题完成进度已经100%')
                                return
                            }
                            autoPracticeStatus=true
                            button_practice.innerHTML="关闭自动刷题"
                            let repeat_url=repeat.getAttribute("repeat-url")
                            let start_exam=exam.getElementsByClassName('start_exam')[0]
                            if(start_exam){
                                exam_status=0
                            }else if(repeat){
                                exam_status=4
                            }
                            let autoPracticeMain=()=>{
                                if(now_sum === sum){
                                    //页面方法
                                    xAlert('提示','刷题完成')
                                    autoPracticeStatus=false
                                    button_practice.innerHTML="开始自动刷题"
                                    return
                                }
                                if(!autoPracticeStatus){return}
                                log.info("start")
                                status_practice.innerHTML="刷题开始"
                                log.info("apply-repeat")
                                status_practice.innerHTML="申请重做"
                                $.ajax({
                                    url: repeat_url,
                                    type : "POST",
                                    contentType: "application/x-www-form-urlencoded; charset=UTF-8",
                                    headers:{'X-CSRFToken':csrf},
                                    data: {'csrfmiddlewaresretoken': csrf},
                                    success: (res)=>{
                                        if(!autoPracticeStatus){return}
                                        status_practice.innerHTML="申请重做成功"
                                        let data=res
                                        if(data.result){
                                            log.info('申请重做成功')
                                            if(data.url){
                                                log.info("practice")
                                                if(!autoPracticeStatus){return}
                                                status_practice.innerHTML="申请考试页面"
                                                $.ajax({
                                                    url: data.url,
                                                    type: 'GET',
                                                    success: (res)=>{
                                                        if(!autoPracticeStatus){return}
                                                        status_practice.innerHTML="自动练习开始"
                                                        let examuser=/var AnswerData = JSON.parse\(localStorage.getItem\("exam(.*)"\)\) \|\| {.*};/.exec(res)[1]
                                                        log.debug(examuser)
                                                        repeat_url=setting.yoocURL + '/group/'+groupId+'/exam/'+examId+'/examuser/'+examuser+'/repeat'
                                                        let practice=document.createElement('html')
                                                        practice.innerHTML=res
                                                        log.debug(practice)
                                                        //获取问题信息
                                                        let question=Array.from(practice.getElementsByClassName('question-board'))
                                                        let AnswerData={}
                                                        question.forEach(q=>{log.debug(q)
                                                            let inputTag=q.getElementsByTagName('input')
                                                            log.debug(inputTag)
                                                            if(inputTag.length>0){
                                                                let Ele=inputTag[0]
                                                                if(Ele.type==="radio"||Ele.type==="checkbox"){
                                                                    let arr=Ele.id.split('_')
                                                                    let questionId=arr[0]
                                                                    let name=arr[1]
                                                                    let qData=[arr[2]]
                                                                    AnswerData[questionId] = {};
                                                                    AnswerData[questionId][name] = qData;
                                                                }else if(Ele.type==="text"){
                                                                    let Eles=Array.from(inputTag)
                                                                    Eles.forEach(e=>{
                                                                        e.value="test"
                                                                        let arr=e.id.split('_')
                                                                        let questionId=arr[0]
                                                                        let name=arr[1]
                                                                        AnswerData[questionId] = {};
                                                                        if (AnswerData[questionId][name]===undefined) {
                                                                            AnswerData[questionId][name] = [e.value.trim()];
                                                                        } else {
                                                                            AnswerData[questionId][name].push(e.value.trim());
                                                                        }
                                                                    })
                                                                }
                                                            }
                                                        })
                                                        status_practice.innerHTML="自动练习完成"
                                                        log.info("save")
                                                        localStorage.setItem("exam"+examuser,JSON.stringify(AnswerData));
                                                        status_practice.innerHTML="提交答案"
                                                        $.ajax({
                                                            url: setting.yoocURL + '/group/'+groupId+'/exam/'+examId+'/answer/save',
                                                            type : "POST",
                                                            contentType: "application/json; charset=UTF-8",
                                                            headers:{'X-CSRFToken':csrf},
                                                            data: JSON.stringify(AnswerData),
                                                            success: (res)=>{
                                                                if(!autoPracticeStatus){return}
                                                                status_practice.innerHTML="提交答案成功"
                                                                log.info("submit")
                                                                let submitUrl = setting.yoocURL + '/group/'+groupId+'/exam/'+examId+'/answer/submit';
                                                                let _AnswerData = [];
                                                                for(let obj in AnswerData){
                                                                    let m = {};
                                                                    m[obj] = AnswerData[obj];
                                                                    _AnswerData.push(m);
                                                                }
                                                                let postData = {
                                                                    'csrfmiddlewaretoken': csrf,
                                                                    'answers': JSON.stringify(_AnswerData),
                                                                    'type': 0,
                                                                    'auto': 0,
                                                                    'completed':1
                                                                };
                                                                if(!autoPracticeStatus){return}
                                                                status_practice.innerHTML="提交试卷"
                                                                $.ajax({
                                                                    url: submitUrl,
                                                                    type : "POST",
                                                                    contentType: "application/x-www-form-urlencoded; charset=UTF-8",
                                                                    headers:{'X-CSRFToken':csrf},
                                                                    data: postData,
                                                                    success: (res)=>{
                                                                        if(!autoPracticeStatus){return}
                                                                        status_practice.innerHTML="提交试卷成功"
                                                                        log.info("upload")
                                                                        status_practice.innerHTML="申请答案页面"
                                                                        getDetailPage(groupId,examId)
                                                                            .then(detailPage=>{
                                                                                if(!autoPracticeStatus){return}
                                                                                status_practice.innerHTML="答案分析"
                                                                                let info=analysisDetailAnswerPage(detailPage)
                                                                                if(!autoPracticeStatus){return}
                                                                                status_practice.innerHTML="上传答案"
                                                                                uploadAnswer(info.group,info.exam,info.questions)
                                                                                    .then(res=>{
                                                                                        log.debug(res)
                                                                                        if(!autoPracticeStatus){return}
                                                                                        status_practice.innerHTML="上传成功"
                                                                                        log.info("end")
                                                                                        refreshStatusSum()
                                                                                            .then((res)=>{
                                                                                                if(!autoPracticeStatus){return}
                                                                                                log.info("update")
                                                                                                status_practice.innerHTML="更新状态"
                                                                                                updateStatus(res.data)
                                                                                                log.info("reboot")
                                                                                                status_practice.innerHTML="正在重新开始"
                                                                                                autoPracticeMain()
                                                                                            },(e)=>{
                                                                                                //页面方法
                                                                                                xAlert('失败','网络请求失败')
                                                                                                autoPracticeStatus=false
                                                                                                button_practice.innerHTML="开始自动刷题"
                                                                                                window.location.href=document.URL
                                                                                            })
                                                                                    },(e)=>{
                                                                                        //页面方法
                                                                                        xAlert('失败','网络请求失败')
                                                                                        autoPracticeStatus=false
                                                                                        button_practice.innerHTML="开始自动刷题"
                                                                                        window.location.href=document.URL
                                                                                    })
                                                                            },(e)=>{
                                                                                //页面方法
                                                                                xAlert('失败','网络请求失败')
                                                                                autoPracticeStatus=false
                                                                                button_practice.innerHTML="开始自动刷题"
                                                                                window.location.href=document.URL
                                                                            })
                                                                    },
                                                                    error:(e)=>{
                                                                        //页面方法
                                                                        xAlert('失败','网络请求失败')
                                                                        autoPracticeStatus=false
                                                                        button_practice.innerHTML="开始自动刷题"
                                                                        window.location.href=document.URL
                                                                    }
                                                                });
                                                            },
                                                            error:(e)=>{
                                                                //页面方法
                                                                xAlert('失败','网络请求失败')
                                                                autoPracticeStatus=false
                                                                button_practice.innerHTML="开始自动刷题"
                                                                window.location.href=document.URL
                                                            }
                                                        })
                                                    },
                                                    error:(e)=>{
                                                        //页面方法
                                                        xAlert('失败','网络请求失败')
                                                        autoPracticeStatus=false
                                                        button_practice.innerHTML="开始自动刷题"
                                                        window.location.href=document.URL
                                                    }
                                                })
                                            }
                                        }else{
                                            //页面方法
                                            xAlert(data.message);
                                            autoPracticeStatus=false
                                            button_practice.innerHTML="开始自动刷题"
                                            window.location.href=document.URL
                                        }
                                    },
                                    error:(e)=>{
                                        //页面方法
                                        xAlert('失败','网络请求失败')
                                        autoPracticeStatus=false
                                        button_practice.innerHTML="开始自动刷题"
                                        window.location.href=document.URL
                                    }
                                });

                            }
                            autoPracticeMain()
                        }
                    }else{
                        //页面方法
                        xAlert('失败','无法获取重做按钮,请测试允许反复练习并且确保有重做按钮在页面上')
                    }
                }
            }else{
                button_practice.innerHTML="刷新刷题进度"
                button_practice.onclick=e=>{
                    log.info("start")
                    log.info("get")
                    log.info("update")
                    refreshStatusSum()
                    log.info("end")
                }
            }
            //初始化状态
            refreshStatusSum(res=>{},ajaxUsualErrorMessage)
            status_practice.innerHTML=""
        }
        let exams_board=document.getElementsByClassName('exams-board')[0]
        if(exams_board){
            let exams=Array.from( exams_board.getElementsByTagName('li'))
            if(exams||exams!==[]){
                exams.forEach(exam=>{
                    autoPractice(exam)
                    seeExam(exam)
                })
            }else{
                return
            }
        }
    }
    let detailPage=()=>{
        //获取考试信息
        let group=document.getElementById('group-data');
        let groupId=group.getAttribute("data-group-id");
        let csrf=group.getAttribute("data-csrf");
        let examId=group.getAttribute("data-exam-id");
        let examQuestionNum=Number(group.getAttribute("data-questions"));
        //获取问题信息
        let questions=document.getElementsByClassName('question-board');
        let questionNum = questions.length;
        //获取答案信息
        let ansElements = document.getElementsByClassName('the-ans');
        let ansNum = ansElements.length;
        let addIdTag=()=>{
            //获取问题信息
            let question=Array.from(document.getElementsByClassName('question-board'))
            question.forEach(q=>{
                let board_type=q.id.split('-')[0]
                let question_id=q.id.split('-')[1]
                let idTag=q.getElementsByClassName('question-id-tag')
                if(idTag.length===0){
                    idTag=document.createElement('span')
                    idTag.classList.add('question-id-tag')
                    q.children[0].appendChild(idTag)
                }
                if(board_type==='question'){
                    idTag.innerHTML=" 题目ID:"+question_id
                }else if(board_type==='answer'){
                    idTag.innerHTML=" 答案ID:"+question_id
                }
            })
        }
        let nullSubmit=()=>{
            //获取问题信息
            let question=Array.from(document.getElementsByClassName('question-board'))
            question.forEach(q=>{log.debug(q)
                let inputTag=q.getElementsByTagName('input')
                log.debug(inputTag)
                if(inputTag.length>0){
                    let Ele=inputTag[0]
                    if(Ele.type==="radio"||Ele.type==="checkbox"){
                        if(Ele.type==="radio"){
                            Ele.checked=true;
                        }else if(Ele.type==="checkbox"){
                            Ele.checked=true;
                        }
                        //页面方法
                        choiceAnswerData($(q))
                    }else if(Ele.type==="text"){
                        let Eles=Array.from(inputTag)
                        Eles.forEach(e=>{
                            e.value="test"
                        })
                        //页面方法
                        inputAnswerData($(q))
                    }
                    let ele_name=Ele.name.replace(/\_[0-9]+/, '')
                    let questionTag=document.getElementById(ele_name)
                    questionTag.classList.add('done')
                }
            })
        }
        let writeAnswer=(question)=>{
            let ansEle=question.getElementsByClassName(('the-ans'))[0]
            let pattern=/\u6b63\u786e\u7b54\u6848\uff1a(.*)/
            let ans=ansEle.children[0].innerText.trim()
            if(pattern.test(ans)){
                let answers=pattern.exec(ans)[1]
                let question_id=question.id.split('-')[1]
                let answers_arr=answers.split('、')
                answers_arr.forEach(answer=>{
                    if(/[A-Z]/.test(answer)){
                        let li_Eles=question.getElementsByTagName('li')
                        let li_Ele=li_Eles[answer.charCodeAt(0)-65]
                        let input_id=li_Ele.dataset.questionName+"_"+li_Ele.dataset.questionValue
                        let Ele=document.getElementById(input_id)
                        if(Ele.type==="radio"){
                            Ele.checked=true;
                        }else if(Ele.type==="checkbox"){
                            Ele.checked=true;
                        }
                        //页面方法
                        choiceAnswerData($(document.getElementById('question-'+question_id)))
                    }else{
                        let input_name=question_id+"_" + (answers_arr.indexOf(answer) + 1)
                        let Ele=$("[name='"+input_name+"']").get(0)
                        if(Ele){
                            Ele.value=answer.split('|')[0]
                            //页面方法
                            inputAnswerData($(document.getElementById('question-'+question_id)))
                        }
                    }
                })
                let questionTag=document.getElementById(question_id)
                questionTag.classList.add('done')
            }
        }

        let autoAnswer=()=>{
            let ansElements = Array.from(document.getElementsByClassName('the-ans'))
            ansElements.forEach(ansEle=>{
                writeAnswer(ansEle.parentNode)
            })
        }
        let copyMobileAnswer=()=>{
            //获取问题信息
            questions=$('.question-board')
            let questionContainer=document.getElementsByClassName('exam-detial-container')[0]
            log.debug(questionContainer)
            $.ajax({
                type : "GET",
                url:setting.yoocURL + "/mobile/group/"+groupId+"/exams/"+examId+"/subject?view_type=result",
            })
                .then(res=>{
                    let pattern_t =/var data=(.*);\n/
                    if(!pattern_t .test(res)){
                        xAlert('提示',res)
                        return
                    }
                    let data=JSON.parse(pattern_t.exec(res)[1])
                    let question_arr=[]
                    let num=0
                    data.forEach(e=>{
                        log.debug(e[2]);
                        e[2].forEach(q=>{
                            let question=document.createElement('div')
                            question.innerHTML=q.question
                            question.classList.add('question-board')
                            question.id=questions.get(num).id
                            log.debug(question)
                            question_arr.push(htmlToQuestionObj(question.id,question.outerHTML))
                            writeAnswer(question)
                            question.id = 'answer-' + question.id.split('-')[1]
                            questionContainer.insertBefore(question,questions.get(num++))
                            log.debug(num)
                        })
                    })
                    log.debug(question_arr)
                    uploadAnswer(groupId,examId,question_arr)
                    addIdTag()
                },ajaxUsualErrorMessage)
        }
        var repeatExam=()=>{
            $.ajax({
                url: 'https://www.yooc.me/group/'+groupId+'/exam/'+examId+'/detail',
                type: 'GET'
            }).then(res=>{
                let examuser=/var AnswerData = JSON.parse\(localStorage.getItem\("exam(.*)"\)\) \|\| {.*};/.exec(res)[1];
                $.ajax({
                    beforeSend: function(xhr){
                        // 取消掉全局loading效果
                        if($('#mask').length>0){
                            $('#mask').hide();
                        }
                    },
                    url:'https://www.yooc.me/group/'+groupId+'/exam/'+examId+'/examuser/'+examuser+'/repeat',
                    type: 'post',
                    data: {'csrfmiddlewaretoken': csrf},
                    success: function(data){
                        if(data.result){
                            window.location.href = data.url;
                        }else{
                            alert(data.message);
                        }
                    }
                });
            },ajaxUsualErrorMessage)

        }
        let appendsomething=()=>{
            let releaseButton=document.getElementsByClassName('release-board')[0]
            let ns=document.createElement('a')
            ns.id="null-submit"
            ns.href="javascript:;"
            ns.innerText="提交白卷"
            ns.style="margin-left: 0px;margin-top: 10px;"
            ns.title="随机答案提交试卷"
            ns.onclick=()=>{
                nullSubmit();
                //页面方法
                xAlert('提示','随机答案选择完毕,可以提交了');
            };
            releaseButton.appendChild(ns);
            let qa=document.createElement('a');
            qa.id="query-answer";
            qa.href="javascript:;";
            qa.innerText="查询答案";
            qa.style="margin-left: 20px;margin-top: 10px;";
            qa.title="云端题库查询答案";
            qa.onclick=()=>{
                let ansElements = document.getElementsByClassName('the-ans');
                let ansNum = ansElements.length
                if(ansNum<=0){
                    showAnswer();
                    addIdTag()
                }else{
                    //页面方法
                    xAlert('失败','已经有答案了哦')
                }
            };
            releaseButton.appendChild(qa);
            let autoAnswerButton=document.createElement('a');
            autoAnswerButton.id="auto-answer-submit";
            autoAnswerButton.href="javascript:;";
            autoAnswerButton.innerText="自动答题";
            autoAnswerButton.style="margin-left: 0px;margin-top: 10px;";
            autoAnswerButton.title="答案自动选择";
            autoAnswerButton.onclick=()=>{
                autoAnswer();
                addIdTag();
                //页面方法
                xAlert('提示','答案自动选择完毕,请自行检查填空题部分')
            }
            releaseButton.appendChild(autoAnswerButton);

            let copyAnswerButton=document.createElement('a');
            copyAnswerButton.id="auto-answer-submit";
            copyAnswerButton.href="javascript:;";
            copyAnswerButton.innerText="正确答案";
            copyAnswerButton.style="margin-left: 20px;margin-top: 10px;";
            copyAnswerButton.title="利用PC端和移动端之间BUG实现获取正确答案";
            let checked_a=false;
            copyAnswerButton.onclick=()=>{
                let ansElements = document.getElementsByClassName('the-ans');
                let ansNum = ansElements.length;
                if(ansNum<=0){
                    copyMobileAnswer();
                    addIdTag();
                    //页面方法
                    xAlert('提示','正确答案复制完毕,请自行检查填空题部分');
                }else{
                    //页面方法
                    xAlert('失败','已经有答案了哦');
                }
            };
            releaseButton.appendChild(copyAnswerButton);

            var repeatButton=document.createElement('a')
            repeatButton.id="repeat-exam-submit"
            repeatButton.href="javascript:;"
            repeatButton.innerText="强制重做"
            repeatButton.style="margin-left: 0px;margin-top: 10px;"
            repeatButton.title="强制申请重做试卷"
            repeatButton.onclick=()=>{
                repeatExam();
                //页面方法
                xAlert('提示','强制申请重做试卷成功')
            }
            releaseButton.appendChild(repeatButton)

            var tempButton=document.createElement('a')
            tempButton.id="temp-submit"
            tempButton.href="javascript:;"
            tempButton.innerText="占位按钮"
            tempButton.style="margin-left: 20px;margin-top: 10px;"
            tempButton.title="未定义功能"
            tempButton.onclick=()=>{
                //页面方法
                xAlert('失败','占位按钮:未定义功能')
            }
            releaseButton.appendChild(tempButton)
        };
        let showAnswer=()=>{
            //获取问题信息
            questions=$('.question-board');
            let question_arr=[];
            questions.each((index,q)=>{
                question_arr.push(q.id.substr(9))
            });
            getAnswer(groupId,examId,question_arr)
                .then(res=>{
                    log.debug(res);
                    let questionContainer=document.getElementsByClassName('exam-detial-container')[0];
                    res.forEach(q=>{
                        let question=document.getElementById('question-'+q.id);
                        let answer = document.createElement("div");
                        answer.innerHTML = q.question;
                        let child=answer.childNodes[0];
                        child.id='answer-'+q.id;
                        questionContainer.insertBefore(child,question);
                        log.debug(question);
                        log.debug(answer)
                    });
                    addIdTag()
                },ajaxUsualErrorMessage)
        };
        if(ansNum>0){
            if(questionNum===examQuestionNum){
                getDetailPage(groupId,examId)
                    .then(detailPage=>{
                        let info=analysisDetailAnswerPage(detailPage);
                        uploadAnswer(info.group,info.exam,info.questions)
                            .then(res=>{log.debug(res)},ajaxUsualErrorMessage)
                    },ajaxUsualErrorMessage)
            }else{
                log.info("现在是考试中,不能上传答案哦。")
            }
        }else{
            appendsomething();
            unblock();
        }
        addIdTag()
    };
    let start=()=>{
        if(url!=location.pathname){
            url=location.pathname;
            log.info(url);
            if(!url.match(/^\/mobile/)){
                if(url.match(/\/group\/[0-9]*\/exams.*/)){
                    examsPage()
                }
                else if(url.match(/\/group\/[0-9]*\/exam\/[0-9]*\/detail/)){
                    detailPage()
                }
            }
        }
    };
    let int=self.setInterval(()=>{
        start()
    },1000);
})();

Java后端

Maven 

        <!--Spring Boot Web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--Spring Mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>
        <!--MyBatis-Plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>
        <!--Spring Thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

Controller

package cn.edu.zstu.myzstu.web.controller.YOOC;

import cn.edu.zstu.myzstu.dto.ApiResponse;
import cn.edu.zstu.myzstu.dto.yooc.ExamDTO;
import cn.edu.zstu.myzstu.dto.yooc.QuestionDTO;
import cn.edu.zstu.myzstu.model.yooc.Question;
import cn.edu.zstu.myzstu.service.IYOOCExamQuestionService;
import cn.edu.zstu.myzstu.web.utils.ApiResponseUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @Author ShenTuZhiGang
 * @Version 1.0.0
 * @Date 2020-04-26 08:26
 */
@Controller
@CrossOrigin
@RequestMapping("/yooc")
public class YOOCController {
    @Autowired
    IYOOCExamQuestionService iyoocExamQuestionService;
    @ResponseBody
    @RequestMapping(value = "/group/{groupId}/exam/{examId}/upload",method = RequestMethod.POST)
    public Object uploadExam(@RequestHeader("JS-ID")String JSID,
                             @PathVariable("groupId")String groupId,
                             @PathVariable("examId")String examId,
                             @RequestBody List<QuestionDTO> questionDTOS){

        List<Question> questions  = new ArrayList<>();
        for (QuestionDTO questionDTO: questionDTOS) {
            Question question =new Question(groupId,
                    examId,
                    questionDTO.getId().substring(9),
                    questionDTO.getQuestion());
            questions.add(question);
            //System.out.println(question);

        }
        iyoocExamQuestionService.saveOrUpdateBatch(questions);
        return questions;
    }
    @ResponseBody
    @RequestMapping(value = "/group/{groupId}/exam/{examId}/answer",method = RequestMethod.GET)
    public Object getAnswerByQuestionId(@RequestHeader("JS-ID")String JSID,
                                        @PathVariable("groupId")String groupId,
                                        @PathVariable("examId")String examId,
                                        @RequestParam("question") List<String> questions){
        List<QuestionDTO> questionDTOS  = new ArrayList<>();
        for (String question:questions) {
            Question questiona=iyoocExamQuestionService.getById(question);
            if(questiona==null){
                questionDTOS.add(QuestionDTO.getNullQuestionDTO(question));
            }else{
                questionDTOS.add(new QuestionDTO(questiona.getId(),questiona.getQuestion()));
            }
        }
        return questionDTOS;
    }
    @ResponseBody
    @RequestMapping(value = "/group/{groupId}/exam/{examId}/answer/search",method = {RequestMethod.GET})
    public Object getUserByPage(@RequestHeader("JS-ID")String JSID,
                                @PathVariable("groupId")String groupId,
                                @PathVariable("examId")String examId,
                                @RequestParam(defaultValue = "1") Integer page,
                                @RequestParam(defaultValue = "10") Integer size,
                                @RequestParam(defaultValue = "false")Boolean onlynow,
                                String key){
        QueryWrapper<Question> queryWrapper = new QueryWrapper<>();
        if(onlynow){
            if(!StringUtils.isEmpty(groupId)){
                queryWrapper.eq("group",groupId);
            }
            if(!StringUtils.isEmpty(examId)){
                queryWrapper.eq("exam",examId);
            }
        }
        queryWrapper.like("question", key);
        return iyoocExamQuestionService.page(new Page<>(page,size), queryWrapper);
    }
    @ResponseBody
    @RequestMapping(value = "/group/{groupId}/exam/{examId}/answer/total",method = RequestMethod.GET)
    public Object getAnswerTotalByQuestionId(@PathVariable("groupId")String groupId,
                                        @PathVariable("examId")String examId){
        int total = iyoocExamQuestionService.count(new QueryWrapper<>(new Question(groupId, examId)));
        ApiResponse retTemp = ApiResponseUtil.getRetTemp();
        retTemp.setData(total);
        return retTemp;
    }

    @RequestMapping(value = "/yooc_helper.js",method = RequestMethod.GET)
    public String updateJS(Model model){
        model.addAttribute("ID", UUID.randomUUID().toString());
        return "yooc_helper.js";
    }
}

无答案时

    public static QuestionDTO getNullQuestionDTO(String id){
        QuestionDTO question = new QuestionDTO();
        question.setId(id);
        question.setQuestion("<div class=\"question-board\" id=\"question-"+id+"\">\n" +
                "               <div class=\"the-ans fls\">\n" +
                "                   <p>这一题还没有正确的答案,快点上传吧!</p>\n" +
                "               </div>\n" +
                "             </div>");
        return question;
    }

 数据库设计

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(二十)整理维护

运行结果

考试列表面板 

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(二十)整理维护

自动刷题过程

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(二十)整理维护

考试面板 

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(二十)整理维护

答题参考 

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(二十)整理维护

完成标记

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(二十)整理维护

模板脚本 

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(二十)整理维护

数据库存储 

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(二十)整理维护

参考文章

https://blog.csdn.net/qq_41523096/article/details/104758355

本文地址:https://blog.csdn.net/weixin_43272781/article/details/107304522