1021 lines
31 KiB
Vue
1021 lines
31 KiB
Vue
<template>
|
|
<view class="wrapper">
|
|
<div class="top-time">已用时间 {{ usedTime }}</div>
|
|
<div class="num-wrapper">
|
|
<div class="correct">
|
|
<u-icon name="/static/images/true.png" size="15" />
|
|
<div class="num">{{ trueNum }}</div>
|
|
</div>
|
|
<div class="error">
|
|
<u-icon name="/static/images/error.png" size="15" />
|
|
<div class="num">{{ falseNum }}</div>
|
|
</div>
|
|
<div class="total" @click="openSelect">
|
|
<u-icon name="/static/images/quanbufenlei.png" size="15" />
|
|
<div class="num">{{ nowNum }}/{{ allNum }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="question-wrapper" v-for="(item, index) in questionList" :key="index">
|
|
<div v-if="item.examType != 2">
|
|
<div class="title">{{ nowNum }}.{{ item.paperTopic }}{{ item.examType == 1 ? '(单选题)' : '(判断题)' }}</div>
|
|
<u--image
|
|
v-if="item.paperTopicUrl"
|
|
:showLoading="true"
|
|
:src="fileUrl + item.paperTopicUrl || ''"
|
|
width="60px"
|
|
height="60px"
|
|
style="margin-bottom: 10px"
|
|
@click="clickImg(fileUrl + item.paperTopicUrl || '')"
|
|
/>
|
|
<div class="options">
|
|
<div
|
|
class="option"
|
|
v-for="(option, index) in item.listOption"
|
|
:key="index"
|
|
@click="handleOption(option, index)"
|
|
:class="{ active: option.isCorrect || option.isError }"
|
|
>
|
|
<div class="label-wrapper">
|
|
<div class="label">
|
|
<div style="width: 18px">{{ option.optionIdent }}.</div>
|
|
<div class="label-cont">{{ option.optionContent }}</div>
|
|
</div>
|
|
<u--image
|
|
v-if="option.optionUrl"
|
|
:showLoading="true"
|
|
:src="fileUrl + option.optionUrl"
|
|
width="60px"
|
|
height="60px"
|
|
style="margin: 10px 0"
|
|
@click="clickImg(fileUrl + option.optionUrl)"
|
|
/>
|
|
</div>
|
|
<u-icon v-if="option.isCorrect" name="/static/images/right.png" size="25" />
|
|
<u-icon v-if="option.isError" name="/static/images/err.png" size="25" />
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="item.isSelect">
|
|
<div>正确答案:{{ item.correctGrade }}</div>
|
|
<div>你的答案:{{ item.select }}</div>
|
|
|
|
<div>
|
|
<div class="analysis">答案解析:</div>
|
|
<div class="analysis-container">{{ item.answerAnaly }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 多选 -->
|
|
<div v-else-if="item.examType == 2">
|
|
<div class="title">{{ nowNum }}. {{ item.paperTopic }}(多选题)</div>
|
|
<u--image
|
|
v-if="item.paperTopicUrl"
|
|
:showLoading="true"
|
|
:src="fileUrl + item.paperTopicUrl || ''"
|
|
width="60px"
|
|
height="60px"
|
|
style="margin-bottom: 10px"
|
|
@click="clickImg(fileUrl + item.paperTopicUrl || '')"
|
|
/>
|
|
<div class="options">
|
|
<div
|
|
class="option"
|
|
v-for="(option, index) in item.listOption"
|
|
:key="index"
|
|
@click="handleCheckbox(option, index, item)"
|
|
:class="{ active: option.isCheck || option.isCorrect || option.isError }"
|
|
>
|
|
<div class="label-wrapper">
|
|
<div class="label">
|
|
<div style="width: 18px">{{ option.optionIdent }}.</div>
|
|
<div class="label-cont">{{ option.optionContent }}</div>
|
|
</div>
|
|
<u--image
|
|
v-if="option.optionUrl"
|
|
:showLoading="true"
|
|
:src="fileUrl + option.optionUrl"
|
|
width="60px"
|
|
height="60px"
|
|
style="margin: 10px 0"
|
|
@click="clickImg(fileUrl + option.optionUrl)"
|
|
/>
|
|
</div>
|
|
<u-icon v-if="option.isCorrect" name="/static/images/right.png" size="25" />
|
|
<u-icon v-if="option.isError" name="/static/images/err.png" size="25" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="btn">
|
|
<u-button
|
|
v-show="item.listOption.some(option => option.isCheck) && !item.isSelect"
|
|
text="选好了"
|
|
shape="circle"
|
|
size="small"
|
|
color="linear-gradient(to right, rgba(47, 195, 255, 1), rgba(5, 70, 173, 1))"
|
|
@click="handleOk"
|
|
/>
|
|
</div>
|
|
|
|
<div v-if="item.isSelect">
|
|
<div>正确答案:{{ item.correctGrade.split('').join('、') }}</div>
|
|
<div>你的答案:{{ item.select && item.select.join('、') }}</div>
|
|
|
|
<div class="analysis">知识点</div>
|
|
<div class="analysis-container">{{ item.answerAnaly }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 底部按钮 -->
|
|
<div class="bottom-btn">
|
|
<div class="btn">
|
|
<u-button
|
|
type="primary"
|
|
size="small"
|
|
shape="circle"
|
|
text="提交"
|
|
color="linear-gradient(to right, rgba(250, 223, 103, 1), rgba(207, 163, 14, 1)"
|
|
@click="handleSubmit"
|
|
/>
|
|
</div>
|
|
<div class="btn">
|
|
<u-button
|
|
v-show="nowNum > 1"
|
|
type="primary"
|
|
size="small"
|
|
shape="circle"
|
|
text="上一题"
|
|
color="linear-gradient(to right, rgba(47, 195, 255, 1), rgba(5, 70, 173, 1))"
|
|
@click="handleJump('prev')"
|
|
/>
|
|
</div>
|
|
<div class="btn">
|
|
<u-button
|
|
v-show="nowNum < allNum"
|
|
type="primary"
|
|
size="small"
|
|
shape="circle"
|
|
text="下一题"
|
|
color="linear-gradient(to right, rgba(47, 195, 255, 1), rgba(5, 70, 173, 1))"
|
|
@click="handleJump('next')"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 提交弹框 -->
|
|
<u-modal
|
|
:show="showModal"
|
|
title="本次答题正确率"
|
|
showCancelButton
|
|
@cancel="handleConfirm"
|
|
@confirm="handleClose"
|
|
cancelText="继续答题"
|
|
confirmText="结束答题"
|
|
:buttonReverse="true"
|
|
confirmColor="#606266"
|
|
cancelColor="#2979ff"
|
|
>
|
|
<view class="slot-content">
|
|
<div class="correctRate">{{ correctRate }}%</div>
|
|
<div class="modal-container">
|
|
<div class="item">
|
|
<div class="num">{{ answerNum }}</div>
|
|
<div>答题数</div>
|
|
</div>
|
|
<div class="item">
|
|
<div class="num">{{ trueNum }}</div>
|
|
<div>正确数</div>
|
|
</div>
|
|
<div class="item">
|
|
<div class="num">{{ usedTime }}</div>
|
|
<div>答题时长</div>
|
|
</div>
|
|
</div>
|
|
</view>
|
|
</u-modal>
|
|
|
|
<!-- 题目选择弹框 -->
|
|
<u-modal :show="showModalSelect" title="题目选择" @confirm="showModalSelect = false">
|
|
<view class="slot-content">
|
|
<div class="topic-content">
|
|
<div
|
|
v-for="(item, index) in questionListSelect"
|
|
:key="index"
|
|
class="topic-wrapper"
|
|
:class="{ correct: item.isTrue == 1, error: item.isTrue == 0 }"
|
|
@click="handleJump('jump', item.index)"
|
|
>
|
|
<div v-if="currentIndex == item.index">*</div>
|
|
<div class="topic">{{ item.index }}</div>
|
|
</div>
|
|
</div>
|
|
</view>
|
|
</u-modal>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import {
|
|
getPracticeItData, // 获取练习上方题数
|
|
getPracticeQuestion, // 获取练习题目
|
|
insertPracticeAnswerById, // 提交答案
|
|
changeQuestion, // 切换题目
|
|
getPracticeQuestionList, // 获取题目列表-弹框
|
|
getPracticeQuestionRate, // 获取练习正确率
|
|
savePracticeDuration, // 保存练习时长
|
|
updateRemoveRecordData, // 错题消除记录
|
|
updStudyDurationExamPractice
|
|
} from '@/api/eduApp'
|
|
import config from '@/config'
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
isLoading: false,
|
|
practiceId: '', // 练习id
|
|
recordId: '', // 记录id
|
|
isNew: 1, // 是否新练习
|
|
isOutOfOrder: 1, // 是否乱序
|
|
isError: false, // 是否错题消除
|
|
nowNum: '', // 当前题目索引
|
|
showModal: false,
|
|
showModalSelect: false,
|
|
// 正确率
|
|
correctRate: '0',
|
|
// 已用时间 - 计时器 - 用于显示已用时间 格式 00:00:00
|
|
usedTime: '00:00:00',
|
|
serviceTime: 0,
|
|
// 正确题数
|
|
trueNum: 0,
|
|
// 错误题数
|
|
falseNum: 0,
|
|
allNum: 0, // 总题数
|
|
// 答题数
|
|
answerNum: 0,
|
|
// 当前题目索引
|
|
currentIndex: 0,
|
|
// 题目列表
|
|
questionList: [],
|
|
// 题目列表-弹框
|
|
questionListSelect: [],
|
|
studyId: '', // 学习id
|
|
fileUrl: config.fileUrl,
|
|
intervalId: '',
|
|
isEnd: false
|
|
}
|
|
},
|
|
onLoad(opt) {
|
|
opt = JSON.parse(opt.params)
|
|
this.practiceId = opt.practiceId
|
|
this.recordId = opt.recordId || ''
|
|
this.isNew = opt.isNew || ''
|
|
this.isOutOfOrder = opt.isOutOfOrder || ''
|
|
this.isError = opt.isError || ''
|
|
this.studyId = opt.studyId || ''
|
|
console.log('🚀 ~ onLoad ~ opt:', opt)
|
|
// 开始计时
|
|
this.startTimer()
|
|
this.getPracticeItData()
|
|
this.getPracticeQuestion()
|
|
},
|
|
onUnload() {
|
|
if (this.isEnd) return
|
|
// 清除计时器
|
|
clearInterval(this.intervalId)
|
|
this.handleClose()
|
|
},
|
|
methods: {
|
|
// 获取题目-上方数量
|
|
getPracticeItData() {
|
|
const params = {
|
|
practiceId: this.practiceId,
|
|
recordId: this.recordId,
|
|
isNew: this.isNew || '',
|
|
isMiss: this.isError ? '1' : ''
|
|
}
|
|
this.$verificationToken()
|
|
uni.request({
|
|
url: config.baseUrl + '/exam-student/studentPractice/getPracticeItData',
|
|
method: 'post',
|
|
data: params,
|
|
header: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
Authorization: uni.getStorageSync('access_token')
|
|
},
|
|
success: res => {
|
|
console.log('🚀 ~ getPracticeItData ~ res:', res)
|
|
res = res.data
|
|
this.trueNum = res.data.trueNum
|
|
this.falseNum = res.data.falseNum
|
|
this.allNum = res.data.allNum
|
|
this.nowNum = res.data.nowNum
|
|
},
|
|
fail: err => {
|
|
console.log(err)
|
|
}
|
|
})
|
|
},
|
|
// 获取题目
|
|
getPracticeQuestion() {
|
|
this.questionList = []
|
|
const params = {
|
|
practiceId: this.practiceId,
|
|
recordId: this.recordId,
|
|
isNew: this.isNew || '',
|
|
isOutOfOrder: this.isOutOfOrder || '',
|
|
isMiss: this.isError ? '1' : ''
|
|
}
|
|
// const res = await getPracticeQuestion(params)
|
|
// this.recordId = res.data.recordId
|
|
// this.questionList.push(res.data)
|
|
// console.log('🚀 ~ getPracticeQuestion ~ res:', res)
|
|
// console.log('🚀 ~ getPracticeQuestion ~ this.questionList:', this.questionList)
|
|
this.$verificationToken()
|
|
uni.request({
|
|
url: config.baseUrl + '/exam-student/studentPractice/getPracticeQuestion',
|
|
method: 'post',
|
|
data: params,
|
|
header: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
Authorization: uni.getStorageSync('access_token')
|
|
},
|
|
success: res => {
|
|
console.log('🚀 ~ getPracticeQuestion ~ res:', res)
|
|
res = res.data
|
|
this.questionList.push(res.data)
|
|
console.log('🚀 ~ getPracticeQuestion ~ :', this.questionList[0])
|
|
this.recordId = res.data.recordId ? res.data.recordId : this.recordId
|
|
if (res.data.selectAnswer) {
|
|
console.log('执行了--')
|
|
if (this.questionList[0].examType == 2) {
|
|
this.questionList[0].select = res.data.selectAnswer.split('')
|
|
this.questionList[0].isSelect = true
|
|
// 给selectAnswer选项如果正确添加正确标记, 错误添加错误标记并给正确选项添加标记
|
|
this.questionList[0].listOption.forEach(item => {
|
|
if (res.data.selectAnswer.includes(item.optionIdent)) {
|
|
item.isSelect = true
|
|
}
|
|
if (res.data.correctGrade.includes(item.optionIdent)) {
|
|
item.isCorrect = true
|
|
}
|
|
if (item.isSelect && !this.questionList[0].correctGrade.includes(item.optionIdent)) {
|
|
item.isError = true
|
|
}
|
|
})
|
|
} else {
|
|
this.questionList[0].select = res.data.selectAnswer
|
|
this.questionList[0].isSelect = true
|
|
// 给selectAnswer选项如果正确添加正确标记, 错误添加错误标记并给正确选项添加标记
|
|
this.questionList[0].listOption.forEach(item => {
|
|
if (res.data.selectAnswer === item.optionIdent) {
|
|
item.isSelect = true
|
|
}
|
|
if (item.optionIdent === this.questionList[0].correctGrade) {
|
|
item.isCorrect = true
|
|
}
|
|
if (item.isSelect && item.optionIdent !== this.questionList[0].correctGrade) {
|
|
item.isError = true
|
|
}
|
|
})
|
|
}
|
|
}
|
|
},
|
|
fail: err => {
|
|
console.log(err)
|
|
}
|
|
})
|
|
},
|
|
// 跳题
|
|
handleJump(item, index) {
|
|
console.log('🚀 ~ handleJump ~ item:', item, this.recordId)
|
|
if (item === 'prev') {
|
|
this.nowNum--
|
|
} else if (item === 'next') {
|
|
this.nowNum++
|
|
} else if (item === 'jump') {
|
|
this.nowNum = index
|
|
}
|
|
console.log('🚀 ~ handleJump ~ this.nowNum:', this.nowNum)
|
|
|
|
this.currentIndex = index
|
|
this.questionList = []
|
|
const params = {
|
|
recordId: this.recordId || '',
|
|
practiceId: this.practiceId,
|
|
operate: item || '',
|
|
sort: this.nowNum,
|
|
isMiss: this.isError ? '1' : ''
|
|
}
|
|
console.log('🚀 ~ handleJump ~ params:', params)
|
|
// const res = await changeQuestion(params)
|
|
// this.questionList.push(res.data)
|
|
// console.log('🚀 ~ handleJump ~ res:', res)
|
|
this.$verificationToken()
|
|
uni.request({
|
|
url: config.baseUrl + '/exam-student/studentPractice/changeQuestion',
|
|
method: 'post',
|
|
data: params,
|
|
header: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
Authorization: uni.getStorageSync('access_token')
|
|
},
|
|
success: res => {
|
|
console.log('🚀 ~ handleJump ~ res:', res)
|
|
res = res.data
|
|
this.questionList.push(res.data)
|
|
if (res.data.selectAnswer) {
|
|
if (this.questionList[0].examType == 2) {
|
|
this.questionList[0].select = res.data.selectAnswer.split('')
|
|
this.questionList[0].isSelect = true
|
|
// 给selectAnswer选项如果正确添加正确标记, 错误添加错误标记并给正确选项添加标记
|
|
this.questionList[0].listOption.forEach(item => {
|
|
if (res.data.selectAnswer.includes(item.optionIdent)) {
|
|
item.isSelect = true
|
|
}
|
|
if (res.data.correctGrade.includes(item.optionIdent)) {
|
|
item.isCorrect = true
|
|
}
|
|
if (item.isSelect && !this.questionList[0].correctGrade.includes(item.optionIdent)) {
|
|
item.isError = true
|
|
}
|
|
})
|
|
} else {
|
|
this.questionList[0].select = res.data.selectAnswer
|
|
this.questionList[0].isSelect = true
|
|
// 给selectAnswer选项如果正确添加正确标记, 错误添加错误标记并给正确选项添加标记
|
|
this.questionList[0].listOption.forEach(item => {
|
|
if (res.data.selectAnswer === item.optionIdent) {
|
|
item.isSelect = true
|
|
}
|
|
if (item.optionIdent === this.questionList[0].correctGrade) {
|
|
item.isCorrect = true
|
|
}
|
|
if (item.isSelect && item.optionIdent !== this.questionList[0].correctGrade) {
|
|
item.isError = true
|
|
}
|
|
})
|
|
}
|
|
}
|
|
},
|
|
fail: err => {
|
|
console.log(err)
|
|
}
|
|
})
|
|
},
|
|
// 获取题目列表-弹框
|
|
getPracticeQuestionList() {
|
|
const params = {
|
|
recordId: this.recordId,
|
|
practiceId: this.practiceId,
|
|
isMiss: this.isError ? '1' : ''
|
|
}
|
|
// const res = await getPracticeQuestionList(params)
|
|
// console.log('🚀 ~ getPracticeQuestionList ~ res:', res)
|
|
// this.questionListSelect = res.data
|
|
this.$verificationToken()
|
|
uni.request({
|
|
url: config.baseUrl + '/exam-student/studentPractice/getPracticeQuestionList',
|
|
method: 'post',
|
|
data: params,
|
|
header: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
Authorization: uni.getStorageSync('access_token')
|
|
},
|
|
success: res => {
|
|
console.log('🚀 ~ getPracticeQuestionList ~ res:', res)
|
|
res = res.data
|
|
this.questionListSelect = res.data
|
|
},
|
|
fail: err => {
|
|
console.log(err)
|
|
}
|
|
})
|
|
},
|
|
// 开始计时 - 实时更新已用时间
|
|
startTimer() {
|
|
this.intervalId = setInterval(() => {
|
|
this.serviceTime++
|
|
this.handleTime()
|
|
// const time = this.usedTime.split(':')
|
|
// let hours = parseInt(time[0])
|
|
// let minutes = parseInt(time[1])
|
|
// let seconds = parseInt(time[2])
|
|
// seconds++
|
|
// if (seconds === 60) {
|
|
// seconds = 0
|
|
// minutes++
|
|
// if (minutes === 60) {
|
|
// minutes = 0
|
|
// hours++
|
|
// }
|
|
// }
|
|
// this.usedTime = `${hours < 10 ? '0' + hours : hours}:${minutes < 10 ? '0' + minutes : minutes}:${
|
|
// seconds < 10 ? '0' + seconds : seconds
|
|
// }`
|
|
}, 1000)
|
|
},
|
|
// 处理时间
|
|
handleTime() {
|
|
// this.serviceTime 是秒数
|
|
let hours = parseInt(this.serviceTime / 3600)
|
|
let minutes = parseInt((this.serviceTime % 3600) / 60)
|
|
let seconds = parseInt(this.serviceTime % 60)
|
|
this.usedTime = `${hours < 10 ? '0' + hours : hours}:${minutes < 10 ? '0' + minutes : minutes}:${
|
|
seconds < 10 ? '0' + seconds : seconds
|
|
}`
|
|
},
|
|
clickImg(url) {
|
|
console.log('🚀 ~ clickImg ~ url:', url)
|
|
uni.previewImage({
|
|
urls: [url]
|
|
})
|
|
},
|
|
// 处理选项点击事件
|
|
handleOption(option, index) {
|
|
console.log(option, index, this.questionList[0])
|
|
// 判断是否已经选择过
|
|
if (this.questionList[0].isSelect) {
|
|
return
|
|
} else {
|
|
// 标记已选择
|
|
this.questionList[0].isSelect = true
|
|
// 判断是否正确
|
|
if (option.optionIdent === this.questionList[0].correctGrade) {
|
|
// 当前选择
|
|
this.questionList[0].select = option.optionIdent
|
|
// 给当前题目添加正确标记
|
|
this.questionList[0].isCorrect = true
|
|
// 正确 - 给当前选项添加正确标记
|
|
this.questionList[0].listOption[index].isCorrect = true
|
|
// 正确题数+1
|
|
this.trueNum++
|
|
} else {
|
|
// 当前选择
|
|
this.questionList[0].select = option.optionIdent
|
|
// 给当前题目添加错误标记
|
|
this.questionList[0].isError = true
|
|
// 错误 - 给当前选项添加错误标记
|
|
this.questionList[0].listOption[index].isError = true
|
|
// 并将正确选项标记
|
|
this.questionList[0].listOption.forEach(item => {
|
|
if (item.optionIdent === this.questionList[0].correctGrade) {
|
|
item.isCorrect = true
|
|
}
|
|
})
|
|
// 错误题数+1
|
|
this.falseNum++
|
|
}
|
|
const params = {
|
|
practiceId: this.practiceId,
|
|
recordId: this.recordId,
|
|
questionId: this.questionList[0].questionId,
|
|
selectAnswer: option.optionIdent,
|
|
isTrue: option.optionIdent == this.questionList[0].correctGrade ? 1 : 0,
|
|
isMiss: this.isError ? '1' : ''
|
|
}
|
|
console.log('🚀 ~ handleOption ~ params:', params)
|
|
// 提交答案
|
|
// insertPracticeAnswerById(params)
|
|
this.$verificationToken()
|
|
uni.request({
|
|
url: config.baseUrl + '/exam-student/studentPractice/insertPracticeAnswerById',
|
|
method: 'post',
|
|
data: params,
|
|
header: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
Authorization: uni.getStorageSync('access_token')
|
|
},
|
|
success: res => {
|
|
console.log('🚀 ~ handleOption ~ res:', res)
|
|
}
|
|
})
|
|
}
|
|
},
|
|
// 处理多选题选项点击事件
|
|
handleCheckbox(option, index, item) {
|
|
console.log('🚀 ~ handleCheckbox ~ option, index:', option, index)
|
|
if (item.isSelect) {
|
|
return
|
|
}
|
|
// 给当前点击的增加边框 再次点击取消
|
|
if (!option.isCheck) {
|
|
this.questionList[0].listOption[index].isCheck = !option.isCheck
|
|
} else {
|
|
this.questionList[0].listOption[index].isCheck = false
|
|
}
|
|
// 将 isCheck: true 的选项的 value 放入 select 数组
|
|
this.questionList[0].select = this.questionList[0].listOption
|
|
.filter(item => item.isCheck)
|
|
.map(item => item.optionIdent)
|
|
console.log('🚀 ~ handleCheckbox ~ this.questionList[0].select:', this.questionList[0].select)
|
|
},
|
|
handleOk() {
|
|
// 判断是否已经选择过
|
|
if (this.questionList[0].isSelect) {
|
|
return
|
|
} else {
|
|
// 标记已选择
|
|
this.questionList[0].isSelect = true
|
|
const select = this.questionList[0].select
|
|
const correctGrade = this.questionList[0].correctGrade.split('')
|
|
// 判断是否正确
|
|
const isCorrect = select.sort().toString() === correctGrade.sort().toString()
|
|
if (isCorrect) {
|
|
// 正确题数+1
|
|
this.trueNum++
|
|
// 给当前题目添加正确标记
|
|
this.questionList[0].listOption.forEach(item => {
|
|
if (item.isCheck) {
|
|
item.isCorrect = true
|
|
}
|
|
})
|
|
// 给正确选项添加标记
|
|
this.questionList[0].listOption.forEach(item => {
|
|
if (correctGrade.includes(item.optionIdent)) {
|
|
item.isCorrect = true
|
|
}
|
|
})
|
|
} else {
|
|
// 错误题数+1
|
|
this.falseNum++
|
|
// 给当前题目添加错误标记
|
|
this.questionList[0].isError = true
|
|
// 给错误选项添加标记
|
|
this.questionList[0].listOption.forEach(item => {
|
|
if (correctGrade.includes(item.optionIdent)) {
|
|
item.isCorrect = true
|
|
}
|
|
if (!correctGrade.includes(item.optionIdent) && item.isCheck) {
|
|
item.isError = true
|
|
}
|
|
})
|
|
}
|
|
const params = {
|
|
practiceId: this.practiceId,
|
|
recordId: this.recordId,
|
|
questionId: this.questionList[0].questionId,
|
|
selectAnswer: select.join(''),
|
|
isTrue: isCorrect ? 1 : 0,
|
|
isMiss: this.isError ? '1' : ''
|
|
}
|
|
console.log('🚀 ~ handleOk ~ params-多选:', params)
|
|
// insertPracticeAnswerById(params)
|
|
this.$verificationToken()
|
|
uni.request({
|
|
url: config.baseUrl + '/exam-student/studentPractice/insertPracticeAnswerById',
|
|
method: 'post',
|
|
data: params,
|
|
header: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
Authorization: uni.getStorageSync('access_token')
|
|
},
|
|
success: res => {
|
|
console.log('🚀 ~ handleOption ~ res:', res)
|
|
}
|
|
})
|
|
}
|
|
},
|
|
// 提交
|
|
handleSubmit() {
|
|
// 暂停时间
|
|
clearInterval(this.intervalId)
|
|
console.log('提交')
|
|
this.answerNum = this.trueNum + this.falseNum
|
|
let rate = ((Number(this.trueNum) / Number(this.answerNum)) * 100).toFixed(2)
|
|
// 计算正确率 = 正确题数 / 已答题数
|
|
this.correctRate = rate == 'NaN' ? '0' : rate
|
|
this.showModal = true
|
|
// const params = {
|
|
// id: this.practiceId
|
|
// }
|
|
// uni.request({
|
|
// url: config.baseUrl + '/exam-student/studentPractice/getPracticeQuestionRate',
|
|
// method: 'post',
|
|
// data: params,
|
|
// header: {
|
|
// 'Content-Type': 'application/x-www-form-urlencoded',
|
|
// Authorization: uni.getStorageSync('access_token')
|
|
// },
|
|
// success: res => {
|
|
// console.log('🚀 ~ handleSubmit ~ res:', res)
|
|
// res = res.data
|
|
// },
|
|
// fail: err => {
|
|
// console.log(err)
|
|
// }
|
|
// })
|
|
},
|
|
handleConfirm() {
|
|
console.log('确认')
|
|
this.showModal = false
|
|
// 继续计时
|
|
this.startTimer()
|
|
},
|
|
// 结束答题
|
|
handleClose() {
|
|
if (this.isLoading) {
|
|
uni.showToast({
|
|
title: '正在提交中, 请稍后',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
this.isLoading = true
|
|
this.isEnd = true
|
|
// 停止计时
|
|
clearInterval(this.intervalId)
|
|
console.log('结束', this.usedTime, this.serviceTime)
|
|
// 保存练习时长
|
|
let time = Math.ceil(this.serviceTime / 60)
|
|
console.log('🚀 ~ handleClose ~ time:', time)
|
|
const params = {
|
|
id: this.recordId,
|
|
practiceDuration: time
|
|
}
|
|
console.log('🚀 ~ handleClose ~ params:', params)
|
|
this.$verificationToken()
|
|
uni.request({
|
|
url: config.baseUrl + '/exam-student/studentPractice/savePracticeDuration',
|
|
method: 'post',
|
|
data: params,
|
|
header: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
Authorization: uni.getStorageSync('access_token')
|
|
},
|
|
fail: err => {
|
|
console.log(err)
|
|
}
|
|
})
|
|
if (this.isError) {
|
|
// 错题消除
|
|
// updateRemoveRecordData({
|
|
// practiceId: this.practiceId
|
|
// })
|
|
this.$verificationToken()
|
|
uni.request({
|
|
url: config.baseUrl + '/exam-student/studentPractice/updateRemoveRecordData',
|
|
method: 'post',
|
|
data: {
|
|
practiceId: this.practiceId
|
|
},
|
|
header: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
Authorization: uni.getStorageSync('access_token')
|
|
},
|
|
fail: err => {
|
|
console.log(err)
|
|
}
|
|
})
|
|
}
|
|
if (this.studyId) {
|
|
const params = {
|
|
userId: uni.getStorageSync('userId'),
|
|
studyId: this.studyId
|
|
}
|
|
// updStudyDurationExamPractice(params)
|
|
this.$verificationToken()
|
|
uni.request({
|
|
url: config.baseUrl + '/exam-student/student/updStudyDurationExamPractice',
|
|
method: 'post',
|
|
data: params,
|
|
header: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
Authorization: uni.getStorageSync('access_token')
|
|
},
|
|
fail: err => {
|
|
console.log(err)
|
|
}
|
|
})
|
|
setTimeout(() => {
|
|
uni.reLaunch({
|
|
url: '/pages/YNEduApp/learnProj/learnProjDetail?id=' + this.studyId
|
|
})
|
|
}, 500)
|
|
} else {
|
|
uni.reLaunch({
|
|
url: '/pages/YNEduApp/prac/prac'
|
|
})
|
|
}
|
|
setTimeout(() => {
|
|
this.isLoading = false
|
|
this.showModal = false
|
|
}, 500)
|
|
},
|
|
// 打开题目选择弹框
|
|
openSelect() {
|
|
this.showModalSelect = true
|
|
// const res = await this.getPracticeQuestionList()
|
|
// console.log('🚀 ~ openSelect ~ res:', res)
|
|
// this.questionListSelect = res.data
|
|
const params = {
|
|
recordId: this.recordId,
|
|
practiceId: this.practiceId,
|
|
isMiss: this.isError ? 1 : ''
|
|
}
|
|
this.$verificationToken()
|
|
uni.request({
|
|
url: config.baseUrl + '/exam-student/studentPractice/getPracticeQuestionList',
|
|
method: 'post',
|
|
data: params,
|
|
header: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
Authorization: uni.getStorageSync('access_token')
|
|
},
|
|
success: res => {
|
|
console.log('🚀 ~ getPracticeQuestionList ~ res:', res)
|
|
res = res.data
|
|
this.questionListSelect = res.data
|
|
},
|
|
fail: err => {
|
|
console.log(err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.wrapper {
|
|
height: 100vh;
|
|
background: url('/static/images/question-bg.png') no-repeat;
|
|
background-size: 100% 100%;
|
|
|
|
.slot-content {
|
|
width: 100%;
|
|
.correctRate {
|
|
font-size: 30px;
|
|
text-align: center;
|
|
}
|
|
|
|
.modal-container {
|
|
display: flex;
|
|
justify-content: space-around;
|
|
align-items: center;
|
|
margin-top: 20px;
|
|
background: #f5f8fb;
|
|
border-radius: 5px;
|
|
height: 73px;
|
|
|
|
.item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
color: #9d9b9b;
|
|
.num {
|
|
font-size: 20px;
|
|
color: #3185f0;
|
|
}
|
|
}
|
|
}
|
|
|
|
.topic-content {
|
|
height: 300px;
|
|
display: flex;
|
|
justify-content: flex-start;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
overflow: auto;
|
|
|
|
.topic-wrapper {
|
|
width: 30px;
|
|
height: 30px;
|
|
border: 1px solid #409eff;
|
|
border-radius: 5px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
margin: 10px;
|
|
.topic {
|
|
font-size: 11px;
|
|
color: #409eff;
|
|
}
|
|
// 正确背景
|
|
&.correct {
|
|
background: #67d279;
|
|
color: #fff;
|
|
.topic {
|
|
color: #fff;
|
|
}
|
|
}
|
|
// 错误背景
|
|
&.error {
|
|
background: #f0514c;
|
|
color: #fff;
|
|
.topic {
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.bottom-btn {
|
|
position: fixed;
|
|
bottom: 30px;
|
|
left: 0;
|
|
display: flex;
|
|
justify-content: space-around;
|
|
width: 100%;
|
|
.btn {
|
|
width: 100px;
|
|
display: flex;
|
|
justify-content: center;
|
|
margin: 0 auto;
|
|
}
|
|
}
|
|
|
|
.btn {
|
|
width: 100px;
|
|
display: flex;
|
|
justify-content: center;
|
|
margin: 0 auto;
|
|
margin-top: 40px;
|
|
}
|
|
|
|
.question-wrapper {
|
|
max-height: 500px;
|
|
overflow: auto;
|
|
padding: 30px;
|
|
color: #08428d;
|
|
|
|
.title {
|
|
font-weight: 500;
|
|
font-size: 15px;
|
|
margin-bottom: 30px;
|
|
}
|
|
.option {
|
|
margin-bottom: 5px;
|
|
padding: 0 15px;
|
|
min-height: 45px;
|
|
max-height: 100px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
background: #ffffff;
|
|
border-radius: 8px;
|
|
overflow: auto;
|
|
.label-wrapper {
|
|
max-height: 100px;
|
|
overflow: auto;
|
|
.label {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-start;
|
|
text-align: left;
|
|
}
|
|
}
|
|
}
|
|
.active {
|
|
border: 1px solid #1f92df;
|
|
}
|
|
|
|
.analysis {
|
|
margin-top: 20px;
|
|
font-weight: 700;
|
|
}
|
|
.analysis-container {
|
|
margin-top: 6px;
|
|
color: #475583;
|
|
text-indent: 1em;
|
|
}
|
|
}
|
|
|
|
.top-time {
|
|
text-align: center;
|
|
font-size: 13px;
|
|
color: #fff;
|
|
padding-top: 50px;
|
|
}
|
|
|
|
.num-wrapper {
|
|
display: flex;
|
|
justify-content: center;
|
|
margin-top: 20px;
|
|
|
|
.correct,
|
|
.error,
|
|
.total {
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 13px;
|
|
margin: 0 6px;
|
|
}
|
|
.correct {
|
|
color: #49ac5a;
|
|
}
|
|
.error {
|
|
color: #e34944;
|
|
}
|
|
.total {
|
|
color: #f08439;
|
|
}
|
|
.num {
|
|
margin-left: 3px;
|
|
}
|
|
}
|
|
}
|
|
</style>
|