| common/api/exam.js | ●●●●● patch | view | raw | blame | history | |
| common/api/examFunc.js | ●●●●● patch | view | raw | blame | history | |
| common/axios.js | ●●●●● patch | view | raw | blame | history | |
| components/dyw-answer/answer - 副本 (2).vue | ●●●●● patch | view | raw | blame | history | |
| components/dyw-answer/answer.vue | ●●●●● patch | view | raw | blame | history | |
| pages.json | ●●●●● patch | view | raw | blame | history | |
| pages/business/business - 副本.vue | ●●●●● patch | view | raw | blame | history | |
| pages/exam/examResultPage.vue | ●●●●● patch | view | raw | blame | history | |
| pages/exam/examReviewPage.vue | ●●●●● patch | view | raw | blame | history | |
| pages/exam/examTextPage.vue | ●●●●● patch | view | raw | blame | history | |
| pages/exam/startexam.vue | ●●●●● patch | view | raw | blame | history | |
| store/state.js | ●●●●● patch | view | raw | blame | history |
common/api/exam.js
@@ -13,4 +13,12 @@ method: 'POST', data: params }) } export const submitExam = (params) => { return request({ url: '/simulateExamRecord/saveSimulateExam', method: 'POST', data: params }) } common/api/examFunc.js
@@ -10,27 +10,48 @@ let questionList = [] let queTypeArr = [] quesModules.forEach((item, index) => { let quesType = item.choicesType queTypeArr.push(quesType) item.template = item.choicesType // 是否答题了 item.selectedFlag = false // 答题的结果 item.tempAnswer = "" // 题目是否做对 item.correctOrError = false queTypeArr.push(quesType) item.template = item.choicesType if (item.template == 1) { item.dualChooseArr = [] } item.options = item.examSubjectOptions if (item.template == 2) { item.rightAnswer = item.answer } item.options.forEach(it => { it.newOptLetter = it.optionName it.optContent = it.optionContent it.optLetter = it.newOptLetter }) if (item.template == 0 || item.template == 1) { item.options.forEach(it => { it.newOptLetter = it.optionName it.optContent = it.optionContent it.optLetter = it.newOptLetter }) item.options.reverse() } questionList.push(item) }) store.state.queTypeArr = unique(queTypeArr) common/axios.js
@@ -8,7 +8,7 @@ import axios from "axios"; const service = axios.create({ baseURL: "http://192.168.0.198:81", //正常接口 baseURL: "http://192.168.0.114:81", //正常接口 timeout: 600000, // request timeout }); components/dyw-answer/answer - 副本 (2).vue
New file @@ -0,0 +1,999 @@ <template> <!-- 此组件用于显示整套试卷· 试卷类型包含 exam 理论考试 paper 模拟考试 知识点练习 --> <view> <!-- 大标题 --> <view class="header" id="header"> <!-- <span class="header-button" @click='leave' v-if='!isReviewed && examType=='know' '>暂离</span> --> <span v-if="examType=='exam'"> {{examDetail.exam.name}}</span> <span v-if="(examType=='paper' )|| (examType=='know') || (examType=='course')"> {{examDetail.paper.name}}</span> <span class="header-button" @click='handleSubmit(1)' v-if='!isReviewed'>交卷</span> <!-- <span class="scoreText" v-else>得分:{{examDetail.score}}</span> --> </view> <!-- 小标题栏 --> <view id="subHeader"> <view class="sub-header" v-if='questionList.length > 0'> <u-tag class="typeTag" :text="answerStatusName" mode="dark" shape="circle" /> <view v-if="examDetail.exam.examTime<=0">不限时</view> <u-count-down v-if="(!isReviewed)&&(examType=='exam')&& (examDetail.exam.examTime>0)" :timestamp="examDetail.exam.examTime / 1000" :show-days="false" @end="end" @change="change"> </u-count-down> <clock v-if="(!isReviewed)&&(examType=='paper' || (examType=='course'))" ref="myClock" :timeOrigin="parseInt(examDetail.time)"> </clock> <span v-if="examType=='exam'">第 {{currentIndex+1}}/{{examDetail.exam.totalQuestion}} 题</span> <span v-if="(examType=='paper' )|| (examType=='know')">第 {{currentIndex+1}}/{{examDetail.totalQuestion}} 题</span> </view> </view> <!-- 答题区域 --> <swiper class="content" :duration='duration' :current=currentIndex @change='handleSwiperChanged' v-if='questionList.length > 0' :style="{'height':swiperHeight}"> <template v-for='item in questionList'> <swiper-item class="content-item"> <scroll-view scroll-y :style="{'height':swiperHeight}"> <!-- 显示题目的题干 --> <view class="content-title"> <rich-text :nodes="item.subjectName"></rich-text> </view> <!-- 以下显示选项 --> <!-- type == 0 单选题 --> <view class="content-solutions" v-if='item.template == 0'> <template v-for='subItem in item.options'> <view :class="[isReviewed && subItem.optAnswer == 1 ? 'right': '',isReviewed && (item.wrongArr.indexOf(subItem.optLetter) >-1) ? 'wrong': '']" class="content-solutions-item" @click='chooseSolution(item,subItem)'> <view v-if="(!isReviewed) && (examType=='exam') " class="content-solutions-item-single"> {{subItem.newOptLetter}} </view> <view v-else class="content-solutions-item-single">{{subItem.optLetter}}</view> <!-- 此处注意optLetter与newOptLetter的区别,newOptLetter是ABCD顺序的,而optLetter乱序的,两者无直接关系 --> <view :class="item.tempAnswer == subItem.optLetter? 'content-solutions-item-select' : ''" class="content-solutions-item-content">{{subItem.optContent}}</view> </view> </template> </view> <!-- type == 1 多选题 --> <view class="content-solutions" v-if='item.template == 1'> <template v-for='subItem in item.options'> <view :class="[isReviewed && subItem.optAnswer == 1 ? 'right': '',isReviewed && (item.wrongArr.indexOf(subItem.optLetter) >-1) ? 'wrong': '']" class="content-solutions-item" @click='chooseMutiSolution(item,subItem)'> <view v-if="(!isReviewed) && (examType=='exam') " class="content-solutions-item-single"> {{subItem.newOptLetter}} </view> <view v-else class="content-solutions-item-single">{{subItem.optLetter}}</view> <!-- TODO 是否被选中的条件判断不对 --> <view :class="item.tempAnswer.indexOf(subItem.optLetter) >-1 ? 'content-solutions-item-select' : ''" class="content-solutions-item-content">{{subItem.optContent}} </view> </view> </template> </view> <!-- type == 2 判断题 --> <view class="content-solutions" v-if='item.template == 2'> <template v-for='subItem in item.options'> <view class="content-solutions-judge"> <view v-for="(judgeItem,judgeIndex) in judgeArr" :class="[item.tempAnswer == judgeItem.value? 'content-solutions-item-select' : '',isReviewed && (item.rightAnswer==judgeItem.name) ? 'right': '',isReviewed && (item.wrongArr ==judgeItem.value) ? 'wrong': '']" class="content-solutions-judge-item" @click='judgeSolution(item,judgeItem.value)'>{{judgeItem.name}}</view> </view> </template> </view> <!-- type == 4 填空题 --> <view class="content-solutions" v-if='item.template == 4'> <template v-if="!isReviewed"> <view class="content-solutions-item" v-for='(subItem,subIndex) in item.options' :keys="subIndex" :class="[isReviewed && item.answerStatus!=4 &&(item.blankString != item.rightAnswer)? 'wrong':'']"> <view class="content-solutions-item-single">{{subIndex+1}}</view> <input :disabled="isReviewed" type="text" class="content-solutions-blank" v-model="item.blankArr[subIndex]" placeholder="请在此处输入答案" /> </view> </template> <template v-else> <view class="content-solutions-item"> <view class="content-solutions-item-single"></view> <!-- TODOvalue的绑定值不对 :value="item.blankArr[subIndex].replace(/"\;/g, '')" --> <input :disabled="isReviewed" :value="(item.blankArr).join(',')" type="text" class="content-solutions-blank" /> </view> </template> </view> <!-- type == 5 简答题 --> <view class="content-solutions" v-if='item.template == 5'> <textarea v-if="!isReviewed" @input="textInput" :disabled="isReviewed" placeholder="请输入您的答案" auto-height /> <textarea v-else :disabled="isReviewed" :value="item.tempAnswer.replace(/"\;/g, '')" auto-height /> </view> <view class="explain" v-if='isReviewed'> <u-tag v-show="item.answerStatus==1" text="未答" type="error" /> <u-tag v-show="item.answerStatus==2" text="正确" type="success" /> <u-tag v-show="item.answerStatus==3" text="错误" type="error" /> <u-tag v-show="item.answerStatus==4" text="未评分" type="warning" /> <u-tag v-show="item.answerStatus==5" text="已评分" type="warning" /> <u-tag v-show="item.answerStatus==6" text="已答" type="warning" /> <view class="explain-title">正确答案:</view> <!-- <span class="text">{{item.rightAnswer}}</span> --> <u-parse :html="item.rightAnswer"></u-parse> <view class="explain-title">试题解析:</view> <!-- <view class="explain-content">{{item.queAnalysis | analysisFilter }}</view> --> <u-parse :html="item.queAnalysis?item.queAnalysis:'暂无'"></u-parse> <view class="noteArea"> <view class="noteAreaTitle"> <view class="explain-title">我的笔记:</view> <view v-if="eidtOrFinishValue=='编辑笔记'" class="funcGroup" @click="editBtnFunc(item)"> <u-icon class="funcBtn" name="edit-pen"></u-icon> <span>编辑笔记</span> </view> <view v-else class="funcGroup" @click="finishBtnFunc(item)"> <u-icon class="funcBtn" name="edit-pen"></u-icon> <span>完成</span> </view> </view> <!-- 只有回答过的题目才能编辑笔记!!! --> <text-editor :noteId="item.id" :textContent="item.theoryExamAnswer.queNote" :isreadOnly="isreadOnly" @editorInput='updateEditorText'> </text-editor> </view> </view> </scroll-view> </swiper-item> </template> </swiper> <!-- 底部栏 --> <view class="footer" id="footer"> <view class="footer-back" @click='handleChangeCurrentSwiper(-1)'>上一题</view> <view class="footer-card" @click="showQuestion = !showQuestion">答题卡</view> <view class="footer-right" @click='handleChangeCurrentSwiper(1)'>下一题</view> </view> <!-- 答题卡弹出层 --> <modal v-model="showQuestion"> <view class='question-modal' :style="{'height': modalHeight}"> <view class="question-modal-header" id="questionHeader"> 答题卡 </view> <scroll-view scroll-y class="question-modal-body" :style="{'height': modalContentHeight}"> <template v-for="(subItem,subIndex) in queTypeArr"> <view class="queTypeName" v-show="queTypeStore[subIndex]>=0">{{subItem.name}}</view> <!-- <u-tag :text="subItem.name" v-show="queTypeStore[subIndex]>0" mode="dark" /> --> <view class="queTypeArea"> <template v-for="(item, index) in questionList"> <view v-show="item.template == subItem.value"> <!-- 1.复习状态且回答正确 --> <!-- <view v-if='item.tempAnswer && item.answer==item.tempAnswer && isReviewed' --> <view v-if='isReviewed && item.answerStatus == "2"' class="question-modal-body-item question-modal-body-item-right" @click="handleJumpSwiper(index)">{{index + 1 }}</view> <!-- 2.复习状态且回答错误 --> <view v-else-if='isReviewed && (item.answerStatus == "1" ||item.answerStatus == "3" )' class="question-modal-body-item question-modal-body-item-failed" @click="handleJumpSwiper(index)">{{index + 1 }}</view> <!-- 3.复习状态且简答题未评分或者已评分 --> <view v-else-if='isReviewed && (item.answerStatus == "4" ||item.answerStatus == "5")' class="question-modal-body-item question-modal-body-item-unScored" @click="handleJumpSwiper(index)">{{index + 1 }}</view> <!-- 3.非复习状态且已经作答 --> <view v-else-if='!isReviewed && item.tempAnswer && item.tempAnswer.length != 0' class="question-modal-body-item question-modal-body-item-select" @click="handleJumpSwiper(index)">{{index + 1 }}</view> <!-- 4.非复习状态且未作答 --> <view v-else class="question-modal-body-item question-modal-body-item-unselect" @click="handleJumpSwiper(index)"> {{index + 1 }} </view> <!-- <u-line color="red" border-style="info"></u-line> --> </view> </template> </view> </template> </scroll-view> <view class="question-modal-foot" id="questionHeader"> <view v-if="!isReviewed" class="ansBlock"> <view class="blockItem"> <view class="block-ansed"></view> <view class="">已答</view> </view> <view class="blockItem"> <view class="block-unansed"></view> <view class="">未答</view> </view> </view> <view v-else class="ansBlock"> <view class="blockItem"> <view class="block-right"></view> <view class="">答对</view> </view> <view class="blockItem"> <view class="block-wrong"></view> <view class="">答错</view> </view> <view class="blockItem"> <view class="block-unScored"></view> <view class="">未评分</view> </view> </view> </view> </view> </modal> <u-toast ref="uToast" /> </view> </template> <script> import Modal from './modal.vue' import clock from '@/components/clock/clock.vue'; export default { data() { return { isreadOnly: true, quesModules: [], areaText: ``, //保存简答题答案 judgeArr: [{ name: '正确', value: '1' }, { name: '错误', value: '0' } ], queTypeArr: [{ name: '单选题', value: '0', be: false, }, { name: '多选题', value: '1', be: false, }, { name: '判断题', value: '2', be: false, }, { name: '填空题', value: '4', be: false, }, { name: '简答题', value: '5', be: false, } ], currentIndex: 0, swiperHeight: '667px', modalHeight: '500px', modalContentHeight: '400px', showQuestion: false, articleEditorValue: '', eidtOrFinishValue: '编辑笔记', // eidtOrFinish: true, editorText: '', editor: 'editor', } }, filters: { // 判断答案状态 analysisFilter(item) { if (item == null) { return "暂无解析" } else { return item } } }, watch: { // 监听currentIndex的变化,改变则提交答案 相同 currentIndex(newVal, oldVal) { let that = this if (!this.isReviewed) { // 对各题型的答案进行处理 switch (that.questionList[oldVal].template) { case 0: // 选择题 break; case 1: // 多选题 // that.questionList[that.currentIndex].tempAnswer = that.questionList[that.currentIndex] // .dualChooseArr.join(',') break; case 2: // 判断题 break; case 4: // 填空题 that.questionList[oldVal].tempAnswer = that.questionList[oldVal].blankArr.join( '||~||') // 数组拼接为字符串 break; case 5: that.questionList[oldVal].tempAnswer = JSON.stringify(that.areaText) // console.log('000:',that.questionList[oldVal].tempAnswer); break; default: } // if (this.examType == 'exam') { // // 保存答案 // var answerObj = { // examRecordId: this.questionList[oldVal].recordId, // paperQueId: this.questionList[oldVal].id, // answer: this.questionList[oldVal].tempAnswer, // template: this.questionList[oldVal].template // } // // 进行答题的api请求 // console.log('answerObj:', oldVal, answerObj); // this.$api.answerExam(answerObj) // .then(res => { // console.log(res); // }) // } else if (this.examType == 'paper' || this.examType == 'know') { // var answerObj = { // exerciseId: this.examDetail.exerciseId, // paperQueId: this.questionList[oldVal].id, // answer: this.questionList[oldVal].tempAnswer, // template: this.questionList[oldVal].template // } // // 进行答题的api请求 // console.log('answerObj:', oldVal, answerObj); // this.$api.answerPaper(answerObj) // .then(res => { // console.log(res); // }) // } else { // return // } // immediate: true, } } }, computed: { // swiperHeight(){ // uni.getSystemInfo({ // success(res) { // console.log(res); // return res.windowHeight+'px' // } // }) // }, examDetail() { return this.$store.state.examDetail }, questionList() { console.log(this.$store.state.questionList, 77777) return this.$store.state.questionList }, queTypeStore() { return this.$store.state.queTypeArr }, max() { return this.questionList.length - 1 }, answerStatusName() { console.log(this.questionList[this.currentIndex].template, 63636636366) switch (this.questionList[this.currentIndex].template) { case 0: return '单选题' break; case 1: return '多选题' break; case 2: return '判断题' break; case 4: return '填空题' break; case 5: return '简答题' break; default: return '考试题' } } }, props: { isReviewed: { type: Boolean, default: false }, examType: { type: String, default: "exam" }, duration: { type: [String, Number], default: 300 }, }, mounted() { var that = this this.setAnswerHeight() if ((!this.isReviewed) && ((this.examType == 'paper') || (this.examType == 'course'))) { this.$refs.myClock.start(); } }, components: { Modal, clock }, methods: { /*设置题目的高度*/ setAnswerHeight() { let that = this let tempHeight = 0 uni.getSystemInfo({ //获取手机屏幕高度信息,让swiper的高度和手机屏幕一样高 success: function(res) { console.log(res, '010101010') tempHeight = res.windowHeight; that.modalHeight = res.windowHeight - uni.upx2px(200) + 'px'; that.modalContentHeight = res.windowHeight - uni.upx2px(380) + 'px'; uni.createSelectorQuery().in(that).select("#header").fields({ size: true, scrollOffset: true }, (data) => { console.log('data', data); tempHeight -= data.height; uni.createSelectorQuery().in(that).select("#subHeader").fields({ size: true, scrollOffset: true }, (data) => { tempHeight -= data.height; uni.createSelectorQuery().in(that).select("#footer").fields({ size: true, scrollOffset: true }, (data) => { tempHeight -= data.height; that.swiperHeight = tempHeight + 'px'; }).exec(); }).exec(); }).exec(); } }); }, /* 跳转指定题目 */ handleJumpSwiper(index) { this.currentIndex = index this.showQuestion = false }, change(timestamp) { // var that = this if (timestamp == 30) { this.$refs.uToast.show({ title: '考试只剩余30s,请注意时间', type: 'warning', duration: 2000, position: 'top' }) } // this.$forceUpdate() }, end() { this.$refs.uToast.show({ title: '考试时间结束,已自动交卷', type: 'warning' }) setTimeout(() => { this.handleSubmit(0) }, 2000) }, textInput(e) { this.areaText = e.detail.value // console.log(e.detail.value) }, /* 滑动题目 */ handleSwiperChanged(event) { this.currentIndex = event.detail.current }, /* 调用上一页,下一页 */ handleChangeCurrentSwiper(operation) { let max = this.questionList.length - 1 let min = 0 // 进行翻页 if ((this.currentIndex > min && operation < 0) || (this.currentIndex < max && operation > 0)) { this.currentIndex += operation // console.log(this.currentIndex) } }, /* 选择答案(单选)*/ chooseSolution(item, subItem) { if (!this.isReviewed) { // tempAnswer为学生答案 item.tempAnswer = subItem.optLetter // 强制刷新更新视图 this.$forceUpdate() // this.questionList[this.currentIndex].tempAnswer = subItem.optLetter if (this.currentIndex < this.max) { setTimeout(() => { this.currentIndex += 1 }, 300) } // this.onAnswerChange(item) } }, /* 选择答案(多选)*/ chooseMutiSolution(item, subItem) { console.log(item, 123) if (!this.isReviewed) { let answerIndex = item.dualChooseArr.indexOf(subItem.optLetter) if (answerIndex > -1) { // 该选项已经在数组中了 item.dualChooseArr.splice(answerIndex, 1) } else { // 该选项不在数组中 item.dualChooseArr.push(subItem.optLetter) } item.tempAnswer = item.dualChooseArr.join(',') // this.onAnswerChange(answerIndex) // 强制刷新更新视图 this.$forceUpdate() } }, /* 判断题答案 */ judgeSolution(item, value) { if (!this.isReviewed) { // tempAnswer为学生答案 item.tempAnswer = value // 强制刷新更新视图 this.$forceUpdate() if (this.currentIndex < this.max) { setTimeout(() => { this.currentIndex += 1 }, 300) } // this.onAnswerChange(item) } }, /* 题目答案变化 */ onAnswerChange(item) { let result = JSON.parse(JSON.stringify(item)) this.$emit('onChange', item) }, /* 交卷 相同 */ handleSubmit(submitORimeEnd) { /*submitORimeEnd == 1,submit submitORimeEnd == 0,stimeEnd*/ if (this.currentIndex == 0) { this.currentIndex++ } else { this.currentIndex = 0 } if (submitORimeEnd) { // this.$emit('submit', this.questionList) this.$emit('submit') } else { this.$emit('timeEnd') } }, // 点击编辑笔记 editBtnFunc(item) { if (item.theoryExamAnswer.id == undefined) { this.$refs.uToast.show({ title: '未作答的题目不可编辑笔记!', type: 'error', // url: '/pages/user/index' }) return } this.isreadOnly = !this.isreadOnly this.eidtOrFinishValue = '完成' }, // 完成编辑 finishBtnFunc(item) { var that = this this.isreadOnly = !this.isreadOnly this.eidtOrFinishValue = '编辑笔记' console.log('保存笔记内容', item, that.editorText); this.$api.examNote(item.theoryExamAnswer.id, that.editorText) .then(res => { console.log('更新笔记成功', res) }) }, updateEditorText(text) { // 从子组件获取输入框输入内容 this.editorText = text }, } } </script> <style lang="scss"> page { background-color: #FFFFFF; } #header, #subHeader { height: 100rpx; } .header { width: 750rpx; // position: fixed; margin-top: 30rpx; position: relative; text-align: center; line-height: 100rpx; font-size: 36rpx; font-weight: 600; color: #103289; letter-spacing: 10rpx; background-color: #FFFFFF; &-button { width: 80rpx; height: 40rpx; line-height: 40rpx; position: absolute; top: 20rpx; right: 40rpx; padding: 10rpx 20rpx; border-radius: 15rpx; letter-spacing: 2rpx; font-weight: 500; color: #FFFFFF; background-color: #103289; } .scoreText { color: #00b060; font-size: 35rpx; } } .sub-header { width: 750rpx; // position: fixed; // margin-top: 130rpx; padding: 30rpx 20rpx; display: flex; align-items: center; justify-content: space-between; color: #000; font-size: 33rpx; font-weight: bold; background-color: #FFFFFF; } .content { // margin-top: 130rpx; letter-spacing: 3rpx; .typeTag { margin-right: 20rpx; } &-item-explain { padding-bottom: 20rpx; font-size: 30rpx; color: #8799a3; letter-spacing: 5rpx; border-top: 1px solid rgba(0, 0, 0, 0.1); &-result { padding: 20rpx 0; span { padding-left: 20rpx; color: #39b54a; } } &-content { padding: 20rpx 0; } } &-item { padding: 0 20rpx; box-sizing: border-box; } &-title { margin-bottom: 30rpx; font-size: 32rpx; line-height: 55rpx; color: #000 } &-solutions { width: 100%; padding-bottom: 20rpx; &-item { margin: 40rpx 0; border: 5rpx solid #103289; border-radius: 20rpx; display: flex; align-items: center; font-size: 30rpx; background-color: #103289; &-check-content { padding: 35rpx 20rpx; width: 100%; border-radius: 15rpx; color: #103289; background-color: #FFFFFF; } &-single { width: 80rpx; text-align: center; color: #FFFFFF; } &-content { padding: 35rpx 20rpx; width: 630rpx; border-top-right-radius: 15rpx; border-bottom-right-radius: 15rpx; color: #000; background-color: #FFFFFF; } &-select { color: #FFFFFF; background-color: #103289; } } &-judge { display: flex; justify-content: space-around; background-color: #FFFFFF; padding: 20rpx; text-align: center; font-size: 30rpx; .content-solutions-judge-item { border: 5rpx solid #103289; border-radius: 60rpx; width: 300rpx; padding: 35rpx 20rpx; // 控制单元格的高度 } .content-solutions-judge-select { color: #FFFFFF; background-color: #103289; } } &-blank { // border: 5rpx solid #103289; height: 60rpx; width: 90%; // border-radius: 20rpx; background-color: #FFFFFF; padding: 20rpx; } &-fillItem { border: 5rpx solid #103289; border-radius: 20rpx; background-color: #FFFFFF; padding: 20rpx; } } .explain { border-top: solid #999999 1px; padding-top: 10rpx; font-size: 28rpx; color: #666666; .explainResult { color: #103289; } .explain-title { font-weight: bold; } .noteArea { border-top: 2rpx solid #103289; padding-top: 10rpx; // background-color: #0077AA; .noteAreaTitle { display: flex; justify-content: space-between; } } } } .footer { width: 750rpx; height: 100rpx; padding: 30rpx 20rpx; position: fixed; bottom: 0; display: flex; align-items: center; justify-content: space-between; font-size: 30rpx; box-sizing: border-box; color: #4c8af3; box-shadow: 0 0 5px 1px #eee; background-color: #FFFFFF; &-card { padding: 10rpx 20rpx; border: 1px solid #103289; border-radius: 15rpx; color: #FFFFFF; background-color: #103289; } } .question-modal { width: 700rpx; padding: 40rpx; background-color: #FFFFFF; &-header { height: 80rpx; line-height: 80rpx; text-align: center; font-size: 35rpx; color: #333333; border-bottom: 1rpx solid #F0F0F0; } &-body { // margin-bottom: 100rpx; .queTypeName { font-size: 32rpx; font-weight: bold; } .queTypeArea { display: flex; flex-direction: row; flex-wrap: wrap; margin-bottom: 20rpx; .question-modal-body-item { width: 80rpx; height: 80rpx; margin: 10rpx 22rpx; line-height: 80rpx; font-size: 35rpx; text-align: center; border-radius: 50%; color: #ffffff; // background-color: #0077AA; } } &-item-unselect { // color: #FFFFFF; background-color: #bbbbbb; } &-item-select { // color: #FFFFFF; background-color: #103289; } &-item-failed { color: #FFFFFF; background-color: #982121; } &-item-right { color: #FFFFFF; background-color: #39b54a; } &-item-unScored { color: #FFFFFF; background-color: #ff9f73; } } .question-modal-foot { height: 100rpx; border-top: 1rpx solid #F0F0F0; // position: fixed; // margin-bottom: 0rpx; margin-top: -60rpx; .ansBlock { display: flex; justify-content: center; // align-items: center; .blockItem { display: flex; align-items: center; margin: 20rpx; } .block-ansed { width: 80rpx; height: 80rpx; border-radius: 50%; background: #103289; margin: 0 10rpx; } .block-unansed { width: 80rpx; height: 80rpx; border-radius: 50%; // border: solid #ffffff 1px; background: #bbbbbb; margin: 0 10rpx; } .block-right { width: 80rpx; height: 80rpx; border-radius: 50%; background: #39b54a; margin: 0 10rpx; } .block-wrong { width: 80rpx; height: 80rpx; border-radius: 50%; background: #982121; margin: 0 10rpx; } .block-unScored { width: 80rpx; height: 80rpx; border-radius: 50%; background: #ff9f73; margin: 0 10rpx; } } } } .right { border: 8rpx solid #39b54a; } .wrong { border: 8rpx solid #d81717; } </style> components/dyw-answer/answer.vue
@@ -3,36 +3,32 @@ 试卷类型包含 exam 理论考试 paper 模拟考试 知识点练习 --> <view> <view class="container"> <!-- 大标题 --> <view class="header" id="header"> <!-- <span class="header-button" @click='leave' v-if='!isReviewed && examType=='know' '>暂离</span> --> <span v-if="examType=='exam'"> {{examDetail.exam.name}}</span> <span v-if="(examType=='paper' )|| (examType=='know') || (examType=='course')"> {{examDetail.paper.name}}</span> <span class="header-button" @click='handleSubmit(1)' v-if='!isReviewed'>交卷</span> <!-- <span class="scoreText" v-else>得分:{{examDetail.score}}</span> --> </view> <u-navbar class="header" id="header" height="44" back-icon-color="#fff" title="模拟考试" title-color="#fff" :background="{background: '#103289'}" :custom-back="exitExam"> <u-button class="slot-wrap-right" type="primary" size="mini" @click="handleSubmit(1)">交卷 </u-button> </u-navbar> <!-- 小标题栏 --> <view id="subHeader"> <view class="sub-header" v-if='questionList.length > 0'> <u-tag class="typeTag" :text="answerStatusName" mode="dark" shape="circle" /> <view v-if="examDetail.exam.examTime<=0">不限时</view> <u-count-down v-if="(!isReviewed)&&(examType=='exam')&& (examDetail.exam.examTime>0)" :timestamp="examDetail.exam.examTime / 1000" :show-days="false" @end="end" @change="change"> <u-count-down v-if="examDetail.exam.examTime" :timestamp="examDetail.exam.examTime / 1000" :show-days="false" @end="end" @change="change"> </u-count-down> <clock v-if="(!isReviewed)&&(examType=='paper' || (examType=='course'))" ref="myClock" :timeOrigin="parseInt(examDetail.time)"> </clock> <span v-if="examType=='exam'">第 <span>第 {{currentIndex+1}}/{{examDetail.exam.totalQuestion}} 题</span> <span v-if="(examType=='paper' )|| (examType=='know')">第 {{currentIndex+1}}/{{examDetail.totalQuestion}} 题</span> </view> </view> <!-- 答题区域 --> <swiper class="content" :duration='duration' :current=currentIndex @change='handleSwiperChanged' <swiper class="content" :duration='duration' :current='currentIndex' @change='handleSwiperChanged' v-if='questionList.length > 0' :style="{'height':swiperHeight}"> <template v-for='item in questionList'> <swiper-item class="content-item"> @@ -43,115 +39,76 @@ </view> <!-- 以下显示选项 --> <!-- type == 0 单选题 --> <view class="content-solutions" v-if='item.template == 0'> <view class="content-solutions" v-if='item.choicesType == 0'> <template v-for='subItem in item.options'> <view :class="[isReviewed && subItem.optAnswer == 1 ? 'right': '',isReviewed && (item.wrongArr.indexOf(subItem.optLetter) >-1) ? 'wrong': '']" class="content-solutions-item" @click='chooseSolution(item,subItem)'> <view v-if="(!isReviewed) && (examType=='exam') " class="content-solutions-item-single"> {{subItem.newOptLetter}} <view class="content-solutions-item" @click="!item.selectedFlag && chooseSolution(item,subItem)"> <view class="content-solutions-item-single"> {{subItem.optionName}} </view> <view v-else class="content-solutions-item-single">{{subItem.optLetter}}</view> <!-- 此处注意optLetter与newOptLetter的区别,newOptLetter是ABCD顺序的,而optLetter乱序的,两者无直接关系 --> <view :class="item.tempAnswer == subItem.optLetter? 'content-solutions-item-select' : ''" class="content-solutions-item-content">{{subItem.optContent}}</view> :class="item.tempAnswer == subItem.optionName? 'content-solutions-item-select' : ''" class="content-solutions-item-content">{{subItem.optionContent}}</view> </view> </template> </view> <!-- type == 1 多选题 --> <view class="content-solutions" v-if='item.template == 1'> <view class="content-solutions" v-if='item.choicesType == 1'> <template v-for='subItem in item.options'> <view :class="[isReviewed && subItem.optAnswer == 1 ? 'right': '',isReviewed && (item.wrongArr.indexOf(subItem.optLetter) >-1) ? 'wrong': '']" class="content-solutions-item" @click='chooseMutiSolution(item,subItem)'> <view v-if="(!isReviewed) && (examType=='exam') " class="content-solutions-item-single"> {{subItem.newOptLetter}} <view class="content-solutions-item" @click='!item.selectedFlag && chooseMutiSolution(item,subItem)'> <view class="content-solutions-item-single"> {{subItem.optionName}} </view> <view v-else class="content-solutions-item-single">{{subItem.optLetter}}</view> <!-- TODO 是否被选中的条件判断不对 --> <view :class="item.tempAnswer.indexOf(subItem.optLetter) >-1 ? 'content-solutions-item-select' : ''" class="content-solutions-item-content">{{subItem.optContent}} </view> :class="item.tempAnswer.indexOf(subItem.optionName) > -1 ? 'content-solutions-item-select' : ''" class="content-solutions-item-content">{{subItem.optionContent}}</view> </view> </template> <u-button v-show="!item.selectedFlag" type="primary" shape="circle" :custom-style="{backgroundColor: '#103289'}" @click="confirm(item)">确认答案 </u-button> </view> <!-- type == 2 判断题 --> <view class="content-solutions" v-if='item.template == 2'> <template v-for='subItem in item.options'> <view class="content-solutions" v-if='item.choicesType == 2'> <template v-for="(judgeItem,judgeIndex) in judgeArr"> <view class="content-solutions-judge"> <view v-for="(judgeItem,judgeIndex) in judgeArr" :class="[item.tempAnswer == judgeItem.value? 'content-solutions-item-select' : '',isReviewed && (item.rightAnswer==judgeItem.name) ? 'right': '',isReviewed && (item.wrongArr ==judgeItem.value) ? 'wrong': '']" <view :class="[item.tempAnswer == judgeItem.name? 'content-solutions-item-select' : '']" class="content-solutions-judge-item" @click='judgeSolution(item,judgeItem.value)'>{{judgeItem.name}}</view> @click="!item.selectedFlag && judgeSolution(item, judgeItem.name)"> {{judgeItem.name}} </view> </view> </template> </view> <!-- type == 4 填空题 --> <view class="content-solutions" v-if='item.template == 4'> <template v-if="!isReviewed"> <view class="content-solutions-item" v-for='(subItem,subIndex) in item.options' :keys="subIndex" :class="[isReviewed && item.answerStatus!=4 &&(item.blankString != item.rightAnswer)? 'wrong':'']"> <view class="content-solutions-item-single">{{subIndex+1}}</view> <input :disabled="isReviewed" type="text" class="content-solutions-blank" v-model="item.blankArr[subIndex]" placeholder="请在此处输入答案" /> </view> </template> <template v-else> <view class="content-solutions-item"> <view class="content-solutions-item-single"></view> <!-- TODOvalue的绑定值不对 :value="item.blankArr[subIndex].replace(/"\;/g, '')" --> <input :disabled="isReviewed" :value="(item.blankArr).join(',')" type="text" class="content-solutions-blank" /> </view> </template> </view> <!-- type == 5 简答题 --> <view class="content-solutions" v-if='item.template == 5'> <textarea v-if="!isReviewed" @input="textInput" :disabled="isReviewed" placeholder="请输入您的答案" auto-height /> <textarea v-else :disabled="isReviewed" :value="item.tempAnswer.replace(/"\;/g, '')" auto-height /> </view> <view class="explain" v-if="item.selectedFlag"> <view> <view style="display: flex; justify-content: flex-start; align-items: center;"> <view class="explain" v-if='isReviewed'> <u-tag v-show="item.answerStatus==1" text="未答" type="error" /> <u-tag v-show="item.answerStatus==2" text="正确" type="success" /> <u-tag v-show="item.answerStatus==3" text="错误" type="error" /> <u-tag v-show="item.answerStatus==4" text="未评分" type="warning" /> <u-tag v-show="item.answerStatus==5" text="已评分" type="warning" /> <u-tag v-show="item.answerStatus==6" text="已答" type="warning" /> <view class="explain-title">正确答案:</view> <!-- <span class="text">{{item.rightAnswer}}</span> --> <u-parse :html="item.rightAnswer"></u-parse> <view class="explain-title">试题解析:</view> <!-- <view class="explain-content">{{item.queAnalysis | analysisFilter }}</view> --> <u-parse :html="item.queAnalysis?item.queAnalysis:'暂无'"></u-parse> <view class="noteArea"> <view class="noteAreaTitle"> <view class="explain-title">我的笔记:</view> <view v-if="eidtOrFinishValue=='编辑笔记'" class="funcGroup" @click="editBtnFunc(item)"> <u-icon class="funcBtn" name="edit-pen"></u-icon> <span>编辑笔记</span> <u-tag style="margin: 0 20rpx;" v-show="item.correctOrError" text="正确" type="success" /> <u-tag style="margin: 0 20rpx;" v-show="!item.correctOrError" text="错误" type="error" /> <view> 答案 <text style="margin: 0 20rpx;">{{item.answer}}</text> </view> <view v-else class="funcGroup" @click="finishBtnFunc(item)"> <u-icon class="funcBtn" name="edit-pen"></u-icon> <span>完成</span> <view> 您选择 <text style="margin: 0 20rpx;">{{item.tempAnswer}}</text> </view> </view> <!-- 只有回答过的题目才能编辑笔记!!! --> <text-editor :noteId="item.id" :textContent="item.theoryExamAnswer.queNote" :isreadOnly="isreadOnly" @editorInput='updateEditorText'> </text-editor> </view> </view> </scroll-view> </swiper-item> </template> @@ -175,53 +132,30 @@ <view class="queTypeName" v-show="queTypeStore[subIndex]>=0">{{subItem.name}}</view> <!-- <u-tag :text="subItem.name" v-show="queTypeStore[subIndex]>0" mode="dark" /> --> <view class="queTypeArea"> <template v-for="(item, index) in questionList"> <view v-show="item.template == subItem.value"> <!-- 1.复习状态且回答正确 --> <!-- <view v-if='item.tempAnswer && item.answer==item.tempAnswer && isReviewed' --> <view v-if='isReviewed && item.answerStatus == "2"' class="question-modal-body-item question-modal-body-item-right" @click="handleJumpSwiper(index)">{{index + 1 }}</view> <!-- 2.复习状态且回答错误 --> <view v-else-if='isReviewed && (item.answerStatus == "1" ||item.answerStatus == "3" )' class="question-modal-body-item question-modal-body-item-failed" @click="handleJumpSwiper(index)">{{index + 1 }}</view> <!-- 3.复习状态且简答题未评分或者已评分 --> <view v-else-if='isReviewed && (item.answerStatus == "4" ||item.answerStatus == "5")' class="question-modal-body-item question-modal-body-item-unScored" @click="handleJumpSwiper(index)">{{index + 1 }}</view> <!-- 3.非复习状态且已经作答 --> <view v-else-if='!isReviewed && item.tempAnswer && item.tempAnswer.length != 0' class="question-modal-body-item question-modal-body-item-select" @click="handleJumpSwiper(index)">{{index + 1 }}</view> <!-- 4.非复习状态且未作答 --> <view v-else class="question-modal-body-item question-modal-body-item-unselect" <view v-show="item.choicesType == subItem.value"> <!-- 未作答 --> <view v-if="item.tempAnswer == ''" class="question-modal-body-item question-modal-body-item-unselect" @click="handleJumpSwiper(index)"> {{index + 1 }} </view> <!-- <u-line color="red" border-style="info"></u-line> --> <!-- 回答正确 --> <view v-else-if='item.tempAnswer == item.answer' class="question-modal-body-item question-modal-body-item-right" @click="handleJumpSwiper(index)">{{index + 1 }}</view> <!-- 回答错误 --> <view v-else-if='item.tempAnswer != item.answer' class="question-modal-body-item question-modal-body-item-failed" @click="handleJumpSwiper(index)">{{index + 1 }}</view> </view> </template> </view> </template> </scroll-view> <view class="question-modal-foot" id="questionHeader"> <view v-if="!isReviewed" class="ansBlock"> <view class="blockItem"> <view class="block-ansed"></view> <view class="">已答</view> </view> <view class="blockItem"> <view class="block-unansed"></view> <view class="">未答</view> </view> </view> <view v-else class="ansBlock"> <view class="ansBlock"> <view class="blockItem"> <view class="block-right"></view> <view class="">答对</view> @@ -231,10 +165,11 @@ <view class="">答错</view> </view> <view class="blockItem"> <view class="block-unScored"></view> <view class="">未评分</view> <view class="block-unansed"></view> <view class="">未答</view> </view> </view> </view> </view> </modal> @@ -250,7 +185,6 @@ return { isreadOnly: true, quesModules: [], areaText: ``, //保存简答题答案 judgeArr: [{ name: '正确', value: '1' @@ -309,14 +243,14 @@ } }, watch: { // 监听currentIndex的变化,改变则提交答案 相同 currentIndex(newVal, oldVal) { let that = this if (!this.isReviewed) { // 对各题型的答案进行处理 switch (that.questionList[oldVal].template) { // 对各题型的答案进行处理 if (that.questionList[oldVal].selectedFlag) { switch (that.questionList[oldVal].choicesType) { case 0: // 选择题 break; case 1: // 多选题 @@ -326,51 +260,9 @@ case 2: // 判断题 break; case 4: // 填空题 that.questionList[oldVal].tempAnswer = that.questionList[oldVal].blankArr.join( '||~||') // 数组拼接为字符串 break; case 5: that.questionList[oldVal].tempAnswer = JSON.stringify(that.areaText) // console.log('000:',that.questionList[oldVal].tempAnswer); break; default: } if (this.examType == 'exam') { // 保存答案 var answerObj = { examRecordId: this.questionList[oldVal].recordId, paperQueId: this.questionList[oldVal].id, answer: this.questionList[oldVal].tempAnswer, template: this.questionList[oldVal].template } // 进行答题的api请求 console.log('answerObj:', oldVal, answerObj); this.$api.answerExam(answerObj) .then(res => { console.log(res); }) } else if (this.examType == 'paper' || this.examType == 'know') { var answerObj = { exerciseId: this.examDetail.exerciseId, paperQueId: this.questionList[oldVal].id, answer: this.questionList[oldVal].tempAnswer, template: this.questionList[oldVal].template } // 进行答题的api请求 console.log('answerObj:', oldVal, answerObj); this.$api.answerPaper(answerObj) .then(res => { console.log(res); }) } else { return } // immediate: true, } } }, @@ -378,7 +270,6 @@ // swiperHeight(){ // uni.getSystemInfo({ // success(res) { // console.log(res); // return res.windowHeight+'px' // } // }) @@ -387,7 +278,6 @@ return this.$store.state.examDetail }, questionList() { console.log(this.$store.state.questionList, 77777) return this.$store.state.questionList }, queTypeStore() { @@ -397,8 +287,7 @@ return this.questionList.length - 1 }, answerStatusName() { console.log(this.questionList[this.currentIndex].template, 63636636366) switch (this.questionList[this.currentIndex].template) { switch (this.questionList[this.currentIndex].choicesType) { case 0: return '单选题' break; @@ -420,14 +309,6 @@ } }, props: { isReviewed: { type: Boolean, default: false }, examType: { type: String, default: "exam" }, duration: { type: [String, Number], default: 300 @@ -436,15 +317,18 @@ mounted() { var that = this this.setAnswerHeight() if ((!this.isReviewed) && ((this.examType == 'paper') || (this.examType == 'course'))) { this.$refs.myClock.start(); } }, components: { Modal, clock }, methods: { exitExam() { uni.redirectTo({ url: '/pages/exam/startexam' }); }, /*设置题目的高度*/ setAnswerHeight() { let that = this @@ -452,15 +336,14 @@ uni.getSystemInfo({ //获取手机屏幕高度信息,让swiper的高度和手机屏幕一样高 success: function(res) { console.log(res, '010101010') tempHeight = res.windowHeight; that.modalHeight = res.windowHeight - uni.upx2px(200) + 'px'; that.modalContentHeight = res.windowHeight - uni.upx2px(380) + 'px'; that.modalContentHeight = res.windowHeight - uni.upx2px(360) + 'px'; uni.createSelectorQuery().in(that).select("#header").fields({ size: true, scrollOffset: true }, (data) => { console.log('data', data); tempHeight -= data.height; uni.createSelectorQuery().in(that).select("#subHeader").fields({ size: true, @@ -505,10 +388,6 @@ this.handleSubmit(0) }, 2000) }, textInput(e) { this.areaText = e.detail.value // console.log(e.detail.value) }, /* 滑动题目 */ handleSwiperChanged(event) { this.currentIndex = event.detail.current @@ -520,62 +399,79 @@ // 进行翻页 if ((this.currentIndex > min && operation < 0) || (this.currentIndex < max && operation > 0)) { this.currentIndex += operation // console.log(this.currentIndex) } }, /* 选择答案(单选)*/ chooseSolution(item, subItem) { if (!this.isReviewed) { // tempAnswer为学生答案 item.tempAnswer = subItem.optLetter // 强制刷新更新视图 this.$forceUpdate() // this.questionList[this.currentIndex].tempAnswer = subItem.optLetter if (this.currentIndex < this.max) { setTimeout(() => { this.currentIndex += 1 }, 300) } // this.onAnswerChange(item) // tempAnswer为学生答案 item.tempAnswer = subItem.optionName item.selectedFlag = true if (item.tempAnswer == item.answer) item.correctOrError = true // 强制刷新更新视图 this.$forceUpdate() if (this.currentIndex < this.max) { setTimeout(() => { this.currentIndex += 1 }, 300) } }, /* 选择答案(多选)*/ chooseMutiSolution(item, subItem) { if (!this.isReviewed) { let answerIndex = item.dualChooseArr.indexOf(subItem.optLetter) if (answerIndex > -1) { // 该选项已经在数组中了 item.dualChooseArr.splice(answerIndex, 1) } else { // 该选项不在数组中 item.dualChooseArr.push(subItem.optLetter) } item.tempAnswer = item.dualChooseArr.join(',') // this.onAnswerChange(answerIndex) // 强制刷新更新视图 this.$forceUpdate() let answerIndex = item.dualChooseArr.indexOf(subItem.optionName) if (answerIndex > -1) { // 该选项已经在数组中了 item.dualChooseArr.splice(answerIndex, 1) } else { // 该选项不在数组中 item.dualChooseArr.push(subItem.optionName) } item.tempAnswer = item.dualChooseArr.join(',') // 强制刷新更新视图 }, // 多选题中的答案确认 confirm(item) { let one = item.answer.split(',') let two = item.tempAnswer.split(',') let flag = true if (one.length == two.length) { one.forEach((item) => { if (two.indexOf(item) == -1) { flag = false return } }) } else { flag = false } item.selectedFlag = true if (flag != false) item.correctOrError = true this.$forceUpdate() if (this.currentIndex < this.max) { setTimeout(() => { this.currentIndex += 1 }, 300) } }, /* 判断题答案 */ judgeSolution(item, value) { if (!this.isReviewed) { // tempAnswer为学生答案 item.tempAnswer = value // 强制刷新更新视图 this.$forceUpdate() if (this.currentIndex < this.max) { setTimeout(() => { this.currentIndex += 1 }, 300) } // this.onAnswerChange(item) // tempAnswer为学生答案 item.tempAnswer = value item.selectedFlag = true if (item.tempAnswer == item.answer) item.correctOrError = true // 强制刷新更新视图 this.$forceUpdate() if (this.currentIndex < this.max) { setTimeout(() => { this.currentIndex += 1 }, 300) } }, /* 题目答案变化 */ onAnswerChange(item) { let result = JSON.parse(JSON.stringify(item)) this.$emit('onChange', item) }, /* 交卷 相同 */ handleSubmit(submitORimeEnd) { @@ -592,97 +488,82 @@ } else { this.$emit('timeEnd') } }, // 点击编辑笔记 editBtnFunc(item) { if (item.theoryExamAnswer.id == undefined) { this.$refs.uToast.show({ title: '未作答的题目不可编辑笔记!', type: 'error', // url: '/pages/user/index' }) return } this.isreadOnly = !this.isreadOnly this.eidtOrFinishValue = '完成' }, // 完成编辑 finishBtnFunc(item) { var that = this this.isreadOnly = !this.isreadOnly this.eidtOrFinishValue = '编辑笔记' console.log('保存笔记内容', item, that.editorText); this.$api.examNote(item.theoryExamAnswer.id, that.editorText) .then(res => { console.log('更新笔记成功', res) }) }, updateEditorText(text) { // 从子组件获取输入框输入内容 this.editorText = text }, } } } </script> <style lang="scss"> .slot-wrap-right { position: absolute; top: 0; left: auto; right: 10px; bottom: 0; margin: auto; color: #fff; letter-spacing: 4rpx; /* 如果您想让slot内容占满整个导航栏的宽度 */ /* flex: 1; */ /* 如果您想让slot内容与导航栏左右有空隙 */ /* padding: 0 30rpx; */ } page { background-color: #FFFFFF; } #header, #subHeader { height: 100rpx; width: 100%; height: 88rpx; line-height: 88rpx; } .header { width: 750rpx; // position: fixed; margin-top: 30rpx; position: relative; text-align: center; line-height: 100rpx; font-size: 36rpx; font-weight: 600; color: #103289; letter-spacing: 10rpx; background-color: #FFFFFF; &-button { width: 80rpx; height: 40rpx; line-height: 40rpx; position: absolute; top: 20rpx; right: 40rpx; padding: 10rpx 20rpx; border-radius: 15rpx; letter-spacing: 2rpx; font-weight: 500; color: #FFFFFF; background-color: #103289; } .scoreText { color: #00b060; font-size: 35rpx; } letter-spacing: 2rpx; } .sub-header { width: 750rpx; // position: fixed; // margin-top: 130rpx; padding: 30rpx 20rpx; padding: 0 20rpx; display: flex; align-items: center; justify-content: space-between; color: #000; font-size: 33rpx; font-size: 32rpx; font-weight: bold; background-color: #FFFFFF; } .footer { width: 100%; height: 88rpx; padding: 30rpx 20rpx; position: fixed; bottom: 0; display: flex; align-items: center; justify-content: space-between; font-size: 30rpx; box-sizing: border-box; color: #4c8af3; box-shadow: 0 0 5px 1px #eee; background-color: #FFFFFF; &-card { padding: 10rpx 20rpx; border: 1px solid #103289; border-radius: 15rpx; color: #FFFFFF; background-color: #103289; } } .content { // margin-top: 130rpx; @@ -808,58 +689,17 @@ .explain { border-top: solid #999999 1px; padding-top: 10rpx; padding: 10rpx; font-size: 28rpx; color: #666666; .explainResult { color: #103289; } .explain-title { font-weight: bold; } .noteArea { border-top: 2rpx solid #103289; padding-top: 10rpx; // background-color: #0077AA; .noteAreaTitle { display: flex; justify-content: space-between; } } } } .footer { width: 750rpx; height: 100rpx; padding: 30rpx 20rpx; position: fixed; bottom: 0; display: flex; align-items: center; justify-content: space-between; font-size: 30rpx; box-sizing: border-box; color: #4c8af3; box-shadow: 0 0 5px 1px #eee; background-color: #FFFFFF; &-card { padding: 10rpx 20rpx; border: 1px solid #103289; border-radius: 15rpx; color: #FFFFFF; background-color: #103289; } } .question-modal { width: 700rpx; padding: 40rpx; padding: 0 40rpx; background-color: #FFFFFF; &-header { @@ -926,11 +766,10 @@ } .question-modal-foot { height: 100rpx; height: 40rpx; border-top: 1rpx solid #F0F0F0; // position: fixed; // margin-bottom: 0rpx; margin-top: -60rpx; .ansBlock { display: flex; @@ -943,46 +782,31 @@ margin: 20rpx; } .block-ansed { width: 80rpx; height: 80rpx; border-radius: 50%; background: #103289; margin: 0 10rpx; } .block-unansed { width: 80rpx; height: 80rpx; border-radius: 50%; // border: solid #ffffff 1px; background: #bbbbbb; margin: 0 10rpx; } .block-right { width: 80rpx; height: 80rpx; width: 40rpx; height: 40rpx; border-radius: 50%; background: #39b54a; margin: 0 10rpx; } .block-wrong { width: 80rpx; height: 80rpx; width: 40rpx; height: 40rpx; border-radius: 50%; background: #982121; margin: 0 10rpx; } .block-unScored { width: 80rpx; height: 80rpx; .block-unansed { width: 40rpx; height: 40rpx; border-radius: 50%; background: #ff9f73; // border: solid #ffffff 1px; background: #bbbbbb; margin: 0 10rpx; } } } pages.json
@@ -648,8 +648,8 @@ } }, { "path": "pages/exam/examReviewPage", "name": "examReviewPage", "path": "pages/exam/examResultPage", "name": "examResultPage", "style": { "navigationStyle": "custom", "navigationBarTitleText": "", pages/business/business - 副本.vue
New file @@ -0,0 +1,30 @@ <template> <view class="container"> <u-empty text="功能研发中" mode="favor" margin-top="400"></u-empty> <!-- 底部导航条 --> <u-tabbar :list="tabbar" :mid-button="false"></u-tabbar> </view> </template> <script> export default { data() { return { tabbar: this.$store.state.tabbar, }; }, onLoad() { }, mounted() { }, methods: { } }; </script> <style lang="scss"> </style> pages/exam/examResultPage.vue
New file @@ -0,0 +1,126 @@ <template> <view class="content"> <u-navbar height="44" back-icon-color="#fff" title="考试结果" :is-back="false" title-color="#fff" :background="{background: '#103289'}"> </u-navbar> <view class="finishText"> <view class="box"> <text class="title">考试名称:</text> <text class="val">模拟考试</text> </view> <view class="box"> <text class="title">总题数:</text> <text class="val">{{totalQueNum}}题</text> </view> <view class="box"> <text class="title">答对:</text> <text class="val">{{rightQueNum}}题</text> </view> <view class="box"> <text class="title">答错:</text> <text class="val">{{wrongQueNum}}题</text> </view> <view class="box"> <text class="title">未答:</text> <text class="val">{{noneQueNum}}题</text> </view> <view class="box"> <text class="title">得分:</text> <text class="val">{{score}}分</text> </view> </view> <view class="btnArea"> <u-button class="btnClass" type="primary" :ripple="true" shape="circle" @click="backToHome">返回首页 </u-button> </view> </view> </template> <script> export default { props: {}, data() { return { totalQueNum: '', rightQueNum: '', wrongQueNum: '', noneQueNum: '', score: '', } }, methods: { backToHome() { uni.switchTab({ url: '/pages/home/home', }) } }, computed: { }, onLoad(options) { console.log(options, 77777) this.totalQueNum = options.totalQueNum this.rightQueNum = options.rightQueNum this.wrongQueNum = options.wrongQueNum this.noneQueNum = options.noneQueNum this.score = options.score } } </script> <style lang="scss" scoped> .finishText { // margin: 100rpx 200rpx; margin: 50rpx 10%; padding: 5%; width: 80%; font-size: 32rpx; display: flex; flex-direction: column; background: #f8f8f8; box-shadow: 0 0 20px 2px #dddddd; border-radius: 5px; letter-spacing: 0.2rpx; text { color: #103289; font-weight: bold; } .box { flex: 1; display: flex; .title { flex: 1; text-align-last: justify; } .val { flex: 1; } } } .btnArea { display: flex; margin-top: 50rpx; .btnClass { width: 300rpx; } } .infoArea { display: flex; flex-direction: column; justify-content: center; } </style> pages/exam/examReviewPage.vue
File was deleted pages/exam/examTextPage.vue
@@ -5,8 +5,7 @@ <u-modal v-model="show" :content="content" :show-cancel-button="true" @confirm="handleConfirm"></u-modal> <!-- 渲染题目 --> <Answer :isReviewed='isReview' :examType="examType" @submit='handleCommit' @timeEnd='handleConfirm' @onChange='onChange'></Answer> <Answer @submit='handleCommit' @timeEnd='handleConfirm' @onChange='onChange'></Answer> <u-toast ref="uToast" /> </view> @@ -15,7 +14,8 @@ <script> import Answer from '@/components/dyw-answer/answer.vue'; import { enterExam enterExam, submitExam } from '@/common/api/exam' import { ModifyQuesList @@ -25,88 +25,36 @@ return { show: false, content: '是否确认交卷', isReview: false, questionList: [], examType: 'exam', //考试类型 } }, onLoad(option) { this.$store.state.questionList = [] this.examType = option.examType var that = this if (option.examType == 'exam') { // 理论考试 enterExam({ idCardNo: option.id }).then(res => { var examObj = res.data.data.simulateExamRecord // 理论考试 enterExam({ idCardNo: option.id }).then(res => { var examObj = res.data.data.simulateExamRecord examObj.exam = { name: '测试考试', examScore: 100, examTime: res.data.data.simulateExamRecord.answerTime, checkFace: 1, ...option } examObj.exam = { name: '模拟考试', examScore: 100, examTime: res.data.data.simulateExamRecord.answerTime, checkFace: 1, ...option } examObj.exam.totalQuestion = res.data.data.examSubjectInfo.length examObj.totalQuestion = res.data.data.examSubjectInfo.length that.$store.state.examDetail = examObj examObj.exam.totalQuestion = res.data.data.examSubjectInfo.length examObj.totalQuestion = res.data.data.examSubjectInfo.length that.$store.state.examDetail = examObj // 提取出所有的题目 ModifyQuesList(res.data.data.examSubjectInfo) }) } else if (option.examType == 'paper') { // 模拟考试 this.$api.paperStart(option.paperId) .then(res => { console.log('paperStart:', res); that.$store.state.examDetail = res.values console.log('paper examDetail:', res.values); var quesModules = res.values.modules that.$api.ModifyQuesList(quesModules) console.log(that.$store.state.pracDetail); console.log(that.$store.state.pracQuesList); }) } else if (option.examType == 'know') { // 知识点练习 const knowSearch = JSON.parse(decodeURIComponent(option.knowSearch)); console.log(knowSearch); this.$api.startKnow(knowSearch) .then(res => { if (res.status == 1) { // 获取知识点失败 this.$refs.uToast.show({ title: res.message, type: 'error', // icon: false, url: '/pages/exam/pracIndexKnow' }) } else { console.log('开始知识点练习的请求结果:', res); that.$store.state.examDetail = res.values var quesModules = res.values.modules that.$api.ModifyQuesList(quesModules) console.log(that.$store.state.pracDetail); console.log(that.$store.state.pracQuesList); } }) } else if (option.examType == 'course') { this.$api.startTheory(that.$store.state.access_token, option.paperId) .then(res => { that.$store.state.examDetail = res.values var quesModules = res.values.modules that.$api.ModifyQuesList(quesModules) }) } else { console.log("考试类型错误,请输入正确的类型"); // return false } that.$store.state.paperDetail = res.data.data.simulateExamRecord // 提取出所有的题目 ModifyQuesList(res.data.data.examSubjectInfo) }) console.log('考题列表:', this.questionList); }, components: { Answer @@ -120,52 +68,58 @@ // 已确认进行答案提交 handleConfirm() { // 进行交卷的api请求 let that = this if (this.examType == 'exam') { this.$api.commitExam(this.$store.state.examDetail.exam.id, this.$store.state.examDetail.recordId) .then(res => { console.log('交卷:', res); that.$u.route('/pages/exam/examResultPage', { recordId: that.$store.state.examDetail.recordId, examType: 'exam' }) }) } else if ((this.examType == 'paper') || (this.examType == 'know')) { this.$api.commitPaper(this.$store.state.examDetail.exerciseId) .then(res => { console.log('交卷:', res); that.$u.route('/pages/exam/examResultPage', { exerciseId: that.$store.state.examDetail.exerciseId, examType: 'paper', }) }) } else if (this.examType == 'store') { this.$api.commitExam(this.$store.state.examDetail.exam.id, this.$store.state.examDetail.recordId) .then(res => { console.log('交卷:', res); that.$u.route('/pages/exam/examResultPage', { recordId: that.$store.state.examDetail.recordId, examType: 'exam' }) }) } else if (this.examType == 'course') { this.$api.commitCourse(this.$store.state.access_token, this.$store.state.examDetail.exerciseId) .then(res => { console.log('交卷:', res); that.$u.route('/pages/exam/examResultPage', { exerciseId: that.$store.state.examDetail.exerciseId, examType: 'course', }) }) } else { console.log("提交的考试类型出错"); let totalQueNum = 0 let rightQueNum = 0 let wrongQueNum = 0 let noneQueNum = 0 let score = 0 let sendData = { simulateExamId: this.$store.state.paperDetail.id, examResultVOS: [] } this.$store.state.questionList.forEach(item => { if (item.selectedFlag == true) { let obj = { subjectChoicesId: item.id, value: item.tempAnswer, grade: item.score } if (item.correctOrError == false) { obj.grade = 0 wrongQueNum += 1 } else { rightQueNum += 1 score += item.score } sendData.examResultVOS.push(obj) } else { noneQueNum += 1 } totalQueNum += 1 }) // 进行交卷的api请求 that.$u.route('/pages/exam/examResultPage', { recordId: that.$store.state.examDetail.recordId, totalQueNum: totalQueNum, rightQueNum: rightQueNum, wrongQueNum: wrongQueNum, noneQueNum: noneQueNum, score: score }) submitExam(sendData).then(res => {}) }, /* 题目答案变化 */ onChange(answer) { console.log(answer) } } } pages/exam/startexam.vue
@@ -13,15 +13,13 @@ <view class="tipsArea"> <ul> <li>1、答题时要注意“剩余时间”提示,当剩余时间为0时,系统将自动交卷。</li> <li>2、答题完成后,点击“我要交卷”按钮进行交卷,否则考试无效。</li> <li>3、如果你准备好了,就点击“进入考场”吧,预祝取得好的成绩。</li> <li>2、答题完成后,点击“交卷”按钮进行交卷,否则考试无效。</li> <li>3、答题时需注意模拟考试不能修改答案。</li> <li>4、如果你准备好了,就点击“进入考场”吧,预祝取得好的成绩。</li> </ul> </view> <view class="btnArea"> <!-- checkFace==1 不需要人脸识别,checkFace==2 需要人脸识别 --> <u-button v-if="needCheckFace==2 && !passFace " class="btnClass" type="primary" :ripple="true" shape="circle" @click="checkFace">开始人脸识别</u-button> <u-button v-if="needCheckFace==1 || passFace" class="btnClass" type="success" :ripple="true" shape="circle" <u-button class="btnClass" type="success" :ripple="true" shape="circle" @click="enterExam">进入考试</u-button> <u-button class="btnClass" type="error" :ripple="true" shape="circle" @click="exitExam">退出考试</u-button> </view> @@ -33,86 +31,46 @@ export default { data() { return { examItem: {}, examNote: ` 1、答题时要注意“剩余时间”提示,当剩余时间为0时,系统将自动交卷。 2、答题完成后,点击“我要交卷”按钮进行交卷,否则考试无效。 3、如果你准备好了,就点击“进入考场”吧,预祝取得好的成绩。`, passFace: false, examItem: {} } }, methods: { enterExam() { // 进入考试 // uni.navigateTo({ // url: '/pages/exam/examTextPage' // }) this.$u.route('/pages/exam/examTextPage', { id: this.examItem.id, examType: 'exam', }) }, exitExam() { // 退出考试 uni.navigateBack({ delta: 1 }) }, checkFace() { var that = this this.$api.uploadImg2('face') .then(res => { console.log('faceRes', res) if (res.data.indexOf('操作成功') >= 0) { this.passFace = true } }) }, } }, computed: { needCheckFace: function() { // checkFace==1 不需要人脸识别,checkFace==2 需要人脸识别 // H5 平台不需要检测人脸 // #ifdef H5 return 1 // #endif // #ifdef APP-PLUS || MP-WEIXIN return this.examItem.checkFace // #endif } }, onLoad(options) { // 页面跳转 传递对象 传对象 options = { id: '360198198812130014', name: '测试考试', name: '保安员模拟考试', examScore: 100, examTime: 90, examTime: 60, checkFace: 1 } this.examItem = options console.log("考试信息:", this.examItem); } } </script> <style lang="scss"> page { font-size: 31rpx; ul li { list-style: none; } } .tipsArea { padding: 0 40rpx; margin-left: -30rpx; line-height: 64rpx; } .subTitle { @@ -124,19 +82,12 @@ } .examContent { line-height: 50rpx; line-height: 56rpx; margin-left: 180rpx; text { font-weight: bold; } } ol { // padding: 80rpx; // background-color: #0077AA; margin: 0 30rpx; line-height: 50rpx; } .btnArea { store/state.js
@@ -4,6 +4,7 @@ const state = { examDetail: {}, // 考试详情 questionList: [], // 考试考题列表 paperDetail: {}, queTypeArr:[0,0,0,0,0], loging: false, message: {