提交 33707f35 authored 作者: lihuihui's avatar lihuihui

错题集对答题

上级 e36aaa7a
...@@ -28,32 +28,24 @@ export function setRoles(params) { ...@@ -28,32 +28,24 @@ export function setRoles(params) {
} }
/** /**
* 获取课程列表 * 获取我的已做试题
*/ */
export function getCourseList() { export function getMyQuestion(params) {
return httpRequest.get('/api/zy/v2/education/courses/list') return httpRequest.get('/api/zy/v2/examination/my-question', { params }, {
headers: { 'Content-Type': 'multipart/form-data' }
})
} }
/** /**
* 获取课程详情 * 获取我的所有试题
* @param {string} courseId 课程ID
*/ */
export function getCourse(courseId) { export function getAllQuestion(params) {
return httpRequest.get(`/api/zy/v2/education/courses/${courseId}`) return httpRequest.get('/api/zy/v2/examination/my-question-all', { params })
} }
/** /**
* 获取课程知识点 * 缓存错题集
* @param {string} courseId 课程ID */
*/ export function setMyCache(params) {
export function getCourseTagList(courseId) { return httpRequest.post('/api/zy/v2/examination/cache-question', params)
return httpRequest.get(`/api/zy/v2/education/tag/tree/${courseId}`)
}
/**
* 知识点详情
* @param {string} tagId 知识点ID
*/
export function getCourseTag(tagId) {
return httpRequest.get(`/api/zy/v2/education/tag/${tagId}`)
} }
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
@on-remove="handleRemove" @on-remove="handleRemove"
@on-addCollection="handleAddCollection" @on-addCollection="handleAddCollection"
@on-removeCollection="handleRemoveCollection" @on-removeCollection="handleRemoveCollection"
@on-goDetails="goDetails(item.num)"
></my-question-list-item> ></my-question-list-item>
</template> </template>
<div class="empty" v-else>暂无试题</div> <div class="empty" v-else>暂无试题</div>
...@@ -81,6 +82,17 @@ export default { ...@@ -81,6 +82,17 @@ export default {
} }
}, },
methods: { methods: {
// 跳详情
goDetails(i) {
this.$router.push({
path: '/my/questions/details',
query: {
type: this.requestParams.type,
qType: this.questionType,
index: i
}
})
},
// 获取试题列表 // 获取试题列表
getMyQuestions() { getMyQuestions() {
this.loaded = false this.loaded = false
......
<template> <template>
<div class="my-question-list-item"> <div class="my-question-list-item" @click="goDetails">
<el-checkbox v-model="data.checked"></el-checkbox> <el-checkbox v-model="data.checked"></el-checkbox>
<div class="badge" :class="`questiont-type_${data.question_type}`">{{ questionTypeName }}</div> <div class="badge" :class="`questiont-type_${data.question_type}`">{{ questionTypeName }}</div>
<div class="name" v-html="data.question_content"></div> <div class="name" v-html="data.question_content"></div>
...@@ -35,6 +35,9 @@ export default { ...@@ -35,6 +35,9 @@ export default {
methods: { methods: {
toggleCollection() { toggleCollection() {
this.data.is_collection ? this.$emit('on-removeCollection', this.data) : this.$emit('on-addCollection', this.data) this.data.is_collection ? this.$emit('on-removeCollection', this.data) : this.$emit('on-addCollection', this.data)
},
goDetails() {
this.$emit('on-goDetails')
} }
} }
} }
......
<template>
<div>
<div class="order-num">
<ul>
<template v-for="(item, index) in questionParams.card">
<li :class="isClass(item.answer)" :key="index" @click="goQuestion(index)">
<div class="circle">{{ index + 1 }}</div>
<div class="txt">{{ questionType(item.question_type) }}</div>
</li>
</template>
</ul>
</div>
<ul class="tips-box">
<li>
<div class="circle1"></div>
<div class="txt">答对</div>
</li>
<li>
<div class="circle2"></div>
<div class="txt">答错</div>
</li>
<li>
<div class="circle3"></div>
<div class="txt">未答</div>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
questionParams: { type: Object, default: () => {} }
},
mounted() {
this.msgCenter.$on('monitoringChanges', this.monitoringChanges)
},
computed: {
questionType() {
return (t) => {
const type = {
1: '单选题',
2: '多选题',
5: '案例题',
6: '判断题'
}
return type[t]
}
},
changeQuestionIndex() {
return this.questionParams.answerRecord
},
isClass() {
return (i) => {
const tClass = {
0: 'stu3',
1: 'stu1',
2: 'stu2'
}
return tClass[parseInt(i)]
}
}
},
methods: {
monitoringChanges(id) {
this.changeCardStatus(id)
this.$forceUpdate()
},
goQuestion(n) {
this.$emit('cardChangeQuention', n)
},
changeCardStatus(id) {
const dataArr1 = this.questionParams.question.rightKey
const dataArr2 = this.questionParams.answerRecord[id] ? this.questionParams.answerRecord[id].answer : []
const findData = this.questionParams.card.find(item => { return item.question_id === id })
if (this.scalarArrayEquals(dataArr1, dataArr2)) {
findData.answer = 1
} else {
dataArr2.length !== 0 && (findData.answer = 2)
}
this.$forceUpdate()
},
scalarArrayEquals(arr1, arr2) {
if (Array.isArray(arr1) && Array.isArray(arr2)) {
if (arr1.sort().toString() === arr2.sort().toString()) {
return true
}
}
return false
}
},
watch: {
changeQuestionIndex(newV, oldV) {
this.$forceUpdate()
}
}
}
</script>
<style lang="scss" scoped>
.order-num{
padding-bottom: 90px;
ul{
display: flex;
list-style: none;
padding: 0;
margin: 0;
flex-wrap: wrap;
li{
cursor: pointer;
position: relative;
margin-right: 10px;
margin-bottom: 10px;
.circle{
border-radius: 50px;
width: 24px;
height: 24px;
border: 1px solid #CCCCCC;
font-size: 12px;
color: #666666;
line-height: 24px;
text-align: center;
margin: 0 auto;
box-sizing: border-box;
}
.txt{
font-size: 12px;
margin-top: 5px;
}
&:nth-child(5n+5){
margin-right: 0;
}
&.stu1{
.circle{
border: 2px solid #0FC118;
line-height: 22px;
}
}
&.stu2{
.circle{
border: 2px solid #C01540;
line-height: 22px;
}
}
&.stu3{
.circle{
color: #fff;
background: #999999;
}
}
}
}
}
.flag-tips{
width: 260px;
position: fixed;
bottom: 60px;
right:0;
display: flex;
justify-content: space-around;
padding: 15px 0 10px;
background: #fff;
margin: 0;
list-style: none;
li{
.circle1{
width: 24px;
height: 24px;
background: #EEEEEE;
border: 1px solid #CCCCCC;
border-radius: 50%;
}
.circle1{
width: 24px;
height: 24px;
border: 1px solid #CCCCCC;
border-radius: 50%;
}
.circle2{
width: 24px;
height: 24px;
border: 1px solid #CCCCCC;
border-radius: 50%;
}
.circle3{
width: 24px;
height: 24px;
border: 2px solid #0FC118;
border-radius: 50%;
}
.circle4{
position: relative;
width: 24px;
height: 24px;
border: 1px solid #CCCCCC;
border-radius: 50%;
&::after{
content: '';
position: absolute;
top: -1px;
right: -1px;
width: 4px;
height: 4px;
background: #C01540;
border-radius: 50%;
}
}
.txt{
margin-top: 5px;
font-size: 12px;
color: #CCCCCC;
line-height: 17px;
}
}
}
.flag-tips{
width: 260px;
position: fixed;
bottom: 60px;
right:0;
display: flex;
justify-content: space-around;
padding: 15px 0 10px;
background: #fff;
margin: 0;
list-style: none;
li{
.circle1{
width: 24px;
height: 24px;
background: #999;
border: 1px solid #999;
border-radius: 50%;
}
.circle2{
width: 24px;
height: 24px;
border: 1px solid #CCCCCC;
border-radius: 50%;
}
.circle3{
width: 24px;
height: 24px;
border: 2px solid #0FC118;
background: rgba(15, 193, 24, 0.1);
border-radius: 50%;
}
.circle4{
position: relative;
width: 24px;
height: 24px;
border: 1px solid #CCCCCC;
border-radius: 50%;
&::after{
content: '';
position: absolute;
top: -1px;
right: -1px;
width: 4px;
height: 4px;
background: #C01540;
border-radius: 50%;
}
}
.txt{
margin-top: 5px;
font-size: 12px;
color: #CCCCCC;
line-height: 17px;
}
}
}
.tips-box{
width: 260px;
position: fixed;
bottom: 60px;
right:0;
display: flex;
justify-content: space-around;
padding: 15px 0 10px;
background: #fff;
margin: 0;
list-style: none;
li{
&:nth-child(2){
margin: 0 50px;
}
.circle1{
width: 24px;
height: 24px;
background: #fff;
border: 2px solid #0FC118;
border-radius: 50%;
box-sizing: border-box;
}
.circle2{
width: 24px;
height: 24px;
border: 2px solid #C01540;
border-radius: 50%;
box-sizing: border-box;
}
.circle3{
width: 24px;
height: 24px;
background: #999999;
border-radius: 50%;
}
.circle4{
position: relative;
width: 24px;
height: 24px;
border: 1px solid #CCCCCC;
border-radius: 50%;
&::after{
content: '';
position: absolute;
top: -1px;
right: -1px;
width: 4px;
height: 4px;
background: #C01540;
border-radius: 50%;
}
}
.txt{
margin-top: 5px;
font-size: 12px;
color: #CCCCCC;
line-height: 17px;
}
}
}
</style>
<template>
<div>
<!-- 单选多选判断题(题目描述dom结构一样,只那选项区分) -->
<template v-if="questionData.question_item_type == 1 || questionData.question_item_type == 2 || questionData.question_item_type == 6">
<div class="title-type">
<div class="type">{{ questionData.question_item_title }}</div>
<div class="num">{{ questionData.q_order }}/{{ questionData.total_question_count }}</div>
</div>
<div class="title">
<div class="num">{{ questionData.q_order }}.</div><div class="des" v-html="questionData.content"></div>
</div>
<ul :class="questionData.question_item_type == 2 ? 'check-option' : 'radio-option'">
<template v-for="(item, index) in questionData.options">
<li
:key="index"
@click="changeOptions(questionData.question_item_type, questionData.id, item.id)"
:class="isClass(questionData.id, item.id)"
>
<div class="icon"></div>
<div class="txt">{{A_Z()[index]}}. {{item.option}}</div>
</li>
</template>
</ul>
</template>
<!-- 解析 -->
<div class="analysis" v-if="!isAnswer && questionData.question_item_type != 5">
<div class="title">答案解析</div>
<div class="analy-mian">
<div class="txt1">正确答案:{{ questionData.question_answer }}</div>
<div class="txt1">您的答案:{{ myAnswer() }}</div>
<div class="explain-box">
<div>解析:</div>
<div class="w" v-html="questionData.question_analysis"></div>
</div>
</div>
</div>
<!-- 复合题 -->
<template v-if="questionData.question_item_type == 5">
<div class="title-type">
<div class="type">{{ questionData.question_item_title }}</div>
<div class="num">{{ questionData.q_order }}/{{ questionData.total_question_count }}</div>
</div>
<div class="case-que">
<div class="flex">
<div class="stem" v-html="questionData.common_content"></div>
<!-- 解析 -->
<div class="analysis" v-if="!isAnswer">
<div class="title">答案解析</div>
<div class="analy-mian">
<div class="txt1">正确答案:{{ questionData.question_answer }}</div>
<div class="txt1">您的答案:{{ myAnswer() }}</div>
<div class="explain-box">
<div>解析:</div>
<div class="w" v-html="questionData.question_analysis"></div>
</div>
</div>
</div>
</div>
<ul class="topics" :style="{height: contentHeight - 60 + 'px'}">
<!-- <template v-for="item in questionData.list"> -->
<!-- <template v-if="questionData.group_id === item[0].group_id"> -->
<!-- <template v-for="(listItem, index) in item"> -->
<li>
<div class="title">
<div class="num">{{ questionData.q_order }}.</div><div class="des" v-html="questionData.content"></div>
</div>
<ul :class="questionData.answer_count > 1 ? 'check-option' : 'radio-option'"><!-- radio-option check-option -->
<!-- <template v-if="listItem.id === questionData.id"> -->
<template v-for="(opt, oIndex) in questionData.options">
<li
:id="opt.id"
:key="'c' + oIndex"
@click="changeOptions(questionData.answer_count > 1 ? 2 : 1, questionData.id, opt.id)"
:class="isClass(questionData.id, opt.id)"
>
<div class="icon"></div>
<div class="txt">{{A_Z()[oIndex]}}. {{opt.option}}</div>
</li>
</template>
<!-- </template> -->
</ul>
</li>
<!-- </template> -->
<!-- </template> -->
<!-- </template> -->
</ul>
</div>
</template>
</div>
</template>
<script>
export default {
props: {
contentHeight: { type: Number, default: () => {} },
questionParams: { type: Object, default: () => {} }
},
data() {
return {
questionData: {},
isAnswer: true,
currentCheck: {}
}
},
created() {
this.questionData = this.questionParams.question
},
mounted() {
},
methods: {
answerConfirm() {
const key = Object.keys(this.currentCheck)
const value = Object.values(this.currentCheck)
this.questionParams.answerRecord[key[0]] = value[0]
this.isChangeAnswer()
// console.log(this.questionParams.answerRecord)
// console.log(key, value)
},
// 自己选择的答案
myAnswer() {
const selectAnswer = this.questionParams.answerRecord
const currentData = this.questionData
return selectAnswer[currentData.id]
? selectAnswer[currentData.id]
? (() => {
const arr = []
selectAnswer[currentData.id].answer.map(i => {
const findIndex = currentData.options.findIndex(d => { return i === d.id })
arr.push(this.A_Z()[findIndex])
})
return arr.sort().toString().replace(new RegExp(',', 'g'), '')
})()
: ''
: ''
},
// 选项选择
changeOptions(type, pId, optId) {
if (this.isAnswer) {
if (parseInt(type) !== 2) {
this.questionParams.answerRecord[pId] = {
answer: [optId]
}
this.isChangeAnswer()
} else {
this.currentCheck[pId]
? (() => {
const optChack = this.currentCheck[pId].answer.findIndex(id => { return id === optId })
optChack === -1
? this.currentCheck[pId].answer.push(optId)
: this.currentCheck[pId].answer.splice(optChack, 1)
})()
: this.currentCheck[pId] = {
answer: [optId]
}
}
}
this.$forceUpdate()
},
isChangeAnswer() {
this.questionParams.answerRecord[this.questionData.id]
? this.isAnswer = false
: this.isAnswer = true
this.msgCenter.$emit('monitoringChanges', this.questionData.id)
},
signCallback() {
const pId = this.questionData.question_item_id
const cId = this.questionData.id
let isSign = false
this.questionParams.answerRecord[pId]
? this.questionParams.answerRecord[pId][cId]
? isSign = this.questionParams.answerRecord[pId][cId].sign
: isSign = false
: isSign = false
this.$emit('isSign', isSign)
},
// ABCD
A_Z() {
const result = []
for (let i = 0; i < 26; i++) {
result.push(String.fromCharCode(65 + i))
}
return result
}
},
computed: {
changeQuestionIndex() {
return this.questionParams.questionIndex
},
isClass() {
return (pId, oId) => {
let active = ''
if (this.questionParams.answerRecord[pId]) {
const findData = this.questionParams.answerRecord[pId].answer.find(id => { return id === oId })
findData && (active = 'active')
} else {
Object.values(this.currentCheck).length !== 0 && (() => {
const findData = this.currentCheck[pId].answer.find(id => { return id === oId })
findData && (active = 'active')
})()
}
return active
}
}
},
watch: {
changeQuestionIndex(newV, oldV) {
this.currentCheck = {}
this.questionData = this.questionParams.question
this.isChangeAnswer()
this.$forceUpdate()
}
}
}
</script>
<style lang="scss" scoped>
.title-type{
width: 100%;
height: 45px;
border-bottom:1px solid #ccc;
display: flex;
align-items: center;
.type{
font-size: 18px;
color: #222222;
}
.num{
margin-left: auto;
font-size: 18px;
color: #222222;
}
}
.title{
font-size: 18px;
font-weight: bold;
color: #222222;
line-height: 25px;
display: flex;
.num{
font-size: 32px;
font-weight: bold;
color: #222222;
line-height: 45px;
margin-top: 5px;
}
.des{
margin-left: 5px;
padding-top: 18px;
&::v-deep p{
margin: 0;
}
}
}
.describe{
font-size: 18px;
color: #222222;
line-height: 25px;
margin-top: 20px;
}
.radio-option,.check-option{
padding: 24px 0 0 0;
margin: 0;
list-style: none;
li{
cursor: pointer;
margin-bottom: 20px;
display: flex;
// align-items: center;
.icon{
width: 18px;
height: 18px;
border: 1px solid #999999;
border-radius: 50%;
margin-top: 3px;
}
.txt{
width: 95%;
font-size: 18px;
color: #222222;
line-height: 28px;
margin-left: 10px;
}
&.active{
.icon{
width: 8px;
height: 8px;
border: 6px solid #C01540;
}
}
}
}
.check-option{
.icon{
border-radius: 3px !important;
}
}
.flex{
flex: 1;
}
.case-que{
display: flex;
.stem{
flex: 1;
font-size: 14px;
font-weight: bold;
color: #222222;
line-height: 28px;
margin-bottom: 20px;
}
.topics{
flex: 1;
margin: 0;
padding: 0 0 0 20px;
list-style: none;
overflow-y: scroll;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
li{
.title{
font-size: 18px;
font-weight: bold;
color: #222222;
line-height: 25px;
span{
font-size: 32px;
font-weight: bold;
color: #222222;
line-height: 45px;
}
}
}
}
}
.analysis{
.title{
font-size: 18px;
font-weight: bold;
color: #222222;
line-height: 25px;
}
.analy-mian{
padding-left: 27px;
.txt1{
margin-top: 10px;
font-size: 18px;
color: #222222;
line-height: 25px;
}
.explain-box{
display: flex;
margin-top: 10px;
flex-wrap: wrap;
div{
font-size: 18px;
font-weight: 400;
color: #222222;
line-height: 25px;
}
.w{
width: 89%;
}
}
}
}
</style>
<template>
<div>
<exam-topic :requestParam="$route.query" @goExamResult="goExamResult"></exam-topic>
</div>
</template>
<script>
export default {
mounted() {
},
methods: {
goExamResult(e) {
this.$router.replace({
path: '/mock/result',
query: e
})
}
},
metaInfo () {
return {
title: '答题',
meta: [
// { vmid: 'description', name: 'description', content: this.description }
]
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div>
<exam-end @cardChange="cardChange"></exam-end>
</div>
</template>
<script>
export default {
data() {
return {
questionsData: null,
requestData: null
}
},
metaInfo () {
return {
title: '成绩报告',
meta: [
// { vmid: 'description', name: 'description', content: this.description }
]
}
},
methods: {
cardChange(e) {
this.$router.push({
path: '/exam/answer',
query: e
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
...@@ -110,11 +110,6 @@ export default { ...@@ -110,11 +110,6 @@ export default {
let sec = parseInt(time) let sec = parseInt(time)
clearInterval(this.time.clearTime) clearInterval(this.time.clearTime)
this.time.clearTime = setInterval(() => { this.time.clearTime = setInterval(() => {
// if (this.requestParam.course_id) {
// this.time.examTimeText = this.secondToDate(sec)
// sec++
// } else {
// }
if (this.$route.query.id) { if (this.$route.query.id) {
this.time.examTimeText = '00:00:00' this.time.examTimeText = '00:00:00'
return false return false
......
<template>
<div class="comp-x">
<div class="mock-box">
<div class="top-tit">
<div class="left">考试时间:90分钟</div>
<!-- <div class="right">总分100分</div> -->
</div>
<div class="top-tit">
<div class="left">考试通过:80分</div>
<div class="right">总分:100分</div>
</div>
<div class="top-tit">
<div class="left new-w">试题类型:</div>
<div class="txt">单项选择题、多项选择题、判断题和
案例题,全部为客观题</div>
</div>
<div class="intr">考试说明:</div>
<div class="answer-type">
<div class="tit">1.模考目的:</div>
<div class="type">
<p>考核道路运输企业主要负责人和安全生产管理人员对安全生产管理知识掌握程度</p>
<!-- <p>单选题共1题</p>
<p>单选题共1题</p> -->
</div>
</div>
<div class="answer-type">
<div class="tit">2.考核范围:</div>
<div class="type">
<p>道路运输安全生产相关法律法规及标准规范、道路运输企业安全生产主体责任、道路运输企业安全管理知识、道路运输安全生产务实务等内容</p>
<!-- <p>单选题共1题</p>
<p>单选题共1题</p> -->
</div>
</div>
<div class="answer-type">
<div class="tit">3.模考试卷:</div>
<div class="type">
<p>道路运输安全生产相关法律法规及标准规范、道路运输企业安全生产主体责任、道路运输企业安全管理知识、道路运输安全生产务实务等内容</p>
<!-- <p>单选题共1题</p>
<p>单选题共1题</p> -->
</div>
</div>
<div class="role-tit">选择角色:</div>
<div class="describe">请认真选择角色,选定后,真题实战题型会针对角色为您匹配最准确的题型!</div>
<div class="sele-role">
<div @click="changeActive(1)" :class="roleChange == 1 ? 'btn active' : 'btn'">
<i></i>
<div class="txt">管理人员</div>
</div>
<div @click="changeActive(2)" :class="roleChange == 2 ? 'btn active' : 'btn'">
<i></i>
<div class="txt">安全人员</div>
</div>
</div>
<div class="new-btit">试卷组卷比例见下表:</div>
<img src="../../assets/images/table.png" alt="" class="table">
<div class="start-exam">
<div class="b" @click="setRole">开始考试</div>
</div>
<div class="exam_submit" v-if="isExamPop">
<div class="pop">
<div class="tit">真题实战</div>
<div class="txt">您上次未做完试题</div>
<div class="btn_box">
<div class="btn" @click="goAbilityExam(1)">重新答题</div>
<div class="btn btn2" @click="goAbilityExam(0)">继续答题</div>
</div>
</div>
</div>
<div class="exam_submit" v-if="isExamPopTo">
<div class="pop">
<div class="tit">真题实战</div>
<div class="txt">考试还未结束确定退出考试?</div>
<div class="btn_box">
<div class="btn" @click="isExamPopTo = false">退出考试</div>
<div class="btn btn2" @click="goAbilityExam(0)">继续考试</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import * as api from '@/api/courseExam.js'
import * as apiMy from '@/api/account.js'
export default {
metaInfo () {
return {
title: '真题实战'
}
},
data() {
return {
roleChange: 1,
isExamPop: false,
isExamPopTo: false
}
},
mounted() {
apiMy.getUser().then(res => {
const userRole = parseInt(res.student_info.role)
if (parseInt(userRole) !== 0) {
this.roleChange = userRole
}
})
if (window.localStorage.isExamEnd === 'true') {
this.abilityExam()
}
},
methods: {
changeActive(e) {
this.roleChange = e
},
abilityExam() {
const param = {
type: 2
}
api.getExamStatus(param).then(res => {
if (parseInt(res.status) === 0 || parseInt(res.status) === 3) {
this.isExamPopTo = true
}
})
},
goAbilityExam(n) {
window.localStorage.isExamEnd = true
this.$router.push({
path: '/mock/answer',
query: {
type: 2,
is_create: n,
papersUrl: 'zy/v2/examination/examination-papers'
}
})
},
setRole() {
// if (this.$store.state.isVip) {
// const param = {
// type: 2
// }
// api.setRole({ role: this.roleChange }).then(res => {
// if (res.code === 0) {
// api.getExamStatus(param).then(res => {
// if (parseInt(res.status) === 0 || parseInt(res.status === 3)) {
// this.isExamPop = true
// } else {
// this.goAbilityExam(1)
// }
// })
// }
// })
// return false
// }
// this.$router.push({
// path: '/payPage'
// })
const param = {
type: 2
}
api.setRole({ role: this.roleChange }).then(res => {
if (res.code === 0) {
api.getExamStatus(param).then(res => {
if (res.status === '0' || res.status === 0 || res.status === '3' || res.status === 3) {
this.isExamPop = true
} else {
this.goAbilityExam(1)
}
})
}
})
}
},
beforeMount() {
// 检测是否是付费用户
this.$store.dispatch('checkIsVip')
}
}
</script>
<style lang="scss" scoped>
.comp-x{
padding-bottom: env(safe-area-inset-bottom);
}
.mock-box{
padding: 0 0.4rem 1rem 0.4rem;
}
.top-tit{
padding-top: .3rem;
// border-bottom: 0.01rem solid #EEE;
display: flex;
// line-height: 1.1rem;
div{
font-weight: bold;
font-size: .3rem;
color: #222;
line-height: 100%;
}
.new-w{
width: 2.5rem;
}
.txt{
font-weight: normal;
line-height: .4rem;
}
.right{
margin-left: auto;
}
}
.intr{
line-height: .6rem;
font-weight: bold;
font-size: .3rem;
color: #222;
}
.answer-type{
padding-bottom: .2rem;
display: flex;
.tit{
font-size: .26rem;
color: #222;
line-height: .4rem;
}
p{
line-height: 100%;
font-size: .26rem;
color: #222;
line-height: .4rem;
width: 5rem;
// font-weight: bold;
// margin-bottom: .2rem;
}
}
.role-tit{
line-height: 100%;
font-size: .3rem;
color: #222;
font-weight: bold;
margin: .4rem 0 .18rem 0;
}
.describe{
font-size: .26rem;
color: #222;
}
.sele-role{
width: 5.09rem;
margin: .4rem auto 0 auto;
display: flex;
.btn:nth-child(2){
margin-left: auto;
}
.btn{
width: 1.76rem;
height: .8rem;
border: 0.01rem solid #F47885;
display: flex;
justify-content: center;
border-radius: .1rem;
align-items: center;
.txt{
font-size: .26rem;
color: #222;
font-weight: bold;
}
i{
width: .28rem;
height: .28rem;
margin-right: .1rem;
background: url('../../assets/images/radio2.png');
background-size: 100% 100%;
}
}
.btn.active{
background:#F47885;
.txt{
color: #fff;
}
i{
background: url('../../assets/images/radio.png');
background-size: 100% 100%;
}
}
}
.start-exam{
position: fixed;
bottom: 0;
left: 0;
width:7.5rem;
height:1rem;
background:rgba(255,255,255,1);
box-shadow:0 0 .06 0px rgba(0,0,0,0.05);
padding-bottom: env(safe-area-inset-bottom);
.b{
width:6.7rem;
height:.7rem;
background:#C62245;
border-radius:.12rem;
margin: .15rem auto;
text-align: center;
line-height: .7rem;
color: #fff;
font-size: .3rem;
}
}
.exam_submit{
position: fixed;
top: 0;
left: 0;
z-index: 999999;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.6);
.pop{
width: 5.9rem;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%,-50%);
background:rgba(255,255,255,1);
border-radius:.12rem;
padding: 0.4rem 0;
.tit{
font-weight:bold;
color:rgba(34,34,34,1);
font-size:.3rem;
text-align: center;
line-height: 100%;
}
.txt{
color:rgba(34,34,34,1);
font-size:.3rem;
text-align: center;
line-height: 100%;
margin-top: .8rem;
}
.btn_box{
padding:0 0.2rem;
display: flex;
margin-top: .8rem;
.btn{
width:2.6rem;
height:.7rem;
background:#C62245;
border-radius:.12rem;
text-align: center;
line-height: .7rem;
color: #fff;
font-size: .3rem;
}
.btn2{
margin-left: auto;
}
}
}
}
.new-btit{
font-size: .3rem;
color: #222;
line-height: 100%;
margin-top: .4rem;
font-weight: bold;
}
.table{
width: 6.79rem;
margin: 0.2rem auto;
display: block;
}
</style>
<template>
<div>
<div class="answer-box">
<div class="head" id="head-h">
<div class="title">全国统一高考试卷A</div>
<div class="right">
<div class="count">{{ questionParams.question.sheet_time }}</div>
</div>
</div>
<div class="exam-main" :style="{height: this.contentHeight + 'px'}">
<div class="left">
<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"
@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">
<div class="icon"></div>
<div class="txt">{{ itemSign ? '取消标记' : '标记' }}</div>
</div> -->
<div class="end-exam-btn">
<div class="btn" @click="clearQuestion">清空记录,重新答题</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import * as api from '@/api/exam.js'
import answerCard from '@/components/myQuestion/answerCard.vue'
import question from '@/components/myQuestion/question.vue'
export default {
components: {
question,
answerCard
},
data() {
return {
// 设置页面高
contentHeight: 0,
// 原数据
questionData: [],
// 存题
container: [],
// 过滤后的数据
afterChangeData: {},
questionParams: {
// 用户选择的选项 --- 提交后台的数据
answerRecord: {},
// 所有题 和题的信息
question: {},
questionIndex: 0,
card: {}
// beforeData: {}
}
}
},
mounted() {
// 赋值页面高度
this.contentHeight = parseInt(document.documentElement.clientHeight - (this.getDom('head-h').offsetHeight + this.getDom('foot-h').offsetHeight))
this.initData()
},
methods: {
// 初始化
initData() {
this.getCardAll()
this.goAppointQuestion(this.$route.query.index - 1)
},
confirmBtn() {
this.$refs.confirmBtn.answerConfirm()
},
getDom(id) {
return document.getElementById(id)
},
// 改变数据
setData(list) {
return list.map(list => {
const type = {
1: '单选题',
2: '多选题',
5: '案例题',
6: '判断题'
}
const typeTotal = {
0: 'total',
1: 'error_total',
2: ''
}
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[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
})
},
// 获取考卷
getTopic(page, call) {
const param = {
type: this.$route.query.type,
question_type: this.$route.query.qType,
page: page,
page_size: 20
}
api
.getMyQuestion(param)
.then(response => {
this.questionData = response
call(response.list)
})
.finally(() => {
})
},
// 获取答题卡所有题
getCardAll() {
const param = {
type: this.$route.query.type,
question_type: this.$route.query.qType
}
api
.getAllQuestion(param)
.then(response => {
this.questionParams.card = response.list
})
.finally(() => {
})
},
// ABC
A_Z() {
const result = []
for (let i = 0; i < 26; i++) {
result.push(String.fromCharCode(65 + i))
}
return result
},
// 点击上一题下一题 答题卡序号
changeData() {
this.questionData.list.map(list => {
if (list.q_order === this.questionParams.questionIndex + 1) {
this.questionParams.question = list
}
})
},
// 进入指定的题
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()
})
}
},
// 改变题序
changeIndex(type) {
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 {
this.questionParams.questionIndex++
const isData = this.questionData.list.find(i => { return i.q_order === this.questionParams.questionIndex + 2 })
!isData && (this.supplyRequest(1))
}
},
supplyRequest(n) {
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
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
this.changeData()
loading.close()
})
},
addCont(data, n) {
const changeData = n ? data : data.reverse()
this.setData(changeData).map(item => {
n ? this.container.push(item) : this.container.unshift(item)
})
},
// 缓存 提交
handlePapers(n) {
const param = {
type: this.$route.query.type,
question_type: this.$route.query.qType,
answer: 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
this.initData()
})
},
chcheReq(param, call) {
api
.setMyCache(param)
.then(response => {
call()
})
.finally(() => {
})
}
},
computed: {
changeQuestionIndex() {
return this.questionParams.questionIndex
}
},
watch: {
// 监听题的变化
changeQuestionIndex(newV, oldV) {
this.changeData()
this.handlePapers()
}
}
}
</script>
<style lang="scss" scoped>
.answer-box{
width: 100%;
height: 100%;
// background: #f9f9f9;
.head{
width: 100%;
height: 80px;
background: #FFFFFF;
display: flex;
.title{
padding-left: 30px;
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{
flex: 1;
padding: 10px 20px 0 53px;
overflow-y: scroll;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
.right{
position: relative;
width: 220px;
background: #fff;
padding: 0 20px;
overflow-y: scroll;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
}
.foot{
position: absolute;
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;
.end-exam-btn{
width: 260px;
display: flex;
justify-content: center;
align-items: center;
.btn{
cursor: pointer;
width: 200px;
height: 40px;
background: #EEEEEE;
border-radius: 4px;
font-size: 14px;
font-weight: bold;
color: #CCCCCC;
line-height: 40px;
text-align: center;
}
}
.sign{
margin-right: 20px;
.icon{
margin: 0 auto;
width: 24px;
height: 24px;
background: url(@/assets/images/sign.png);
background-size:100% 100%;
}
.txt{
font-size: 14px;
color: #CCCCCC;
line-height: 20px;
margin-top: 2px;
}
}
}
}
}
</style>
...@@ -121,5 +121,10 @@ export default [ ...@@ -121,5 +121,10 @@ export default [
path: '/mock/exam', path: '/mock/exam',
component: () => import(/* webpackChunkName: "course-learn" */ '@/pages/mockExam/exam/index') component: () => import(/* webpackChunkName: "course-learn" */ '@/pages/mockExam/exam/index')
}, },
/* 错题收藏全部列表详情 */
{
path: '/my/questions/details',
component: () => import(/* webpackChunkName: "course-learn" */ '@/pages/my/questions/questionDetails')
},
...viewerRoutes ...viewerRoutes
] ]
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论