1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > JavaScript——易班优课YOOC课群测试自动答题解决方案(十四)自动刷题

JavaScript——易班优课YOOC课群测试自动答题解决方案(十四)自动刷题

时间:2018-11-27 08:46:34

相关推荐

JavaScript——易班优课YOOC课群测试自动答题解决方案(十四)自动刷题

前文

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(一)答案获取

Spring Boot——易班优课YOOC课群在线测试自动答题解决方案(二)答案储存

Spring Boot——易班优课YOOC课群在线测试自动答题解决方案(三)答案查询

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(四)答案显示

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(五)简单脚本

Spring Boot——易班优课YOOC课群在线测试自动答题解决方案(六)后端改造

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(七)随机答案

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(八)功能面板

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(九)ID标签

Vue + Element UI + Spring Boot——易班优课YOOC课群在线测试自动答题解决方案(十)问题管理页面

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(十一)恢复右键、选择和复制

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

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(十三)自动答题

辅助工具

正则表达式代码生成工具

问题分析

考试列表页

重做按钮

每次练习以后,重做按钮的链接都会发生改变,这个链接可以通过考试页面一个参数生成。

对整个考试页面就行正则匹配即可

let examuser=/var AnswerData = JSON.parse\(localStorage.getItem\("exam(.*)"\)\) \|\| {};/.exec(res.responseText)[1]console.log(examuser)

考试页

提交按钮事件

submitAnswer()方法

如果直接使用submitAnswer()方法,服务端的校验不能通过。

_AnswerData()方法和AnswerData

题目事件监听

答案保存

大致流程:点击选项/或者填写内容 -> 触发事件监听 -> 保存答案到浏览器缓存和服务器 ->提交试卷

答案页

考试信息

题目ID

答案隐藏脚本

答案上传

JavaScript——易班优课YOOC课群在线测试自动答题解决方案(一)答案获取

解决方案

前端

