From 893ff90c6e21fa3a5241a8ae9b33836037cd5912 Mon Sep 17 00:00:00 2001 From: 马宇豪 <978517621@qq.com> Date: 星期四, 29 八月 2024 15:19:17 +0800 Subject: [PATCH] 提交 --- pages/tabBar/firstPage/exam.vue | 213 +++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 165 insertions(+), 48 deletions(-) diff --git a/pages/tabBar/firstPage/exam.vue b/pages/tabBar/firstPage/exam.vue index 9a64d19..2171269 100644 --- a/pages/tabBar/firstPage/exam.vue +++ b/pages/tabBar/firstPage/exam.vue @@ -16,10 +16,10 @@ </view> </view> <view class="m-p-15"> - <view class="timer" v-if="viewType == 1"> + <view class="timer" v-if="viewType == 1 && bank.examPaper.limited == 1"> <u--image :showLoading="true" :src="sandPic" width="18px" height="18px"></u--image> <view class="timer-b"> - <span>开考时间:</span> + <span>剩余时间:</span> <span>{{ formattedTime }}</span> </view> </view> @@ -34,12 +34,11 @@ </view> <view class="content"> <u-checkbox-group - v-if="currentQ.questionType==2" + v-if="viewType == 1 && currentQ.questionType==2" v-model="currentB" placement="column" class="myRadio" iconPlacement="right" - :disabled="viewType==1?false:true" @change="checkboxChange" > <u-checkbox @@ -52,7 +51,28 @@ > </u-checkbox> </u-checkbox-group> - <u-radio-group v-model="currentA" class="myRadio" iconPlacement="right" placement="column" @change="groupChange" v-if="currentQ.questionType==1||currentQ.questionType==3" :disabled="viewType==1?false:true"> + + <u-checkbox-group + v-if="viewType == 2 && currentQ.questionType==2" + v-model="currentB" + placement="column" + class="myRadio" + iconPlacement="right" + disabled + @change="checkboxChange" + > + <u-checkbox + :customStyle="{marginBottom: '15px'}" + v-for="(item, index) in currentQ.content.items" + :key="index" + :label="item.prefix +':'+ item.content" + :name="item.prefix" + :class="{'picked': currentQ.answer.includes(item.prefix),'wronged': currentB.includes(item.prefix) && !currentQ.answer.includes(item.prefix)}" + > + </u-checkbox> + </u-checkbox-group> + + <u-radio-group v-model="currentA" class="myRadio" iconPlacement="right" placement="column" @change="groupChange" v-if="viewType == 1 && (currentQ.questionType==1||currentQ.questionType==3)"> <u-radio :customStyle="{marginBottom: '15px'}" v-for="(item, index) in currentQ.content.items" @@ -66,12 +86,29 @@ </u-radio> </u-radio-group> - <u-button style="width: 80%;margin: 30px auto" + <u-radio-group v-model="currentA" class="myRadio" iconPlacement="right" placement="column" @change="groupChange" v-if="viewType == 2 && (currentQ.questionType==1||currentQ.questionType==3)" disabled> + <u-radio + :customStyle="{marginBottom: '15px'}" + v-for="(item, index) in currentQ.content.items" + :key="index" + shape="square" + :label="item.prefix +':'+ item.content" + :name="item.prefix" + @change="radioChange" + :class="{'picked': currentQ.answer == item.prefix, 'wronged': currentA == item.prefix && currentA != currentQ.answer}" + > + </u-radio> + </u-radio-group> + + <u--textarea v-model="currentA" v-if="viewType == 1 &&(currentQ.questionType==4)" style="margin-bottom: 15px" :maxlength="-1" placeholder="请输入答案" autoHeight @focus="openAnswer"></u--textarea> + <u--textarea v-model="currentA" v-if="viewType == 2 &&(currentQ.questionType==4)" :class="currentQ.answer == currentA?'pickedText':'wrongText'" style="margin-bottom: 15px" :maxlength="-1" placeholder="请输入答案" autoHeight disabled></u--textarea> + + <u-button style="width: 80%;margin: 5px auto 15px" v-if="currentQ.questionType==2 && currentB.length>0 && viewType ==1" - type="primary" shape="circle" text="确认答案" @click="confirmAnswer"></u-button> - <view class="answers" v-if="viewType == 2 && currentQ.studentAnswer && currentQ.studentAnswer.answer"> + type="primary" shape="circle" text="确认答案" @click="confirmAnswer(2)"></u-button> + <view class="answers" v-if="viewType == 2"> <view>你的答案: - <span :class="currentQ.answer == currentQ.studentAnswer.answer?'right':'wrong'">{{currentQ.studentAnswer.answer}}</span> + <span :class="(currentQ.studentAnswer && currentQ.studentAnswer.answer) && (currentQ.answer == currentQ.studentAnswer.answer)?'right':'wrong'">{{(currentQ.studentAnswer && currentQ.studentAnswer.answer)?currentQ.studentAnswer.answer:'暂未作答'}}</span> <!-- <span v-else :class="currentQ.answer == currentQ.studentAnswer.answer?'right':'wrong'">{{currentQ.studentAnswer.answer}}</span>--> </view> <view>正确答案:<span class="right">{{currentQ.answer}}</span></view> @@ -85,11 +122,22 @@ <u-button v-if="curTotalIndex < idList.length - 1" style="width: 30%" type="error" shape="circle" size="small" text="下一题" @click="nextQ"></u-button> <u-button v-if="curTotalIndex == idList.length - 1 && viewType == 2" style="width: 30%" type="primary" shape="circle" size="small" text="退出" @click="goBack"></u-button> </view> - <u-popup :show="showPanel" :round="40" mode="right" @close="close" @open="open"> - <view class="panel"> + <u-popup :show="showPanel" :round="40" mode="bottom" @close="close" @open="open"> + <view class="panel" v-if="viewType == 1"> + <view :class="item.state==1?'right-a':''" v-for="(item,index) in idList" @click="toQuestion(item,index)"> + {{index + 1}} + </view> + </view> + <view class="panel" v-else> <view :class="item.passed==1?'right-a':item.passed==0?'wrong-a':''" v-for="(item,index) in idList" @click="toQuestion(item,index)"> {{index + 1}} </view> + </view> + </u-popup> + <u-popup :show="showInput" :round="40" mode="bottom" @close="closeInput" @open="openInput"> + <view class="panelTwo"> + <u--textarea v-model="currentA" :maxlength="-1" placeholder="请输入答案"></u--textarea> + <u-button shape="circle" type="primary" style="width: 80%;margin-top: 20px" text="确认答案" @click="confirmAnswer(1)"></u-button> </view> </u-popup> </view> @@ -129,7 +177,9 @@ startTime: null, elapsedTime: 0, timerInterval: null, - showPanel: false + showPanel: false, + showInput: false, + limitTime: 0 } }, onReady(){ @@ -140,25 +190,27 @@ this.viewType = e.type && JSON.parse(decodeURIComponent(e.type)) this.startTime = this.bank.startTime?this.bank.startTime:0 this.getQuestionIds(this.bank.paperId) - + this.limitTime = this.bank.examPaper.limited == 1?this.bank.examPaper.limitTime:0 + if(this.viewType == 1){ + this.startTimer() + } }, onShow(){ }, mounted() { - if(this.viewType == 1){ - this.startTimer() - } + }, computed: { formattedTime() { - const totalSeconds = Math.floor(this.elapsedTime / 1000); + const totalSeconds = Math.floor((this.limitTime * 60) - this.elapsedTime / 1000); const hours = Math.floor(totalSeconds / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`; } }, + beforeUnmount() { }, @@ -174,7 +226,8 @@ if(res.code == 200){ let list = res.data || [] if(list.length>0){ - t.idList = list.sort((a, b) => a.id - b.id) + // t.idList = list.sort((a, b) => a.id - b.id) + this.idList = list }else{ t.idList = [] uni.showToast({ @@ -186,13 +239,16 @@ uni.$u.toast(res.message) } }, - + openAnswer(){ + const t = this + t.showInput = true + }, async toQuestion(item,index){ this.curTotalIndex = index const curIdList = this.idList.slice(this.curTotalIndex,this.curTotalIndex + 20) this.currentId = this.idList[this.curTotalIndex].id await this.getQuestionsByIds(curIdList) - this.currentQ = this.questionList[0] + this.currentQ = this.questionList.find(i=>i.id == this.currentId) this.showAnswer() this.showPanel = false }, @@ -203,6 +259,13 @@ close() { this.showPanel = false // console.log('close'); + }, + + openInput() { + // console.log('open'); + }, + closeInput(){ + this.showInput = false }, updateTimer() { @@ -219,12 +282,13 @@ if(res.code == 200){ let list = res.data || [] if(list.length>0){ - this.idList = list.sort((a, b) => a.id - b.id) + // this.idList = list.sort((a, b) => a.id - b.id) + this.idList = list this.curTotalIndex = this.bank.questionId ? this.idList.findIndex(i=>i.id == this.bank.questionId):0 const curIdList = this.idList.slice(this.curTotalIndex,this.curTotalIndex + 20) this.currentId = this.idList[this.curTotalIndex].id await this.getQuestionsByIds(curIdList) - this.currentQ = this.questionList[0] + this.currentQ = this.questionList.find(i=>i.id == this.currentId) this.showAnswer() }else{ this.idList = [] @@ -243,12 +307,13 @@ if(res.code == 200){ let list = res.data || [] if(list.length>0){ - this.idList = list.sort((a, b) => a - b) + // this.idList = list.sort((a, b) => a - b) + this.idList = list this.curTotalIndex = 0 const curIdList = this.idList.slice(0,20) this.currentId = this.idList[0].id await this.getQuestionsByIds(curIdList) - this.currentQ = this.questionList[0] + this.currentQ = this.questionList.find(i=>i.id == this.currentId) this.showAnswer() }else{ this.idList = [] @@ -279,14 +344,18 @@ }, groupChange(n) { if(this.currentA !== ''){ - this.confirmAnswer() + this.confirmAnswer(1) } }, radioChange(n) { console.log('radioChange', n); }, - confirmAnswer(){ + confirmAnswer(type){ + if(type == 1 && this.currentA == ''){ + uni.$u.toast('答案为空,请先作答') + return + } const data = { answer: this.currentQ.questionType==2?this.currentB.join(','):this.currentA, paperId: this.bank.paperId, @@ -296,8 +365,16 @@ postExamAnswer(data).then(res=>{ if(res.code == 200){ this.currentQ.passed = res.data - // this.currentQ.exExerciseAnswer.passed = res.data.passed - this.currentQ.studentAnswer.answer = res.data.answer + if (!this.currentQ.studentAnswer) { + Vue.set(this.currentQ, 'studentAnswer', {}); + } + Vue.set(this.currentQ.studentAnswer, 'answer', data.answer); + if(type == 2){ + this.nextQ() + } + if(this.showInput == true){ + this.showInput = false + } // uni.$u.toast('答案已提交') }else{ uni.$u.toast(res.message) @@ -308,13 +385,13 @@ prevQ(){ if(this.curTotalIndex - 1>=0){ this.curTotalIndex-- - if(this.curTotalIndex == 0){ - this.getQuestionsByIds([this.idList[0]]).then(()=>{ - // this.currentQ = this.questionList[this.questionList.length-1] - this.$set(this, 'currentQ', this.questionList[this.questionList.length-1]) - this.showAnswer() - }) - }else{ + // if(this.curTotalIndex == 0){ + // this.getQuestionsByIds([this.idList[0]]).then(()=>{ + // // this.currentQ = this.questionList[this.questionList.length-1] + // this.$set(this, 'currentQ', this.questionList[this.questionList.length-1]) + // this.showAnswer() + // }) + // }else{ this.currentId = this.idList[this.curTotalIndex].id if(this.questionList.find(i=>i.id == this.currentId)){ this.$set(this, 'currentQ', this.questionList.find(i=>i.id == this.currentId)) @@ -324,11 +401,11 @@ const curIdList = this.idList.slice(startIndex, this.curTotalIndex+1); this.getQuestionsByIds(curIdList).then(()=>{ // this.currentQ = this.questionList[this.questionList.length-1] - this.$set(this, 'currentQ', this.questionList[this.questionList.length-1]) + this.$set(this, 'currentQ', this.questionList.find(i=>i.id == this.currentId)) this.showAnswer() }) } - } + // } }else{ uni.showToast({ title: '已经是第一题了', @@ -347,8 +424,8 @@ }else{ const curIdList = this.idList.slice(this.curTotalIndex,this.curTotalIndex + 20) this.getQuestionsByIds(curIdList).then(()=>{ - this.$set(this, 'currentQ', this.questionList[0]) - // this.currentQ = this.questionList[0] + this.$set(this, 'currentQ', this.questionList.find(i=>i.id == this.currentId)) + // this.$set(this, 'currentQ', this.questionList[0]) this.showAnswer() }) } @@ -405,6 +482,7 @@ title: '本次考试结束', duration: 1500 }) + clearInterval(this.timerInterval) setTimeout(()=>{ const url = uni.getStorageSync("prevPage"); if(url){ @@ -464,8 +542,7 @@ } .panel{ - height: 100vh; - width: 60vw; + height: 60vh; background: #f2f2f2; overflow-y: auto; padding: 15px; @@ -477,7 +554,8 @@ &>view{ padding: 5px; - min-width: calc(20% - 12px); + box-sizing: border-box; + min-width: 33px; border-radius: 4px; text-align: center; background: rgba(41,121,255,0); @@ -485,7 +563,7 @@ color: #333; background: #f2f2f2; transition: all 100ms cubic-bezier(0.175, 0.885, 0.32, 1.275); - box-shadow: 0px -6px 10px rgba(255, 255, 255, 1), 0px 4px 15px rgba(0, 0, 0, 0.15); + box-shadow: 0px -6px 10px rgba(255, 255, 255, 1), 0px 4px 15px rgba(0, 0, 0, 0.1); cursor: pointer; &:active { @@ -508,6 +586,17 @@ background: rgba(237,100,100,.1); border: 1px solid #ed6464; color: #ed6464; + } +} + +.panelTwo{ + height: 60vh; + background: #f2f2f2; + padding: 15px; + box-sizing: border-box; + + /deep/ .u-textarea__field{ + height: calc(60vh - 110px) !important; } } @@ -558,7 +647,7 @@ border-radius: 4px; color: #2979ff; background: #f5f7fa; - border: 1px solid rgba(41,121,255,.4); + border: 1px solid rgba(41,121,255,.2); box-shadow: 0px -6px 10px rgba(255, 255, 255, 1), 0px 4px 15px rgba(0, 0, 0, 0.1); transition: box-shadow .25s ease !important; } @@ -571,13 +660,24 @@ .questions{ width: 100%; - margin-top: 40px; + margin-top: 40rpx; .title{ font-size: 16px; margin-bottom: 20px; } .content{ padding-left: 10rpx; + + .pickedText{ + border: 1.5px solid #2979ff !important; + } + .wrongText{ + border: 1.5px solid #ed6464 !important; + } + + /deep/ .u-textarea__field{ + min-height: 80px; + } .answers{ background: #ecf5ff; @@ -587,7 +687,11 @@ } span{ + width: 100%; + display: block; + white-space: pre-wrap; font-weight: bolder; + word-break: break-word; } .right{ color: #3c9cff @@ -606,7 +710,7 @@ align-items: center; justify-content: space-around; z-index: 99; - bottom: 60px; + bottom: 20px; left: 0; } @@ -622,14 +726,14 @@ box-sizing: border-box; border-radius: 8px; background: #f5f7fa; - border: 1px solid #fff; + border: 1.5px solid #fff; box-shadow: 0px -6px 10px rgba(255, 255, 255, 1), 0px 4px 15px rgba(0, 0, 0, 0.1); transition: box-shadow .25s ease !important; } .myRadio{ /deep/ .picked{ - border: 2px solid #2979ff; + border: 1.5px solid #2979ff; .u-radio__icon-wrap,.u-checkbox__icon-wrap{ border-color: #fff !important; @@ -641,6 +745,19 @@ color: #2979ff } } + /deep/ .wronged{ + border: 1.5px solid #ed6464; + + .u-radio__icon-wrap,.u-checkbox__icon-wrap{ + border-color: #fff !important; + span{ + color: #fff !important; + } + } + span{ + color: #ed6464 + } + } } /deep/ .u-checkbox:active { -- Gitblit v1.9.2