unknown
2 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