2019-07-26 13:32:43 +08:00
|
|
|
|
<template>
|
2019-08-19 10:31:11 +08:00
|
|
|
|
<div v-drag class="reminder-drag">
|
|
|
|
|
<div ref="drapBox" class="reminder-box">
|
|
|
|
|
<div class="tip-title">
|
|
|
|
|
<i v-show="isShrink" class="icon el-icon-minus" @click="shrink" />
|
|
|
|
|
<i v-show="!isShrink" class="icon el-icon-plus" @click="shrink" />
|
|
|
|
|
<p v-if="!isShrink" style="color: #fff;">
|
|
|
|
|
<span class="time-label">考试计时:</span>
|
|
|
|
|
<span class="time-elem">{{ formatExamUsedTime }}</span>
|
|
|
|
|
</p>
|
|
|
|
|
<p v-if="isShrink" style="color: #fff;">
|
|
|
|
|
<span>{{ examName }}</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div ref="dragBody" class="tip-body-box">
|
|
|
|
|
<div v-show="detailShow" class="tip-body">
|
|
|
|
|
<el-scrollbar wrap-class="scrollbar-wrapper">
|
|
|
|
|
<el-tree
|
|
|
|
|
ref="treeQuestion"
|
|
|
|
|
:data="trainingList"
|
|
|
|
|
node-key="id"
|
|
|
|
|
highlight-current
|
|
|
|
|
@node-click="getTrainDetail"
|
|
|
|
|
>
|
|
|
|
|
<span slot-scope="{ node, data }">
|
|
|
|
|
<span :style="{color: data.usedTime !== undefined ? 'green':''}"> {{ trainingList.indexOf(data)+1 }}.{{
|
|
|
|
|
data.trainingName }}
|
|
|
|
|
</span>
|
|
|
|
|
</span>
|
|
|
|
|
</el-tree>
|
|
|
|
|
</el-scrollbar>
|
2019-07-26 13:32:43 +08:00
|
|
|
|
</div>
|
2019-08-19 10:31:11 +08:00
|
|
|
|
<div v-show="!detailShow" class="tip-body">
|
|
|
|
|
<el-scrollbar wrap-class="scrollbar-wrapper">
|
|
|
|
|
<p class="list-item">
|
|
|
|
|
<span class="list-label">本题名称:</span>
|
|
|
|
|
<span class="list-elem">{{ courseModel.name }}</span>
|
|
|
|
|
</p>
|
|
|
|
|
<p class="list-item">
|
|
|
|
|
<span class="list-label">最佳用时:</span>
|
|
|
|
|
<span class="list-elem">{{ courseModel.minDuration }}秒 </span>
|
|
|
|
|
</p>
|
|
|
|
|
<p class="list-item">
|
|
|
|
|
<span class="list-label">最大用时:</span>
|
|
|
|
|
<span class="list-elem">{{ courseModel.maxDuration }}秒 </span>
|
|
|
|
|
</p>
|
|
|
|
|
<p class="list-item">
|
|
|
|
|
<span class="list-label"> 实训说明:</span>
|
|
|
|
|
<span class="list-elem">{{ courseModel.remarks }}</span>
|
|
|
|
|
</p>
|
|
|
|
|
</el-scrollbar>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="tip-foot">
|
|
|
|
|
<div v-show="!detailShow" class="foot-detail">
|
|
|
|
|
<el-button class="btn" @click="backList">查看试题</el-button>
|
|
|
|
|
<el-button v-if="!isFirst" class="btn" type="primary" @click="lastExam">上一题</el-button>
|
|
|
|
|
<el-button v-if="!isLast" class="btn" type="primary" @click="nextExam">下一题</el-button>
|
|
|
|
|
<el-button v-if="isLast" class="btn" type="primary" @click="overExam">提交试卷</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-show="detailShow" class="foot-submit">
|
|
|
|
|
<el-button class="btn" type="primary" @click="overExam">提交试卷</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
<p style="color: #000; float: left;">
|
|
|
|
|
<span class="time-label">考试计时:</span>
|
|
|
|
|
<span class="time-elem">{{ formatExamUsedTime }}</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="drag-right" />
|
|
|
|
|
<div class="drag-left" />
|
|
|
|
|
<div class="drag-bottom" />
|
|
|
|
|
<div class="drag-top" />
|
|
|
|
|
</div>
|
2019-07-26 13:32:43 +08:00
|
|
|
|
</div>
|
2019-08-19 10:31:11 +08:00
|
|
|
|
</div>
|
2019-07-26 13:32:43 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
2019-08-19 10:31:11 +08:00
|
|
|
|
import { mapGetters } from 'vuex';
|
|
|
|
|
import { timeFormat } from '@/utils/date';
|
|
|
|
|
import { refreshExamList } from '@/api/management/userexam';
|
|
|
|
|
import { getTrainingDetail } from '@/api/jmap/training';
|
|
|
|
|
import { launchFullscreen, exitFullscreen } from '@/utils/screen';
|
2019-07-26 13:32:43 +08:00
|
|
|
|
|
2019-08-19 10:31:11 +08:00
|
|
|
|
export default {
|
|
|
|
|
name: 'TipExamList',
|
|
|
|
|
components: {
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
training: {
|
|
|
|
|
id: '',
|
|
|
|
|
name: '',
|
|
|
|
|
remarks: ''
|
|
|
|
|
},
|
|
|
|
|
isShrink: false,
|
|
|
|
|
examName: '',
|
|
|
|
|
courseModel: {
|
|
|
|
|
id: '',
|
|
|
|
|
name: '',
|
|
|
|
|
maxDuration: '',
|
|
|
|
|
minDuration: '',
|
|
|
|
|
remarks: '',
|
|
|
|
|
updateTime: ''
|
|
|
|
|
},
|
|
|
|
|
detailShow: false,
|
|
|
|
|
examIndex: 0
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
...mapGetters('trainingList', [
|
|
|
|
|
'trainingList'
|
|
|
|
|
]),
|
|
|
|
|
formatExamUsedTime() {
|
|
|
|
|
return timeFormat(this.$store.state.exam.usedTime);
|
|
|
|
|
},
|
|
|
|
|
isFirst() {
|
|
|
|
|
return this.examIndex == 0;
|
|
|
|
|
},
|
|
|
|
|
isLast() {
|
|
|
|
|
return this.examIndex == this.trainingList.length - 1;
|
|
|
|
|
}
|
2019-07-26 13:32:43 +08:00
|
|
|
|
|
2019-08-19 10:31:11 +08:00
|
|
|
|
},
|
|
|
|
|
mounted() {
|
|
|
|
|
this.loadInitData();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
backList() {
|
|
|
|
|
this.detailShow = true;
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.$refs.treeQuestion.setCurrentKey(this.$route.query.examQuestionId); // value 绑定的node-key
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
// 获取试题详情
|
|
|
|
|
selectedTraining(obj) {
|
|
|
|
|
this.trainingList.forEach((item, index) => {
|
|
|
|
|
if (item.id == obj.id) {
|
|
|
|
|
this.examIndex = index;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if (obj) {
|
|
|
|
|
const that = this;
|
|
|
|
|
const data = { id: obj.trainingId };
|
|
|
|
|
getTrainingDetail(data).then(res => {
|
|
|
|
|
that.courseModel = {
|
|
|
|
|
id: res.data.id,
|
|
|
|
|
name: res.data.name,
|
|
|
|
|
maxDuration: res.data.maxDuration,
|
|
|
|
|
remarks: res.data.remarks,
|
|
|
|
|
minDuration: res.data.minDuration,
|
|
|
|
|
updateTime: res.data.updateTime
|
|
|
|
|
};
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
that.$message.error('获取试题息失败:' + error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
2019-07-26 13:32:43 +08:00
|
|
|
|
|
2019-08-19 10:31:11 +08:00
|
|
|
|
this.jump(obj);
|
|
|
|
|
},
|
|
|
|
|
getTrainDetail(obj) {
|
|
|
|
|
this.selectedTraining(obj);
|
|
|
|
|
this.detailShow = false;
|
|
|
|
|
},
|
|
|
|
|
// 获取试题列表
|
|
|
|
|
loadInitData() {
|
|
|
|
|
this.$store.dispatch('exam/countUsedTime');
|
|
|
|
|
// 刷新考试列表
|
|
|
|
|
refreshExamList(this.$route.query.userExamId).then(response => {
|
|
|
|
|
this.examName = response.data.examName;
|
|
|
|
|
this.$store.dispatch('exam/setUsedTime', response.data.usedTime);
|
|
|
|
|
this.$store.dispatch('exam/setTotalTime', response.data.duration);
|
|
|
|
|
this.$store.dispatch('trainingList/setTrainingList', response.data.userExamQuestionsVOs).then(response => { });
|
|
|
|
|
const obj = {
|
|
|
|
|
trainingId: '',
|
|
|
|
|
id: ''
|
|
|
|
|
};
|
|
|
|
|
if (this.$route.query.examQuestionId && this.$route.query.trainingId) {
|
|
|
|
|
obj.trainingId = this.$route.query.trainingId;
|
|
|
|
|
obj.id = this.$route.query.examQuestionId;
|
|
|
|
|
} else {
|
|
|
|
|
obj.trainingId = response.data.userExamQuestionsVOs[0].trainingId;
|
|
|
|
|
obj.id = response.data.userExamQuestionsVOs[0].id;
|
|
|
|
|
}
|
|
|
|
|
this.selectedTraining(obj);
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
// 如果时50009则表示考试已完成,不能再次进行y
|
|
|
|
|
if (error.code === 500009) {
|
|
|
|
|
this.$router.replace({ path: `/exam/result/${this.$route.params.userExamId}` });
|
|
|
|
|
} else {
|
|
|
|
|
this.$messageBox(`刷新列表失败`);
|
|
|
|
|
}
|
|
|
|
|
});
|
2019-07-26 13:32:43 +08:00
|
|
|
|
|
2019-08-19 10:31:11 +08:00
|
|
|
|
this.shrink();
|
|
|
|
|
},
|
|
|
|
|
nextExam() {
|
|
|
|
|
const obj = {
|
|
|
|
|
trainingId: '',
|
|
|
|
|
id: ''
|
|
|
|
|
};
|
|
|
|
|
if (this.trainingList[this.examIndex + 1] && this.trainingList[this.examIndex + 1].trainingId) {
|
|
|
|
|
obj.trainingId = this.trainingList[this.examIndex + 1].trainingId;
|
|
|
|
|
obj.id = this.trainingList[this.examIndex + 1].id;
|
|
|
|
|
this.examIndex = this.examIndex + 1;
|
|
|
|
|
}
|
|
|
|
|
if (obj.trainingId && obj.id) {
|
|
|
|
|
this.selectedTraining(obj);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
lastExam() {
|
|
|
|
|
const obj = {
|
|
|
|
|
trainingId: '',
|
|
|
|
|
id: ''
|
|
|
|
|
};
|
|
|
|
|
if (this.trainingList[this.examIndex - 1] && this.trainingList[this.examIndex - 1].trainingId) {
|
|
|
|
|
obj.trainingId = this.trainingList[this.examIndex - 1].trainingId;
|
|
|
|
|
obj.id = this.trainingList[this.examIndex - 1].id;
|
|
|
|
|
this.examIndex = this.examIndex - 1;
|
|
|
|
|
}
|
|
|
|
|
if (obj.trainingId && obj.id) {
|
|
|
|
|
this.selectedTraining(obj);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
jump(obj) {
|
|
|
|
|
const query = {
|
|
|
|
|
group: this.$route.query.group,
|
|
|
|
|
userExamId: this.$route.query.userExamId,
|
|
|
|
|
trainingId: obj.trainingId,
|
|
|
|
|
examQuestionId: obj.id
|
|
|
|
|
};
|
|
|
|
|
this.$router.push({ path: '/display/exam', query: query });
|
|
|
|
|
this.$emit('refresh');
|
|
|
|
|
launchFullscreen();
|
|
|
|
|
},
|
|
|
|
|
overExam() {
|
|
|
|
|
this.$store.dispatch('exam/isOver').then(isOver => {
|
|
|
|
|
if (isOver) {
|
|
|
|
|
this.submit();
|
|
|
|
|
} else {
|
|
|
|
|
this.$confirm('考试未完成,是否确认退出?', '提示', {
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
type: 'warning',
|
|
|
|
|
center: true
|
|
|
|
|
}).then(() => {
|
|
|
|
|
this.submit();
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
submit() {
|
|
|
|
|
exitFullscreen();
|
|
|
|
|
this.$store.dispatch('exam/over').then(() => {
|
|
|
|
|
this.$store.dispatch('trainingList/clearTrainingList');
|
|
|
|
|
this.$router.replace({ path: `/exam/result/${this.$route.query.userExamId}` });
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
shrink() {
|
|
|
|
|
const height = this.$refs.dragBody.offsetHeight + 40;
|
|
|
|
|
const top = this.$refs.drapBox.style.top;
|
|
|
|
|
if (this.isShrink) {
|
|
|
|
|
this.$refs.drapBox.style.height = '40px';
|
|
|
|
|
this.$refs.drapBox.style.top = '';
|
|
|
|
|
this.isShrink = false;
|
|
|
|
|
} else {
|
|
|
|
|
this.$refs.drapBox.style.height = height + 'px';
|
|
|
|
|
this.$refs.drapBox.style.top = top;
|
|
|
|
|
this.isShrink = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2019-07-26 13:32:43 +08:00
|
|
|
|
</script>
|
|
|
|
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
|
|
|
|
@import "src/styles/mixin.scss";
|
|
|
|
|
|
|
|
|
|
.tip-body-box {
|
|
|
|
|
position: relative;
|
|
|
|
|
height: 430px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.reminder-box {
|
|
|
|
|
position: absolute;
|
|
|
|
|
float: left;
|
|
|
|
|
left: 15px;
|
|
|
|
|
bottom: 15px;
|
|
|
|
|
width: 650px;
|
|
|
|
|
height: 470px;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
z-index: 10;
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
|
|
|
|
.tip-title {
|
|
|
|
|
width: 100%;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
height: 40px;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
flex-direction: row-reverse;
|
|
|
|
|
background-color: #409EFF;
|
|
|
|
|
border-radius: 5px 5px 0 0;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
padding: 0 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.drag-right,
|
|
|
|
|
.drag-left {
|
|
|
|
|
width: 10px;
|
|
|
|
|
cursor: e-resize;
|
|
|
|
|
background-color: yellow;
|
|
|
|
|
height: 100%;
|
|
|
|
|
position: absolute;
|
|
|
|
|
right: 0;
|
|
|
|
|
top: 0;
|
|
|
|
|
opacity: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.drag-left {
|
|
|
|
|
left: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.drag-bottom {
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 10px;
|
|
|
|
|
cursor: s-resize;
|
|
|
|
|
background-color: yellow;
|
|
|
|
|
opacity: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.drag-top {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: -45px;
|
|
|
|
|
left: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 10px;
|
|
|
|
|
cursor: s-resize;
|
|
|
|
|
background-color: yellow;
|
|
|
|
|
opacity: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tip-body {
|
|
|
|
|
height: 366px;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
|
|
|
|
|
.list-label {
|
|
|
|
|
width: 105px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tip-foot {
|
|
|
|
|
width: 100%;
|
|
|
|
|
position: absolute;
|
|
|
|
|
right: 0px;
|
|
|
|
|
bottom: 0px;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
padding: 10px 0 10px 10px;
|
|
|
|
|
|
|
|
|
|
.foot-detail {
|
|
|
|
|
height: 100%;
|
|
|
|
|
float: right;
|
|
|
|
|
margin-top: 9px;
|
|
|
|
|
padding-right: 15px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.foot-submit {
|
|
|
|
|
float: right;
|
|
|
|
|
margin-top: 9px;
|
|
|
|
|
padding-right: 15px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
|
float: right;
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
background-color: #f3f3f3;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/deep/ {
|
|
|
|
|
.el-tree-node__content {
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
|
|
|
|
|
background-color: #d6e5f7;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-08-19 10:31:11 +08:00
|
|
|
|
</style>
|