Files
learning-system-portal/src/views/exam/Test.vue
2022-08-25 15:00:35 +08:00

971 lines
35 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="test">
<el-container>
<el-header>
<div class="title">{{ testPaper.testName }}</div>
</el-header>
<el-container>
<el-main>
<div v-if="testStatus == 1">
<div class="test-info" >
<ul>
<li>考试时长: {{ testPaper.testDuration }}分钟</li>
<li>及格线: {{ testPaper.passLine }}</li>
<li v-if="testPaper.entranceTime">开始时间:
{{ testPaper.entranceTime }}</li>
<li v-if="testPaper.times">尝试次数: {{ testPaper.times }}</li>
<li v-if="testPaper.deadlineTime">结束时间: {{ testPaper.deadlineTime }}</li>
</ul>
</div>
<div v-if="testPaper.testFront" style="padding: 20px;text-align: center;" v-html="testPaper.testFront">
<!--考前说明-->
</div>
<div v-if="canExam" class="test-time" style="margin-top:20px" >
<div v-if="examStatus==0" style="text-align: center;color:#6d6d6d; ">考试还未开始</div>
<div v-if="examStatus==1">
<div v-if="tipText!=''" style="text-align: center;color:red">
<span>{{tipText}}</span>
</div>
<div v-else>
<el-button type="primary" :disabled="startButton" v-if="testStatus == 1" @click="startTest()">{{btnText}}</el-button>
</div>
</div>
<div v-if="examStatus==2" style="text-align: center;color:#6d6d6d; ">考试已结束</div>
</div>
<div v-else class="no-text">
<span v-if="noExam">您没有需要的考试</span>
</div>
<div class="re-list" v-if="canExam">
<p>历史记录</p>
<div style="height:300px" v-if="loading == 1" v-loading="loading == 1">
</div>
<el-table :data="tableData" style="width: 100%" v-if="loading == 2">
<el-table-column prop="startTime" label="完成时间" width="180"></el-table-column>
<el-table-column prop="score" align="center" label="成绩">
<template slot-scope="scope">
<span>{{toScoreTow(scope.row.score)}}</span>
</template>
</el-table-column>
<el-table-column prop="score" align="center" label="状态">
<template slot-scope="scope">
<span v-if="scope.row.status==1" style="color: #ff0000;">未提交</span>
<span v-if="scope.row.status==8">中断</span>
<span v-if="scope.row.status==9" style="color: #00aa00; ">完成</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-button v-if="scope.row.status>5" type="text" @click="viewUserPaper(scope.row)"><i class="el-icon-edit"></i> 查看考卷</el-button>
<el-button v-if="scope.row.status<5 && examStatus==1" type="text" @click="reStartTest(scope.row)"><i class="el-icon-edit"></i> 继续考试</el-button>
<el-button v-if="scope.row.status<5 && examStatus==2" type="text" @click="viewUserPaper(scope.row)"><i class="el-icon-edit"></i> 查看考卷</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<!-- <div v-if="testStatus == 1" style="text-align: center;font-size:12px;color:#666666;margin-top:20px">
{{testPaper.testFront}}
</div> -->
<div v-if="testStatus == 2">
<div style="text-align: center;padding: 10px;color: #ff0000;"><span v-if="testStatus == 2">剩余时间:<span class="reckon-time">{{formatSeconds(remainingTime)}}</span></span></div>
<div v-if="judge.length > 0">
<div class="question-type">判断题</div>
<div v-for="(question, i) in judge" :key="question.id" class="question-info">
<div>{{ i + 1 }}{{ question.title }} {{question.defaultScore}}</div>
<div>
<div class="question-option">
<el-radio v-model="question.userAnswer" label="true">正确</el-radio>
</div>
<div class="question-option">
<el-radio v-model="question.userAnswer" label="false">错误</el-radio>
</div>
</div>
</div>
</div>
<div v-if="single.length > 0">
<div class="question-type">单选题</div>
<div v-for="(question, i) in single" :key="question.id" class="question-info">
<div>{{ i + 1 + judge.length }}{{ question.title }}{{question.defaultScore}}</div>
<div>
<div class="question-option" v-for="(option, j) in question.optionList" :key="option.id">
<el-radio v-model="question.userAnswer":label="option.id">
{{ numberToLetter(j+1) }}{{ option.content }}
</el-radio>
</div>
</div>
</div>
</div>
<div v-if="multiple.length > 0">
<div class="question-type">多选题</div>
<div v-for="(question, i) in multiple" :key="question.id" class="question-info">
<div>
{{ i + 1 + judge.length + single.length }}{{ question.title }}{{question.defaultScore}}
</div>
<div>
<el-checkbox-group v-model="question.userAnswer">
<div class="question-option" v-for="(option, j) in question.optionList" :key="option.id">
<el-checkbox :label="option.id">{{ numberToLetter(j + 1) }}{{ option.content }}</el-checkbox>
</div>
</el-checkbox-group>
</div>
</div>
</div>
<div class="test-submit">
<el-button type="primary" @click="manualSubmit" :disabled="submitButton">提交试卷</el-button>
</div>
</div>
<div v-if="testStatus == 3" style="margin-top:20px">
<div style="text-align: center;font-size: 20px;">您本次考试得分<span style="color: #08a890;font-size:24px">{{toScoreTow(score)}}</span></div>
<div style="text-align: center;font-size:12px;color:#666666;margin-top:20px">{{testPaper.testUp}}</div>
<div style="text-align: center;margin-top: 20px;">
<el-button type="primary" @click="closeTest()">关闭</el-button>
</div>
</div>
<div v-if="showPaperAnser === true">
<div v-if="judge.length > 0" style="margin-top:20px">
<div class="question-type">判断题</div>
<div v-for="(question, i) in judge" :key="question.id" class="question-info">
<div>{{ i + 1 }}{{ question.title }} {{question.defaultScore}}</div>
<div>
<div class="question-option">
<el-radio v-model="question.userAnswer" disabled :label="true">正确</el-radio>
</div>
<div class="question-option">
<el-radio v-model="question.userAnswer" disabled :label="false">错误</el-radio>
</div>
</div>
<p v-if="testPaper.showAnswer">正确答案{{question && question.answer?'正确':'错误'}}</p>
<p v-if="testPaper.showAnalysis">解析{{question.analysis}}</p>
</div>
</div>
<div v-if="single.length > 0">
<div class="question-type">单选题</div>
<div v-for="(question, i) in single" :key="question.id" class="question-info">
<div>{{ i + 1 + judge.length }}{{ question.title }}{{question.defaultScore}}</div>
<div>
<div class="question-option" v-for="(option, j) in question.optionList" :key="option.id">
<el-radio disabled v-model="question.userAnswer" :label="option.id" >{{ numberToLetter(j+1) }}{{ option.content }}</el-radio>
</div>
</div>
<p v-if="testPaper.showAnswer">正确答案:<span v-for="(item,a) in question.optionList" :key="a">{{item.isAnswer?numberToLetter(a+1):''}}</span></p>
<p v-if="testPaper.showAnalysis">解析{{question.analysis}}</p>
</div>
</div>
<div v-if="multiple.length > 0">
<div class="question-type">多选题</div>
<div v-for="(question, i) in multiple" :key="question.id" class="question-info">
<div>
{{ i + 1 + judge.length + single.length }}{{ question.title }}{{question.defaultScore}}
</div>
<div>
<el-checkbox-group v-model="question.userAnswer">
<div class="question-option" v-for="(option, j) in question.optionList" :key="option.id">
<el-checkbox disabled
:label="option.id">{{ numberToLetter(j + 1) }}{{ option.content }}</el-checkbox>
</div>
</el-checkbox-group>
</div>
<p v-if="testPaper.showAnswer">正确答案:<span v-for="(q, b) in question.optionList" :key="b">{{q.isAnswer?numberToLetter(b+1):''}}</span></p>
<p v-if="testPaper.showAnalysis">解析{{question.analysis}}</p>
</div>
</div>
</div>
</el-main>
</el-container>
</el-container>
<el-dialog title="查看试卷" append-to-body :visible.sync="viewUserPapereShow" width="70%" custom-class="g-dialog">
<div style="padding: 10px; font-size: 20px" class="upaper">
<div v-for="(ditem,didx) in paperDetailData" :key="didx" class="upaper-item">
<div class="upaper-item-q">{{didx +1}}.{{getTypeName(ditem.type)}}{{ditem.title}}</div>
<div class="upaper-item-opts" style="padding-left: 20px;">
<div v-for="(opt,optIdx) in ditem.optionList" :key="optIdx" class="upaper-item-opt" :class="{'upaper-item-opt-user':ditem.userOptIdxs.indexOf(optIdx)>-1}">
<div>
<div>{{numberToLetter(optIdx+1)}}, {{opt.content}}</div>
</div>
<div>
<span v-if="ditem.userOptIdxs.indexOf(optIdx)>-1 && ditem.correctOptIdxs.indexOf(optIdx)>-1" style="color: #00aa00;font-size: 25px; "></span>
<span v-if="ditem.userOptIdxs.indexOf(optIdx)>-1 && ditem.correctOptIdxs.indexOf(optIdx)==-1" style="color: #ff0000;font-size: 25px; ">×</span>
</div>
</div>
</div>
<div class="upaper-item-answer" style="display: flex;">
<div class="upaper-item-answer-cell">
<span v-if="ditem.result" style="color: #00aa00; ">回答正确</span>
<span v-else style="color: #ff0000; ">回答错误</span>
</div>
<div v-if="ditem.type !=3" style="display:flex">
<div v-if="testPaper.showAnswer" class="upaper-item-answer-cell" >
<span class="response-tit">正确答案</span>
<span v-for="op in ditem.correctOptIdxs" :key="op">{{numberToLetter(op+1)}}</span>
</div>
<div class="upaper-item-answer-cell">
<span class="response-tit">我的答案</span>
<span v-for="op in ditem.userOptIdxs" :key="op">{{numberToLetter(op+1)}}</span>
</div>
</div>
<div v-else style="display:flex">
<div v-if="testPaper.showAnswer" class="upaper-item-answer-cell" >
<span class="response-tit">正确答案</span>
<span>{{ditem.correctOptIdxs[0]=='true' ? '正确':'错误'}}</span>
</div>
<div class="upaper-item-answer-cell">
<span class="response-tit">我的答案</span>
<span>{{ditem.userOptIdxs[0] == 'true' ? '正确':'错误'}}</span>
</div>
</div>
</div>
<!--答案解析-->
<div v-if="ditem.analysis && testPaper.showAnalysis" style="padding-top: 10px;">
解析{{ditem.analysis}}
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="viewUserPapereShow = false">关闭</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import apiTestPaper from '@/api/modules/testPaper.js'
import apiExamTask from "@/api/modules/examTask";
import { numberToLetter,examType,toScoreTow} from '@/utils/tools.js'
import { formatSeconds } from '@/utils/datetime.js'
export default {
data() {
return {
loading:0,
toScoreTow,
examId:'',//考试的id
taskId:'',//考试任务的id
lastId:'',//最后一次提交的答卷
canExam:false,//能否参加考试
noExam:false,//不能参加考试
tipText:'',//提示信息
examStatus:0,//0表无1表考试中2表已结束
btnText:'开始考试',
handleSaveTest:null,//对应timout定时任务的指向
getTypeName:examType,
viewUserPapereShow:false,
paperDetailData:[],
showPaperAnser:false,
testPaper: {
id: '',
testName: '',//考试名称
testDuration: null,//考试时长 分钟
showAnalysis: false,//显示解析
showAnswer: false,//显示答案
times: null,//尝试次数 默认是0无限制
arrange: null,//试题排列 1试题乱序2选项乱序3全部乱序
scoringType: null,//评分方式 1最高一次2最后一次
passLine: null,//及格线
randomMode: false,//随机模式
randomCount: null,//随机数量
testType: null,//考试的类型 1测试模式独立考试
publishTime: '',//发布时间
testRemark: '',//考试描述
testFront: '',//考前描述
testUp: '',//考后描述
entranceTime: '',//入场时间
paperId: '',//试卷的ID
paperContent: '',//试卷内容
},
remainingTime: 0,
paperQuestion: [], //试卷内容经过排序后的数据,该数据就是试卷
judge: [],
single: [],
multiple: [],
startButton:false,
aloneExamAnswerId:null,// 考试提交答案ID
curTestAnswer:{},//当前考试的内容
testStatus: 1,// 1考前 2考中 3考后
reckonTimeer:null,// 计时器
updateAnswerTimeer:null,//定时提交答案
submitButton:false,
score:0,
tableData:[]
}
},
computed:{
...mapGetters(['userInfo'])
},
mounted() {
this.examId = this.$route.query.id
if(this.examId) {
this.loadData()
}else{
this.$message.error('非法请求');
}
},
methods: {
loadData() { //加载考试信息
apiTestPaper.getTestInfo(this.examId).then(res=>{
if(res.status==200){
this.canExam = res.result.hasTask;
if(!this.canExam) {
this.noExam = true;
}
this.examStatus=res.result.examStatus;
this.testPaper = res.result.exam;
this.taskId=res.result.taskId;
if( res.result.hasLast && res.result.lastStatus<9){
this.lastId=res.result.lastId;
}
if(!this.testPaper.published){
this.tipText="此考试已取消请与管理员联系";
}
//转换testDuration为秒,此转化在点击开始考试时才应该执行
this.remainingTime = this.testPaper.testDuration * 60;
//加载考试记录
if(res.result.hasTask){
if(res.result.hasLast){
this.btnText='重新考试';
this.testAnswers();
}
}
}else{
this.$message.error(res.message);
}
});
},
viewUserPaper(row) { //查看答卷信息
this.viewUserPapereShow = true;
this.getAnswerDetail(row.id);
},
getAnswerDetail(id) { //获取答卷的详细信息
apiTestPaper.getAnswerDetail(id).then(res=>{
if(res.status === 200) {
let answerJson = [];
answerJson=JSON.parse(res.result.answerJson);
let paperJson = [];
paperJson=JSON.parse(res.result.paperJson);
let answer = [];
let data = [];
for(let key in answerJson){
answer.push(key);
paperJson.forEach((item,index) => {
item.result=true;
if(item.id == key) {
if(item.type==1){
item.userAnswer='';
}else if(item.type==2){
item.userAnswer=[];
}else{
item.userAnswer=''
}
item.correctOptIdxs=[];
item.userOptIdxs=[];
if(item.type==1){
item.userAnswer=answerJson[key];
}else if(item.type==2){
item.userAnswer.push(...answerJson[key].split(','));
}else{
item.userAnswer=answerJson[key]
}
data.push(item);
// item.userAnswer.push(answerJson[key]);
}
});
}
this.paperDetailData = data;
this.paperDetailData.forEach((item,index)=>{
if(item.type ==3) {
item.correctOptIdxs.push(item.answer);
item.userOptIdxs.push(item.userAnswer);
}
item.optionList.forEach((opt,idx)=>{
//填充正确答案
if(opt.isAnswer){
item.correctOptIdxs.push(idx);
}
if(item.type==1){ //单选或判断
if(opt.id==item.userAnswer){
item.userOptIdxs.push(idx);
}
}else if(item.type==2){ //多选
if(item.userAnswer.indexOf(opt.id)>-1){
item.userOptIdxs.push(idx);
}
}
// else if(item.type==3){ //判断
// if(item.userAnswer.indexOf(opt.id)>-1){
// item.userOptIdxs.push(idx);
// }
// }
});
//判断答案是否正确
if(item.correctOptIdxs.toString()==item.userOptIdxs.toString()){
item.result=true;
}else{
item.result=false;
}
})
}
})
},
testAnswers(){ //获取当前考试的历史记录
this.loading = 1;
apiTestPaper.myTestAnswers(this.examId).then(res=>{
if(res.status ==200) {
this.loading = 2;
this.tableData = res.result;
let len=res.result.length;
let times=this.testPaper.times? this.testPaper.times:0;
if(times!=0 && len>=times){
//考试次数限制
this.tipText='已达到允许考试次数上限';
}
}else{
this.loading = 2;
this.$message.error('加载考试记录失败');
}
})
},
//开始考试
startTest(){
this.curTestAnswer={};
// 先禁用,防止重复提交
if(this.testPaper.entranceTime && this.testPaper.entranceTime !=='') {
let time = new Date();
let entranceTime = new Date(this.testPaper.entranceTime);
if(time < entranceTime) {
this.$message.warning('考试还未开始,请耐心等候!')
return;
}
}
this.startButton = true;
this.remainingTime = this.testPaper.testDuration * 60;
//提取考试试卷内容
let startParams={
exam:this.examId,
task:this.taskId,
lastId:this.lastId
}
let $this=this;
apiTestPaper.getTestStart(startParams).then(rs=>{
if(rs.status==200){
//处理试卷内容
this.paperQuestion=JSON.parse(rs.result.paper);
if(this.paperQuestion.length==0){
this.$message.error('此考试无试题内容,可能试卷已删除,请与管理员联系');
}else{
this.arrangeQuestion();
this.splitQuestionType();
//进入考试阶段
this.testStatus = 2;
this.startReckon();
//60秒后执行保存处理
this.startUpdateAnswer();
// window.setTimeout(function(){
// $this.saveUserTest();
// },10000);
}
}else{
this.startButton = false;
this.$message.error('加载试卷内容失败:'+rs.message);
}
});
},
closeTest(){
window.location.href='test?id='+this.examId;
},
saveUserTest(){ //保存用户的考试,此时包括了考试信息,不只是答案,先在后台建立一条记录
if(this.handleSaveTest!=null){
window.clearTimeout(this.handleSaveTest);
}
if(this.testStatus!=2){
//只有在第二阶段才会保存
return;
}
//一个题都没有答的情况,不能提交
let strAnswer=this.getAnswer();
let objAnswer=JSON.parse(strAnswer);
let total=0;
let hasOne=false;
this.paperQuestion.forEach(item=>{
if(item.defaultScore){
total+=item.defaultScore;
}
if(item.type<900){
if(objAnswer[item.id]!=''){
hasOne=true;
}
}
});
if(!hasOne){
return;
}
let that = this;
let data = {};
data.testId = this.testPaper.id;
data.testName = this.testPaper.testName;
data.testDuration = this.testPaper.testDuration;
data.useSecond=10;//用时秒
data.arrange = this.testPaper.arrange;
data.passLine = this.testPaper.passLine;
data.ucode = this.userInfo.userNo;
data.paperJson = this.clearPagerJson();
data.answerJson=strAnswer;
data.totalScore=total;
//计算出当前的成绩
data.realScore=this.countScore();
apiTestPaper.start(data).then((res) => {
if(res.status == 200){
that.aloneExamAnswerId = res.result.id;
that.curTestAnswer=res.result;//
//that.startUpdateAnswer();
}else{
this.$message.error(res.message);
}
})
},
clearPagerJson(){
let paperJson = [];
this.paperQuestion.forEach((item,index) => {
let option = {
id:item.id,
optionList:[]
};
item.optionList.forEach(it=>{
option.optionList.push({id:it.id})
})
paperJson.push(option);
})
return JSON.stringify(paperJson);
},
countScore(){
let total=0;
if(this.judge.length > 0){
this.judge.forEach(item => {
//console.log(total,'判断',item);
if(item.answer=='true' && item.userAnswer=='true'){
total+=item.defaultScore;
}else{
if(item.answer=='false' && item.userAnswer=='false'){
total+=item.defaultScore;
}
}
//console.log(total,'分数');
});
}
if(this.single.length > 0){
this.single.forEach(item => {
item.optionList.forEach(opt=>{
if(opt.id==item.userAnswer && opt.isAnswer){
total+=item.defaultScore;
}
})
});
}
if(this.multiple.length > 0){
this.multiple.forEach(item => {
//提取正确答案
let tempAnswer=[];
item.optionList.forEach(opt=>{
if(opt.isAnswer){
tempAnswer.push(opt.id);
}
})
tempAnswer.sort(function(n1,n2){
return n1>n2? -1:1;
});
if(item.userAnswer){
item.userAnswer.sort(function(n1,n2){
return n1>n2? -1:1;
});
}
let str1=item.userAnswer.join();
let str2=tempAnswer.join();
if(str1==str2){
console.log('str1='+str1);
console.log('str2='+str2);
total+=item.defaultScore;
}
});
}
console.log('实际得分:'+total)
return total;
},
reStartTest(row){ //继续考试
this.curTestAnswer=row;
apiTestPaper.getAnswerDetail(row.id).then(res=>{
if(res.status === 200) {
this.paperQuestion= JSON.parse(res.result.paperJson);
//填充答案
let answerJson = JSON.parse(res.result.answerJson);
//设置已答题内容
this.paperQuestion.forEach((qitem,index) => {
let avalue=answerJson[qitem.id];
if(avalue){
if(qitem.type==1){ //单选
qitem.userAnswer=avalue;
}else if(qitem.type==2){ //多选
qitem.userAnswer=avalue.split(',');
}else if(qitem.type==3){ //判断
qitem.userAnswer=avalue;
//console.log(avalue,'avalue');
}
}
});
//console.log(this.paperQuestion,'this.paperQuestion')
this.arrangeQuestion();
this.splitQuestionType();
//进入考试阶段
this.testStatus = 2;
if(res.result.useSecond){
this.remainingTime=this.testPaper.testDuration*60-res.result.useSecond;
}else{
this.remainingTime=this.testPaper.testDuration*60;
}
this.startReckon();
//启时定时保存
this.aloneExamAnswerId = row.id;
this.startUpdateAnswer();
}else{
this.$message.error('读取已考试卷错误:'+res.message);
}
});
},
formatSeconds(time){
return formatSeconds(time);
},
numberToLetter(x){
return numberToLetter(x);
},
//试题排序
arrangeQuestion() {
if (this.testPaper.arrange) {
if (this.testPaper.arrange == 1 || this.testPaper.arrange == 3) {
this.randArray(this.paperQuestion, this.paperQuestion.length)
}
if(this.testPaper.arrange == 2 || this.testPaper.arrange == 3){
this.paperQuestion.forEach((item) => {
if (item.optionList && item.optionList.length > 0) {
this.randArray(item.optionList, item.optionList.length)
}
})
}
}
},
// 拆分题型,用于页面显示
splitQuestionType() {
this.judge = this.splitByType(this.paperQuestion, 3)
this.single = this.splitByType(this.paperQuestion, 1)
this.multiple = this.splitByType(this.paperQuestion, 2)
},
// 按题目类型拆分数组
splitByType(arr, type) {
let result = []
arr.forEach((item, i) => {
if (item.type == type) {
if(!item.userAnswer){
if(type == 1){
this.$set(item, 'userAnswer', null)
}else if (type == 2) {
// 多选题,多选题的答案是数组初始化会报错且必须通过this.$set初始化
this.$set(item, 'userAnswer', [])
}else if(type == 3){
this.$set(item, 'userAnswer', null)
}
}
result.push(item)
}
})
return result
},
// 数组乱序
randArray(m, len) {
m.sort(function () {
return Math.random() - 0.5
})
return m.slice(0, len)
},
// 开始计时,计时过程中如果最后到0了自动提交
startReckon:function(){
let that = this;
this.reckonTimeer = window.setInterval(function(){
if(that.remainingTime <= 0){
that.stopReckon();
that.stopUpdateAnswer();
that.$message({
type: 'success',
message: '考试时间已结束,自动提交试卷'
});
that.submit(0);//表时间表了自动提交
}else{
that.remainingTime--;
}
},1000);
},
// 停止计时
stopReckon:function(){
window.clearInterval(this.reckonTimeer)
},
/**
* 开始提交答案
*/
startUpdateAnswer:function(){
if(this.paperQuestion.length==0){
return;
}
if(this.updateAnswerTimeer!=null){
window.clearInterval(this.updateAnswerTimeer)
}
let that = this;
this.updateAnswerTimeer =window.setInterval(function(){
that.updateAnswer();
},10000);//测试时可以修改的变小了
},
// 停止提交答案
stopUpdateAnswer(){
window.clearInterval(this.updateAnswerTimeer)
},
getAnswer:function(){
let answer = {};
if(this.judge.length > 0){
this.judge.forEach(item => {
let judgeUserAnswer = "";
//if(String(item.userAnswer) && item.userAnswer != null){
judgeUserAnswer = item.userAnswer + "";
//}
answer[item.id] = judgeUserAnswer;
});
}
if(this.single.length > 0){
this.single.forEach(item => {
let singleUserAnswer = "";
if(item.userAnswer && item.userAnswer != null){
singleUserAnswer = item.userAnswer + "";
}
answer[item.id]=singleUserAnswer;
});
}
if(this.multiple.length > 0){
this.multiple.forEach(item => {
let multipleUserAnswer = "";
if(item.userAnswer && item.userAnswer != null && item.userAnswer.length > 0){
multipleUserAnswer = item.userAnswer.join(",");
}
answer[item.id]=multipleUserAnswer;
});
}
return JSON.stringify(answer);
},
//自动保存提交答案
updateAnswer:function(){
if(!this.aloneExamAnswerId){
this.saveUserTest();
return;
}
let data = {};
data.id = this.aloneExamAnswerId;
data.json = this.getAnswer();
//检查
data.second=this.testPaper.testDuration*60-this.remainingTime;
data.score=this.countScore();
apiTestPaper.updateAnswer(data).then((res) => {
if (res.status == 200) {
}else{
console.log('自动记录答卷失败:'+res.message,res.error);
}
})
},
// 人工提交
manualSubmit(){
// let tempScore=this.countScore();
let that = this;
this.$confirm('您确定要提交试卷吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
that.stopUpdateAnswer();
that.submit(1);//人工提交
}).catch(() => { });
},
// 提交考卷
submit(t){
// if(!this.aloneExamAnswerId || !this.curTestAnswer.totalScore){
// this.$message.error('请先答题');
// return;
// }
let strAnswer=this.getAnswer();
//一个题都没有答的情况,不能提交
let objAnswer=JSON.parse(strAnswer);
let total=0;
let hasOne=false;
this.paperQuestion.forEach(item=>{
if(item.defaultScore){
total+=item.defaultScore;
}
if(item.type<900){
if(objAnswer[item.id]!=''){
hasOne=true;
}
}
});
if(!hasOne){
if(t==1){
this.$message.error('请先答题再提交');
return;
}else{
this.testStatus = 3;
//转化为百分制显示
this.score = 0;
this.submitButton = false;
return;
}
}
let that = this;
this.submitButton = true;
let data = {};
data.id = this.aloneExamAnswerId;
data.testId = this.testPaper.id;
data.testName = this.testPaper.testName;
data.testDuration = this.testPaper.testDuration;
data.arrange = this.testPaper.arrange;
data.passLine = this.testPaper.passLine;
data.ucode = this.userInfo.userNo;
if(!this.aloneExamAnswerId){
//大字段在需要的时候才会提交
data.paperJson = JSON.stringify(this.paperQuestion);
}
data.scoreType=this.testPaper.scoringType;
data.taskId = this.taskId;
data.totalScore=total;
data.answerJson = strAnswer;
data.realScore=this.countScore();;
data.useSecond=this.testPaper.testDuration*60-this.remainingTime;
//计算百分制显示
data.score=data.realScore*100/data.totalScore;
apiTestPaper.submit(data).then((res) => {
if (res.status == 200) {
this.testStatus = 3;
//转化为百分制显示
this.score = data.score;
this.submitButton = false;
} else {
this.submitButton = false;
this.$message.error(res.message)
}
})
},
},
}
</script>
<style scoped lang="scss">
.no-text{
text-align: center;
margin-top: 50px;
color: red;
}
.upaper{
text-align: left;
.upaper-item{
border-bottom: 1px solid #dadada;
padding: 10px;
.upaper-item-q{
padding: 8px 0px;
}
.upaper-item-opts{
padding: 8px 0px;
line-height: 20px;
.upaper-item-opt{
min-height: 50px;
border-radius: 4px;
display: flex;
background-color: #FFFFFF;
justify-content: space-between;
padding: 10px 20px;
}
.upaper-item-opt-user{
background-color: #fff3e5;
}
}
.upaper-item-answer{
display: flex;
.upaper-item-answer-cell{
margin-right: 20px;
}
}
}
}
.re-list{
margin-top: 50px;
p{
margin: 20px;
margin-left: 0;
font-size: 24px;
}
}
.test {
width: 900px;
margin: 0 auto;
background: #fff;
padding-bottom: 100px;
}
.title {
font-size: 30px;
line-height: 65px;
text-align: center;
}
.test-info {
// text-align: center;
width: 500px;
margin: 0 auto;
background: #eee;
border-radius: 16px;
ul{
list-style:none;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
padding: 20px;
li{
flex: 50%;
line-height: 60px;
}
}
span {
margin: 0 20px;
}
}
.question-type {
font-weight: 500;
font-size: 20px;
line-height: 45px;
background: rgb(250, 244, 244);
padding-left: 20px;
}
.question-info{
margin: 5px 0;
padding: 20px
}
.question-option{
margin: 5px 0;
}
.test-time {
text-align: center;
line-height: 45px;
.reckon-time {
color: red;
}
}
.test-submit{
text-align: center;
line-height: 65px;
}
</style>