// ==UserScript==// @name YOOC Exams// @namespace /// @version0.2// @description try to take over the world!// @author STZG// @match https://www.yooc.me/group/*/exams*// @grant none// ==/UserScript==(function() {var ajax=(options)=>{// 1. 首先简单验证传进来的参数是否合法if(!options) return undefined;// 2. 对参数容错处理options.method = options.method ? options.method.toUpperCase() : 'GET'; // 默认 GET 请求options.data = options.data || {};options.type = options.type || 'FormData';if(options.type==='JSON'){options.data = JSON.stringify(options.data)}else if(options.type==='FormData'){var formData = [];for(let key in options.data) { // Object.keys.forEachformData.push(''.concat(key, '=', options.data[key]))}options.data = formData.join('&') //eg: a=b&c=d&e=f}// 3. 实例化 XMLHttpRequest 对象,并进行一些设置var xmlhttp = new XMLHttpRequest();//获取对象// 4. 处理请求回调xmlhttp.onreadystatechange = function(){//设置回调函数if(xmlhttp.readyState == 4){//这里的4是请求的状态码,代表请求已经完成if(xmlhttp.status == 200 || xmlhttp.status == 304){//这里是获得响应的状态码,200代表成功,304代表无修改可以直接从缓存中读取options.success(xmlhttp)}else if(xmlhttp.status==500||xmlhttp.status==404){options.failure(xmlhttp)}else {options.failure(xmlhttp)}}}// 5. 打开请求xmlhttp.open(options.method,options.url,true);// 6. 设置请求头if(options.header){for(let key in options.header){xmlhttp.setRequestHeader(key, options.header[key])}}// 7. 发送请求xmlhttp.send(options.method==='POST'?options.data:null);//GET请求}//获取考试信息var group=document.getElementById('group-data')var groupId=group.getAttribute("data-group-id")var csrf=group.getAttribute("data-csrf")var auth=group.getAttribute("data-auth")var 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].hrefa_score.href=edit_history_url.replace('edit_history','detail')a_score.innerHTML='查看详情'}}var 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: 30%;text-align: center;display: inline-block;"><span class="status-practice" style="margin: 10px;">正在xxxx</span></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>'//添加伪元素CSSdocument.styleSheets[0].addRule('progress::-webkit-progress-bar','background-color: #d7d7d7;'); // 支持IEdocument.styleSheets[0].addRule('progress::-webkit-progress-value','background-color: #aadd6a;'); // 支持IElet board_bottom=document.createElement('div')board_bottom.innerHTML=templateboard_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]console.log(exam)console.log(board_bottom)console.log(button_practice)console.log(count_practice)console.log(progress)sum_practice.innerHTML=sumprogress.value=0/sum*100count_practice.innerHTML=0let updateFlag=false;let updateStatus=(now_sum)=>{if(updateFlag){return}else{let timer=setInterval(()=>{let now_num=Math.round(Number(count_practice.innerHTML))let cmp=now_sum-now_numif(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_numprogress.value=now_num/sum*100}},50)}}let refreshStatusSum=()=>{ajax({url:'https://localhost/MyZSTU/yooc/group/'+groupId+'/exam/'+examId+'/answer/total',method:'get',success:(res)=>{updateStatus(JSON.parse(res.responseText).data)},failure:(e)=>{//页面方法xAlert('失败','网络请求失败')}})}if(is_repeat){button_practice.innerHTML="开始自动刷题"let autoPracticeStatus=falsebutton_practice.onclick=e=>{let exam_status=0let repeat=exam.getElementsByClassName('repeat')[0]if(repeat){if(autoPracticeStatus){autoPracticeStatus=falsebutton_practice.innerHTML="开始自动刷题"window.location.href=document.URL}else{autoPracticeStatus=truebutton_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(!autoPracticeStatus){return}console.log("start")status_practice.innerHTML="刷题开始"console.log("apply-repeat")status_practice.innerHTML="申请重做"ajax({url: repeat_url,method: 'post',header:{'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8','X-CSRFToken':csrf},data: {'csrfmiddlewaresretoken': csrf},success: (res)=>{if(!autoPracticeStatus){return}status_practice.innerHTML="申请重做成功"let data=JSON.parse(res.responseText)if(data.result){console.log('申请重做成功')if(data.url){console.log("practice")if(!autoPracticeStatus){return}status_practice.innerHTML="申请考试页面"ajax({url: data.url,method: 'get',success: (res)=>{if(!autoPracticeStatus){return}status_practice.innerHTML="自动练习开始"let examuser=/var AnswerData = JSON.parse\(localStorage.getItem\("exam(.*)"\)\) \|\| {};/.exec(res.responseText)[1]console.log(examuser)repeat_url='https://www.yooc.me/group/'+groupId+'/exam/'+examId+'/examuser/'+examuser+'/repeat'let practice=document.createElement('html')practice.innerHTML=res.responseTextconsole.log(practice)//获取问题信息var question=Array.from(practice.getElementsByClassName('question-board'))let AnswerData={}question.forEach(q=>{console.log(q)let inputTag=q.getElementsByTagName('input')console.log(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="自动练习完成"console.log("save")localStorage.setItem("exam"+examuser,JSON.stringify(AnswerData));status_practice.innerHTML="提交答案"ajax({url: 'https://www.yooc.me/group/'+groupId+'/exam/'+examId+'/answer/save',method: 'post',type:'JSON',header:{'Content-Type':'application/json; charset=UTF-8','X-CSRFToken':csrf},data: AnswerData,success: (res)=>{if(!autoPracticeStatus){return}status_practice.innerHTML="提交答案成功"console.log("submit")var submitUrl = 'https://www.yooc.me/group/'+groupId+'/exam/'+examId+'/answer/submit';var _AnswerData = [];for(obj in AnswerData){var m = {};m[obj] = AnswerData[obj];_AnswerData.push(m);}var postData = {'csrfmiddlewaretoken': csrf,'answers': JSON.stringify(_AnswerData),'type': 0,'auto': 0,'completed':1};if(!autoPracticeStatus){return}status_practice.innerHTML="提交试卷"ajax({url: submitUrl,method:'post',header:{'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8','X-CSRFToken':csrf},data: postData,success: (res)=>{if(!autoPracticeStatus){return}status_practice.innerHTML="提交试卷成功"console.log("upload")status_practice.innerHTML="申请答案页面"ajax({url: 'https://www.yooc.me/group/'+groupId+'/exam/'+examId+'/detail',method: 'get',success: (res)=>{if(!autoPracticeStatus){return}status_practice.innerHTML="答案分析"console.log(res);//创建DOMvar html=document.createElement("html");html.innerHTML=res.responseTextconsole.log(html)//获取问题信息var question=Array.from(html.getElementsByClassName('question-board'))console.log(question)//数据封装var question_arr=[]question.forEach(q=>{question_arr.push({id:q.id,question:q.outerHTML.replace(/the-ans fls/g,"the-ans crt").replace(/<li class="crt"/g,'<li class=""').replace(/<li class="fls"/g,'<li class=""')}) })//上传服务器if(!autoPracticeStatus){return}status_practice.innerHTML="上传答案"ajax({url:"https://localhost/MyZSTU/yooc/group/"+groupId+"/exam/"+examId+"/upload",method:'POST',type:'JSON',header:{"Content-Type":"application/json"},data:question_arr,success: (res)=>{if(!autoPracticeStatus){return}status_practice.innerHTML="上传成功"console.log("end")ajax({url:'https://localhost/MyZSTU/yooc/group/'+groupId+'/exam/'+examId+'/answer/total',method:'get',success:(res)=>{if(!autoPracticeStatus){return}console.log("update")status_practice.innerHTML="更新状态"updateStatus(JSON.parse(res.responseText).data)console.log("reboot")status_practice.innerHTML="正在重新开始"autoPracticeMain()},failure:(e)=>{//页面方法xAlert('失败','网络请求失败')autoPracticeStatus=falsebutton_practice.innerHTML="开始自动刷题"window.location.href=document.URL}})},failure:(e)=>{//页面方法xAlert('失败','网络请求失败')autoPracticeStatus=falsebutton_practice.innerHTML="开始自动刷题"window.location.href=document.URL}});},failure:(e)=>{//页面方法xAlert('失败','网络请求失败')autoPracticeStatus=falsebutton_practice.innerHTML="开始自动刷题"window.location.href=document.URL}});},failure:(e)=>{//页面方法xAlert('失败','网络请求失败')autoPracticeStatus=falsebutton_practice.innerHTML="开始自动刷题"window.location.href=document.URL}});},failure:(e)=>{//页面方法xAlert('失败','网络请求失败')autoPracticeStatus=falsebutton_practice.innerHTML="开始自动刷题"window.location.href=document.URL}})},failure:(e)=>{//页面方法xAlert('失败','网络请求失败')autoPracticeStatus=falsebutton_practice.innerHTML="开始自动刷题"window.location.href=document.URL}})}}else{//页面方法xAlert(data.message);autoPracticeStatus=falsebutton_practice.innerHTML="开始自动刷题"window.location.href=document.URL}},failure:(e)=>{//页面方法xAlert('失败','网络请求失败')autoPracticeStatus=falsebutton_practice.innerHTML="开始自动刷题"window.location.href=document.URL}});}autoPracticeMain()}}else{//页面方法xAlert('失败','无法获取重做按钮,请测试允许反复练习并且确保有重做按钮在页面上')}}}else{button_practice.innerHTML="刷新刷题进度"button_practice.onclick=e=>{console.log("start")console.log("get")console.log("update")refreshStatusSum()console.log("end")}}//初始化状态refreshStatusSum()status_practice.innerHTML=""}var start=()=>{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}}}var int=self.setInterval(()=>{start()},1000);})();

后端

答案上传

@ResponseBody@RequestMapping(value = "/group/{groupId}/exam/{examId}/upload",method = RequestMethod.POST)public Object uploadExam(@PathVariable("groupId")String groupId,@PathVariable("examId")String examId,@RequestBody List<QuestionDTO> questionDTOS,HttpServletResponse response){response.setHeader("Content-Security-Policy","upgrade-insecure-requests");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/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;}

运行结果

参考文章

https://shentuzhigang./article/details/105878462

https://shentuzhigang./article/details/105878607

https://shentuzhigang./article/details/105847036

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。