<template>
|
<view class="page_bg">
|
<!-- #ifdef APP-PLUS -->
|
<view class="status_bar">
|
<view class="top_view"></view>
|
</view>
|
<!-- #endif -->
|
<view class="top_nav">
|
<image src="/static/local/3546451940011a031009b939a8b26314.png" class="image_1" @click="pageBack" />
|
<view class="cate">{{cardHidden ? pageTitle : '答题卡'}}</view>
|
<block v-if="!checkAnswer" @tap="collectQuestion">
|
<u-icon name="more-dot-fill" class="more_fun" @tap="collection = !collection"></u-icon>
|
<view class="collection_bg" v-if="collection">
|
<block v-if="questionList.length!=0 && vk.pubfn.isNull(questionList[currentIndex].star)">
|
<u-icon name="star" color="#fff" size="32"></u-icon>收藏本题
|
</block>
|
<block v-else>
|
<u-icon name="star-fill" color="#fff" size="32"></u-icon>已收藏本题
|
</block>
|
</view>
|
</block>
|
</view>
|
<view class="main">
|
<view class="exam_title">{{detail.title}}</view>
|
<pw-swiper ref="swiper" class="pw_swiper" :list="questionList" :dataIndex="currentIndex" @change="change">
|
<template v-slot:default="{item,index}">
|
<scroll-view scroll-y class="scroll_bg">
|
<view class="item_top">
|
<text class="item_type">{{qType(item.type)}}</text>
|
<text class="number"><text>{{index + 1}}</text> / {{questionList.length}}</text>
|
</view>
|
<mp-html class="item_body" :content="item.title"></mp-html>
|
<!-- 单选 -->
|
<view class="single" v-if="item.type == 1 || item.type == 3">
|
<view class="answer_item" v-for="(answer,a_index) in item.answerList"
|
:key="item._id + a_index" @tap="choose(a_index,answer.isRight,item,item.type)">
|
<view class="left_icon" :class="{'selected':a_index == answercard[item._id].a}">
|
{{ letter[a_index] }}
|
</view>
|
{{answer.content}}
|
</view>
|
</view>
|
|
<!-- 多选 -->
|
<view class="single" v-if="item.type == 2">
|
<view class="answer_item" v-for="(answer,a_index) in item.answerList"
|
:key="item._id + a_index" @tap="choose(a_index,answer.isRight,item,item.type)">
|
<view class="left_icon"
|
:class="{'selected':answercard[item._id].a && answercard[item._id].a.indexOf(a_index)!=-1}">
|
{{ letter[a_index] }}
|
</view>
|
{{answer.content}}
|
</view>
|
</view>
|
|
<view class="answer_check" v-if="checkAnswer">
|
<view class="check_title">答案解析</view>
|
<view class="right_answer">正确答案:{{rightAnswer(item)}}</view>
|
<mp-html class="check_detail" :content="item.analysis"></mp-html>
|
</view>
|
</scroll-view>
|
</template>
|
</pw-swiper>
|
<view class="end_nav" :class="{end_nav_show: !cardHidden}">
|
<block v-if="cardHidden">
|
<view class="btn" :class="{cant: currentIndex == 0}" @tap="changeIndex('before')">
|
上一题
|
</view>
|
<view class="icon">
|
<image src="/static/local/16403089344736532213.png" class="image_8" />
|
<view class="text" @tap="cardHidden = false">答题卡</view>
|
</view>
|
<view class="icon" v-if="checkAnswer==false" @tap="checkAnswer = true">
|
<image src="/static/local/16403089465091811020.png" class="image_8" />
|
<view class="text">答案解析</view>
|
</view>
|
<view class="icon" v-else @tap="collectQuestion">
|
<block v-if="questionList.length!=0 && vk.pubfn.isNull(questionList[currentIndex].star)">
|
<u-icon name="star" color="#000" size="42"></u-icon>
|
<view class="text">收藏</view>
|
</block>
|
<block v-else>
|
<u-icon name="star-fill" color="#000" size="42"></u-icon>
|
<view class="text">已收藏</view>
|
</block>
|
</view>
|
<block v-if="questionList && currentIndex < questionList.length - 1">
|
<view class="btn" @tap="changeIndex('after')">下一题</view>
|
</block>
|
<block v-else>
|
<view class="btn" @tap="sendExam()">交卷</view>
|
</block>
|
</block>
|
<block v-else>
|
<scroll-view scroll-y class="card_bg">
|
<view class="card_top">
|
<text class="ready"></text>已选
|
<text class="not_ready"></text>未选
|
</view>
|
<view class="card_main">
|
<!-- 单选 -->
|
<block v-if="single">
|
<view class="title">单选题</view>
|
<view class="item_bg" v-for="item in questionList" :key="item._id" v-if="item.type == 1"
|
@tap="cardHidden=true;currentIndex=item.no-1">
|
<view class="item" :class="{selected: answercard[item._id].r != 0}">
|
{{item.no}}
|
</view>
|
</view>
|
</block>
|
<!-- 多选 -->
|
<block v-if="more">
|
<view class="title">多选题</view>
|
<view class="item_bg" v-for="item in questionList" :key="item._id" v-if="item.type == 2"
|
@tap="cardHidden=true;currentIndex=item.no-1">
|
<view class="item" :class="{selected: answercard[item._id].r != 0}">
|
{{item.no}}
|
</view>
|
</view>
|
</block>
|
<!-- 判断 -->
|
<block v-if="judge">
|
<view class="title">判断题</view>
|
<view class="item_bg" v-for="item in questionList" :key="item._id" v-if="item.type == 3"
|
@tap="cardHidden=true;currentIndex=item.no-1">
|
<view class="item" :class="{selected: answercard[item._id].r != 0}">
|
{{item.no}}
|
</view>
|
</view>
|
</block>
|
</view>
|
</scroll-view>
|
<view class="save_btn" @tap="sendExam()">交卷</view>
|
</block>
|
</view>
|
</view>
|
|
<u-modal v-model="modalShow" :show-title="false" :content="content" :show-cancel-button="true"
|
@confirm="sendExamAnswer">
|
</u-modal>
|
<u-toast ref="uToast" />
|
</view>
|
</template>
|
|
<script>
|
var that; // 当前页面对象
|
var vk; // vk依赖
|
export default {
|
data() {
|
// 页面数据变量
|
return {
|
typeId: '',
|
pageTitle: '',
|
detail: [],
|
questionList: [],
|
answercard: {}, //留有最新结果的答题版
|
answercardNew: {}, //本次答的题目,用于统计
|
// 各类问题
|
single: false,
|
more: false,
|
judge: false,
|
|
currentIndex: 0,
|
cardHidden: true,
|
checkAnswer: false,
|
letter: ['A', "B", "C", "D", "E", "F", "G", "H", "I", "G", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
|
"T", "U", "V", 'W', "X", "Y", "Z"
|
],
|
// 保存提示模态框
|
modalShow: false,
|
content: '',
|
collection: false,
|
outWay: 1 // 退出方式 0左上角退出 1交卷退出
|
}
|
},
|
// 监听 - 页面每次【加载时】执行(如:前进)
|
onLoad(options = {}) {
|
that = this;
|
vk = that.vk;
|
that.init(options)
|
},
|
// 监听 - 页面【首次渲染完成时】执行。注意如果渲染速度快,会在页面进入动画完成前触发
|
onReady() {},
|
// 监听 - 页面每次【显示时】执行(如:前进和返回) (页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面)
|
onShow() {},
|
// 监听 - 页面每次【隐藏时】执行(如:返回)
|
onHide() {},
|
// 函数
|
computed: {
|
qType() {
|
return (type) => {
|
switch (type) {
|
case '1':
|
return '单选题'
|
case '2':
|
return '多选题'
|
case '3':
|
return '判断题'
|
}
|
}
|
},
|
rightAnswer() {
|
return (item) => {
|
let str = ''
|
for (let k in item.answerList) {
|
if (item.answerList[k].isRight) str += ` ${this.letter[k]}`
|
}
|
return str
|
}
|
}
|
},
|
methods: {
|
// 页面数据初始化函数
|
init(options) {
|
// 当前显示标题
|
this.typeId = options.id
|
this.pageTitle = options.pageTitle
|
if (options.check) this.checkAnswer = true
|
this.getInfo(options.id, options.pageTitle)
|
},
|
pageBack() {
|
if (!this.cardHidden) {
|
this.cardHidden = true
|
return
|
}
|
this.saveExam()
|
},
|
// 获取信息
|
getInfo(id, tit) {
|
let str = ''
|
switch (tit) {
|
case '历年真题':
|
str = 'client/quest-bank/kh/real-exam/getOneRealExam'
|
break
|
case '章节练习':
|
str = 'client/quest-bank/kh/chapter/getOneChapter'
|
break
|
case '每日一练':
|
str = 'client/quest-bank/kh/everyday/getOneEveryDay'
|
break
|
case '模拟试题':
|
str = 'client/quest-bank/kh/simulation/getOneSimulation'
|
break
|
case '会员练习':
|
str = 'client/quest-bank/kh/vip/getOneVip'
|
break
|
}
|
vk.callFunction({
|
url: str,
|
data: { id, need_user_info: true },
|
success(res) {
|
that.detail = res.data
|
that.questionList = res.data.questions
|
let temp = {}
|
let num = 1
|
let obj = vk.pubfn.arrayToJson(res.data.history, "question_id");
|
res.data.questions.forEach(v => {
|
v.no = num
|
num++
|
if (v.type == 1) that.single = true
|
if (v.type == 2) that.more = true
|
if (v.type == 3) that.judge = true
|
if (obj != null && obj[v._id] != null) {
|
temp[v._id] = { a: obj[v._id].answer, r: obj[v._id].is_right }
|
} else {
|
temp[v._id] = { a: null, r: 0 }
|
}
|
})
|
that.answercard = temp
|
}
|
})
|
},
|
choose(index, right, item, type) {
|
let res = this.answercard[item._id]
|
//单选 判断
|
if (type == 1 || type == 3) {
|
res = { a: index, r: right ? 1 : 2 }
|
} else if (type == 2) {
|
if (res.a == null) {
|
//第一次选择
|
res.a = [index]
|
} else {
|
//判断是选中还是取消
|
const find_index = res.a.indexOf(index)
|
if (find_index > -1) {
|
if (res.a.length < 2) {
|
this.$refs.uToast.show({
|
title: '请至少选择一个答案',
|
type: 'warning',
|
duration: 1000
|
})
|
return
|
}
|
res.a.splice(find_index, 1)
|
} else {
|
res.a.push(index)
|
}
|
}
|
//判断答案是否正确
|
let my_choice = res.a.sort(function(a, b) {
|
return a - b
|
}).join(',')
|
let answerArr = []
|
item.answerList.forEach((item, index) => {
|
if (item.isRight) answerArr.push(index)
|
});
|
let answer_str = answerArr.sort(function(a, b) {
|
return a - b
|
}).join(',')
|
res.r = my_choice == answer_str ? 1 : 2
|
}
|
this.answercard[item._id] = res
|
this.answercardNew[item._id] = res
|
},
|
change(e) {
|
this.collection = false
|
this.currentIndex = e
|
},
|
changeIndex(type) {
|
if (type == 'before' && this.currentIndex > 0) {
|
this.$refs.swiper.goPrevious()
|
return
|
}
|
if (type == 'after' && this.currentIndex < this.detail.questions.length - 1) {
|
this.$refs.swiper.goNext()
|
return
|
}
|
},
|
// 收藏题目
|
collectQuestion() {
|
let item = this.questionList[this.currentIndex]
|
vk.callFunction({
|
url: 'client/quest-bank/kh/collection/saveInCollection',
|
title: '收藏中...',
|
data: {
|
qid: item._id,
|
star: vk.pubfn.isNull(item.star) ? 0 : 1,
|
need_user_info: true,
|
},
|
success(res) {
|
that.$refs.uToast.show({
|
title: res.msg,
|
type: 'success',
|
duration: 1200
|
})
|
that.$forceUpdate()
|
if (res.status == 0) {
|
that.questionList[that.currentIndex].star = {}
|
return
|
}
|
that.questionList[that.currentIndex].star = { id: res.id }
|
}
|
})
|
},
|
// 退出前弹框提示
|
saveExam() {
|
this.content = '退出并保存当前进度么?'
|
this.modalShow = true
|
this.outWay = 0
|
},
|
// 交卷提示
|
sendExam() {
|
this.content = '确认交卷么?'
|
this.modalShow = true
|
this.outWay = 1
|
},
|
// 交卷
|
sendExamAnswer() {
|
let cateInfo = vk.getStorageSync('bank_cate');
|
let time = vk.pubfn.timeFormat(new Date(), "yyyy-MM-dd hh:mm:ss");
|
// 只更新本次选择过的答案
|
vk.callFunction({
|
url: 'client/quest-bank/kh/saveAnswer',
|
title: '提交中...',
|
data: {
|
answercard: that.answercardNew,
|
typeId: that.typeId,
|
need_user_info: true,
|
cate_id: cateInfo ? cateInfo.id : null
|
},
|
success(res) {
|
// 退出方式为点击左上角
|
if (that.outWay == 0) {
|
that.$refs.uToast.show({
|
title: '保存成功',
|
type: 'success',
|
duration: 1200,
|
url: '/pages/question-bank/index',
|
isTab: true
|
})
|
uni.$emit('bankUpdate');
|
return
|
}
|
// 退出方式为点交卷
|
let result = {
|
answerCardNow: that.answercard,
|
questions: that.questionList
|
}
|
vk.setStorageSync('exam-result', result);
|
|
that.$refs.uToast.show({
|
title: '交卷成功',
|
type: 'success',
|
duration: 1200,
|
url: '/pages/question-bank/exam-result',
|
params: {
|
id: that.typeId,
|
type: that.pageTitle,
|
title: that.detail.title,
|
time
|
}
|
})
|
}
|
})
|
}
|
},
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.page_bg {
|
background-color: #ffffff;
|
width: 100%;
|
height: 100vh;
|
overflow-y: auto;
|
|
.status_bar,
|
.top_view {
|
background-color: #FFFFFF;
|
}
|
|
.top_nav {
|
padding-bottom: 24rpx;
|
color: rgb(51, 51, 51);
|
font-size: 34rpx;
|
line-height: 41rpx;
|
white-space: nowrap;
|
background-color: rgb(255, 255, 255);
|
box-shadow: 0px 6rpx 12rpx 0px rgba(0, 0, 0, 0.1);
|
border-radius: 0px 0px 30rpx 30rpx;
|
height: 90rpx;
|
position: relative;
|
|
.image_1 {
|
left: 21rpx;
|
top: 27rpx;
|
width: 19rpx;
|
height: 35rpx;
|
position: absolute;
|
}
|
|
.cate {
|
width: 100%;
|
padding: 20rpx 0;
|
color: rgb(51, 51, 51);
|
font-size: 34rpx;
|
line-height: 41rpx;
|
white-space: nowrap;
|
text-align: center;
|
}
|
|
.more_fun {
|
position: absolute;
|
right: 41rpx;
|
top: 27rpx;
|
}
|
|
.collection_bg {
|
position: absolute;
|
right: 21rpx;
|
top: 110rpx;
|
width: 188rpx;
|
height: 68rpx;
|
background: #515151;
|
box-shadow: 0px 0px 16rpx rgba(0, 0, 0, 0.12);
|
opacity: 1;
|
border-radius: 12rpx;
|
font-size: 24rpx;
|
color: #FFFFFF;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
|
.u-icon {
|
margin-right: 6rpx;
|
}
|
}
|
}
|
|
.main {
|
height: calc(100vh - 188rpx);
|
display: flex;
|
flex-direction: column;
|
|
.exam_title {
|
font-size: 28rpx;
|
font-weight: bold;
|
color: #999999;
|
padding: 36rpx 20rpx;
|
}
|
|
.pw_swiper {
|
flex: 1;
|
|
.scroll_bg {
|
height: calc(100vh - 388rpx);
|
}
|
|
.item_top {
|
font-size: 24rpx;
|
display: flex;
|
justify-content: space-between;
|
padding: 0 30rpx;
|
|
.item_type {
|
display: inline-block;
|
padding: 5rpx 10rpx;
|
background: linear-gradient(163deg, #FDD303 0%, #FF960C 100%);
|
border-radius: 4rpx;
|
}
|
|
.number {
|
color: #999999;
|
display: flex;
|
align-items: center;
|
|
text {
|
font-size: 28rpx;
|
font-weight: bold;
|
color: #333333;
|
margin-right: 4rpx;
|
}
|
}
|
}
|
|
.item_body {
|
font-size: 32rpx;
|
line-height: 52rpx;
|
color: #333333;
|
padding: 28rpx 30rpx;
|
min-height: 10vh;
|
}
|
|
.answer_item {
|
display: flex;
|
font-size: 32rpx;
|
align-items: center;
|
padding: 30rpx;
|
|
.left_icon {
|
width: 72rpx;
|
height: 72rpx;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
border: 2rpx solid #999999;
|
border-radius: 50%;
|
font-size: 34rpx;
|
font-weight: bold;
|
color: #333333;
|
margin-right: 30rpx;
|
}
|
|
.selected {
|
color: #FFFFFF;
|
background: #FF960C;
|
border-color: #FF960C;
|
box-shadow: 0px 3rpx 6rpx rgba(255, 150, 12, 0.26);
|
}
|
}
|
|
.answer_check {
|
border-top: 1px solid #F0F0F0;
|
padding: 40rpx 30rpx;
|
margin-top: 20rpx;
|
|
.check_title {
|
font-size: 32rpx;
|
font-weight: bold;
|
color: #140005;
|
margin-bottom: 30rpx;
|
}
|
|
.right_answer {
|
font-size: 24rpx;
|
font-weight: 400;
|
color: #333333;
|
margin-bottom: 32rpx;
|
}
|
}
|
}
|
|
.end_nav {
|
position: fixed;
|
left: 0;
|
bottom: 0;
|
right: 0;
|
background: rgba(255, 255, 255, 0.39);
|
box-shadow: 0px -6rpx 16rpx rgba(0, 0, 0, 0.08);
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 25rpx 20rpx;
|
background-color: #FFFFFF;
|
|
.btn {
|
color: #FFFFFF;
|
width: 164rpx;
|
height: 66rpx;
|
background-color: #333333;
|
border-radius: 33rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.cant {
|
background-color: #D1D1D1;
|
}
|
|
.icon {
|
text-align: center;
|
font-size: 20rpx;
|
font-weight: 400;
|
color: #333333;
|
|
.image_8 {
|
width: 42rpx;
|
height: 42rpx;
|
}
|
|
.u-icon {
|
margin-bottom: 6rpx;
|
}
|
}
|
|
.card_bg {
|
height: 100%;
|
width: 100%;
|
|
.card_top {
|
display: flex;
|
align-items: center;
|
margin-bottom: 65rpx;
|
|
.ready,
|
.not_ready {
|
display: inline-block;
|
width: 44rpx;
|
height: 44rpx;
|
border-radius: 50%;
|
margin: 0 22rpx;
|
}
|
|
.ready {
|
background: rgba(255, 150, 12, 1);
|
box-shadow: 0px 3rpx 6rpx rgba(255, 150, 12, 1);
|
}
|
|
.not_ready {
|
border: 2rpx solid #999999;
|
margin-left: 60rpx;
|
}
|
}
|
|
.card_main {
|
display: flex;
|
flex-wrap: wrap;
|
|
.title {
|
font-size: 30rpx;
|
font-weight: bold;
|
margin-bottom: 28rpx;
|
width: 100%;
|
}
|
|
.item_bg {
|
width: 20%;
|
display: flex;
|
align-items: center;
|
margin-bottom: 36rpx;
|
|
.item {
|
width: 72rpx;
|
height: 72rpx;
|
background: rgba(255, 255, 255, 0.39);
|
border: 2rpx solid #999999;
|
border-radius: 50%;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
margin-left: 20rpx;
|
}
|
|
.selected {
|
color: #FFFFFF;
|
background: #FF960C;
|
border-color: #FF960C;
|
box-shadow: 0px 3rpx 6rpx rgba(255, 150, 12, 0.26);
|
}
|
}
|
}
|
}
|
|
.save_btn {
|
position: absolute;
|
bottom: 0;
|
left: 0;
|
right: 0;
|
height: 98rpx;
|
background: #333333;
|
color: #FFFFFF;
|
line-height: 98rpx;
|
text-align: center;
|
}
|
}
|
|
.end_nav_show {
|
height: calc(100vh - 200rpx);
|
box-shadow: none;
|
}
|
}
|
}
|
</style>
|