|
|
<template> <view id="brushQuestions"> <view class="content"> <view class="row row1"> <view class="userInfoBox"> <view class="examNo"> <view class="h3">洛阳学车</view> <view class="card">第0{{ randomNumber }}号台</view> <view class="back" @click="goBack"> <u-icon name="arrow-left" size="16"></u-icon> </view> </view> <view class="user"> <view class="card"> <view class="h3">考生信息</view> <view class="avatar"> <image src="@/static/images/avatarbg.png" mode=""></image> </view> <view class="txt">用户: <text style="margin-top: 10rpx;">{{ phone }}</text></view> <!-- <view class="txt">性别:男</view> --> <view class="txt">类型:{{ usecarStore.carInfo.carTypeName}}</view> <view class="txt">科目:科目{{ usecarStore.carInfo.stepType==1?'一': '四'}}</view> </view> </view> </view> <view class="examConBox"> <view class="leftBox"> <view class="h3">考试题目</view> <view class="questionTxt"> <view class="txt">{{currentIndex+1}}.{{ questionBank.title }}</view> <view class="txt" v-for="(item,index) in questionBank.optionArr"> <view class="text"><text >{{item.key}}</text> {{item.text}}</view> </view> </view> <view class="answer flex-b"> <view class="lab">您的答案: <text v-if="questionBank.types==3">{{ curOption.answer=='true'?'A':'B'}}</text> <text v-else>{{ curOption.answer}}</text> </view> <view class="rightSelect flex"> <view class="lab">选项:</view> <view class="optio flex" v-for="(item,index) in questionBank.optionArr" > <view class="optionItem" :class="{ active: curOption.answer?.includes(item.key)}" @click="chooseOption(item)">{{item.key}}</view> </view> </view> </view> </view> <view class="rightBox"> <!-- 右边盒子 --> <table style="width: 100%;height: 100%;" v-if="ansCard.length"> <tr> <th class="blueItem br">题目</th> <th v-for="(item,index) in usecarStore.carInfo.stepType==1?10:5" class="blueItem br">{{index+1}}列</th> </tr> <tr v-for="(item,index) in ansCard"> <td class="blueItem bb">{{index+1}}行</td> <td v-for="(item2,index2) in item" class="ansItem" :class="{green: item2.answer==item2.answerMy}" @click="ansCardClick(item2)"> <text v-if="item2.types==3&&item2.answerMy" class="flex" style="justify-content: center;"> <up-icon name="checkmark" color="#55ff7f" size="18" v-if="item2.answer==item2.answerMy"></up-icon> <up-icon name="close" color="#ff0000" size="18" v-else></up-icon> </text> <text v-else>{{ item2.answerMy }}</text> </td> </tr> </table> </view> </view> </view> <view class="row row2"> <view class="timeBox"> <view class="h3">考试时间</view> <view class="time"><up-count-down :time="info.totalExamTime * 60 * 1000" format="mm:ss" @finish="finishFn" ref="countDownRef"></up-count-down></view> </view> <view class="leftTpsBox"> <view class="card"> <view class="h3">操作提示</view> <view class="txt">本题为{{types[questionBank.types-1]}},请在备选答案中选择 {{ questionBank.types==2? '多': '一'}}个你认为正确的答案!</view> </view> </view> <view class="rightBtnBox"> <button class="btn hui" @click="debounce(nextQuestion(-1), 500)" :class="{disable: currentIndex==0}" :disabled="currentIndex==0">上一题</button> <button class="btn hui" @click="debounce(nextQuestion(1), 500)" :class="{disable: currentIndex>=questionBankList.length-1}" :disabled="currentIndex>=questionBankList.length-1">下一题</button> <view class="btn"@click="handApaper">交 卷</view> </view> </view> <view class="picBox"> <view class="h3">考题图片</view> <view class="imgBox"> <image :src="questionBank.img" v-if="questionBank.img" @click="previewImg" mode="aspectFit"></image> </view> <u-popup :show="show" mode="center" :closeable="true" @close="show=false" bgColor="transparent"> <view class="imgView"> <!-- <view class="closeIcon" @click="show=false"> <u-icon name="close-circle" color="#fff" size="28"></u-icon> </view> --> <view class="img"> <image :src="questionBank.img" mode="aspectFit"></image> </view> </view> </u-popup> </view> </view> <u-popup :show="showCommit" mode="center" :closeable="true" round="10" @close="closeCommitPopup" > <view class="commitView"> <view class="commitTit">考试确认窗口</view> <view class="commitTxt">你当前考试答对{{yesNum}}题,答错{{ questionBankList.length-yesNum-noNum}}题,未答{{ noNum }}题。 </view> <view class="commitTxt">1、点击【确认交卷】,将提交考试成绩,考试结束。</view> <view class="commitTxt">2、点击【继续考试】,将关闭本窗口,继续考试。</view> <view class="commitBtn"> <view class="btn border" @click="submitBtnFn">确定交卷</view> <view class="btn" @click="closeCommitPopup">继续考试</view> </view> </view> </u-popup> <u-popup :show="showNoPass" mode="center" :closeable="true" @close="showNoPass=false" round="10" > <view class="commitView"> <view class="commitTit">考试不合格</view> <view class="commitTxt">学员、您本次成绩为{{grade}}分</view> <view class="commitTxt">考试不合格,预祝您下次顺利</view> <view class="commitBtn"> <view class="btn" @click="goBack">确定</view> </view> <view class="djs"> <up-count-down :time="4 * 1000" format="ss" @finish="goBack" style="color: red;"></up-count-down> <view class="djsTxt"> <text style="color: red;">秒</text>自动关闭,自动回到页面</view> </view> </view> </u-popup> <u-popup :show="showWrong" mode="center" :closeable="true" round="10" @close="showWrongClose" > <view class="commitView"> <view class="commitTit">错题学习</view> <view class="commitTxt">{{ questionBank.title }}</view> <view class="commitTxt" v-for="(item,index) in questionBank.optionArr" > <view class="text"><text >{{item.key}}</text> {{item.text}}</view> </view> <view class="rowBg"> <view class="ans">正确答案: <text v-if="questionBank.types==3">{{ questionBank.answer=='true'?'A':'B'}}</text> <text v-else>{{ questionBank.answer}}</text> </view> <view class="ans blue">你的答案: <text v-if="questionBank.types==3">{{ questionBank.answerMy=='true'?'A':'B'}}</text> <text v-else>{{ questionBank.answerMy}}</text> </view> </view> <view class="commitBtn"> <view class="btn" @click="showWrongClose">继续考试</view> </view> <view class="djs"> <view class="djsTxt">页面将在</view> <up-count-down :time="6 * 1000" format="ss" style="color: red;" @finish="showWrongClose" ></up-count-down> <view class="djsTxt"> <text style="color: red;">秒</text> 后自动关闭并返还考试主页面</view> </view> </view> </u-popup>
</view> </template> <script setup> import { detectOrient } from '@/utils/utils.js' import { startExamDo, startExam, questionExam } from '@/config/api.js' import { ref, onMounted, nextTick } from 'vue' import { debounce } from '@/uni_modules/uview-plus'; import { onLoad, } from "@dcloudio/uni-app" import carStore from '@/store/modules/car.js' let usecarStore = carStore() let randomNumber = '' onLoad((options)=>{ randomNumber = options.randomNumber }) const types = ref([ '单选题', '多选题', '判断题' ]) let phone = uni.getStorageSync('loginInfo')?.phone const showCommit = ref(false) const showNoPass = ref(false) const showWrong = ref(false) const show = ref(false)
onMounted(()=>{ detectOrient('#brushQuestions') }) function previewImg() { show.value = true } function goBack() { uni.navigateBack() } // 请求数据
const questionBank = ref({}) const questionBankList = ref([]) let ansCard = ref([]) let examInfo = ref({}) let currentIndex = ref(0) async function startQuestionFn() { try{ uni.showLoading({ title: '正在加载...' }) let obj = { carType: usecarStore.carInfo.carType, stepType: usecarStore.carInfo.stepType, examType: 2, } const {data: res} = await startExam(obj) uni.hideLoading() questionBank.value = res.questionBank[0] questionBankList.value = res.questionBank let size = usecarStore.carInfo.stepType==1?10:5 ansCard.value = chunk(questionBankList.value, size) initOptionArr() examInfo.value = res }catch(e){ uni.hideLoading() } } startQuestionFn() // 搞个二维数组来
function chunk(arr, size) { if(arr.length==0) return [] let result = [] let tmp = [] arr.forEach((item,index)=>{ if(tmp.length==0) { result.push(tmp) } item.index = index tmp.push(item) if(tmp.length==size) { tmp = [] } }) return result } 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) } }) // 如果是判断题
// if(questionBank.value.types==3) {
// questionBank.value.optionArr[0].key1 = 'true'
// questionBank.value.optionArr[1].key1 = 'false'
// }
// console.log(questionBank.value.optionArr)
} // 选择答案
const curOption = ref({}) async function chooseOption(item) { if(questionBank.value.answerMy) return console.log(item) if(questionBank.value.types != 2) { item.answer = item.key curOption.value = item }else if(questionBank.value.types == 2){ if(!curOption.value.answer) curOption.value.answer = '' if(curOption.value.answer.includes(item.key)) { curOption.value.answer = curOption.value.answer.replace(item.key, '') return } curOption.value.answer = (curOption.value.answer + item.key).split('').sort().join('') // console.log(curOption.value.ans)
} } // 下一题
async function nextQuestion(num) { // 如果有答案,给答题卡上添加
if(curOption.value.answer) { questionBank.value.answerMy = curOption.value.answer if(questionBank.value.types==3) questionBank.value.answerMy = curOption.value.answer=='A'? 'true': 'false' } // 如果答错了 并且是第一次点
if(questionBank.value.answerMy&&questionBank.value.answer != questionBank.value.answerMy&&curOption.value.isNext != 'next') { curOption.value.isNext = 'next' showWrong.value = true if (countDownRef.value) { countDownRef.value.pause(); } return false } curOption.value = {} currentIndex.value = currentIndex.value + num getQuestionFn() } // 请求下一题
async function getQuestionFn() { console.log(currentIndex.value) questionBank.value = questionBankList.value[currentIndex.value] curOption.value = {} curOption.value.isNext = '' if(questionBank.value.answerMy) curOption.value.answer = questionBank.value.answerMy initOptionArr() } // 点击题卡片里
function ansCardClick(item) { currentIndex.value = item.index getQuestionFn() } function goOnExam() { showWrong.value = false } // 交卷
let grade = ref(0) async function submitBtnFn() { // 如果是最后一题也把答案交上去
if(curOption.value.answer) questionBank.value.answerMy = curOption.value.answer let wrongArr = questionBankList.value.filter(item=>item.answer!=item.answerMy) let worngId = wrongArr.map(item=>item.id).join(',') // grade = 100分/总题数 * 做对题数
grade.value = info.value.funllScore / questionBankList.value.length * (questionBankList.value.length - wrongArr.length) let obj = { "answer": null, "carType": usecarStore.carInfo.carType, "examId": examInfo.value.id, "examType": 2, "grade": grade.value, "isEnd": 1, "pass": 1, "sort": examInfo.value.sort, "stepType": usecarStore.carInfo.stepType, "userId": examInfo.value.userId, "wrongQuestionIds": worngId } const res = await startExamDo(obj) console.log(res) // uni.$u.toast('已交卷')
if(showCommit.value) showCommit.value = false if(grade.value<info.value.score) { showNoPass.value = true }else { setTimeout(()=>{ uni.navigateBack() },1500) } } function finishFn() { uni.$u.toast('考试时间已到,准备自动为您交卷') setTimeout(()=>{ submitBtnFn() },1500) } // 点击交卷
const countDownRef = ref(null) const yesNum = ref(0) const noNum = ref(0) function handApaper() { // 如果是最后一题也要把题算上去
if(curOption.value.answer) questionBank.value.answerMy = curOption.value.answer yesNum.value = questionBankList.value.filter(item=>item.answer==item.answerMy).length noNum.value = questionBankList.value.filter(item=>item.answerMy==undefined).length console.log(questionBankList.value) // 不有没有做完的题
if(noNum) { showCommit.value = true if (countDownRef.value) { countDownRef.value.pause(); } }else { submitBtnFn() } } // 关闭交卷弹框
function closeCommitPopup() { showCommit.value = false if (countDownRef.value) { countDownRef.value.start(); } } // 关闭错题弹框
function showWrongClose() { showWrong.value = false if (countDownRef.value) { countDownRef.value.start(); } curOption.value = {} currentIndex.value = currentIndex.value + 1 getQuestionFn() } // 合格标准
let info = ref({}) async function questionExamFn() { const {data:res} = await questionExam({stepType: usecarStore.carInfo.stepType, carType: usecarStore.carInfo.carType}) info.value = res } questionExamFn() </script>
<style lang="scss" scoped> uni-page-body { width: 100%; height: 100%; }
html { width: 100vh; height: 100vw; -webkit-transform: rotate(90deg); -webkit-transform-origin: 50vw 50vw; transform: rotate(90deg); transform-origin: 50vw 50vw;
}
image { display: block; width: 100%; height: 100%; } .imgView { position: relative; background: none; // max-width: 80%;
// padding: 50px;
.closeIcon { position: absolute; color: #fff; top: 40rpx; left: 40rpx; z-index: 99; background-color: #333; border-radius: 50%; } .img { // width: calc(100vh - 200rpx);
// height: calc(100vw - 100rpx);
width: 750rpx; height: 750rpx; } } .content { padding: 30rpx 30rpx 0rpx 30rpx; width: 100%; height: 100%; display: flex; flex-direction: column; background-color: #F7FBFE; font-size: 20rpx; // display: flex;
.h3 { position: absolute; top: -16rpx; left: 0; width: 100%; text-align: center; color: $themC; } .row { width: 100%; display: flex; .userInfoBox { width: 140rpx; // height: 408rpx;
// background-color: pink;
display: flex; flex-direction: column; .examNo { width: 100%; height: 60rpx; background: #FFFFFF; border: 1px solid #F0F0F0; position: relative; .card { line-height: 70rpx; text-align: center; padding-left: 20rpx; } .back { position: absolute; left: -20rpx; top: 50%; transform: translateY(-50%); width: 40rpx; height: 40rpx; background: #fff; border-radius: 50%; display: flex; align-items: center; justify-content: center; u-icon { } } } .user { // position: relative;
flex: 1; height: 0; padding: 10rpx 0 0 0rpx; .h3 { } .card { padding-left: 15rpx; position: relative; background: #FFFFFF; border: 1px solid #F0F0F0; height: 100%; .avatar { width: 90rpx; height: 90rpx; border-radius: 50%; overflow: hidden; margin-top: 36rpx; margin-bottom: 20rpx; img { } } .txt { margin: 10px 0; font-size: 18rpx; } } } } .examConBox { width: 0; flex: 1; display: flex; // height: 408rpx;
padding-left: 20rpx; .leftBox { flex: 2; background-color: #fff; position: relative; display: flex; flex-direction: column; .h3 { left: 40rpx; text-align: left; } .questionTxt { padding: 30rpx; flex: 1; line-height: 2em; .txt { } } .answer.flex-b { height: 60rpx; border-top: 1px solid #F0F0F0; padding-left: 20rpx; .lab { } .rightSelect { .lab { } .optio { padding-left: 20rpx; .optionItem { width: 38rpx; height: 38rpx; border: 1px solid #F0F0F0; font-size: 18rpx; color: #333; text-align: center; line-height: 38rpx; margin-right: 20rpx; &.active { color: #fff; background-color: $themC; } } } } } } .rightBox { flex: 1.4; background-color: #fff; table { display: table; border-collapse: collapse; border-spacing: 0px; table-layout: fixed; td, th { width: 9.09%; // text-overflow: ellipsis;
overflow: hidden; white-space: nowrap; } // border-color: gray;
} .ansItem { font-size: 24rpx; text-align: center; border-bottom: 1px solid #E1DFDF; border-right: 1px solid #E1DFDF; color: #ff0000; &.green { color: #55ff7f; } &.red { color: red; } } .blueItem { background-color: $themC; color: #fff; text-align: center; font-size: 24rpx; &.br { border-right: 1px solid #fff; &:last-child { border: none; } } &.bb { border-top: 1px solid #fff; // &:last-child {
// border: none;
// }
} } } } &.row1 { flex: 4; } &.row2 { height: 100rpx; padding: 20rpx 0; .timeBox { width: 140rpx; height: 100%; background-color: #fff; border: 1px solid #F0F0F0; position: relative; .h3 { font-weight: 400; } .time { font-weight: bold; font-size: 24rpx; color: #333333; line-height: 60rpx; text-align: center; } } .leftTpsBox { padding-left: 20rpx; flex: 2; position: relative; .card { background-color: #fff; height: 100%; } .h3 { text-align: left; left: 40rpx; } .txt { padding: 14rpx 20rpx 0 20rpx; } } .rightBtnBox { flex: 1; padding-left: 20rpx; display: flex; // justify-content: space-between;
justify-content: flex-end; .btn { width: 133rpx; margin: 0 0 0 20rpx; text-align: center; font-size: 24rpx; height: 60rpx; line-height: 60rpx; background: #3776FF; line-height: 60rpx; color: #fff; border: none; border-radius: 8rpx; &.disable { opacity: 0.4; } &.hui { background: #F4F4F4; color: #333; // border: 1rpx solid #E1DFDF;
} } } } } .picBox { width: 100%; flex: 1.8; background-color: #fff; border: 1px solid #F0F0F0; padding: 20rpx; position: relative; .h3 { text-align: left; left: 40rpx; } .imgBox { width: 650px; // max-height: 163rpx;
// background-color: skyblue;
height: 100%; overflow: hidden; margin: 0 auto; } } } .commitView { width: 780rpx; // height: 400rpx;
background: #FFFFFF; border-radius: 10rpx; padding: 40rpx; .commitTit { font-weight: bold; font-size: 32rpx; color: #333333; line-height: 40rpx; margin-bottom: 34rpx; text-align: center; } .commitTxt { font-family: PingFang SC; font-weight: 500; font-size: 24rpx; color: #333333; line-height: 42rpx; } .rowBg { width: 100%; height: 64rpx; background: #F4F4F4; border-radius: 10rpx; font-size: 24rpx; margin-top: 20rpx; color: #333333; line-height: 64rpx; display: flex; align-items: center; padding: 0 0 0 20rpx; .blue { color: #3776FF; margin-left: 30rpx; } } .commitBtn { display: flex; align-items: center; justify-content: center; margin: 50rpx 0 20rpx 0; .btn.border { background: none; color: #3776FF; border: 1px solid #3776FF; } .btn { width: 180rpx; height: 60rpx; background: #3776FF; border-radius: 10rpx; font-weight: 500; font-size: 24rpx; color: #FFFFFF; text-align: center; line-height: 60rpx; margin: 0 20rpx; } } } .djs { display: flex; align-items: center; justify-content: center; margin-top: 6rpx; .djsTxt { font-size: 24rpx; color: #999; margin: -4rpx 0 0 2rpx; } } </style>
<style lang="scss"> .djs { :deep .u-count-down__text { color: red !important; } } </style>
|