YNUtdPlatform/pages/YNEduApp/exam/examination.vue

494 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<u-navbar leftIcon="" title="考试" :placeholder="true" />
<div class="content">
<div class="top-content">
<div class="top-wrapper">
<div class="time">
<div>距离考试结束</div>
<div>
<u-count-down
class="count-down"
ref="countDown"
:autoStart="false"
:time="time"
@change="changeCountDown"
/>
</div>
</div>
<div>
<span style="color: #1989fa">{{ currentIndex + 1 }}</span>
/{{ questionList.length }}
</div>
</div>
<div class="center-wrapper">
<div class="answer-wrapper">
<div
class="item-wrapper"
v-for="(item, index) in questionList"
:key="index"
v-show="item.isShow"
@click="handleQuestionNumber(item, index)"
>
<div class="answer-item" :class="{ isActive: item.isActive }">{{ index + 1 }}</div>
</div>
</div>
<div class="unfold" @click="handleUnfold">
{{ isRotating ? '收起' : '展开' }}
<u-icon v-if="!this.isRotating" name="arrow-down-fill" size="10" />
<u-icon v-else name="arrow-up-fill" size="10" />
</div>
</div>
</div>
<!-- 题目 -->
<div class="question-wrapper" v-for="(item, index) in questionList" :key="index" v-show="index == currentIndex">
<div class="question-type-wrapper">
<div class="line" />
<div class="question-type">
<div v-if="item.type == 1">单选题({{ item.score }}分)</div>
<div v-if="item.type == 2">多选题({{ item.score }}分)</div>
<div v-if="item.type == 3">判断题({{ item.score }}分)</div>
</div>
</div>
<div class="question">{{ currentIndex + 1 }}. {{ item.question }}</div>
<div class="options">
<div
class="option"
v-for="(option, optionIndex) in item.options"
:key="optionIndex"
:class="{ isActive: option.isActive }"
@click="handleSelectOption(item, index, option, optionIndex)"
>
<div class="option-item">{{ option.value }}.</div>
<div class="option-content">{{ option.label }}</div>
</div>
</div>
</div>
<!-- 底部按钮 -->
<div class="bottom-btn">
<div class="btn" v-show="currentIndex != 0">
<u-button size="small" shape="circle" text="上一题" @click="currentIndex--" />
</div>
<div class="btn" v-if="currentIndex !== questionList.length - 1">
<u-button type="primary" size="small" shape="circle" text="下一题" @click="currentIndex++" />
</div>
<div class="btn" v-else>
<u-button type="primary" size="small" shape="circle" text="交 卷" @click="openConfirmModal" />
</div>
</div>
</div>
<!-- 提交弹框 -->
<u-modal
:show="showConfirmModal"
title="提示"
showCancelButton
@cancel="showConfirmModal = false"
@confirm="handleConfirmSubmit"
>
<view class="slot-content">
<view v-if="unDoCount > 0">
本场考试还有
<span style="color: #1989fa; margin: 0 5px">{{ unDoCount }}</span>
题尚未完成
</view>
<view style="text-align: center;">确定交卷</view>
</view>
</u-modal>
</view>
</template>
<script>
export default {
data() {
return {
showConfirmModal: false,
time: 30 * 60 * 1000,
// 答题时间
answerTime: 0,
currentIndex: 0,
// 是否展开
isRotating: false,
// 是否结束
isEnd: false,
// 未做题目数
unDoCount: 0,
// 答题卡
answerCard: [],
// 题目列表
questionList: [
{
id: 1,
// 题目类型
type: 1, // 1: 单选题, 2: 多选题, 3: 判断题
// 分数
score: 2,
// 题目
question: '送配电线路架设工的主要工作是?',
// 选项
options: [
{ label: '电力设备的安装、调试、维护和检修', value: 'A' },
{ label: '电力设备的安装、调试、维护和检修', value: 'B' },
{ label: '电力设备的安装、调试、维护和检修', value: 'C' },
{ label: '电力设备的安装、调试、维护和检修', value: 'D' }
]
},
{
id: 2,
type: 2,
score: 2,
question: '送配电线路架设工的主要工作是?',
options: [
{ label: '电力设备的安装、调试、维护和检修', value: 'A' },
{ label: '电力设备的安装、调试、维护和检修', value: 'B' },
{ label: '电力设备的安装、调试、维护和检修', value: 'C' },
{ label: '电力设备的安装、调试、维护和检修', value: 'D' }
]
},
{
id: 3,
type: 3,
score: 2,
question: '送配电线路架设工的主要工作是: 好好工作?',
options: [
{ label: '对', value: 'A' },
{ label: '错', value: 'B' }
]
},
{
id: 11,
// 题目类型
type: 1, // 1: 单选题, 2: 多选题, 3: 判断题
// 分数
score: 2,
// 题目
question: '送配电线路架设工的主要工作是?',
// 选项
options: [
{ label: '电力设备的安装、调试、维护和检修', value: 'A' },
{ label: '电力设备的安装、调试、维护和检修', value: 'B' },
{ label: '电力设备的安装、调试、维护和检修', value: 'C' },
{ label: '电力设备的安装、调试、维护和检修', value: 'D' }
]
},
{
id: 21,
type: 2,
score: 2,
question: '送配电线路架设工的主要工作是?',
options: [
{ label: '电力设备的安装、调试、维护和检修', value: 'A' },
{ label: '电力设备的安装、调试、维护和检修', value: 'B' },
{ label: '电力设备的安装、调试、维护和检修', value: 'C' },
{ label: '电力设备的安装、调试、维护和检修', value: 'D' }
]
},
{
id: 31,
type: 3,
score: 2,
question: '送配电线路架设工的主要工作是: 好好工作?',
options: [
{ label: '对', value: 'A' },
{ label: '错', value: 'B' }
]
},
{
id: 12,
// 题目类型
type: 1, // 1: 单选题, 2: 多选题, 3: 判断题
// 分数
score: 2,
// 题目
question: '送配电线路架设工的主要工作是?',
// 选项
options: [
{ label: '电力设备的安装、调试、维护和检修', value: 'A' },
{ label: '电力设备的安装、调试、维护和检修', value: 'B' },
{ label: '电力设备的安装、调试、维护和检修', value: 'C' },
{ label: '电力设备的安装、调试、维护和检修', value: 'D' }
]
},
{
id: 22,
type: 2,
score: 2,
question: '送配电线路架设工的主要工作是?',
options: [
{ label: '电力设备的安装、调试、维护和检修', value: 'A' },
{ label: '电力设备的安装、调试、维护和检修', value: 'B' },
{ label: '电力设备的安装、调试、维护和检修', value: 'C' },
{ label: '电力设备的安装、调试、维护和检修', value: 'D' }
]
},
{
id: 32,
type: 3,
score: 2,
question: '送配电线路架设工的主要工作是: 好好工作?',
options: [
{ label: '对', value: 'A' },
{ label: '错', value: 'B' }
]
},
]
}
},
mounted() {
this.getList()
},
methods: {
// 获取列表
getList() {
if (this.questionList.length > 0) {
this.questionList.forEach((item, index) => {
this.$set(item, 'isShow', index < 7)
this.$set(item, 'isActive', false)
if (item.options) {
item.options.forEach(option => {
this.$set(option, 'isActive', false)
})
}
})
console.log('🚀 ~ this.questionList.forEach ~ this.questionList:', this.questionList)
this.$refs.countDown.start()
}
},
changeCountDown(time) {
// console.log('🚀 ~ changeCountDown ~ time:', time)
this.answerTime =
this.time - (time.days * 24 * 60 * 60 + time.hours * 60 * 60 + time.minutes * 60 + time.seconds) * 1000
if (this.answerTime == this.time) {
// 提示: 时间结束, 自动提交
this.$refs.uToast.show({
message: '考试时间结束, 系统将自动提交',
duration: 1000
})
this.handleConfirmSubmit()
setTimeout(() => {
this.isEnd = true
}, 1000)
}
},
// 点击题号
handleQuestionNumber(item, index) {
console.log('🚀 ~ handleQuestionNumber ~ item:', item)
this.currentIndex = index
},
// 展开
handleUnfold() {
this.questionList.forEach((item, index) => {
if (index > 6) {
this.$set(item, 'isShow', !item.isShow)
}
})
this.isRotating = !this.isRotating
console.log('🚀 ~ this.questionList.forEach ~ this.isRotating:', this.isRotating)
},
handleSelectOption(item, index, option, optionIndex) {
console.log('🚀 ~ handleSelectOption ~ option:', option, optionIndex)
item.isActive = true
// 如果是单选题与判断题 则只能选中一个 多选题可以选中多个
if (item.type == 1 || item.type == 3) {
this.$set(option, 'isActive', true)
// 单选题与判断题只能有一个是选中的, 如果当前是选中状态, 再次点击不做处理, 如果当前是未选中状态, 设置当前项为选中状态, 其他项为未选中状态
item.options.forEach((option, optIndex) => {
// 除了当前选中的其他都设置为未选中
if (optIndex != optionIndex) {
this.$set(option, 'isActive', false)
}
})
} else {
this.$set(option, 'isActive', !option.isActive)
// 如果所有选项都是未选中状态, 则题目也是未选中状态
let isActive = item.options.some(option => option.isActive)
item.isActive = isActive
}
},
openConfirmModal() {
this.unDoCount = this.questionList.filter(item => !item.isActive).length
this.showConfirmModal = true
},
// 答题卡
handleAnswerCard() {
// 根据questionList.options.isActive 计算答题卡
this.questionList.forEach((item, index) => {
if (item.type == 1 || item.type == 3) {
item.options.forEach(option => {
if (option.isActive) {
this.answerCard.push({
id: item.id,
answer: option.value
})
}
})
} else {
let answer = []
item.options.forEach(option => {
if (option.isActive) {
answer.push(option.value)
}
})
this.answerCard.push({
id: item.id,
answer
})
}
})
},
// 确认提交
handleConfirmSubmit() {
this.handleAnswerCard()
// 停止计时
this.$refs.countDown.pause()
console.log('🚀 ~ handleConfirmSubmit ~ this.answerCard:', this.answerCard, this.answerTime)
this.showConfirmModal = false
uni.navigateTo({
url: '/pages/YNEduApp/exam/examinationDetails'
})
}
}
}
</script>
<style lang="scss" scoped>
.content {
padding: 10px;
.top-content {
background: #fff;
padding: 10px;
border-radius: 5px;
}
.top-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
.time {
display: flex;
justify-content: flex-start;
}
}
.center-wrapper {
display: flex;
justify-content: space-between;
.unfold {
height: 50px;
line-height: 50px;
text-align: center;
display: flex;
justify-content: center;
}
.answer-wrapper {
width: 86%;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: wrap;
.item-wrapper {
padding: 5px 5px 0 0;
width: 12%;
height: 45px;
display: flex;
justify-content: center;
align-items: center;
.answer-item {
width: 33px;
height: 33px;
line-height: 33px;
text-align: center;
border-radius: 5px;
background: #f4f9fe;
color: #333;
&.isActive {
background: #1989fa;
}
}
}
}
}
.question-wrapper {
.question-type-wrapper {
margin: 20px 0;
display: flex;
justify-content: flex-start;
align-items: center;
.line {
width: 2px;
height: 11px;
background: #1989fa;
margin-right: 3px;
}
.question-type {
color: #8a8a8a;
}
}
.question {
font-weight: 800;
font-size: 15px;
color: #333333;
}
}
.options {
margin-top: 10px;
.option {
display: flex;
justify-content: flex-start;
align-items: center;
margin-top: 10px;
background: #f4f9fe;
border-radius: 5px;
&.isActive {
background: #8cbff1;
color: #fff;
}
.option-item {
width: 33px;
height: 33px;
line-height: 33px;
text-align: center;
color: #333;
}
.option-content {
margin-left: 10px;
color: #333;
}
}
}
.bottom-btn {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background-color: #fff;
padding: 15px 0;
display: flex;
justify-content: flex-end;
align-items: center;
.btn {
width: 100px;
margin-right: 10px;
}
}
}
::v-deep .u-count-down__text {
font-weight: 700;
color: #1989fa;
}
</style>