From 893ff90c6e21fa3a5241a8ae9b33836037cd5912 Mon Sep 17 00:00:00 2001 From: 马宇豪 <978517621@qq.com> Date: 星期四, 29 八月 2024 15:19:17 +0800 Subject: [PATCH] 提交 --- pages/tabBar/wearhouse/questions.vue | 465 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 370 insertions(+), 95 deletions(-) diff --git a/pages/tabBar/wearhouse/questions.vue b/pages/tabBar/wearhouse/questions.vue index 3d1e42e..c2be645 100644 --- a/pages/tabBar/wearhouse/questions.vue +++ b/pages/tabBar/wearhouse/questions.vue @@ -16,26 +16,23 @@ </view> </view> <view class="m-p-15" v-if="idList && idList.length>0"> - <u-divider - :text="'第'+ (currentIndex+1) +'题'" - textColor="#2979ff" - lineColor="#2979ff" - textSize="16" - style="margin: 40px 0" - ></u-divider> + <view class="top"> + <view class="ind">{{'第 ' + (curTotalIndex+1) + ' 题'}}</view> + <view v-if="type == 1 || type == 2" class="panelBtn" @click="openPanel">答题卡</view> + </view> <view class="questions"> <view class="title"> - <span>【{{currentQ.questionType == 1?'单选题':currentQ.questionType == 2?'多选题':'判断题'}}】</span> + <span>【{{currentQ.questionType == 1?'单选题':currentQ.questionType == 2?'多选题':currentQ.questionType == 3?'判断题':'简答题'}}】</span> {{currentQ.title}} </view> <view class="content"> <u-checkbox-group - v-if="currentQ.questionType==2" - v-model="currentQ.exExerciseAnswer.answer" + v-if="(type == 1 || type == 2)&& currentQ.questionType==2" + v-model="currentB" placement="column" iconPlacement="right" @change="checkboxChange" - :disabled="type==3?true:false" + class="myRadio" > <u-checkbox :customStyle="{marginBottom: '15px'}" @@ -43,10 +40,32 @@ :key="index" :label="item.prefix +':'+ item.content" :name="item.prefix" + :class="{'picked': currentB.includes(item.prefix)}" > </u-checkbox> </u-checkbox-group> - <u-radio-group v-model="currentQ.exExerciseAnswer.answer" iconPlacement="right" placement="column" @change="groupChange" v-if="currentQ.questionType==1||currentQ.questionType==3" :disabled="type==3?true:false"> + + <u-checkbox-group + v-if="type == 3 && currentQ.questionType==2" + v-model="currentB" + placement="column" + iconPlacement="right" + @change="checkboxChange" + disabled + class="myRadio" + > + <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="(type == 1 || type == 2)&&(currentQ.questionType==1||currentQ.questionType==3)"> <u-radio :customStyle="{marginBottom: '15px'}" v-for="(item, index) in currentQ.content.items" @@ -55,14 +74,35 @@ :label="item.prefix +':'+ item.content" :name="item.prefix" @change="radioChange" + :class="{'picked': currentA == item.prefix}" > </u-radio> </u-radio-group> - <u-button style="width: 80%;margin: 30px auto" v-if="currentQ.exExerciseAnswer && currentQ.exExerciseAnswer.answer && type !== 3" type="primary" shape="circle" text="确认答案" @click="confirmAnswer"></u-button> - <view class="answers" v-if="currentQ.exExerciseAnswer && (currentQ.exExerciseAnswer.passed==0||currentQ.exExerciseAnswer.passed==1)"> + + <u-radio-group v-model="currentA" class="myRadio" iconPlacement="right" placement="column" @change="groupChange" v-if="type == 3 && (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="(type == 1 || type == 2)&&(currentQ.questionType==4)" style="margin-bottom: 15px" :maxlength="-1" placeholder="请输入答案" autoHeight @focus="openAnswer"></u--textarea> + <u--textarea v-model="currentA" v-if="type == 3&&(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 && type !== 3" + type="primary" shape="circle" text="确认答案" @click="confirmAnswer(2)"></u-button> + <view class="answers" v-if="currentA !==''||currentB.length>0"> <view>你的答案: - <span v-if="currentQ.questionType==2" :class="currentQ.answer == currentQ.exExerciseAnswer.answer.join(',')?'right':'wrong'">{{currentQ.exExerciseAnswer.answer.join(',')}}</span> - <span v-else :class="currentQ.answer == currentQ.exExerciseAnswer.answer?'right':'wrong'">{{currentQ.exExerciseAnswer.answer}}</span> + <span v-if="currentQ.questionType==2" :class="currentQ.answer == currentB.join(',')?'right':'wrong'">{{currentB.join(',')}}</span> + <span v-else :class="currentQ.answer == currentA?'right':'wrong'">{{currentA}}</span> </view> <view>正确答案:<span class="right">{{currentQ.answer}}</span></view> </view> @@ -72,8 +112,8 @@ <view class="btns" v-if="idList && idList.length>0"> <u-button style="width: 30%" type="error" shape="circle" size="small" text="上一题" @click="prevQ"></u-button> <!-- <u-button style="width: 30%" type="error" shape="circle" plain size="small" text="查看答案" @click="showA"></u-button>--> - <u-button v-if="currentIndex<questionList.length - 1" style="width: 30%" type="error" shape="circle" size="small" text="下一题" @click="nextQ"></u-button> - <u-button v-if="currentIndex==questionList.length - 1" style="width: 30%" type="primary" shape="circle" size="small" text="退出" @click="goBack"></u-button> + <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" style="width: 30%" type="primary" shape="circle" size="small" text="退出" @click="goBack"></u-button> </view> <view v-else> <u-empty @@ -82,6 +122,19 @@ > </u-empty> </view> + <u-popup :show="showPanel" :round="40" mode="bottom" @close="close" @open="open"> + <view class="panel"> + <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> </template> @@ -98,9 +151,14 @@ bank: {}, idList: [], questionList: [], - currentIndex: 0, + curTotalIndex: 0, + currentId: null, currentQ: {}, - type: '' + currentA: '', + currentB: [], + type: '', + showPanel: false, + showInput: false } }, onReady(){ @@ -110,7 +168,6 @@ this.bank = e.bank && JSON.parse(decodeURIComponent(e.bank)) this.type = e.type && JSON.parse(decodeURIComponent(e.type)) if(this.type == '1' || this.type == '2'){ - this.currentIndex = this.bank.exerciseCount this.getQuestionIds(this.bank.id) }else{ this.getErrorIds(this.bank.id) @@ -134,28 +191,66 @@ }, methods: { + async openPanel(){ + const t = this + t.showPanel = true + const res = await getQuestionIdList({bankId: t.bank.id}) + if(res.code == 200){ + let list = res.data || [] + if(list.length>0){ + // t.idList = list.sort((a, b) => a.id - b.id) + this.idList = list + }else{ + t.idList = [] + uni.showToast({ + title: '本题库暂无题目', + duration: 1000 + }); + } + }else{ + 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.find(i=>i.id == this.currentId) + this.showAnswer() + this.showPanel = false + }, + + open() { + // console.log('open'); + }, + close() { + this.showPanel = false + // console.log('close'); + }, + openInput() { + // console.log('open'); + }, + closeInput(){ + this.showInput = false + }, async getQuestionIds(id){ const res = await getQuestionIdList({bankId: id}) 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 - getQuestionByIds({questionIds: list.map(i=>i.id)}).then(re=>{ - if(re.code == 200){ - this.questionList = re.data.map(i=>{ - i.content = JSON.parse(i.content) - if(i.questionType == 2){ - if(i.exExerciseAnswer.answer){ - i.exExerciseAnswer.answer = i.exExerciseAnswer.answer.split(',') - } - } - return i - }) - this.currentQ = this.questionList[this.currentIndex] - }else{ - uni.$u.toast(res.message) - } - }) + 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.find(i=>i.id == this.currentId) + this.showAnswer() }else{ this.idList = [] uni.showToast({ @@ -173,23 +268,14 @@ if(res.code == 200){ let list = res.data || [] if(list.length>0){ + // this.idList = list.sort((a, b) => a - b) this.idList = list - getQuestionByIds({questionIds: list}).then(re=>{ - if(re.code == 200){ - this.questionList = re.data.map(i=>{ - i.content = JSON.parse(i.content) - if(i.questionType == 2){ - if(i.exExerciseAnswer.answer){ - i.exExerciseAnswer.answer = i.exExerciseAnswer.answer.split(',') - } - } - return i - }) - this.currentQ = this.questionList[0] - }else{ - uni.$u.toast(res.message) - } - }) + this.curTotalIndex = 0 + const curIdList = this.idList.slice(0,20) + this.currentId = this.idList[0] + await this.getQuestionsByIds(curIdList) + this.currentQ = this.questionList.find(i=>i.id == this.currentId) + this.showAnswer() }else{ this.idList = [] uni.showToast({ @@ -202,26 +288,57 @@ } }, + async getQuestionsByIds(idList){ + let list = [] + if(this.type == 3){ + list = idList + }else{ + list = idList.map(i=>i.id) + } + const res = await getQuestionByIds({questionIds: list}) + if(res.code == 200){ + this.questionList = res.data.map(i=>{ + i.content = JSON.parse(i.content) + return i + }) + }else{ + uni.$u.toast(res.message) + } + }, + checkboxChange(n) { console.log('change', n); }, groupChange(n) { - console.log('groupChange', n); + if(this.currentA !== ''){ + 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.currentQ.exExerciseAnswer.answer.join(','):this.currentQ.exExerciseAnswer.answer, + answer: this.currentQ.questionType==2?this.currentB.join(','):this.currentA, bankId: this.bank.id, questionId: this.currentQ.id } postExerciseAnswer(data).then(res=>{ if(res.code == 200){ this.currentQ.exExerciseAnswer.passed = res.data.passed - uni.$u.toast('答案已提交') + this.currentQ.exExerciseAnswer.answer = res.data.answer + if(type == 2){ + this.nextQ() + } + if(this.showInput == true){ + this.showInput = false + } + // uni.$u.toast('答案已提交') }else{ uni.$u.toast(res.message) } @@ -229,33 +346,79 @@ }, prevQ(){ - if(this.currentIndex - 1>=0){ - this.currentIndex-- - this.currentQ = this.questionList[this.currentIndex] + 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.find(i=>i.id == this.currentId)) + // this.showAnswer() + // }) + // }else{ + if(this.type == 3){ + this.currentId = this.idList[this.curTotalIndex] + }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)) + this.showAnswer() + }else{ + const startIndex = Math.max(0, this.curTotalIndex - 19); + 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.find(i=>i.id == this.currentId)) + this.showAnswer() + }) + } + // } }else{ uni.showToast({ title: '已经是第一题了', duration: 1000 }); } - console.log(this.currentQ,'current') }, nextQ(){ - if(this.currentQ.exExerciseAnswer.passed==null){ - uni.$u.toast('请先完成当前题目') - return - } - if(this.currentIndex + 1<this.questionList.length){ - this.currentIndex++ - this.currentQ = this.questionList[this.currentIndex] + if(this.curTotalIndex + 1<this.idList.length){ + this.curTotalIndex++ + if(this.type == 3){ + this.currentId = this.idList[this.curTotalIndex] + }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)) + this.showAnswer() + }else{ + const curIdList = this.idList.slice(this.curTotalIndex,this.curTotalIndex + 20) + this.getQuestionsByIds(curIdList).then(()=>{ + this.$set(this, 'currentQ', this.questionList.find(i=>i.id == this.currentId)) + // this.currentQ = this.questionList[0] + this.showAnswer() + }) + } }else{ uni.showToast({ title: '已经是最后一题了', duration: 1000 }); } - console.log(this.currentQ,'current') + }, + + showAnswer(){ + if(this.currentQ.exExerciseAnswer && this.currentQ.exExerciseAnswer.answer){ + if(this.currentQ.questionType == 2){ + this.currentB = this.currentQ.exExerciseAnswer.answer.split(',') + }else{ + this.currentA = this.currentQ.exExerciseAnswer.answer + } + }else{ + this.currentB = [] + this.currentA = '' + } }, showA(){ @@ -319,17 +482,100 @@ margin-right: 10rpx; } +.panel{ + height: 60vh; + background: #f2f2f2; + overflow-y: auto; + padding: 15px; + box-sizing: border-box; + display: grid; + grid-template-columns: repeat(5, 1fr); + gap: 15px; + grid-auto-rows: min-content; + + &>view{ + padding: 5px; + box-sizing: border-box; + min-width: 33px; + border-radius: 4px; + text-align: center; + background: rgba(41,121,255,0); + border: 1px solid #fff; + 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.1); + cursor: pointer; + + &:active { + box-shadow: 0 15px 20px rgba(0, 0, 0, 0.02); + &:after { + box-shadow: inset 0px -2px 5px rgb(255, 255, 255), + inset 0px 2px 5px rgba(0, 0, 0, 0.15); + } + } + + } + + .right-a{ + background: rgba(41,121,255,.1); + border: 1px solid #2979ff; + color: #2979ff; + } + + .wrong-a{ + 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; + } +} + .m-p-15{ width: 100%; padding: 0 15px; box-sizing: border-box; .top{ - text-align: center; - margin: 20rpx 0; - font-weight: bolder; - } + display: flex; + align-items: center; + justify-content: space-between; + margin: 20px 0; + .ind{ + font-size: 18px; + font-weight: bold; + color: #2979ff; + } + + .panelBtn{ + width: 25%; + margin: 0; + text-align: center; + padding: 4px 0; + border-radius: 4px; + color: #2979ff; + background: #f5f7fa; + 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; + } + .panelBtn:active{ + background: #f5f7fa; + border: 1px solid rgba(41,121,255,1); + box-shadow: 0 15px 20px rgba(0, 0, 0, 0.02); + } + } .questions{ width: 100%; margin-top: 40px; @@ -340,15 +586,31 @@ .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; padding: 10px; + &>view{ margin-bottom: 5px; } span{ + width: 100%; + display: block; + white-space: pre-wrap; font-weight: bolder; + word-break: break-word; } .right{ color: #3c9cff @@ -367,7 +629,7 @@ align-items: center; justify-content: space-around; z-index: 99; - bottom: 60px; + bottom: 20px; left: 0; } @@ -383,32 +645,45 @@ box-sizing: border-box; border-radius: 8px; background: #f5f7fa; - border: 1px solid #fff; - box-shadow: 7px 7px 15px rgba(55, 84, 170, .15), - -7px -7px 20px rgba(255, 255, 255, 1), - inset 0px 0px 4px rgba(255, 255, 255, .2), - inset 7px 7px 15px rgba(55, 84, 170, 0), - inset -7px -7px 20px rgba(255, 255, 255, 0), - 0px 0px 4px rgba(255, 255, 255, 0) !important; - transition: box-shadow .25s ease !important; + 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,box-width .25s ease !important; +} + +.myRadio{ + /deep/ .picked{ + border: 1.5px solid #2979ff; + + .u-radio__icon-wrap,.u-checkbox__icon-wrap{ + border-color: #fff !important; + span{ + color: #fff !important; + } + } + span{ + 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 { - box-shadow: 7px 7px 15px rgba(55, 84, 170, .15), - -7px -7px 20px rgba(255, 255, 255, 1), - inset 0px 0px 4px rgba(255, 255, 255, 0), - inset 7px 7px 15px rgba(55, 84, 170, .15), - inset -7px -7px 20px rgba(255, 255, 255, 1), - 0px 0px 4px rgba(255, 255, 255, .2) !important; + box-shadow: 0 15px 20px rgba(0, 0, 0, 0.02); } /deep/ .u-radio:active { - box-shadow: 7px 7px 15px rgba(55, 84, 170, .15), - -7px -7px 20px rgba(255, 255, 255, 1), - inset 0px 0px 4px rgba(255, 255, 255, 0), - inset 7px 7px 15px rgba(55, 84, 170, .15), - inset -7px -7px 20px rgba(255, 255, 255, 1), - 0px 0px 4px rgba(255, 255, 255, .2) !important; + box-shadow: 0 15px 20px rgba(0, 0, 0, 0.02); } - </style> \ No newline at end of file -- Gitblit v1.9.2