提交 7b5fff92 authored 作者: lihuihui's avatar lihuihui
...@@ -28,7 +28,7 @@ export default { ...@@ -28,7 +28,7 @@ export default {
}, },
computed: { computed: {
questionTypeName() { questionTypeName() {
const map = { 1: '单选题', 2: '多选题', 5: '案例题', 6: '判断题' } const map = { 1: '单选题', 2: '多选题', 3: '问答题', 5: '案例题', 6: '判断题', 7: '实操题', 8: '情景题' }
return map[this.data.question_type] return map[this.data.question_type]
} }
}, },
......
...@@ -19,12 +19,13 @@ ...@@ -19,12 +19,13 @@
:index="index" :index="index"
:list="questionList" :list="questionList"
:data="currentExam" :data="currentExam"
@change="handlePageChange" @page-change="handlePageChange"
></question-numbers> ></question-numbers>
</div> </div>
</div> </div>
<div class="foot" id="foot-h"> <div class="foot" id="foot-h">
<div class="exam-btn"> <div class="exam-btn">
<div class="confirm" @click="showResult">确认答案</div>
<div @click="prevQuestion">上一题</div> <div @click="prevQuestion">上一题</div>
<div @click="nextQuestion">下一题</div> <div @click="nextQuestion">下一题</div>
</div> </div>
...@@ -37,8 +38,9 @@ ...@@ -37,8 +38,9 @@
<div :class="currentItem.sign ? 'icon active' : 'icon'"></div> <div :class="currentItem.sign ? 'icon active' : 'icon'"></div>
<div class="txt">{{ currentItem.sign ? '已标记' : '标记' }}</div> <div class="txt">{{ currentItem.sign ? '已标记' : '标记' }}</div>
</div> </div>
<div class="del-btn" v-if="hasDeleteBtn">删除</div>
<div class="end-exam-btn"> <div class="end-exam-btn">
<div class="btn" v-if="hasSubmitBtn && !disabled" @click="submitExam">交卷</div> <div class="btn" v-if="hasSubmitBtn && !disabled" @click="submitExam">{{ submitButtonText }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -54,11 +56,14 @@ export default { ...@@ -54,11 +56,14 @@ export default {
components: { questionList, questionNumbers }, components: { questionList, questionNumbers },
props: { props: {
title: { type: String }, title: { type: String },
hasMark: { type: Boolean, default: true }, hasMark: { type: Boolean, default: true }, // 标记
hasCollect: { type: Boolean, default: true }, hasCollect: { type: Boolean, default: true }, // 收藏
hasSubmitBtn: { type: Boolean, default: true }, hasSubmitBtn: { type: Boolean, default: true }, // 提交按钮
hasCountDown: { type: Boolean, default: true }, hasDeleteBtn: { type: Boolean, default: false }, // 删除按钮
data: { type: Object, default: () => {} } hasCountDown: { type: Boolean, default: true }, // 计时
data: { type: Object, default: () => {} },
questionItems: { type: Array, default: () => [] },
submitButtonText: { type: String, default: '交卷' } // 提交按钮显示的文字
}, },
data() { data() {
return { return {
...@@ -87,6 +92,10 @@ export default { ...@@ -87,6 +92,10 @@ export default {
deep: true, deep: true,
immediate: true, immediate: true,
handler(value) { handler(value) {
if (this.questionItems.length) {
this.questionList = this.questionItems
return
}
if (value) { if (value) {
const { status } = value const { status } = value
this.disabled = ['1', '2'].includes(status) this.disabled = ['1', '2'].includes(status)
...@@ -94,6 +103,9 @@ export default { ...@@ -94,6 +103,9 @@ export default {
this.genQuestions(value) this.genQuestions(value)
} }
} }
},
index(value) {
this.hasResult = this.currentExam.hasResult
} }
}, },
beforeDestroy() { beforeDestroy() {
...@@ -136,14 +148,21 @@ export default { ...@@ -136,14 +148,21 @@ export default {
} }
return result return result
}, },
// 确认答案
showResult() {
this.hasResult = true
this.questionList[this.index].hasResult = true
},
// 下一题 // 下一题
nextQuestion() { nextQuestion() {
const totalNumber = this.questionList.length const totalNumber = this.questionList.length
if (this.index + 1 < totalNumber) this.index++ if (this.index + 1 < totalNumber) this.index++
this.$emit('page-change', this.currentExam)
}, },
// 上一题 // 上一题
prevQuestion() { prevQuestion() {
if (this.index !== 0) this.index-- if (this.index !== 0) this.index--
this.$emit('page-change', this.currentExam)
}, },
handlePageChange(index) { handlePageChange(index) {
this.index = index this.index = index
...@@ -173,11 +192,10 @@ export default { ...@@ -173,11 +192,10 @@ export default {
}, },
// 组装试题数据 // 组装试题数据
genQuestions(data) { genQuestions(data) {
const { questions = [], answers = {} } = data const { questions, answers = {} } = data
if (!questions) return [] if (!questions) return []
this.questionList = questions.question_items.reduce((result, question) => { this.questionList = questions.question_items.reduce((result, question) => {
question.question_list.forEach(list => { question.question_list.forEach(list => {
console.log(list)
list = list.map(item => { list = list.map(item => {
let userAnswers = [] let userAnswers = []
let sign = false let sign = false
...@@ -316,6 +334,19 @@ export default { ...@@ -316,6 +334,19 @@ export default {
.rigth-btn { .rigth-btn {
display: flex; display: flex;
margin-left: auto; margin-left: auto;
.del-btn {
margin-top: 10px;
width: 100px;
height: 40px;
border-radius: 4px;
border: 1px solid #cccccc;
line-height: 40px;
font-size: 14px;
font-weight: bold;
color: #999999;
text-align: center;
margin-right: 30px;
}
.end-exam-btn { .end-exam-btn {
background: #fff; background: #fff;
height: 62px; height: 62px;
...@@ -325,6 +356,7 @@ export default { ...@@ -325,6 +356,7 @@ export default {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
.btn { .btn {
cursor: pointer; cursor: pointer;
width: 200px; width: 200px;
......
...@@ -88,7 +88,7 @@ export default { ...@@ -88,7 +88,7 @@ export default {
} }
}, },
handleClick(data) { handleClick(data) {
this.$emit('change', data.index, data) this.$emit('page-change', data.index, data)
} }
} }
} }
......
<template> <template>
<div> <exam-card
<div class="answer-box"> :title="title"
<div class="head" id="head-h"> :questionItems="questionItems"
<el-button icon="el-icon-arrow-left" circle @click="$router.back()"></el-button> :hasMark="false"
<div class="title">{{ $route.query.type == 1 ? '我的错题' : $route.query.type == 2 ? '收藏试题' : '已做试题' }}</div> :hasDeleteBtn="true"
<div class="right"> :hasCountDown="false"
<div class="count">{{ questionParams.question.sheet_time }}</div> submitButtonText="清空记录,重新答题"
</div> @submitExam="handleSubmit"
</div> @page-change="handlePageChange"
<div class="exam-main" :style="{height: this.contentHeight + 'px'}"> v-if="Object.keys(data).length"
<div class="left"> ></exam-card>
<question
v-if="Object.keys(questionParams.question).length"
:contentHeight="contentHeight"
:questionParams="questionParams"
ref="confirmBtn"
></question>
</div>
<div class="right">
<answer-card
:questionParams="questionParams"
@cardChangeQuention="goAppointQuestion"
></answer-card>
</div>
</div>
<div class="foot" id="foot-h">
<div class="exam-btn">
<div class="confirm"
v-if="this.questionParams.question.answer_count > 1 && $route.query.type != 3"
@click="confirmBtn"
>
确认答案
</div>
<div
@click="changeIndex('prev')"
:class="this.questionParams.questionIndex !== 0 ? 'active' : ''"
>上一题</div>
<div
:class="questionParams.questionIndex + 1 !== questionParams.question.total_question_count ? 'active' : ''"
@click="changeIndex('next')"
>下一题</div>
</div>
<div class="rigth-btn">
<div class="sign" @click="collectQuestion" v-if="$route.query.type != 2">
<div :class="questionParams.question.is_collection ? 'icon active' : 'icon'"></div>
<div class="txt">{{ questionParams.question.is_collection ? '已收藏' : '收藏' }}</div>
</div>
<div class="del-btn" @click="deleteQuestion">删除</div>
<div class="end-exam-btn" v-if="$route.query.type != 3">
<div class="btn" @click="clearQuestion">清空记录,重新答题</div>
</div>
</div>
</div>
</div>
</div>
</template> </template>
<script> <script>
import * as api from '@/api/exam.js' import * as api from '@/api/exam.js'
import answerCard from './components/answerCard.vue' import ExamCard from '@/components/exam/examCard.vue'
import question from './components/question.vue'
export default { export default {
components: { components: { ExamCard },
question,
answerCard
},
data() { data() {
return { return {
// 设置页面高 data: {},
contentHeight: 0, page: 0
// 原数据
questionData: [],
// 存题
container: [],
// 过滤后的数据
afterChangeData: {},
questionParams: {
// 用户选择的选项 --- 提交后台的数据
answerRecord: {},
// 所有题 和题的信息
question: {},
questionIndex: 0,
card: {}
// beforeData: {}
}
} }
}, },
mounted() { computed: {
// 赋值页面高度 title() {
this.setPageHeight() return this.$route.query.type === '1' ? '错题集合' : '收藏试题'
this.initData()
},
methods: {
setPageHeight() {
this.contentHeight = parseInt(document.documentElement.clientHeight - (this.getDom('head-h').offsetHeight + this.getDom('foot-h').offsetHeight))
},
// 删除试题
deleteQuestion() {
this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
const param = {
question_id: this.questionParams.question.id,
type: this.$route.query.type
}
api
.deleteQuestion(param)
.then(response => {
this.$router.go(0)
})
.finally(() => {
})
},
// 初始化
initData() {
this.getCardAll()
this.goAppointQuestion(this.$route.query.index - 1)
this.questionParams.questionIndex = 0
window.localStorage.answerRecord
? this.questionParams.answerRecord = JSON.parse(window.localStorage.answerRecord)
: this.questionParams.answerRecord = {}
},
confirmBtn() {
this.$refs.confirmBtn.answerConfirm()
},
getDom(id) {
return document.getElementById(id)
},
// 收藏试题
collectQuestion() {
const data = this.questionParams.question
console.log(data)
data.is_collection
? this.removeCall(data.id, () => {
data.is_collection = false
})
: this.addCall(data.id, () => {
data.is_collection = true
})
},
addCall(id, call) {
api
.addCollection({ question_id: id })
.then(response => {
call(response.list)
})
.finally(() => {
})
},
removeCall(id, call) {
api
.deleteCollection({ question_id: id })
.then(response => {
call(response.list)
})
.finally(() => {
})
}, },
// 改变数据 questionItems() {
setData(list) { return this.data.list.map(groups => {
return list.map(pList => { const [first = {}] = groups
return pList.map(list => { return { question_item_id: '', question_type: first.question_type, question_list: groups, hasResult: false }
const type = {
1: '单选题',
2: '多选题',
5: '案例题',
6: '判断题'
}
const typeTotal = {
3: 'total',
1: 'error_total',
2: 'collection_total'
}
const data = {
q_order: list.num,
question_item_type: list.question_type,
content: list.question_content,
id: list.question_id,
options: list.question_options,
question_item_title: type[parseInt(list.question_type)],
total_question_count: this.questionData[typeTotal[parseInt(this.$route.query.type)]],
question_analysis: list.question_analysis,
user_answer: list.user_answer,
is_collection: list.is_collection,
answer_count: list.answer_count,
common_content: list.common_content,
sheet_time: list.sheet_time,
rightKey: list.question_answer
}
const findAB = data.question_answer = list.question_answer.map(i => {
const findIndex = list.question_options.findIndex(opt => { return opt.id === i })
return this.A_Z()[findIndex]
})
data.question_answer = findAB.sort().toString().replace(new RegExp(',', 'g'), '')
return data
})
}) })
}, }
},
beforeMount() {
// 获取考卷 // 获取考卷
getTopic(page, call) { this.getTopic()
},
methods: {
// 获取考卷
getTopic() {
const query = this.$route.query
const param = { const param = {
type: this.$route.query.type, type: query.type,
question_type: this.$route.query.qType, question_type: query.qType,
page: page, page: this.page,
page_size: 20 page_size: 20
} }
api api.getMyQuestion(param).then(response => {
.getMyQuestion(param) this.data = response
.then(response => {
this.questionData = response
call(response.list)
})
.finally(() => {
})
},
// 获取答题卡所有题
getCardAll() {
const param = {
type: parseInt(this.$route.query.type) === 3 ? 0 : this.$route.query.type,
question_type: this.$route.query.qType
}
api
.getAllQuestion(param)
.then(response => {
if (response.list[0].question) {
this.questionParams.card = this.setCardData(response.list)
} else {
this.questionParams.card = response.list
}
})
.finally(() => {
})
},
setCardData(list) {
return list.map(item => {
item.question = JSON.parse(item.question)
return item
}) })
}, },
// ABC // 缓存答案
A_Z() { handleCache(data) {
const result = [] const params = this.genSubmitData(data)
for (let i = 0; i < 26; i++) { api.setCourseCache(Object.assign(params, { status: 0 }))
result.push(String.fromCharCode(65 + i))
}
return result
}, },
// 点击上一题下一题 答题卡序号 // 清空
changeData() { handleSubmit(data) {
let datas = [] const params = this.genSubmitData(data)
this.questionData.list.map(list => { api.setCourseCache(Object.assign(params, { status: 1 })).then(res => {
const findData = list.find(item => { this.$router.replace({
return item.q_order === this.questionParams.questionIndex + 1 path: '/course/chapter/result',
query: Object.assign({}, this.$route.query, { type: 2 })
}) })
if (findData) {
datas = list
return false
}
}) })
this.questionParams.question = datas
},
// 进入指定的题
goAppointQuestion(n) {
this.container = []
this.questionData.list = []
const page = parseInt(n / 20)
if (page === 0) {
this.getTopic(page + 1, data => {
this.container = this.setData(data)
this.questionData.list = this.container
this.questionParams.questionIndex = parseInt(n)
this.changeData()
})
} else {
this.getTopic(page, data => {
this.container = this.setData(data)
this.questionData.list = this.container
})
this.getTopic(page + 1, data => {
this.addCont(data, 1)
this.questionData.list = this.container
this.questionParams.questionIndex = parseInt(n)
this.changeData()
})
}
}, },
// 改变题序 handlePageChange(data) {
changeIndex(type) { console.log(data)
if (type === 'prev') {
if (this.questionParams.questionIndex > 0) {
this.questionParams.questionIndex--
const isData = this.questionData.list.findIndex(i => { return i.q_order === this.questionParams.questionIndex + 1 })
!isData && (this.supplyRequest())
}
} else {
if (parseInt(this.questionParams.questionIndex + 1) !== parseInt(this.questionParams.question.total_question_count)) {
this.questionParams.questionIndex++
const isData = this.questionData.list.find(i => { return i.q_order === this.questionParams.questionIndex + 2 })
!isData && (this.supplyRequest(1))
}
}
}, },
// 加载部分试题 // 组装提交数据
supplyRequest(n) { genSubmitData(questionList) {
// const loading = this.$loading({ const answers = {}
// lock: true, questionList.forEach(item => {
// text: 'Loading', if (!answers[item.question_item_id]) {
// spinner: 'el-icon-loading', answers[item.question_item_id] = {}
// background: 'rgba(0, 0, 0, 0.7)'
// })
this.getTopic(parseInt((n ? this.questionParams.questionIndex + 2 : this.questionParams.questionIndex - 2) / 20) + 1, data => {
if (this.container.length >= 40) {
n ? this.container.splice(0, 20) : this.container.splice(20, 20)
this.addCont(data, n)
} else {
this.addCont(data, n)
} }
this.questionData.list = this.container item.question_list.forEach(cItem => {
this.changeData() answers[item.question_item_id][cItem.id] = {
// loading.close() sign: cItem.sign ? cItem.sign : false,
}) answers: cItem.user_answer
}, }
addCont(data, n) { })
const changeData = n ? data : data.reverse()
this.setData(changeData).map(item => {
n ? this.container.push(item) : this.container.unshift(item)
}) })
}, return {
// 缓存 提交 type: 1,
handlePapers(n) { sheet_id: this.data.id,
const answerData = {} status: 0,
for (const data in this.questionParams.answerRecord) { answers: JSON.stringify(answers),
answerData[data] = this.questionParams.answerRecord[data].answer duration: 0
}
const param = {
type: this.$route.query.type,
question_type: this.$route.query.qType,
answer: JSON.stringify(answerData)
} }
window.localStorage.answerRecord = JSON.stringify(this.questionParams.answerRecord)
this.chcheReq(param, () => {})
},
// 清除所有答案 重新答题
clearQuestion() {
const param = {
type: this.$route.query.type,
question_type: this.$route.query.qType,
clear: 1
}
this.chcheReq(param, () => {
this.questionParams.questionIndex = 0
window.localStorage.removeItem('answerRecord')
this.initData()
this.$router.go(0)
})
},
chcheReq(param, call) {
api
.setMyCache(param)
.then(response => {
call()
})
.finally(() => {
})
}
},
computed: {
changeQuestionIndex() {
return this.questionParams.questionIndex
}
},
watch: {
// 监听题的变化
changeQuestionIndex(newV, oldV) {
this.changeData()
parseInt(this.$route.query.type) !== 3 && (this.handlePapers())
} }
} }
} }
</script> </script>
<style lang="scss" scoped>
.answer-box{
width: 100%;
height: 100%;
// background: #f9f9f9;
.head{
border-bottom: 1px solid #ccc;
height: 80px;
background: #FFFFFF;
display: flex;
align-items: center;
padding-left: 40px;
.title{
padding-left: 20px;
font-size: 24px;
font-weight: bold;
color: #222222;
line-height: 80px;
}
.right{
width: 260px;
margin-left: auto;
display: flex;
justify-content: space-around;
align-items: center;
.count{
font-size: 18px;
font-weight: bold;
color: #222222;
}
.time{
display: flex;
.icon{
width: 23px;
height: 23px;
// background: url(../../assets/images/tick.png);
background-size:100% 100%;
}
.mun{
font-size: 18px;
font-weight: bold;
color: #222222;
line-height: 25px;
margin-left: 10px;
}
}
}
}
.exam-main{
display: flex;
.left{
background: #fff;
flex: 1;
padding: 10px 20px 0 53px;
overflow-y: scroll;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
.right{
border-left: 1px solid #ccc;
position: relative;
width: 220px;
background: #fff;
padding: 0 20px;
overflow-y: scroll;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
}
.foot{
border-top: 1px solid #ccc;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 60px;
background: #FFFFFF;
display: flex;
align-items: center;
.exam-btn{
display: flex;
padding-left: 40px;
.confirm{
width: 140px;
height: 40px;
background: #C01540;
border-radius: 4px;
font-size: 14px;
font-weight: bold;
color: #FFFFFF;
line-height: 40px;
text-align: center;
}
cursor: pointer;
div{
width: 100px;
height: 40px;
border-radius: 4px;
border: 1px solid #CCCCCC;
font-size: 14px;
font-weight: bold;
color: #999999;
line-height: 40px;
text-align: center;
margin-right: 20px;
&.active{
background: #C01540;
border-radius: 4px;
color: #fff;
}
}
}
.rigth-btn{
display: flex;
margin-left: auto;
.del-btn{
margin-top: 10px;
width: 100px;
height: 40px;
border-radius: 4px;
border: 1px solid #CCCCCC;
line-height: 40px;
font-size: 14px;
font-weight: bold;
color: #999999;
text-align: center;
margin-right: 30px;
}
.end-exam-btn{
background: #fff;
height: 62px;
margin-top: -2px;
border-left: 1px solid #ccc;
width: 260px;
display: flex;
justify-content: center;
align-items: center;
.btn{
cursor: pointer;
width: 200px;
height: 40px;
background: #c01540;
border-radius: 4px;
font-size: 14px;
font-weight: bold;
color: #fff;
line-height: 40px;
text-align: center;
}
}
.sign{
margin-right: 20px;
margin-top: 8px;
.icon{
margin: 0 auto;
width: 24px;
height: 24px;
background: url(@/assets/images/collection.png);
background-size:100% 100%;
&.active{
background: url(@/assets/images/collection2.png);
background-size:100% 100%;
}
}
.txt{
font-size: 14px;
color: #CCCCCC;
line-height: 20px;
margin-top: 2px;
}
}
}
}
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论