unknown
4 weeks ago
7 changed files with 629 additions and 7 deletions
-
2manifest.json
-
9pages.json
-
21pages/exercises/brushQuestions/brushQuestions.vue
-
588pages/exercises/brushQuestions/examQuestions.vue
-
13pages/exercises/examSubjiect1/examSubjiect1.vue
-
3pages/exercises/theoryStudy/theoryStudy.vue
-
BINstatic/images/theory/scActive.png
@ -0,0 +1,588 @@ |
|||||
|
<template> |
||||
|
<view class="content"> |
||||
|
<up-navbar leftText=" " title="" :safeAreaInsetTop="false" :autoBack="true"> |
||||
|
<template #center> |
||||
|
<view class="flex"> |
||||
|
<view class="lastText">剩余时间</view> |
||||
|
<view class="lastText" style="margin-left: 8rpx;">44:00</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
</up-navbar> |
||||
|
|
||||
|
|
||||
|
<view class="con padding"> |
||||
|
<view class="h1_row"> |
||||
|
<text class="tag" :class="{red: questionBank.types==2, blue: questionBank.types==3}">{{types[questionBank.types-1]}}</text> |
||||
|
<text class="h1" @click="speak(questionBank.title)">{{ questionBank.title}}</text> |
||||
|
</view> |
||||
|
<view class="imgBox" style="width: 100%;padding: 0 0 30rpx 0;" v-if="questionBank.img"> |
||||
|
<image :src="questionBank.img" mode="widthFix"></image> |
||||
|
</view> |
||||
|
<view class="option"> |
||||
|
<view v-for="(item,index) in questionBank.optionArr" @click="chooseOption(item)"> |
||||
|
<!-- 多选题 --> |
||||
|
<view class="optionItem flex" v-if="questionBank.types ==2&& (!curOption.answer||curOption.answer==questionBank.answer)"> |
||||
|
<up-icon name="checkmark-circle-fill" color="#55ff7f" size="20" v-if="curOption.ans?.includes(item.key)"></up-icon> |
||||
|
<view class="icon" v-else></view> |
||||
|
<view class="text"><text >{{item.key}}</text> {{item.text}}</view> |
||||
|
</view> |
||||
|
<!-- 正常答案 --> |
||||
|
<view class="optionItem flex" v-else @click="chooseOption(item)"> |
||||
|
<view class="icon" v-if="!curOption.key&&questionBank.types !=2"></view> |
||||
|
<up-icon name="checkmark-circle-fill" color="#55ff7f" size="20" v-else-if="questionBank.answer.includes(item.key)"></up-icon> |
||||
|
<up-icon name="close-circle-fill" color="#ff0000" size="20" v-else></up-icon> |
||||
|
<view class="text"><text v-if="questionBank.types!=3">{{item.key}}</text> {{item.text}}</view> |
||||
|
</view> |
||||
|
<!-- ans --> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="answerCss flex" v-if="curOption.answer&&questionBank.answer!=curOption.answer"> |
||||
|
<view class="ans">正确答案是 |
||||
|
<text v-if="questionBank.types==3" >{{ questionBank.answer=='false'?'错误':'正确' }}</text> |
||||
|
<text v-else >{{ questionBank.answer }}</text> |
||||
|
</view> |
||||
|
<view class="ans">您的答案是 |
||||
|
<text v-if="questionBank.types==3" class="red">{{ curOption.answer=='false'?'错误':'正确' }}</text> |
||||
|
<text v-else class="red">{{ curOption.answer }}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="btn_row flex-b"> |
||||
|
<!-- @click="$goPage('/pages/exercises/lastPage/lastPage')" --> |
||||
|
<button class="btn border" @click="debounce(nextQuestion(-1), 500)" :class="{disable: currentIndex==1}" :disabled="currentIndex==1">上一题</button> |
||||
|
<button class="btn bg" @click="debounce(nextQuestion(1), 500)" :class="{disable: currentIndex>=quesIdList.length}" :disabled="currentIndex>=quesIdList.length">下一题</button> |
||||
|
</view> |
||||
|
<view class="analysis" v-if="currentNav==2||(curOption.answer&&curOption.answer!=questionBank.answer)"> |
||||
|
<view class="tit">题目解析</view> |
||||
|
<view class="txt">{{ questionBank.resolving }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="bottomBar"> |
||||
|
|
||||
|
<view class="ul"> |
||||
|
<!-- <view class="li"> |
||||
|
<view class="icon" style="color: #55ff7f;">{{ yesNum }}</view> |
||||
|
<view class="text">答对</view> |
||||
|
</view> |
||||
|
<view class="li"> |
||||
|
<view class="icon" style="color: #ff0000;">{{ noNum }}</view> |
||||
|
<view class="text">答错</view> |
||||
|
</view> |
||||
|
<view class="li"> |
||||
|
<view class="icon">{{currentIndex}}/<text style="color: #999; font-size: 24rpx;">{{quesIdList.length}}</text></view> |
||||
|
<view class="text">题目</view> |
||||
|
</view> --> |
||||
|
<view class="flex leftCotrl"> |
||||
|
<view class="li" @click="showCommt=true"> |
||||
|
<view class="icon"> |
||||
|
<image src="@/static/images/theory/fankui.png" mode=""></image> |
||||
|
</view> |
||||
|
<view class="text">反馈</view> |
||||
|
</view> |
||||
|
<view class="li" @click="openPopup"> |
||||
|
<view class="icon"> |
||||
|
<image src="@/static/images/theory/dtk.png" mode=""></image> |
||||
|
</view> |
||||
|
<view class="text">答题卡</view> |
||||
|
</view> |
||||
|
<view class="li" @click="$noDoFn"> |
||||
|
<view class="icon"> |
||||
|
<image src="@/static/images/theory/sc.png" mode=""></image> |
||||
|
</view> |
||||
|
<view class="text">收藏</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="submitBtn">交卷</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<up-popup :show="show" @close="closePopup" @open="openPopup" mode="bottom" round="20" closeable> |
||||
|
<view class="popupCon"> |
||||
|
<view class="h3">答题卡</view> |
||||
|
<view class="ulRow"> |
||||
|
<view class="ul"> |
||||
|
<view class="li"> |
||||
|
<view class="icon" style="color: #55ff7f;">{{ yesNum }}</view> |
||||
|
<view class="text">答对</view> |
||||
|
</view> |
||||
|
<view class="li"> |
||||
|
<view class="icon" style="color: #ff0000;">{{ noNum }}</view> |
||||
|
<view class="text">答错</view> |
||||
|
</view> |
||||
|
<view class="li" style="margin-left: auto;"> |
||||
|
<view class="icon">{{currentIndex}}/<text style="color: #999; font-size: 24rpx;">{{quesIdList.length}}</text></view> |
||||
|
<view class="text">题目</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="ul2"> |
||||
|
<view class="li2" v-for="(item,index) in quesIdList" :key="index" @click="quesIdListClick(item,index)"> |
||||
|
<view class="num" :class="{active: index+1==currentIndex}">{{ index+1 }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</up-popup> |
||||
|
|
||||
|
<up-popup :show="showCommt" @close="showCommtClose" mode="bottom" round="20rpx" closeable> |
||||
|
<view class="commtCon" style="padding: 30rpx"> |
||||
|
<up-textarea v-model.trim="contentStr" placeholder="请输入反馈内容" style="margin-top: 50rpx;" maxlength="300"></up-textarea> |
||||
|
<up-button text="提 交" style="margin-top: 20rpx;" type="primary" @click="submitCommt"></up-button> |
||||
|
</view> |
||||
|
</up-popup> |
||||
|
|
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
function speak(text) { |
||||
|
const speech = new SpeechSynthesisUtterance(text); // 创建语音消息 |
||||
|
window.speechSynthesis.speak(speech); // 播报消息 |
||||
|
} |
||||
|
|
||||
|
import { startExam, submitAnswerResultApi, getQuestionApi, questionCommentAdd } from '@/config/api.js' |
||||
|
import { debounce } from '@/uni_modules/uview-plus'; |
||||
|
import { |
||||
|
ref, |
||||
|
reactive |
||||
|
} from 'vue'; |
||||
|
const currentNav = ref('1') |
||||
|
const types = ref([ |
||||
|
'单选题', |
||||
|
'多选题', |
||||
|
'判断题' |
||||
|
]) |
||||
|
const yesNum = ref(0) |
||||
|
const noNum = ref(0) |
||||
|
|
||||
|
import carStore from '@/store/modules/car.js' |
||||
|
let usecarStore = carStore() |
||||
|
|
||||
|
import { |
||||
|
onLoad, |
||||
|
onReady |
||||
|
} from "@dcloudio/uni-app" |
||||
|
// 1:单选题,2:多选题,3:判断题 |
||||
|
function changeNav(val) { |
||||
|
console.log(window) |
||||
|
if(currentNav.value == val) return |
||||
|
currentNav.value = val |
||||
|
} |
||||
|
function goEmam() { |
||||
|
uni.navigateTo({ |
||||
|
// url: '/pages/exercises/exam/exam', |
||||
|
// url: '/pages/exercises/beforeExam/beforeExam', |
||||
|
// url: '/pages/exercises/examResults/examResults', |
||||
|
// url: '/pages/exercises/wrongQuestion/wrongQuestion', |
||||
|
// url: '/pages/exercises/theoryStudy/theoryStudy', |
||||
|
url: '/pages/vip/vipEntry/vipEntry' |
||||
|
|
||||
|
}) |
||||
|
} |
||||
|
function changeTabbar(val) { |
||||
|
console.log(val) |
||||
|
} |
||||
|
const show = ref(false) |
||||
|
function closePopup() { |
||||
|
show.value = false |
||||
|
} |
||||
|
function openPopup() { |
||||
|
show.value = true |
||||
|
} |
||||
|
|
||||
|
let showCommt = ref(false) |
||||
|
let contentStr = ref('') |
||||
|
function showCommtClose() { |
||||
|
showCommt.value = false |
||||
|
contentStr.value = '' |
||||
|
} |
||||
|
// 提交反馈 |
||||
|
async function submitCommt() { |
||||
|
if(!contentStr.value) return uni.$u.toast('请输入内容') |
||||
|
let obj = { |
||||
|
content: contentStr.value, |
||||
|
questionId: questionBank.value.id |
||||
|
} |
||||
|
const res = await questionCommentAdd(obj) |
||||
|
if(res.errorcode==0) { |
||||
|
uni.$u.toast('提交成功,感谢您的反馈') |
||||
|
showCommt.value = false |
||||
|
} |
||||
|
} |
||||
|
// 请求数据 |
||||
|
const questionBank = ref({}) |
||||
|
let quesIdList = ref([]) |
||||
|
let currentIndex = ref(1) |
||||
|
async function startQuestionFn() { |
||||
|
try{ |
||||
|
uni.showLoading({ |
||||
|
title: '正在加载...' |
||||
|
}) |
||||
|
let obj = { |
||||
|
carType: usecarStore.carInfo.carType, |
||||
|
stepType: usecarStore.carInfo.stepType, |
||||
|
examType: 1, |
||||
|
} |
||||
|
const {data: res} = await startExam(obj) |
||||
|
uni.hideLoading() |
||||
|
questionBank.value = res.questionBank |
||||
|
initOptionArr() |
||||
|
quesIdList.value = res.quesIdList |
||||
|
}catch(e){ |
||||
|
uni.hideLoading() |
||||
|
} |
||||
|
} |
||||
|
startQuestionFn() |
||||
|
|
||||
|
function initOptionArr() { |
||||
|
questionBank.value.optionArr = [] |
||||
|
let abcd = [ |
||||
|
'a', |
||||
|
'b', |
||||
|
'c', |
||||
|
'd', |
||||
|
'e', |
||||
|
'f' |
||||
|
] |
||||
|
abcd.forEach((k,i)=>{ |
||||
|
let option = 'option'+k |
||||
|
if(questionBank.value[option]) { |
||||
|
let obj = { |
||||
|
key: k.toLocaleUpperCase(), |
||||
|
text: questionBank.value[option], |
||||
|
index: i+1 |
||||
|
} |
||||
|
questionBank.value.optionArr.push(obj) |
||||
|
// console.log(questionBank.value.optionArr) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
// 如果是判断题 |
||||
|
if(questionBank.value.types==3) { |
||||
|
questionBank.value.optionArr[0].key = 'true' |
||||
|
questionBank.value.optionArr[1].key = 'false' |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// 下一题 |
||||
|
async function nextQuestion(num) { |
||||
|
// 如果是多选题,什么时候不直接请求下一题,是多选题 ,并且有答案,答错了,并且不是next |
||||
|
if(questionBank.value.types==2 && curOption.value.ans) { |
||||
|
// 如果没有请求就请求一下 |
||||
|
if(!curOption.value.answer) { |
||||
|
curOption.value.answer = curOption.value.ans |
||||
|
await submitAnswerResultFn() |
||||
|
} |
||||
|
// 如果答案不一样,并且是第一次请求 |
||||
|
if(questionBank.value.answer != curOption.value.ans&&curOption.value.isNext != 'next') { |
||||
|
curOption.value.isNext = 'next' |
||||
|
return false |
||||
|
} |
||||
|
} |
||||
|
curOption.value = {} |
||||
|
currentIndex.value = currentIndex.value + num |
||||
|
getQuestionFn() |
||||
|
|
||||
|
} |
||||
|
// 请求下一题 |
||||
|
async function getQuestionFn() { |
||||
|
console.log(currentIndex.value) |
||||
|
let questionId = quesIdList.value[currentIndex.value-1] |
||||
|
let obj = { |
||||
|
"carType": usecarStore.carInfo.carType, |
||||
|
"questionId": questionId, |
||||
|
"sort": currentIndex.value, |
||||
|
"stepType": usecarStore.carInfo.stepType, |
||||
|
'tempId': questionBank.value.questionDoTemp.id |
||||
|
} |
||||
|
const {data: res} = await getQuestionApi(obj) |
||||
|
questionBank.value = res |
||||
|
curOption.value.isNext = '' |
||||
|
initOptionArr() |
||||
|
} |
||||
|
async function quesIdListClick(id, index) { |
||||
|
curOption.value = {} |
||||
|
currentIndex.value = index + 1 |
||||
|
getQuestionFn() |
||||
|
show.value = false |
||||
|
} |
||||
|
|
||||
|
// 选择答案 |
||||
|
const curOption = ref({}) |
||||
|
async function chooseOption(item) { |
||||
|
// console.log(item) |
||||
|
if(curOption.value.answer) return |
||||
|
if(questionBank.value.types != 2) { |
||||
|
item.answer = item.key |
||||
|
curOption.value = item |
||||
|
submitAnswerResultFn() |
||||
|
}else if(questionBank.value.types == 2){ |
||||
|
if(!curOption.value.ans) curOption.value.ans = '' |
||||
|
if(curOption.value.ans.includes(item.key)) { |
||||
|
curOption.value.ans = curOption.value.ans.replace(item.key, '') |
||||
|
return |
||||
|
} |
||||
|
curOption.value.ans = curOption.value.ans + item.key |
||||
|
// console.log(curOption.value.ans) |
||||
|
} |
||||
|
} |
||||
|
// 提交请求 |
||||
|
async function submitAnswerResultFn() { |
||||
|
let obj = { |
||||
|
answer: curOption.value.answer, |
||||
|
carType: 'car', |
||||
|
questionId: questionBank.value.id, |
||||
|
result: '0', |
||||
|
stepType: 1, |
||||
|
tempId: questionBank.value.questionDoTemp.id |
||||
|
} |
||||
|
const res = await submitAnswerResultApi(obj) |
||||
|
if(res.errorcode!=0) return |
||||
|
if(curOption.value.answer==questionBank.value.answer) { |
||||
|
console.log('答对了') |
||||
|
curOption.value = {} |
||||
|
yesNum.value ++ |
||||
|
nextQuestion(1) |
||||
|
}else { |
||||
|
noNum.value ++ |
||||
|
} |
||||
|
// console.log(res) |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
image {display: block;width: 100%;height: 100%;} |
||||
|
.bottomBar { |
||||
|
position: fixed; |
||||
|
bottom: 0; |
||||
|
left: 0; |
||||
|
width: 100%; |
||||
|
height: 98rpx; |
||||
|
background: #FFFFFF; |
||||
|
border-top: 1rpx solid #F4F4F4; |
||||
|
|
||||
|
} |
||||
|
.ul { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
height: 100%; |
||||
|
align-items: center; |
||||
|
.leftCotrl { |
||||
|
flex: 1; |
||||
|
} |
||||
|
.submitBtn { |
||||
|
width: 100rpx; |
||||
|
height: 50rpx; |
||||
|
background: linear-gradient(0deg, #4FACFE 0%, #00F2FE 100%); |
||||
|
border-radius: 25rpx; |
||||
|
font-size: 24rpx; |
||||
|
line-height: 50rpx; |
||||
|
text-align: center; |
||||
|
margin-right: 32rpx; |
||||
|
color: #fff; |
||||
|
} |
||||
|
.li { |
||||
|
// width: 16.6%; |
||||
|
padding: 0 30rpx; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
.icon { |
||||
|
font-size: 30rpx; |
||||
|
height: 30rpx; |
||||
|
line-height: 30rpx; |
||||
|
image { |
||||
|
display: block; |
||||
|
margin-top: 4rpx; |
||||
|
width: 26rpx; |
||||
|
height: 26rpx; |
||||
|
} |
||||
|
} |
||||
|
.text { |
||||
|
font-weight: 500; |
||||
|
font-size: 24rpx; |
||||
|
color: #999999; |
||||
|
margin-top: 10rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.content { |
||||
|
padding: 120rpx 0; |
||||
|
min-height: 100vh; |
||||
|
.u-nav-slot { |
||||
|
width: 306rpx; |
||||
|
height: 54rpx; |
||||
|
border-radius: 10rpx; |
||||
|
border: 1px solid #333333; |
||||
|
display: flex; |
||||
|
|
||||
|
.btn { |
||||
|
font-size: 24rpx; |
||||
|
color: #333333; |
||||
|
flex: 1; |
||||
|
text-align: center; |
||||
|
line-height: 54rpx; |
||||
|
|
||||
|
&.active { |
||||
|
background-color: #333333; |
||||
|
color: #fff; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.btn_row { |
||||
|
padding: 60rpx 0 30rpx 0; |
||||
|
.btn { |
||||
|
width: 44%; |
||||
|
height: 76rpx; |
||||
|
border-radius: 38rpx; |
||||
|
border: 1rpx solid $themC; |
||||
|
line-height: 76rpx; |
||||
|
text-align: center; |
||||
|
font-size: 28rpx; |
||||
|
color: $themC; |
||||
|
&.disable { |
||||
|
opacity: 0.4; |
||||
|
} |
||||
|
&.bg { |
||||
|
background: #3776FF; |
||||
|
border-radius: 38rpx; |
||||
|
color: #fff; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
.con { |
||||
|
.h1_row { |
||||
|
margin-bottom: 50rpx; |
||||
|
.tag { |
||||
|
display: inline-block; |
||||
|
// width: 66px; |
||||
|
height: 36rpx; |
||||
|
line-height: 36rpx; |
||||
|
padding: 4rpx 6rpx; |
||||
|
background: #63C168; |
||||
|
border-radius: 6rpx; |
||||
|
margin-top: -2rpx; |
||||
|
margin-right: 16rpx; |
||||
|
font-size: 28rpx; |
||||
|
color: #fff; |
||||
|
&.blue { |
||||
|
background: #3776FF; |
||||
|
} |
||||
|
&.red { |
||||
|
background: orangered; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
text.h1 { |
||||
|
font-size: 36rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.option { |
||||
|
width: 100%; |
||||
|
.optionItem { |
||||
|
margin-bottom: 50rpx; |
||||
|
align-items: center; |
||||
|
.icon { |
||||
|
width: 36rpx; |
||||
|
height:36rpx; |
||||
|
border-radius: 50%; |
||||
|
border: 1rpx solid #999; |
||||
|
} |
||||
|
|
||||
|
.text { |
||||
|
font-size: 32rpx; |
||||
|
margin-left: 16rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.answerCss { |
||||
|
height: 90rpx; |
||||
|
background: #F4F4F4; |
||||
|
padding: 30rpx; |
||||
|
margin-top: 20rpx; |
||||
|
justify-content: space-around; |
||||
|
.ans { |
||||
|
font-size: 30rpx; |
||||
|
text { |
||||
|
&.red { |
||||
|
color: red; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.analysis { |
||||
|
margin-top: 60rpx; |
||||
|
.tit { |
||||
|
font-weight: 700; |
||||
|
font-size: 32rpx; |
||||
|
position: relative; |
||||
|
padding-left: 30rpx; |
||||
|
&::after { |
||||
|
content: ''; |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: 8rpx; |
||||
|
width: 6rpx; |
||||
|
height: 30rpx; |
||||
|
background: linear-gradient(0deg, #43EA80 0%, #38F8D4 100%); |
||||
|
border-radius: 3rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.txt { |
||||
|
margin-top: 39rpx; |
||||
|
font-size: 32rpx; |
||||
|
color: #333333; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.popupCon { |
||||
|
width: 100%; |
||||
|
height: calc(100vh - 200rpx); |
||||
|
.h3 { |
||||
|
height: 88rpx; |
||||
|
border-bottom: 1px solid #F4F4F4; |
||||
|
line-height: 88rpx; |
||||
|
font-size: 30rpx; |
||||
|
padding: 0rpx 0 0 30rpx; |
||||
|
} |
||||
|
.ulRow { |
||||
|
height: 100rpx; |
||||
|
padding: 30rpx 0; |
||||
|
} |
||||
|
.ul2 { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
padding: 30rpx 10rpx; |
||||
|
height: calc(100vh - 388rpx); |
||||
|
overflow-y: auto; |
||||
|
.li2 { |
||||
|
width: 16.6%; |
||||
|
margin-bottom: 20rpx; |
||||
|
.num { |
||||
|
width: 100rpx; |
||||
|
height: 100rpx; |
||||
|
border-radius: 50%; |
||||
|
margin: auto; |
||||
|
background: #F6F7FA; |
||||
|
font-size: 32rpx; |
||||
|
line-height: 100rpx; |
||||
|
text-align: center; |
||||
|
&.active { |
||||
|
border: 1px solid #63C168; |
||||
|
background: rgba(99,193,104,0.1); |
||||
|
color: #63C168; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
After Width: 24 | Height: 24 | Size: 835 B |
Write
Preview
Loading…
Cancel
Save
Reference in new issue