<template>
|
<!-- 此组件用于题库练习的单题展示 -->
|
<view>
|
<!-- 大标题 -->
|
<view class="header" id="header">
|
<span v-if="type=='store'" > {{storeInfo.storeName}}题库练习</span>
|
<span v-if="type=='error'" > {{storeInfo.storeName}}错题练习</span>
|
<!-- <span class="header-button" @click='handleSubmit(1)' v-if='!isReviewed'>提交</span> -->
|
</view>
|
<!-- 小标题栏 -->
|
<!-- <view id="subHeader">
|
<view class="sub-header" v-if='questionList.length>0'>
|
<clock v-if="(!isReviewed)&&examType=='paper'" ref="myClock" :timeOrigin="parseInt(examDetail.time)"></clock>
|
<clock @clockend="clockend" ref="myClock"></clock>
|
<u-toast ref="uToast" />
|
<span class='sub-header-number' 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">
|
<u-tag v-if="item.template == 1" class="typeTag" text="单选题" mode="dark" shape="circle" />
|
<u-tag v-if="item.template == 2" class="typeTag" text="多选题" mode="dark" shape="circle" />
|
<u-tag v-if="item.template == 3" class="typeTag" text="判断题" mode="dark" shape="circle" />
|
<u-tag v-if="item.template == 4" class="typeTag" text="填空题" mode="dark" shape="circle" />
|
<u-tag v-if="item.template == 5" class="typeTag" text="简答题" mode="dark" shape="circle" />
|
<rich-text :nodes="item.queContent"></rich-text>
|
</view>
|
<!-- 以下显示选项 -->
|
<!-- type == 1 单选题 -->
|
<view class="content-solutions" v-if='item.template == 1'>
|
<template v-for='subItem in item.toptions'>
|
<view
|
:class="[item.isReviewed && subItem.optAnswer == 1 ? 'right': '',item.isReviewed && (item.wrongArr.indexOf(subItem.optLetter) >-1) ? 'wrong': '']"
|
class="content-solutions-item" @click='chooseSolution(item,subItem)'>
|
<view class="content-solutions-item-single">{{subItem.optLetter}}</view>
|
<view
|
:class="item.tempAnswer == subItem.optLetter? '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.toptions'>
|
<view
|
:class="[item.isReviewed && subItem.optAnswer == 1 ? 'right': '',item.isReviewed && (item.wrongArr.indexOf(subItem.optLetter) >-1) ? 'wrong': '']"
|
class="content-solutions-item" @click='chooseMutiSolution(item,subItem)'>
|
<view class="content-solutions-item-single">{{subItem.optLetter}}</view>
|
<view
|
:class="item.tempAnswer.indexOf(subItem.optLetter) >-1 ? 'content-solutions-item-select' : ''"
|
class="content-solutions-item-content">{{subItem.optContent}}
|
</view>
|
</view>
|
</template>
|
</view>
|
|
<!-- type == 3 判断题 -->
|
<view class="content-solutions" v-if='item.template == 3'>
|
<template v-for='(subItem,subIndex) in item.toptions' :keys="subIndex">
|
<view class="content-solutions-judge">
|
<view v-for="(judgeItem,judgeIndex) in judgeArr"
|
:class="[item.tempAnswer == judgeItem.value? 'content-solutions-item-select' : '',item.isReviewed && (item.rightAnswer==judgeItem.name) ? 'right': '',item.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>
|
<view class="content-solutions-item" v-for='(subItem,subIndex) in item.toptions'
|
:keys="subIndex"
|
:class="[item.isReviewed && item.blankString != item.rightAnswer ? 'wrong':'']">
|
<view class="content-solutions-item-single">{{subIndex+1}}</view>
|
<input :disabled="item.isReviewed" type="text" class="content-solutions-blank"
|
v-model="item.blankArr[subIndex]" placeholder="请在此处输入答案" />
|
<!-- TODOvalue的绑定值不对 :value="item.blankArr[subIndex].replace(/"\;/g, '')" -->
|
<!-- <input v-else :disabled="isReviewed" :value="item.blankArr"
|
type="text" class="content-solutions-blank" /> -->
|
</view>
|
</template>
|
</view>
|
<!-- type == 5 简答题 -->
|
<view class="content-solutions" v-if='item.template == 5'>
|
<textarea v-if="!item.isReviewed" @input="textInput" :disabled="isReviewed"
|
placeholder="请输入您的答案" auto-height />
|
<textarea v-else :disabled="item.isReviewed"
|
:value="item.tempAnswer.replace(/"\;/g, '')" auto-height />
|
</view>
|
<view class="explain" v-if='item.isReviewed'>
|
|
<u-tag v-show="item.isRight==1" text="正确" type="success" />
|
<u-tag v-show="item.isRight==2" text="错误" type="error" />
|
<u-tag v-show="item.isRight==3" 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">
|
<u-parse :html="item.queAnalysis?item.queAnalysis:'暂无'"></u-parse>
|
</view>
|
<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.notes.length>0? item.notes[0].noteContent:''"
|
:isreadOnly="isreadOnly" @editorInput='updateEditorText'>
|
</text-editor>
|
</view>
|
</view>
|
</scroll-view>
|
</swiper-item>
|
</template>
|
</swiper>
|
|
<!-- 底部栏 -->
|
<view class="footer" id="footer">
|
<u-button type="success" shape="circle" @click="submitAns">提交</u-button>
|
<u-button type="primary" shape="circle" @click="changeQues">换一题</u-button>
|
<!-- <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>
|
<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,
|
// isReviewed: false,
|
quesModules: [],
|
areaText: ``, //保存简答题答案
|
judgeArr: [{
|
name: '正确',
|
value: '1'
|
},
|
{
|
name: '错误',
|
value: '0'
|
}
|
],
|
currentIndex: 0,
|
swiperHeight: '800px',
|
modalHeight: '400px',
|
modalContentHeight: '300px',
|
showQuestion: false,
|
articleEditorValue: '',
|
eidtOrFinishValue: '编辑笔记',
|
editor: 'editor',
|
editorText: ''
|
}
|
},
|
filters: {
|
// 判断答案状态
|
answerStatusFilter(item) {
|
switch (item) {
|
case 1:
|
return '未答'
|
break;
|
case 2:
|
return '答题正确'
|
break;
|
case 3:
|
return '答题错误'
|
break;
|
case 4:
|
return '未评分'
|
break;
|
case 5:
|
return '已评分'
|
break;
|
case 6:
|
return '已答'
|
break;
|
default:
|
// ad
|
}
|
},
|
|
analysisFilter(item) {
|
if (item == null) {
|
return "暂无解析"
|
} else {
|
return item
|
}
|
}
|
},
|
watch: {
|
|
},
|
computed: {
|
storeInfo() {
|
return this.$store.state.storeInfo
|
},
|
questionList() {
|
return this.$store.state.questionList
|
},
|
max() {
|
return this.questionList.length - 1
|
},
|
},
|
props: {
|
type: {
|
type: String,
|
default: 'error'
|
},
|
duration: {
|
type: [String, Number],
|
default: 300
|
},
|
// isReviewed: {
|
// type: Boolean,
|
// default: false
|
// },
|
|
},
|
|
onReady() {
|
this.$refs.myClock.start();
|
// console.log('examDetail',this.examDetail);
|
},
|
components: {
|
Modal,
|
clock
|
},
|
methods: {
|
/* 跳转指定题目 */
|
handleJumpSwiper(index) {
|
this.currentIndex = index
|
this.showQuestion = false
|
},
|
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 (!item.isReviewed) {
|
// tempAnswer为学生答案
|
item.tempAnswer = subItem.optLetter
|
// if (this.currentIndex < this.max) {
|
// setTimeout(() => {
|
// this.currentIndex += 1
|
// }, 300)
|
// }
|
}
|
},
|
/* 选择答案(多选)*/
|
chooseMutiSolution(item, subItem) {
|
if (!item.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)
|
}
|
},
|
/* 判断题答案 */
|
judgeSolution(item, value) {
|
if (!item.isReviewed) {
|
// tempAnswer为学生答案
|
item.tempAnswer = value
|
// if (this.currentIndex < this.max) {
|
// setTimeout(() => {
|
// this.currentIndex += 1
|
// }, 300)
|
// }
|
}
|
},
|
changeQues() {
|
if (this.currentIndex < this.max) {
|
this.currentIndex += 1
|
} else {
|
this.$refs.uToast.show({
|
title: '已无更多试题',
|
type: 'warning',
|
})
|
}
|
},
|
submitAns() {
|
//--------------
|
// 对各题型的答案进行处理
|
let that = this
|
switch (that.questionList[that.currentIndex].template) {
|
case 1:
|
// 选择题
|
if (that.questionList[that.currentIndex].rightAnswer == that.questionList[that.currentIndex]
|
.tempAnswer) {
|
// 回答正确
|
that.questionList[that.currentIndex].isRight = 1
|
} else {
|
// 回答错误
|
that.questionList[that.currentIndex].isRight = 2
|
}
|
var rightArr = that.questionList[that.currentIndex].rightAnswer.split(',')
|
var userArr = that.questionList[that.currentIndex].tempAnswer.split(',')
|
that.questionList[that.currentIndex].wrongArr = [] // 保存选中的错误的选项
|
|
for (var item of userArr) {
|
// 用户的该答案不在正确答案数组在
|
if (rightArr.indexOf(item) < 0) {
|
that.questionList[that.currentIndex].wrongArr.push(item)
|
}
|
}
|
break;
|
case 2:
|
var rightArr = that.questionList[that.currentIndex].rightAnswer.split(',').sort()
|
var userArr = that.questionList[that.currentIndex].tempAnswer.split(',').sort()
|
// that.questionList[that.currentIndex].wrongArr = [] // 保存选中的错误的选项
|
|
for (var i = 0; i < rightArr.length; i++) {
|
if (rightArr.length != userArr.length) {
|
// 回答错误,漏选了
|
that.questionList[that.currentIndex].isRight = 2
|
} else {
|
if (rightArr[i] != userArr[i]) {
|
// 回答错误
|
that.questionList[that.currentIndex].isRight = 2
|
}
|
// 回答正确
|
that.questionList[that.currentIndex].isRight = 1
|
}
|
}
|
for (var item of userArr) {
|
// 用户的该答案不在正确答案数组在
|
if (rightArr.indexOf(item) < 0) {
|
that.questionList[that.currentIndex].wrongArr.push(item)
|
}
|
}
|
break;
|
case 3:
|
if (that.questionList[that.currentIndex].rightAnswer == that.questionList[that
|
.currentIndex]
|
.tempAnswer) {
|
// 回答正确
|
that.questionList[that.currentIndex].isRight = 1
|
} else {
|
// 回答错误
|
that.questionList[that.currentIndex].isRight = 2
|
}
|
// 判断题
|
if (that.questionList[that.currentIndex].tempAnswer != that.questionList[that.currentIndex]
|
.toptions[0].optAnswer) {
|
that.questionList[that.currentIndex].wrongArr = that.questionList[that.currentIndex]
|
.tempAnswer
|
}
|
break;
|
case 4:
|
// 填空题
|
that.questionList[that.currentIndex].tempAnswer = that.questionList[that.currentIndex]
|
.blankArr.join('||~||') // 数组拼接为字符串
|
that.questionList[that.currentIndex].isRight = 3 // 自行核对
|
break;
|
case 5:
|
that.questionList[that.currentIndex].isRight = 3 // 自行核对
|
that.questionList[that.currentIndex].tempAnswer = JSON.stringify(that.areaText)
|
break;
|
default:
|
}
|
console.log('提交题库的信息', that.questionList[that.currentIndex].id, that.$store.state.storeInfo
|
.storeId);
|
|
if(that.type == 'store'){
|
that.$api.storeSave(that.questionList[that.currentIndex].id, that.$store.state.storeInfo.storeId)
|
.then(res => {
|
that.questionList[that.currentIndex].isReviewed = !that.questionList[that.currentIndex]
|
.isReviewed
|
if (res.status == 1) {
|
console.log('保存题库练习记录失败', res);
|
uni.showToast({
|
title: '提交失败',
|
duration: 2000,
|
image: '../../static/error.png'
|
});
|
} else {
|
console.log('保存题库练习记录成功', res);
|
// this.isReviewed = !this.isReviewed
|
}
|
})
|
.catch(res => {
|
uni.showToast({
|
title: '提交失败',
|
duration: 2000,
|
image: '../../static/error.png'
|
});
|
console.log("提交失败");
|
})
|
|
}
|
// ------------------------
|
},
|
|
// 点击编辑笔记
|
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.addNote(item.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 {
|
position: relative;
|
text-align: center;
|
line-height: 100rpx;
|
font-size: 36rpx;
|
font-weight: 600;
|
color: $theme-color;
|
letter-spacing: 10rpx;
|
|
&-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: $theme-color;
|
}
|
|
.scoreText {
|
color: #00b060;
|
font-size: 35rpx;
|
}
|
}
|
|
.sub-header {
|
padding: 30rpx 20rpx;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
color: #000;
|
font-size: 33rpx;
|
font-weight: bold;
|
}
|
|
.content {
|
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 $theme-color;
|
border-radius: 20rpx;
|
display: flex;
|
align-items: center;
|
font-size: 30rpx;
|
background-color: $theme-color;
|
|
&-check-content {
|
padding: 35rpx 20rpx;
|
width: 100%;
|
border-radius: 15rpx;
|
color: $theme-color;
|
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: $theme-color;
|
}
|
}
|
|
&-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 $theme-color;
|
border-radius: 60rpx;
|
width: 300rpx;
|
padding: 35rpx 20rpx; // 控制单元格的高度
|
}
|
|
.content-solutions-judge-select {
|
color: #FFFFFF;
|
background-color: $theme-color;
|
}
|
|
}
|
|
&-blank {
|
// border: 5rpx solid $theme-color;
|
height: 60rpx;
|
width: 90%;
|
// border-radius: 20rpx;
|
background-color: #FFFFFF;
|
padding: 20rpx;
|
}
|
|
&-fillItem {
|
border: 5rpx solid $theme-color;
|
border-radius: 20rpx;
|
background-color: #FFFFFF;
|
padding: 20rpx;
|
}
|
}
|
|
.explain {
|
border-top: solid #999999 1px;
|
padding-top: 10rpx;
|
font-size: 28rpx;
|
color: #666666;
|
|
.explainResult {
|
color: $theme-color;
|
}
|
|
.explain-title {
|
font-weight: bold;
|
}
|
|
.noteArea {
|
border-top: 2rpx solid $theme-color;
|
padding-top: 10rpx;
|
|
// background-color: #0077AA;
|
.noteAreaTitle {
|
display: flex;
|
justify-content: space-between;
|
}
|
}
|
}
|
}
|
|
.footer {
|
width: 750rpx;
|
height: 100rpx;
|
padding: 30rpx 20rpx;
|
position: fixed;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
bottom: 0;
|
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 $theme-color;
|
border-radius: 15rpx;
|
color: #FFFFFF;
|
background-color: $theme-color;
|
}
|
}
|
|
.question-modal {
|
width: 700rpx;
|
padding: 40rpx;
|
background-color: #FFFFFF;
|
|
&-header {
|
height: 100rpx;
|
text-align: center;
|
font-size: 35rpx;
|
line-height: 100rpx;
|
color: #333333;
|
border-bottom: 1rpx solid #F0F0F0;
|
}
|
|
&-body {
|
|
&-item {
|
width: 80rpx;
|
margin: 10rpx 22rpx;
|
height: 80rpx;
|
line-height: 80rpx;
|
font-size: 35rpx;
|
display: inline-block;
|
text-align: center;
|
border-radius: 50%;
|
color: #8799a3;
|
// background-color: #0077AA;
|
}
|
|
&-item-failed {
|
color: #FFFFFF;
|
background-color: #982121;
|
}
|
|
&-item-right {
|
color: #FFFFFF;
|
background-color: #39b54a;
|
}
|
|
&-item-select {
|
color: #FFFFFF;
|
background-color: $theme-color;
|
}
|
}
|
|
.question-modal-foot {
|
height: 100rpx;
|
border-top: 1rpx solid #F0F0F0;
|
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: $theme-color;
|
margin: 0 10rpx;
|
}
|
|
.block-unansed {
|
width: 80rpx;
|
height: 80rpx;
|
border-radius: 50%;
|
border: solid #999999 1px;
|
// background: $font-color-ps ;
|
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;
|
}
|
}
|
|
}
|
}
|
|
.right {
|
border: 8rpx solid #39b54a;
|
}
|
|
.wrong {
|
border: 8rpx solid #d81717;
|
}
|
</style>
|