提交 b1a87ba8 authored 作者: lihuihui's avatar lihuihui

开发考试

上级 b34826a2
module.exports = {
domain: 'dev.ezijing.com',
url: 'https://transport.ezijing.com/api',
url: 'https://transport2.ezijing.com/api',
webpack: {
externals: {
CKEDITOR: 'window.CKEDITOR',
......
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
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
6M22MuuP1pLviPZEE4ZlPXvltUV/Qq47LvZkTg==
LmNydDAJBgNVHRMEAjAAMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHYA9lyUL9F3
MCIUVBgIMJRWjuNNExkzv98MLyALzE7xZOMAAAF1qpa6jQAABAMARzBFAiAwHOcp
Ua1H0WK4OZUHiQ1rndqnYxPHhP9XWunwpRMoagIhAOB2MPSW9M4qj6Yih7eQkydl
lgawpoBZzRzhisU+TN67AHYAXNxDkv7mq0VEsV6a1FbmEDf71fpH3KFzlLJe5vbH
DsoAAAF1qpa63gAABAMARzBFAiEA92ZeW0PgyWW3j+3wypLS0O/wI63C+x0WTvMZ
Vngp6AMCIBoThjaKif+XY11YbaV89ndqs1nDlzbEfBrFftoB9fchMA0GCSqGSIb3
DQEBCwUAA4IBAQA2geo9wQAd+vx+lwAafVRxCBQyBiS0qT413ewYpZYDnSkLX0l1
5kRdxDGWQhPzOio0ckj/jOtOlbbSsiovBBVTyYPB8WfkNjMd0psMNx2e6Wy/WKkQ
X3DqEOB4XGg0RwpebiAmz6lWxyFwIAbCrwCntkkaIF4LnIvczn6pvPFBtK2nXJJC
HL0Igbxo+xJLt3Hql7TcwkFDXz/LIB8AwhhkkhhwW45r3Eyjw8eOyzvflDPwSNH+
ByadQ+AH4H4vYYVo0ILNIPCdaokLQ+u4FttB9VQ+iGmpJ56Yg2muxWh8Qckca+vH
40RbC5aK1RSy2RIRpC5fwvq2JuV/CksP5G5Q
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEqjCCA5KgAwIBAgIQAnmsRYvBskWr+YBTzSybsTANBgkqhkiG9w0BAQsFADBh
......
......@@ -6,7 +6,7 @@
"scripts": {
"lint": "eslint --ext .js --ext .jsx --ext .vue src/",
"lint:fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/",
"dev": "npm run check:node && cross-env NODE_ENV=development node build/getSSL.js && cross-env NODE_ENV=development SERVER_PORT=3001 webpack-dev-server --inline --progress --config build/webpack.client.conf.js",
"dev": "cross-env NODE_ENV=development node build/getSSL.js && cross-env NODE_ENV=development SERVER_PORT=3001 webpack-dev-server --inline --progress --config build/webpack.client.conf.js",
"build:test": "npm run check:node && cross-env NODE_ENV=test webpack --progress --config build/webpack.client.conf.js && cross-env NODE_ENV=test node ./build/uploadAliyunCDN.js",
"build:pro": "npm run check:node && cross-env NODE_ENV=production webpack --progress --config build/webpack.client.conf.js && cross-env NODE_ENV=production node ./build/uploadAliyunCDN.js",
"check:node": "node build/checkNodeVersion.js"
......
......@@ -6,6 +6,20 @@ export function getExamQuestion(params) {
return httpRequest.get('/api/zy/v2/examination/examination-papers', { params }, { headers: { 'Content-Type': 'multipart/form-data' } })
}
/**
* 缓存考前摸底试题
*/
export function setCache(data) {
return httpRequest.post('/api/zy/v2/examination/examination-papers', data)
}
/**
* 获取考试的状态
*/
export function getExamStatus(params) {
return httpRequest.get('/api/zy/v2/examination/examination-papers-status', { params })
}
/**
* 获取课程列表
*/
......
<template>
<div>
<!-- <div class="info">
<div class="shape">
<img :src="info.id_photo" alt="">
</div>
<div class="right">
<div class="name">{{ info.name }}</div>
<div class="code">{{ info.examinee_number }}</div>
</div>
</div> -->
<!-- {{ questionParams.card }} -->
<div class="order-num">
<template v-for="(item, index) in questionParams.card">
<div :key="index" v-if="item.question_item_type != 5">
<div :key="index">
<div class="tit">{{ item.find(tit => { return tit.question_item_title }).question_item_title }}</div>
<ul>
<template v-for="(cItem, cIndex) in item">
......@@ -20,54 +10,48 @@
<li
:key="cItem.q_order + '-' + cIndex"
@click="goQuestion(cItem.q_order)"
:class="isClass(cItem)"
:class="$route.query.id ? isAnalysisClass(cItem) + ' analy' : isClass(cItem)"
>{{ cItem.q_order }}</li>
</template>
</ul>
</div>
<div :key="index" v-else>
<div class="tit">{{ item.find(tit => { return tit.question_item_title }).question_item_title }}</div>
<ul>
<template v-for="cItem in item.question_list">
<template v-for="(lItem, lIndex) in cItem.list">
<li
:key="lItem.q_order +'-'+ lIndex"
@click="goQuestion(lItem.q_order)"
:class="questionParams.questionIndex + 1 === lItem.q_order
? questionParams.answerRecord[item.question_item_id]
? questionParams.answerRecord[item.question_item_id][lItem.id]
? questionParams.answerRecord[item.question_item_id][lItem.id].answer.length !== 0
? questionParams.answerRecord[item.question_item_id][lItem.id].sign
? 'stu1 stu2 stu3'
: 'stu1 stu2'
: questionParams.answerRecord[item.question_item_id][lItem.id].sign
? 'stu2 stu3'
: 'stu2'
: 'stu2'
: 'stu2'
: questionParams.answerRecord[item.question_item_id]
? questionParams.answerRecord[item.question_item_id][lItem.id]
? questionParams.answerRecord[item.question_item_id][lItem.id].answer.length !== 0
? questionParams.answerRecord[item.question_item_id][lItem.id].sign
? 'stu1 stu3'
: 'stu1'
: questionParams.answerRecord[item.question_item_id][lItem.id].sign
? 'stu3'
: ''
: ''
: ''
"
>{{ lItem.q_order }}</li>
</template>
</template>
</ul>
</div>
</template>
</div>
<ul class="flag-tips" v-if="!this.$route.query.id">
<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>
<!-- <li>
<div class="circle4"></div>
<div class="txt">标记</div>
</li> -->
</ul>
<ul class="tips-box" v-else>
<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>
// import Bus from '../../components/common/bus.js'
export default {
props: {
questionParams: { type: Object, default: () => {} },
......@@ -107,11 +91,25 @@ export default {
: ''
: ''
}
},
isAnalysisClass() {
return (cItem) => {
const findItems = this.questionParams.beforeData.answers[cItem.question_item_id]
const scoreItems = this.questionParams.beforeData.score_items[cItem.question_item_id][cItem.id]
return findItems
? findItems[cItem.id]
? findItems[cItem.id].answer.length
? scoreItems.is_right
? 'stu1'
: 'stu2'
: 'stu3'
: 'stu3'
: 'stu3'
}
}
},
methods: {
monitoringChanges() {
console.log(this.questionParams.answerRecord)
this.$forceUpdate()
},
goQuestion(n) {
......@@ -120,7 +118,6 @@ export default {
},
watch: {
changeQuestionIndex(newV, oldV) {
console.log(111)
this.$forceUpdate()
}
}
......@@ -187,9 +184,34 @@ export default {
&:nth-child(5n+5){
margin-right: 0;
}
&.analy{
&.stu1{
border: 2px solid #0FC118;
line-height: 22px;
}
&.stu2{
border: 2px solid #C01540;
line-height: 22px;
}
&.stu3{
color: #fff;
background: #999999;
&::after{
content: '';
position: absolute;
top: -1px;
right: -1px;
width: 4px;
height: 4px;
background: none;
border-radius: 50%;
}
}
}
&.stu1{
background: #EEEEEE;
border: 1px solid #CCCCCC;
background: #999;
border: 1px solid #999;
color: #fff;
}
&.stu2{
width: 22px;
......@@ -274,4 +296,122 @@ export default {
}
}
}
.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 class="chart">
<svg width="148" height="148" viewbox="0 0 148 148" class="svg-rotate">
<circle cx="74" cy="74" r="70" stroke-width="7" stroke="#efefef" fill="none"></circle>
<circle cx="74" cy="74" r="70" stroke-width="7" stroke="#4cce8c" fill="none" :stroke-dasharray="data" stroke-linecap="round"></circle>
</svg>
<div class="chart-txt">
<div class="num">{{ accuracy }}%</div>
<div class="t">正确率</div>
</div>
</div>
</template>
<script>
export default {
props: {
accuracy: { type: Number }
},
data() {
return {
data: ''
}
},
mounted() {
const percent = this.accuracy / 100
const perimeter = Math.PI * 2 * 70
this.data = perimeter * percent + ' ' + perimeter * (1 - percent)
}
}
</script>
<style lang="scss" scoped>
.chart{
position: relative;
width: auto;
.chart-txt{
position: absolute;
top: 0;
left: 0;
width: 100%;
text-align: center;
.num{
color: #000;
font-size: 38px;
font-weight: bold;
padding-top: 32px;
}
.t{
color: #999;
font-size: 18px;
}
}
}
.svg-rotate{
transform:rotate(-90deg);
}
</style>
......@@ -23,11 +23,23 @@
: ''"
>
<div class="icon"></div>
<div class="txt">{{item.option}}</div>
<div class="txt">{{A_Z()[index]}}. {{item.option}}</div>
</li>
</template>
</ul>
</template>
<!-- 解析 -->
<div class="analysis" v-if="questionData.question_item_type != 5 && $route.query.id">
<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">
......@@ -35,7 +47,21 @@
<div class="num">{{ questionData.q_order }}/{{ questionParams.question.total_question_count }}</div>
</div>
<div class="case-que">
<div class="stem" v-html="questionData.common_content"></div>
<div class="flex">
<div class="stem" v-html="questionData.common_content"></div>
<!-- 解析 -->
<div class="analysis" v-if="$route.query.id">
<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">
......@@ -60,7 +86,7 @@
: ''"
>
<div class="icon"></div>
<div class="txt">{{opt.option}}</div>
<div class="txt">{{A_Z()[oIndex]}}. {{opt.option}}</div>
</li>
</template>
</template>
......@@ -75,8 +101,6 @@
</div>
</template>
<script>
// import action from '@action'
// import Bus from '../../components/common/bus.js'
export default {
props: {
contentHeight: { type: Number, default: () => {} },
......@@ -93,58 +117,65 @@ export default {
mounted() {
},
methods: {
// 自己选择的答案
myAnswer() {
const selectAnswer = this.questionParams.answerRecord
const currentData = this.questionData
return selectAnswer[currentData.question_item_id]
? selectAnswer[currentData.question_item_id][currentData.id]
? (() => {
const arr = []
selectAnswer[currentData.question_item_id][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, cId, optId) {
if (parseInt(type) !== 2) {
this.questionParams.answerRecord[pId]
? this.questionParams.answerRecord[pId][cId]
? this.questionParams.answerRecord[pId][cId].answer = [optId]
: this.questionParams.answerRecord[pId][cId] = {
answer: [optId],
sign: false
}
: this.questionParams.answerRecord[pId] = {
[cId]: {
answer: [optId],
sign: false
}
}
} else {
this.questionParams.answerRecord[pId]
? this.questionParams.answerRecord[pId][cId]
? (() => {
const optChack = this.questionParams.answerRecord[pId][cId].answer.findIndex(item => { return item === optId })
if (optChack === -1) {
this.questionParams.answerRecord[pId][cId].answer.push(optId)
} else {
this.questionParams.answerRecord[pId][cId].answer.splice(optChack, 1)
if (!this.$route.query.id) {
if (parseInt(type) !== 2) {
this.questionParams.answerRecord[pId]
? this.questionParams.answerRecord[pId][cId]
? this.questionParams.answerRecord[pId][cId].answer = [optId]
: this.questionParams.answerRecord[pId][cId] = {
answer: [optId],
sign: false
}
: this.questionParams.answerRecord[pId] = {
[cId]: {
answer: [optId],
sign: false
}
})()
: this.questionParams.answerRecord[pId][cId] = {
answer: [optId],
sign: false
}
: this.questionParams.answerRecord[pId] = {
[cId]: {
answer: [optId],
sign: false
} else {
this.questionParams.answerRecord[pId]
? this.questionParams.answerRecord[pId][cId]
? (() => {
const optChack = this.questionParams.answerRecord[pId][cId].answer.findIndex(item => { return item === optId })
if (optChack === -1) {
this.questionParams.answerRecord[pId][cId].answer.push(optId)
} else {
this.questionParams.answerRecord[pId][cId].answer.splice(optChack, 1)
}
})()
: this.questionParams.answerRecord[pId][cId] = {
answer: [optId],
sign: false
}
: this.questionParams.answerRecord[pId] = {
[cId]: {
answer: [optId],
sign: false
}
}
}
}
this.msgCenter.$emit('monitoringChanges')
this.$forceUpdate()
}
this.msgCenter.$emit('monitoringChanges')
// Bus.$emit('monitoringChanges')
this.$forceUpdate()
},
setCache() {
// const param = {
// answer: JSON.stringify(this.questionParams.answerRecord)
// }
// action.Exam.setCache(this.$route.params.examId, param).then(res => {
// }).catch(err => {
// this.$alert(err.message, {
// callback: action => {}
// })
// })
},
// 标记
onSignHandle() {
......@@ -177,6 +208,14 @@ export default {
: 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: {
......@@ -187,6 +226,7 @@ export default {
watch: {
changeQuestionIndex(newV, oldV) {
this.questionData = this.questionParams.question
console.log(this.questionData)
this.$forceUpdate()
}
}
......@@ -274,6 +314,9 @@ export default {
border-radius: 3px !important;
}
}
.flex{
flex: 1;
}
.case-que{
display: flex;
.stem{
......@@ -282,6 +325,7 @@ export default {
font-weight: bold;
color: #222222;
line-height: 28px;
margin-bottom: 20px;
}
.topics{
flex: 1;
......@@ -309,4 +353,35 @@ export default {
}
}
}
.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 class="card-box">
<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 class="order-num">
<template v-for="item in changeQuestion">
<div :key="item[0].id">
<div class="tit">{{ item[0].itemTitle }}</div>
<ul>
<template v-for="cItem in item">
<!-- childId id -->
<li @click="goQuestion(cItem.childId)" :class="isClass(cItem.id, cItem.childId)" :key="cItem.order ">{{ cItem.order }}</li>
</template>
</ul>
</div>
</template>
</div>
<slot name="btnBox"></slot>
<!-- <div class="btn-box">
<div class="btn" @click="goPage('all')">全部解析</div>
<div class="btn" @click="goPage('err')">错误解析</div>
</div> -->
</div>
</template>
<script>
export default {
props: {
data: { type: Object }
},
data() {
return {
changeQuestion: []
}
},
computed: {
isClass() {
return (id, cId) => {
const findItems = this.data.answers[id]
const scoreItems = this.data.score_items[id][cId]
return findItems
? findItems[cId]
? findItems[cId].answer.length
? scoreItems.is_right
? 'stu1'
: 'stu2'
: 'stu3'
: 'stu3'
: 'stu3'
}
}
},
mounted() {
this.changeQuestion = this.setData()
// console.log(this.ChangeQuestion)
},
methods: {
setData() {
let countNum = 0
const type = {
1: '单选题',
2: '多选题',
5: '案例题',
6: '判断题'
}
return this.data.questions.question_items.map(item => {
return item.question_list.map(cItem => {
countNum++
const data = {
order: countNum,
id: item.question_item_id,
childId: cItem.id,
itemTitle: type[item.question_type]
}
return data
})
})
},
goQuestion(id) {
this.$router.push({
path: '/testExam/exam',
query: {
id: id
}
})
}
}
}
</script>
<style lang="scss" scoped>
.card-box{
position: relative;
height: 100%;
.tips-box{
display: flex;
justify-content: center;
padding: 15px 0 10px;
background: #fff;
margin: 0;
list-style: none;
border-bottom: 1px solid #ccc;
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;
}
}
}
.order-num{
height: 420px;
overflow-y: scroll;
padding-left: 30px;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
// padding-bottom: 90px;
.tit{
font-size: 12px;
color: #999999;
line-height: 17px;
margin-bottom: 12px;
margin-top: 30px;
}
ul{
display: flex;
list-style: none;
padding: 0;
margin: 0;
flex-wrap: wrap;
li{
box-sizing: border-box;
cursor: pointer;
position: relative;
border-radius: 50px;
width: 24px;
height: 24px;
border: 1px solid #CCCCCC;
font-size: 12px;
color: #666666;
line-height: 24px;
margin-right: 20px;
margin-bottom: 10px;
text-align: center;
// &:nth-child(5n+5){
// margin-right: 0;
// }
&.stu1{
border: 2px solid #0FC118;
line-height: 22px;
}
&.stu2{
border: 2px solid #C01540;
line-height: 22px;
}
&.stu3{
color: #fff;
background: #999999;
}
}
}
}
.btn-box{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
height: 60px;
background: #fff;
.btn{
width: 116px;
height: 40px;
text-align: center;
line-height: 40px;
border-radius: 4px;
cursor: pointer;
&:nth-child(1){
border: 1px solid #CCCCCC;
font-size: 14px;
font-weight: bold;
color: #999999;
box-sizing: border-box;
}
&:nth-child(2){
background: #C01540;
border-radius: 4px;
font-size: 14px;
font-weight: bold;
color: #FFFFFF;
margin-left: 30px;
}
}
}
}
</style>
......@@ -28,7 +28,7 @@ export default {
return {
defaultMenus: [
{ title: '考前摸底', icon: '', path: '/testExam' },
{ title: '真题实战', icon: '', path: '/exam' },
{ title: '真题实战', icon: '', path: '/mockExam' },
{ title: '错题集合', icon: '', path: '/my/questions/wrong' },
{ title: '收藏试题', icon: '', path: '/my/questions/collection' },
{ title: '必考考点', icon: '', path: '/course/test' },
......
<template>
<app-container title="真题实战介绍">
<div class="exam">
<div class="item">
<p>
<span><b>考试时间:90分钟</b></span>
<span><b>考试通过:80分</b></span>
<span><b>总分:100分</b></span>
</p>
<p>试题类型:单项选择题、多项选择题、判断题和案例题,全部为客观题。</p>
</div>
<div class="item">
<p><b>考试说明</b></p>
<p>1.考试目的:考核道路运输企业主要负责人和安全生产管理人员对安全生产管理知识掌握程度</p>
<p>
2.考核范围:道路运输安全生产相关法律法规及标准规范、道路运输企业安全生产主体责任、道路运输企业安全管理知识、道路运输安全生产实务等内容。
</p>
<p>3.考试试卷:按照考试大纲的考点出题,精准模拟。</p>
</div>
<div class="item">
<p><b>选择角色</b></p>
<el-radio-group v-model="role">
<el-radio :label="0">管理人员</el-radio>
<el-radio :label="1">安全人员</el-radio>
</el-radio-group>
</div>
<div class="item">
<p><b>试卷组卷比例见下表</b></p>
<img src="../../assets/images/exam_table.png" style="max-width: 100%" />
</div>
</div>
<template #footer>
<div class="app-container-ft"><el-button type="primary">开始考试</el-button></div>
</template>
</app-container>
</template>
<script>
import AppContainer from '@/components/AppContainer'
export default {
components: { AppContainer },
data() {
return {
role: 0
}
}
}
</script>
<style lang="scss" scoped>
.exam {
.item {
margin-bottom: 20px;
line-height: 30px;
}
.item span {
margin-right: 20px;
}
}
</style>
<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>
<app-container title="真题实战介绍">
<div class="exam">
<div class="item">
<p>
<span><b>考试时间:90分钟</b></span>
<span><b>考试通过:80分</b></span>
<span><b>总分:100分</b></span>
</p>
<p>试题类型:单项选择题、多项选择题、判断题和案例题,全部为客观题。</p>
</div>
<div class="item">
<p><b>考试说明</b></p>
<p>1.考试目的:考核道路运输企业主要负责人和安全生产管理人员对安全生产管理知识掌握程度</p>
<p>
2.考核范围:道路运输安全生产相关法律法规及标准规范、道路运输企业安全生产主体责任、道路运输企业安全管理知识、道路运输安全生产实务等内容。
</p>
<p>3.考试试卷:按照考试大纲的考点出题,精准模拟。</p>
</div>
<div class="item">
<p><b>选择角色</b></p>
<el-radio-group v-model="role">
<el-radio :label="0">管理人员</el-radio>
<el-radio :label="1">安全人员</el-radio>
</el-radio-group>
</div>
<div class="item">
<p><b>试卷组卷比例见下表</b></p>
<img src="../../assets/images/exam_table.png" style="max-width: 100%" />
</div>
</div>
</div>
<template #footer>
<div class="app-container-ft"><el-button type="primary">开始考试</el-button></div>
</template>
</app-container>
</template>
<script>
import * as api from '@/api/courseExam.js'
import * as apiMy from '@/api/account.js'
import AppContainer from '@/components/AppContainer'
export default {
metaInfo () {
return {
title: '真题实战'
}
},
components: { AppContainer },
data() {
return {
roleChange: 1,
isExamPop: false,
isExamPopTo: false
role: 0
}
},
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%;
.exam {
.item {
margin-bottom: 20px;
line-height: 30px;
}
.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;
.item span {
margin-right: 20px;
}
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 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>
......@@ -4,11 +4,7 @@
<div class="head" id="head-h">
<div class="title">全国统一高考试卷A</div>
<div class="right">
<div class="count">00:60:00倒计时</div>
<!-- <div class="time">
<div class="icon"></div>
<div class="mun">60:00</div>
</div> -->
<div class="count">{{ time.examTimeText }}</div>
</div>
</div>
<div class="exam-main" :style="{height: this.contentHeight + 'px'}">
......@@ -24,8 +20,9 @@
<div class="right">
<answer-card
:questionParams="questionParams"
ref="signHandle"
@isSign="isSign"
></answer-card>
<!-- :info="sInfo.info" -->
</div>
</div>
<div class="foot" id="foot-h">
......@@ -39,23 +36,17 @@
@click="changeIndex('next')"
>下一题</div>
</div>
<div class="rigth-btn" @click="signHandle">
<div class="sign">
<div class="rigth-btn" @click="signHandle" v-if="!$route.query.id">
<!-- <div class="sign">
<div class="icon"></div>
<div class="txt"></div>
</div>
<div class="txt">{{ itemSign ? '取消标记' : '标记' }}</div>
</div> -->
<div class="end-exam-btn">
<div class="btn" @click="endExam">结束考试</div>
<div class="btn" @click="endExam">交卷</div>
</div>
</div>
</div>
</div>
<my-dia :title="title" :prompt="prompt" v-if="isPopup" @close="close">
<template v-slot:button>
<button @click="close">关闭</button>
<button @click="endExamRequest">确定</button>
</template>
</my-dia>
</div>
</template>
<script>
......@@ -69,11 +60,15 @@ export default {
},
data() {
return {
isExamTimeDate: true,
time: {
// 考试持续时间
duration: 0,
examTimeText: '00:00:00',
clearTime: null
},
// isExamTimeDate: true,
// 标记
itemSign: false,
examTime: '00:00:00 倒计时',
clearTime: null,
isPopup: false,
// 设置页面高
contentHeight: 0,
// 原数据
......@@ -89,12 +84,13 @@ export default {
questionIndex: 0,
// 所有题 和题的信息
question: {},
card: {}
card: {},
beforeData: {}
}
}
},
mounted() {
// this.setTick()
// 赋值页面高度
this.contentHeight = parseInt(document.documentElement.clientHeight - (this.getDom('head-h').offsetHeight + this.getDom('foot-h').offsetHeight))
this.getTopic()
},
......@@ -108,43 +104,54 @@ export default {
},
// 提交考试
endExam() {
this.isExamTimeDate
? this.isPopup = true
: this.endExamRequest()
this.handlePapers(1)
},
endExamRequest() {
},
countDown(time) {
const lefttime = parseInt((time) / 1000)
const h = this.addZero(parseInt(lefttime / (60 * 60) % 24))
const m = this.addZero(parseInt(lefttime / 60 % 60))
const s = this.addZero(parseInt(lefttime % 60))
this.examTime = `${h} : ${m} : ${s} 倒计时`
},
setTick() {
this.clearTime = setInterval(() => {
const nowtime = new Date()
const endtime = new Date(this.examInfo.end_time)
const countTime = endtime.getTime() - nowtime.getTime()
if (countTime <= 0) {
this.isExamTimeDate = false
clearInterval(this.clearTime)
this.examTime = '00:00:00 倒计时'
this.endExam()
} else {
this.countDown(countTime)
setClock(time) {
let sec = parseInt(time)
clearInterval(this.time.clearTime)
this.time.clearTime = setInterval(() => {
// if (this.requestParam.course_id) {
// this.time.examTimeText = this.secondToDate(sec)
// sec++
// } else {
// }
if (this.$route.query.id) {
this.time.examTimeText = '00:00:00'
return false
}
sec--
if (sec === 0) {
clearInterval(this.time.clearTime)
this.$alert('考试时间结束,自动提交试卷', '', {
confirmButtonText: '确定',
callback: action => {
this.endExam()
}
})
return false
}
this.time.examTimeText = this.secondToDate(sec)
this.time.duration++
}, 1000)
},
secondToDate(result) {
const h = Math.floor(result / 3600) < 10 ? '0' + Math.floor(result / 3600) : Math.floor(result / 3600)
const m = Math.floor((result / 60 % 60)) < 10 ? '0' + Math.floor((result / 60 % 60)) : Math.floor((result / 60 % 60))
const s = Math.floor((result % 60)) < 10 ? '0' + Math.floor((result % 60)) : Math.floor((result % 60))
if (h === 0) {
result = m + ':' + s
} else {
result = h + ':' + m + ':' + s
}
return result
},
addZero(i) {
return i < 10 ? '0' + i : i + ''
},
close() {
this.isPopup = false
},
getDom(id) {
return document.getElementById(id)
},
// 改变题序
changeIndex(type) {
if (type === 'prev') {
this.questionParams.questionIndex > 0 && (this.questionParams.questionIndex--)
......@@ -152,25 +159,33 @@ export default {
this.questionParams.questionIndex + 1 !== this.questionParams.question.total_question_count && (this.questionParams.questionIndex++)
}
this.changeData()
this.handlePapers()
},
// 获取考卷
getTopic() {
const param = {
type: 1,
is_create: 1
is_create: this.$route.query.id || !this.$route.query.is_create ? 0 : 1
}
api
.getExamQuestion(param)
.then(response => {
const data = JSON.parse(response.data)
this.beforeChangeData = data.sheet
this.questionParams.beforeData = data.sheet
this.afterChangeData = this.setData(data.sheet.questions.question_items)
this.questionParams.card = this.setData(data.sheet.questions.question_items)
this.changeData()
data.sheet.answers !== null && (this.questionParams.answerRecord = data.sheet.answers)
this.$route.query.id && this.$route.query.id.length > 5
? this.analysisInit()
: this.changeData()
this.setClock(data.sheet.remaining_times)
this.time.duration = data.sheet.duration
})
.finally(() => {
// this.loaded = true
})
},
// 重组数据
setData(data) {
let countNum = 0
const type = {
......@@ -192,6 +207,19 @@ export default {
question_item_title: type[item.question_type],
total_question_count: this.beforeChangeData.questions.total_question_count
}
if (this.$route.query.id) {
if (this.$route.query.id.length > 5 || this.$route.query.id === 'all' || this.$route.query.id === 'err') {
const qAnswer = Array.isArray(cItem.question_answer) ? cItem.question_answer : cItem.question_answer = [cItem.question_answer]
let optGroup = ''
const findAB = qAnswer.map(qOpt => {
const findIndex = cItem.question_options.findIndex(i => { return i.id === qOpt })
return this.A_Z()[findIndex]
})
data.question_analysis = cItem.question_analysis
optGroup = (findAB.sort().toString().replace(new RegExp(',', 'g'), ''))
data.question_answer = optGroup
}
}
if (parseInt(item.question_type) === 5) {
data.common_content = cItem.common_content
data.group_id = cItem.group_id
......@@ -202,6 +230,14 @@ export default {
})
})
},
// ABC
A_Z() {
const result = []
for (let i = 0; i < 26; i++) {
result.push(String.fromCharCode(65 + i))
}
return result
},
// 合并案例题
mergeData(arr, str) {
const _arr = []
......@@ -220,6 +256,7 @@ export default {
_arr.push(_t)
return _arr
},
// 点击上一题下一题 答题卡序号
changeData() {
this.afterChangeData.map(item => {
item.map(cItem => {
......@@ -227,17 +264,38 @@ export default {
})
})
},
getCache() {
// action.Exam.getCache(this.$route.params.examId).then(res => {
// const data = JSON.parse(res.answer)
// if (data !== null && data !== 'null') {
// this.questionParams.answerRecord = data
// }
// }).catch(err => {
// this.$alert(err.message, {
// callback: action => {}
// })
// })
// 结果页进入设置默认点击的题
analysisInit() {
this.afterChangeData.map(item => {
const findData = item.find(datas => { return datas.id === this.$route.query.id })
if (findData) {
this.questionParams.questionIndex = findData.q_order - 1
this.questionParams.questions = findData
findData.q_order === 1 && (this.changeData())
}
})
},
// 缓存 提交
handlePapers(n) {
if (!this.$route.query.id) {
const param = {
sheet_id: this.beforeChangeData.id,
status: n || 0,
answers: JSON.stringify(this.questionParams.answerRecord),
duration: this.time.duration
}
api
.setCache(param)
.then(response => {
if (n) {
this.$router.replace({
path: '/testExam/result'
})
}
})
.finally(() => {
})
}
}
},
computed: {
......@@ -246,6 +304,7 @@ export default {
}
},
watch: {
// 监听题的变化
changeQuestionIndex(newV, oldV) {
this.changeData()
}
......@@ -379,7 +438,7 @@ export default {
margin: 0 auto;
width: 24px;
height: 24px;
// background: url(../../assets/images/sign.png);
background: url(@/assets/images/sign.png);
background-size:100% 100%;
}
.txt{
......
<template>
<div class="result-box">
<div class="card-left">
<div class="title">成绩报告</div>
<div class="chart-box">
<chart :accuracy="accuracy"/>
</div>
<div class="assess">测试评估</div>
<div class="assess-box">
<div class="prog">
<div class="line-box">
<div class="line" :style="setStyle"></div>
</div>
<div class="icon"></div>
</div>
<div class="text">{{ accuracy !== 100 ? '您离成功还有一段距离,继续努力!' : '成功近在眼前,再接再厉!' }}</div>
<div class="btn">全部考试服务</div>
</div>
</div>
<div class="card-right">
<card v-if="data.sheet" :data="data.sheet">
<template v-slot:btnBox>
<div class="btn-box">
<div class="btn" @click="goPage('all')">全部解析</div>
<div class="btn" @click="goPage('err')">错误解析</div>
</div>
</template>
</card>
</div>
</div>
</template>
<script>
import chart from '@/components/exam/pieChart.vue'
import card from '@/components/exam/resultCard.vue'
import * as api from '@/api/exam.js'
export default {
components: {
chart,
card
},
data() {
return {
data: {},
accuracy: 0
}
},
created() {
this.getExamPapers()
},
computed: {
setStyle() {
return `width: ${this.accuracy}%`
}
},
mounted() {
},
methods: {
goPage(param) {
this.$router.push({
path: '/testExam/exam',
query: {
id: param
}
})
},
getExamPapers() {
const param = {
type: 1,
is_create: 0
}
api
.getExamQuestion(param)
.then(response => {
const data = JSON.parse(response.data)
this.data = data
this.accuracy = parseInt(data.sheet.score) / parseInt(data.sheet.questions.total_score)
// console.log(this.accuracy)
})
.finally(() => {
// this.loaded = true
})
}
}
}
</script>
<style lang="scss" scoped>
.result-box{
width: 100%;
display: flex;
.card-left{
box-sizing: border-box;
padding: 10px 30px 20px;
flex: 1;
background: #fff;
margin-right: 10px;
height: 560px;
border-radius: 8px;
.title{
font-size: 18px;
color: #222222;
line-height: 45px;
border-bottom: 1px solid #ccc;
}
.chart-box{
width: 148px;
margin: 26px auto 0;
}
.assess{
font-size: 18px;
color: #222222;
line-height: 45px;
border-bottom: 1px solid #ccc;
}
.assess-box{
padding-top: 27px;
.prog{
width: 350px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: space-between;
.line-box{
width: 300px;
width: 300px;
height: 10px;
background: #F9F9F9;
border-radius: 5px;
.line{
width: 80%;
height: 10px;
background: linear-gradient(90deg, #F47C46 0%, #F22F48 100%);
border-radius: 5px;
}
}
.icon{
width: 41px;
height: 38px;
background: url(@/assets/images/res-icon.png);
background-size: 100% 100%;
}
}
.text{
font-size: 14px;
color: #222222;
line-height: 20px;
text-align: center;
margin: 50px 0 68px 0;
}
.btn{
cursor: pointer;
text-align: center;
line-height: 40px;
width: 144px;
height: 40px;
background: #C01540;
border-radius: 4px;
font-size: 14px;
font-weight: bold;
color: #FFFFFF;
margin: 0 auto;
}
}
}
.card-right{
box-sizing: border-box;
flex: 1;
background: #fff;
height: 560px;
border-radius: 8px;
margin-left: 10px;
padding: 10px 30px 0;
}
}
</style>
......@@ -5,17 +5,80 @@
<p>考试题目共22题,分四部分:单选题共8题,多选题共8题,判断题共5题,案例题共1题。</p>
</div>
<template #footer>
<div class="app-container-ft"><el-button type="primary">开始考试</el-button></div>
<div class="app-container-ft"><el-button type="primary" @click="getExamStatus">开始考试</el-button></div>
</template>
</app-container>
</template>
<script>
import * as api from '@/api/exam.js'
import AppContainer from '@/components/AppContainer'
export default {
components: { AppContainer },
data() {
return {}
},
mounted() {
// this.open()
},
methods: {
getExamStatus() {
const param = {
type: 1
}
api
.getExamStatus(param)
.then(response => {
if (response.status === 0 || response.status === 3) {
this.open()
} else {
this.$router.push({
path: '/testExam/exam',
query: {
is_create: true
}
})
}
})
.finally(() => {
// this.loaded = true
})
},
open() {
const h = this.$createElement
this.$msgbox({
title: '消息',
message: h('p', null, [
h('span', null, '您上次未做完试题 ')
]),
showCancelButton: true,
confirmButtonText: '继续答题',
cancelButtonText: '重新答题',
beforeClose: (action, instance, done) => {
done()
if (action === 'confirm') {
this.$router.push({
path: '/testExam/exam',
query: {
is_create: false
}
})
} else {
this.$router.push({
path: '/testExam/exam',
query: {
is_create: true
}
})
}
}
}).then(action => {
this.$message({
type: 'info',
message: 'action: ' + action
})
})
}
}
}
</script>
......
......@@ -38,10 +38,15 @@ const examAnswer = [
path: '/testExam',
component: () => import(/* webpackChunkName: "exam" */ '@/pages/testExam')
},
/* 考前摸底结果页 */
{
path: '/testExam/result',
component: () => import(/* webpackChunkName: "exam" */ '@/pages/testExam/exam/result')
},
// 真题实战
{
path: '/exam',
component: () => import(/* webpackChunkName: "exam" */ '@/pages/exam')
path: '/mockExam',
component: () => import(/* webpackChunkName: "exam" */ '@/pages/mockExam')
}
]
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论