|
|
@@ -1,11 +1,11 @@
|
|
|
<!-- 开始训练 -->
|
|
|
<template>
|
|
|
- <div class="app-container startTraining-addPage">开始训练
|
|
|
+ <div class="app-container startTraining-addPage">
|
|
|
<div class="page-container-top-max-big-box">
|
|
|
<p class="top-1-p">开始训练</p>
|
|
|
<p class="top-2-p" @click="backPage()">返回</p>
|
|
|
</div>
|
|
|
- <div class="content-box" v-if="pageType === 1">
|
|
|
+ <div class="content-box">
|
|
|
<!-- 左侧面板 -->
|
|
|
<div class="left-panel">
|
|
|
<div class="exam-title">刷题练习</div>
|
|
|
@@ -88,44 +88,27 @@
|
|
|
<div class="question-button-box">
|
|
|
<p class="previous-question" :class="!isFirstQuestion?'check-button':''" @click="prevQuestion">上一题</p>
|
|
|
<p class="null-p"></p>
|
|
|
- <!--<p class="submit-exam" @click="submitExam()">交卷</p>-->
|
|
|
<p class="null-p"></p>
|
|
|
<p class="next-question" :class="!isLastQuestion?'check-button':''" @click="nextQuestion">下一题</p>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="shade-max-big-box" v-if="shadeType">
|
|
|
- <div class="shade-big-box">
|
|
|
- <div class="title-box">
|
|
|
- <p><span>{{shadeData.totalScore}}</span>分</p>
|
|
|
- </div>
|
|
|
- <p class="text-p">{{shadeData.type==1?'本次模拟考试成绩不及格!':(shadeData.type==2?'本次模拟考试成绩有效':'')}}</p>
|
|
|
- <div class="button-box">
|
|
|
- <p class="null-p"></p>
|
|
|
- <p class="button-p-2" v-if="shadeData.type == 1" @click="retakeExam()">重新考试</p>
|
|
|
- <p class="button-p-2" v-if="shadeData.type == 2" @click="backPage()">确定</p>
|
|
|
- <p class="null-p"></p>
|
|
|
- </div>
|
|
|
- <p class="out-button el-icon-close" @click="backPage()"></p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import {
|
|
|
- examUserPracticePanel, examUserPracticeQuestionDetail,
|
|
|
+ examUserPracticeTrainPanel, examUserPracticeQuestionDetail,
|
|
|
examUserPracticeSubmit,
|
|
|
examUserExamSubmit,examUserExamStart,
|
|
|
} from '@/api/safetyEducationExaminationNew/index'
|
|
|
export default {
|
|
|
name: 'addPage',
|
|
|
props: {
|
|
|
- propsData: {}
|
|
|
+ startTrainingPropsData: {}
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
- pageType:1,
|
|
|
newData: {},
|
|
|
//考试信息
|
|
|
examInfo: {
|
|
|
@@ -146,7 +129,6 @@
|
|
|
totalScore:0,//分数
|
|
|
canContinueExam:0, //重新考试 0不可以1可以
|
|
|
},
|
|
|
- historyOfIncorrectQuestionsPropsData:{},
|
|
|
viewAnswerShowType:false,
|
|
|
}
|
|
|
},
|
|
|
@@ -218,18 +200,23 @@
|
|
|
return
|
|
|
}
|
|
|
this.$nextTick(() => {
|
|
|
- this.examUserPracticePanel();
|
|
|
+ this.examUserPracticeTrainPanel();
|
|
|
})
|
|
|
},
|
|
|
//左侧数据
|
|
|
- examUserPracticePanel(){
|
|
|
- examUserPracticePanel({ knowledgePointId: this.newData.knowledgePointId, }).then(response => {
|
|
|
+ examUserPracticeTrainPanel(){
|
|
|
+ examUserPracticeTrainPanel(this.newData).then(response => {
|
|
|
this.$set(this,'groupIndex',0);
|
|
|
this.$set(this,'questionIndex',0);
|
|
|
this.$set(this, 'examInfo', {
|
|
|
knowledgePointName: response.data.knowledgePointName ? response.data.knowledgePointName : '',
|
|
|
totalCount: response.data.totalCount ? response.data.totalCount : 0,
|
|
|
})
|
|
|
+ for(let i=0;i<response.data.questionTypeGroups.length;i++){
|
|
|
+ for(let o=0;o<response.data.questionTypeGroups[i].questions.length;o++){
|
|
|
+ response.data.questionTypeGroups[i].questions[o].userAnswer='';
|
|
|
+ }
|
|
|
+ }
|
|
|
this.$set(this, 'questionTypeGroups', response.data.questionTypeGroups)
|
|
|
// 默认选中第一题(假数据直接从 data 里读取,无需接口)
|
|
|
const firstGroup = this.questionTypeGroups[0]
|
|
|
@@ -252,76 +239,53 @@
|
|
|
}else if(item.questionType == 3){
|
|
|
item.userAnswer = [minItem.optionTag]
|
|
|
}
|
|
|
+ this.checkAnswer(item.correctAnswer,item.userAnswer)
|
|
|
+ this.$set(this.questionTypeGroups[this.groupIndex].questions[this.questionIndex],'userAnswer',item.userAnswer+'');
|
|
|
+ // this.$set(this.questionTypeGroups[this.groupIndex].questions[this.questionIndex],'answerStatus',response.data.answerStatus);
|
|
|
+ },
|
|
|
+ checkAnswer(correctAnswer, userAnswer) {
|
|
|
+ // 1. 防御性编程:处理空值或异常数据
|
|
|
+ if (!correctAnswer || !Array.isArray(userAnswer)) return 2;
|
|
|
+ // 2. 将正确答案字符串统一切割为数组,并去除可能的空格
|
|
|
+ // 'C' -> ['C']
|
|
|
+ // 'A,B,C' -> ['A', 'B', 'C']
|
|
|
+ const correctArr = correctAnswer.split(',').map(item => item.trim());
|
|
|
+ // 3. 核心判断:两个数组长度必须一致,且正确数组中的每一项都存在于用户选择中
|
|
|
+ // 这样可以完美处理 ['A','B'] 和 ['B','A'] 顺序不一致的情况
|
|
|
+ const isCorrect =
|
|
|
+ correctArr.length === userAnswer.length &&
|
|
|
+ correctArr.every(item => userAnswer.includes(item));
|
|
|
+ this.$set(this.questionTypeGroups[this.groupIndex].questions[this.questionIndex],'answerStatus',isCorrect ? 1 : 2);
|
|
|
+ // return isCorrect ? 1 : 2;
|
|
|
},
|
|
|
// 上一题
|
|
|
prevQuestion() {
|
|
|
// 如果已经是第一题,不做任何操作
|
|
|
if (this.isFirstQuestion) return
|
|
|
- //判断当前提是否已作答
|
|
|
- if(this.currentQuestion.userAnswer[0]){
|
|
|
- examUserPracticeSubmit({
|
|
|
- attemptId: this.newData.attemptId,
|
|
|
- questionId:this.currentQuestion.id,
|
|
|
- userAnswer:this.currentQuestion.userAnswer+'',
|
|
|
- }).then(response => {
|
|
|
- this.$set(this.questionTypeGroups[this.groupIndex].questions[this.questionIndex],'answerStatus',response.data.answerStatus);
|
|
|
- //切换索引至下一题
|
|
|
- if (this.questionIndex > 0) {
|
|
|
- // 当前组内还有上一题,直接题索引减 1
|
|
|
- this.questionIndex--
|
|
|
- } else {
|
|
|
- // 当前已经是该组的第一题,需要切换到上一个组的最后一题
|
|
|
- this.groupIndex--
|
|
|
- const prevGroup = this.questionTypeGroups[this.groupIndex]
|
|
|
- this.questionIndex = prevGroup.questions.length - 1
|
|
|
- }
|
|
|
- })
|
|
|
- }else{
|
|
|
- //切换索引至下一题
|
|
|
- if (this.questionIndex > 0) {
|
|
|
- // 当前组内还有上一题,直接题索引减 1
|
|
|
- this.questionIndex--
|
|
|
- } else {
|
|
|
- // 当前已经是该组的第一题,需要切换到上一个组的最后一题
|
|
|
- this.groupIndex--
|
|
|
- const prevGroup = this.questionTypeGroups[this.groupIndex]
|
|
|
- this.questionIndex = prevGroup.questions.length - 1
|
|
|
- }
|
|
|
+ //切换索引至下一题
|
|
|
+ if (this.questionIndex > 0) {
|
|
|
+ // 当前组内还有上一题,直接题索引减 1
|
|
|
+ this.questionIndex--
|
|
|
+ } else {
|
|
|
+ // 当前已经是该组的第一题,需要切换到上一个组的最后一题
|
|
|
+ this.groupIndex--
|
|
|
+ const prevGroup = this.questionTypeGroups[this.groupIndex]
|
|
|
+ this.questionIndex = prevGroup.questions.length - 1
|
|
|
}
|
|
|
},
|
|
|
// 下一题
|
|
|
nextQuestion() {
|
|
|
// 如果已经是最后一题,不做任何操作
|
|
|
if (this.isLastQuestion) return
|
|
|
- //判断当前提是否已作答
|
|
|
- if(this.currentQuestion.userAnswer[0]){
|
|
|
- examUserPracticeSubmit({
|
|
|
- questionId:this.currentQuestion.id,
|
|
|
- userAnswer:this.currentQuestion.userAnswer+'',
|
|
|
- }).then(response => {
|
|
|
- this.$set(this.questionTypeGroups[this.groupIndex].questions[this.questionIndex],'answerStatus',response.data.answerStatus);
|
|
|
- //切换索引至下一题
|
|
|
- const currentGroup = this.questionTypeGroups[this.groupIndex]
|
|
|
- if (this.questionIndex < currentGroup.questions.length - 1) {
|
|
|
- // 当前组内还有下一题,直接题索引加 1
|
|
|
- this.questionIndex++
|
|
|
- } else {
|
|
|
- // 当前已经是该组的最后一题,需要切换到下一个组的第一题
|
|
|
- this.groupIndex++
|
|
|
- this.questionIndex = 0
|
|
|
- }
|
|
|
- })
|
|
|
- }else{
|
|
|
- //切换索引至下一题
|
|
|
- const currentGroup = this.questionTypeGroups[this.groupIndex]
|
|
|
- if (this.questionIndex < currentGroup.questions.length - 1) {
|
|
|
- // 当前组内还有下一题,直接题索引加 1
|
|
|
- this.questionIndex++
|
|
|
- } else {
|
|
|
- // 当前已经是该组的最后一题,需要切换到下一个组的第一题
|
|
|
- this.groupIndex++
|
|
|
- this.questionIndex = 0
|
|
|
- }
|
|
|
+ //切换索引至下一题
|
|
|
+ const currentGroup = this.questionTypeGroups[this.groupIndex]
|
|
|
+ if (this.questionIndex < currentGroup.questions.length - 1) {
|
|
|
+ // 当前组内还有下一题,直接题索引加 1
|
|
|
+ this.questionIndex++
|
|
|
+ } else {
|
|
|
+ // 当前已经是该组的最后一题,需要切换到下一个组的第一题
|
|
|
+ this.groupIndex++
|
|
|
+ this.questionIndex = 0
|
|
|
}
|
|
|
},
|
|
|
//右侧数据
|
|
|
@@ -329,6 +293,12 @@
|
|
|
examUserPracticeQuestionDetail({
|
|
|
questionId: questionId,
|
|
|
}).then(response => {
|
|
|
+ if(response.data.questionType == 3){
|
|
|
+ response.data.options = [
|
|
|
+ { optionContent:"对",optionTag:"Y",sortOrder:1 },
|
|
|
+ { optionContent:"错",optionTag:"N",sortOrder:2 },
|
|
|
+ ]
|
|
|
+ }
|
|
|
response.data.userAnswer = userAnswer?userAnswer.split(','):[];
|
|
|
this.$set(this, 'currentQuestion', response.data)
|
|
|
this.$set(this, 'viewAnswerShowType', false)
|
|
|
@@ -338,96 +308,15 @@
|
|
|
backPage() {
|
|
|
this.$router.back()
|
|
|
},
|
|
|
- //交卷按钮
|
|
|
- submitExam(){
|
|
|
- let self = this;
|
|
|
- let num = 0;
|
|
|
- for(let i=0;i<self.questionTypeGroups.length;i++){
|
|
|
- for(let o=0;o<self.questionTypeGroups[i].questions.length;o++){
|
|
|
- if(self.questionTypeGroups[i].questions[o].answerStatus == 0){
|
|
|
- num++
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- self.$confirm(num==0?'确认要交卷吗?':'还有'+num+'题未答,确认要交卷吗??', "提示", {
|
|
|
- confirmButtonText: "确定",
|
|
|
- cancelButtonText: "取消",
|
|
|
- type: "warning"
|
|
|
- }).then(async () => {
|
|
|
- self.examUserExamAnswerSaveExamUserExamSubmit();
|
|
|
- }).catch(() => {})
|
|
|
- },
|
|
|
- examUserExamAnswerSaveExamUserExamSubmit(){
|
|
|
- if(this.currentQuestion.userAnswer[0]){
|
|
|
- examUserPracticeSubmit({
|
|
|
- attemptId: this.newData.attemptId,
|
|
|
- questionId:this.currentQuestion.id,
|
|
|
- userAnswer:this.currentQuestion.userAnswer+'',
|
|
|
- }).then(response => {
|
|
|
- this.$set(this.questionTypeGroups[this.groupIndex].questions[this.questionIndex],'answerStatus',response.data.answerStatus);
|
|
|
- this.examUserExamSubmit();
|
|
|
- })
|
|
|
- }else{
|
|
|
- this.examUserExamSubmit();
|
|
|
- }
|
|
|
- },
|
|
|
- //交卷
|
|
|
- examUserExamSubmit(){
|
|
|
- examUserExamSubmit({ attemptId: this.newData.attemptId, }).then(response => {
|
|
|
- this.$set(this,'shadeData',{
|
|
|
- type:response.data.totalScore >= this.examInfo.totalScore?2:1,
|
|
|
- totalScore:response.data.totalScore,
|
|
|
- canContinueExam:0,
|
|
|
- });
|
|
|
- this.$set(this,'shadeType',true);
|
|
|
- })
|
|
|
- },
|
|
|
- //查看错题
|
|
|
- reviewMistakes(){
|
|
|
- this.$set(this,'historyOfIncorrectQuestionsPropsData',{
|
|
|
- type:2,
|
|
|
- attemptId:this.newData.attemptId,
|
|
|
- });
|
|
|
- this.$set(this,'shadeType',false);
|
|
|
- this.$set(this,'pageType',2);
|
|
|
- },
|
|
|
//查看错题返回
|
|
|
tableButton(){
|
|
|
this.$router.back();
|
|
|
},
|
|
|
- //重新考试
|
|
|
- retakeExam(){
|
|
|
- examUserExamStart({examId:this.newData.examId,examScene:2,}).then(response => {
|
|
|
- if(response.data.attemptId){
|
|
|
- this.$set(this.newData, 'attemptId',response.data.attemptId)
|
|
|
- this.$set(this,'shadeType',false);
|
|
|
- this.$nextTick(() => {
|
|
|
- this.examUserPracticePanel();
|
|
|
- })
|
|
|
- }else{
|
|
|
- this.msgError(response.message)
|
|
|
- this.$router.back()
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
// 点击左侧题号:切换当前题目,按需从接口加载详情
|
|
|
selectQuestion(item, index, minIndex) {
|
|
|
- if(this.currentQuestion.userAnswer[0]){
|
|
|
- examUserPracticeSubmit({
|
|
|
- attemptId: this.newData.attemptId,
|
|
|
- questionId:this.currentQuestion.id,
|
|
|
- userAnswer:this.currentQuestion.userAnswer+'',
|
|
|
- }).then(response => {
|
|
|
- this.$set(this.questionTypeGroups[this.groupIndex].questions[this.questionIndex],'answerStatus',response.data.answerStatus);
|
|
|
- this.$set(this, 'groupIndex', index)
|
|
|
- this.$set(this, 'questionIndex', minIndex)
|
|
|
- this.examUserPracticeQuestionDetail(item.questionId,item.userAnswer)
|
|
|
- })
|
|
|
- }else {
|
|
|
- this.$set(this, 'groupIndex', index)
|
|
|
- this.$set(this, 'questionIndex', minIndex)
|
|
|
- this.examUserPracticeQuestionDetail(item.questionId,item.userAnswer)
|
|
|
- }
|
|
|
+ this.$set(this, 'groupIndex', index)
|
|
|
+ this.$set(this, 'questionIndex', minIndex)
|
|
|
+ this.examUserPracticeQuestionDetail(item.questionId,item.userAnswer)
|
|
|
},
|
|
|
// 判断选项是否被选中
|
|
|
isSelectedOption(q, key) {
|