Merge branch 'test_dispaly' of https://git.code.tencent.com/lian-cbtc/jl-client into test_dispaly
This commit is contained in:
commit
1d565398e9
@ -124,11 +124,12 @@ export function regenerateRule(mapId) {
|
||||
/**
|
||||
* LIST -
|
||||
* 根据试卷蓝图名称简介分页查找某个组织的试卷蓝图
|
||||
* @param {Number} orgId 组织ID
|
||||
* @param {String} name 试卷蓝图名称
|
||||
* @param {String} profile 试卷蓝图简介
|
||||
* @param {Number} findState 状态: (All(1)-所有,Editing(2)-正在编辑的,CanUse(3)-可以用于生成试卷的,Locked(4)-封存,Used(5)-已经被使用过)
|
||||
* @param {Number} orderBy 排序依据: (1--创建时间 2--更新时间 3--名称;默认值为1)
|
||||
* @param {Object} data
|
||||
* @param {Number} data.orgId 组织ID
|
||||
* @param {String} data.name 试卷蓝图名称
|
||||
* @param {String} data.profile 试卷蓝图简介
|
||||
* @param {Number} data.findState 状态: (All(1)-所有,Editing(2)-正在编辑的,CanUse(3)-可以用于生成试卷的,Locked(4)-封存,Used(5)-已经被使用过)
|
||||
* @param {Number} data.orderBy 排序依据: (1--创建时间 2--更新时间 3--名称;默认值为1)
|
||||
*/
|
||||
export function getPapaerListOfOrg({ orgId, ...data }) {
|
||||
return request({
|
||||
@ -140,6 +141,7 @@ export function getPapaerListOfOrg({ orgId, ...data }) {
|
||||
|
||||
/**
|
||||
* 创建试卷蓝图
|
||||
* @param {Object} data
|
||||
* @param {Number} data.orgId 组织ID
|
||||
* @param {String} data.name 试卷蓝图名称
|
||||
* @param {String} data.profile 简介
|
||||
@ -166,6 +168,7 @@ export function createPaper(data) {
|
||||
}
|
||||
|
||||
/** 修改试卷蓝图基本信息
|
||||
* @param {Object} data
|
||||
* @param {Number} data.id 试卷蓝图ID
|
||||
* @param {Number} data.orgId 组织ID
|
||||
* @param {String} data.name 试卷蓝图名称
|
||||
@ -203,6 +206,7 @@ export function getPaperDetail(pcId) {
|
||||
}
|
||||
|
||||
/** 查询组织下各类型题的数量
|
||||
* @param {Object} data
|
||||
* @param {Number} data.orgId
|
||||
* @param {Number} data.subtype
|
||||
* @param {Array<String>} data.tags
|
||||
@ -260,12 +264,11 @@ export function deleteUserExam(param) {
|
||||
return request({
|
||||
url: `/api/v2/paper/user/${puId}`,
|
||||
method: 'method',
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取用户试卷完整信息
|
||||
* @param {Number} pcId 用户试卷Id
|
||||
* @param {Number} puId 用户试卷Id
|
||||
*/
|
||||
export function getUserExamInfo(puId) {
|
||||
return request({
|
||||
@ -273,3 +276,38 @@ export function getUserExamInfo(puId) {
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/** 加载用户试卷试题 */
|
||||
export function loadQuestion({ type, questionId, puId }) {
|
||||
return request({
|
||||
url: `/api/v2/paper/user/question/${type}/${questionId}/${puId}`,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/** 提交答案
|
||||
* @param {Object} data
|
||||
* @param {Number} data.puId 用户试卷id
|
||||
* @param {Number} data.pqId 用户试卷试题id
|
||||
* @param {Number} data.type 试题类型
|
||||
* @param {Number} data.subType 试题子类型
|
||||
* @param {Number} data.answer 答案(理论题)
|
||||
* @param {Boolean} data.trainingSuccess 是否完成(实训题)
|
||||
*/
|
||||
export function submitAnswer(data) {
|
||||
return request({
|
||||
url: `/api/v2/paper/user/question/answer`,
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
/** 交卷
|
||||
* @param {Number} puId 用户试卷id
|
||||
*/
|
||||
export function submitPaper(puId) {
|
||||
return request({
|
||||
url: `/api/v2/paper/user/${puId}/submit`,
|
||||
method: 'POST',
|
||||
})
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ export function handlerUrl() {
|
||||
// BASE_API = 'https://joylink.club/jlcloud';
|
||||
// BASE_API = 'https://test.joylink.club/jlcloud';
|
||||
// BASE_API = 'http://114.116.51.125/jlcloud';
|
||||
// BASE_API = 'http://192.168.3.90:9100'; // 周寅
|
||||
// BASE_API = 'http://192.168.3.90:9000'; // 周寅
|
||||
// BASE_API = 'http://192.168.3.94:9000'; // 旭强
|
||||
// BASE_API = 'http://192.168.3.15:9000'; // 张赛
|
||||
// BASE_API = 'http://192.168.3.5:9000'; // 夏增彬
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-dialogDrag :close-on-click-moda="false" :title="title" :visible.sync="show" width="860px" :close-on-click-modal="false" :before-close="doClose">
|
||||
<el-dialog v-dialogDrag :title="title" :visible.sync="show" width="860px" :close-on-click-modal="false" :before-close="doClose">
|
||||
<div class="ql-editor" v-html="$escapeHTML(`【${mapType[type] || ''}】题 目: ${form.topic}`)" />
|
||||
<template v-if="checkType(form, 'judge')">
|
||||
<div class="answer">
|
||||
|
@ -1,28 +1,140 @@
|
||||
<template>
|
||||
<div class="examPanel">
|
||||
<div class="examPanel" v-if="show">
|
||||
<div class="header">
|
||||
<div>满分: {{ composition.fullScore }}</div>
|
||||
<div>考试时间: {{ composition.validDuration }}分钟</div>
|
||||
</div>
|
||||
<div class="questionList"></div>
|
||||
<div class="legend-area">
|
||||
<div class="legend">
|
||||
<div class="box finished"></div>
|
||||
<div class="text">已作答</div>
|
||||
</div>
|
||||
<div class="legend">
|
||||
<div class="box"></div>
|
||||
<div class="text">未作答</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>理论题</div>
|
||||
<div class="questionList">
|
||||
<div
|
||||
class="item theory"
|
||||
v-for="(question, index) in questionList[0]"
|
||||
:key="index"
|
||||
@click="questionSelect(index, 1)"
|
||||
:class="{
|
||||
current: currentQuestionIndex === index && currentQuestionType === 1,
|
||||
submited: questionStateList[0][index],
|
||||
}"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</div>
|
||||
</div>
|
||||
<div>实训题</div>
|
||||
<div class="questionList">
|
||||
<div
|
||||
class="item training"
|
||||
v-for="(question, index) in questionList[1]"
|
||||
:key="index"
|
||||
@click="questionSelect(index, 2)"
|
||||
:class="{ current: currentQuestionIndex === index && currentQuestionType === 2 }"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<el-button @click="submitExam" size="small" type="primary">交卷</el-button>
|
||||
</div>
|
||||
<TheoryQuestion
|
||||
ref="theoryQuestion"
|
||||
:question-info="
|
||||
questionList[0][currentQuestionIndex]
|
||||
? {
|
||||
...questionList[0][currentQuestionIndex],
|
||||
index: currentQuestionIndex,
|
||||
total: questionList[0].length,
|
||||
}
|
||||
: {}
|
||||
"
|
||||
@submit="recordSubmit"
|
||||
@navigate="navigate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TheoryQuestion from './theoryQuestion'
|
||||
import { submitPaper } from '@/api/management/exam'
|
||||
export default {
|
||||
name: 'ExamPanel',
|
||||
emits: ['select'],
|
||||
components: { TheoryQuestion },
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
composition: {},
|
||||
paper: {},
|
||||
questionList: {},
|
||||
questionList: [[], []],
|
||||
questionStateList: [[], []],
|
||||
currentQuestionIndex: 0,
|
||||
currentQuestionType: 0, //1-理论, 2-实训
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init(data) {
|
||||
this.show = true
|
||||
this.currentQuestionIndex = -1
|
||||
this.composition = data.composition
|
||||
this.paper = data.paper
|
||||
this.questionList = data.questionList
|
||||
this.questionList = [
|
||||
data.questionList.filter(e => e.type === 1),
|
||||
data.questionList.filter(e => e.type === 2),
|
||||
]
|
||||
this.questionStateList = [
|
||||
Array.from(this.questionList[0], () => false),
|
||||
Array.from(this.questionList[1], () => false),
|
||||
]
|
||||
},
|
||||
questionSelect(index, type) {
|
||||
this.currentQuestionIndex = index
|
||||
this.currentQuestionType = type
|
||||
if (type === 1) {
|
||||
this.$refs.theoryQuestion.doShow()
|
||||
}
|
||||
},
|
||||
recordSubmit(index) {
|
||||
this.$set(this.questionStateList[0], index, true)
|
||||
},
|
||||
navigate(direction) {
|
||||
if (direction === '+') {
|
||||
this.currentQuestionIndex++
|
||||
} else if (direction === '-') {
|
||||
this.currentQuestionIndex--
|
||||
}
|
||||
},
|
||||
submitExam() {
|
||||
const execSubmit = () => {
|
||||
submitPaper(this.paper.id).then(resp => {
|
||||
const { score, passScore, commonScore, trainingScore } = resp.data
|
||||
const pass = score >= passScore
|
||||
this.$alert(
|
||||
`${pass ? '恭喜您考试合格' : '考试不通过'}
|
||||
总分: ${score}
|
||||
理论: ${commonScore}
|
||||
实训: ${trainingScore}`,
|
||||
'考试结果'
|
||||
).then(() => {
|
||||
this.show = false
|
||||
})
|
||||
})
|
||||
}
|
||||
const finished = this.questionStateList.every(list => list.every(item => item === true))
|
||||
if (!finished) {
|
||||
this.$confirm('您还有题目未答完, 确认交卷吗?').then(() => {
|
||||
execSubmit()
|
||||
})
|
||||
} else {
|
||||
execSubmit()
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -31,9 +143,65 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
.examPanel {
|
||||
position: fixed;
|
||||
background: #fff;
|
||||
background: #fff;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 190px;
|
||||
.header {
|
||||
padding: 10px;
|
||||
}
|
||||
.legend-area {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
.legend {
|
||||
display: flex;
|
||||
.box {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
background: #eee;
|
||||
}
|
||||
.finished {
|
||||
border: 1px solid #67c23a;
|
||||
}
|
||||
}
|
||||
}
|
||||
.questionList {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
|
||||
.item {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-color: #eee;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
margin: 3px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
&:active {
|
||||
background: #409eff;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.current {
|
||||
background: #409eff;
|
||||
color: #fff;
|
||||
&:hover {
|
||||
background: #66b1ff;
|
||||
}
|
||||
}
|
||||
.submited {
|
||||
border: 1px solid #67c23a;
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -98,6 +98,7 @@ export default {
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e)
|
||||
this.$message.error(e.message)
|
||||
})
|
||||
},
|
||||
},
|
||||
|
146
src/views/newMap/display/exam/theoryQuestion.vue
Normal file
146
src/views/newMap/display/exam/theoryQuestion.vue
Normal file
@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-dialogDrag
|
||||
:title="`第 ${index + 1} 题`"
|
||||
:visible.sync="show"
|
||||
width="860px"
|
||||
:close-on-click-modal="false"
|
||||
:before-close="doClose"
|
||||
:append-to-body="true"
|
||||
>
|
||||
<div class="questionTitle">[{{ questionData.typeString }}] {{ questionData.title }}</div>
|
||||
<div class="options">
|
||||
<component
|
||||
:is="type === 2 ? 'el-checkbox-group' : 'el-radio-group'"
|
||||
v-model="questionData.answer"
|
||||
class="options-container"
|
||||
>
|
||||
<component
|
||||
class="option"
|
||||
:is="type === 2 ? 'el-checkbox' : 'el-radio'"
|
||||
v-for="el in questionData.options"
|
||||
:key="el.value"
|
||||
:label="el.value"
|
||||
>{{ el.label }}</component
|
||||
>
|
||||
</component>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<el-button size="small" :disabled="index === 0" @click="navigate('-')">上一题</el-button>
|
||||
<el-button type="danger" size="small" @click="navigate()">关闭</el-button>
|
||||
<el-button size="small" :disabled="index >= questionInfo.total - 1" @click="navigate('+')"
|
||||
>下一题</el-button
|
||||
>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const types = ['', '单选题', '多选题', '判断题']
|
||||
import { loadQuestion, submitAnswer } from '@/api/management/exam'
|
||||
export default {
|
||||
name: 'theoryQuestion',
|
||||
emits: ['submit'],
|
||||
props: {
|
||||
questionInfo: {
|
||||
type: Object,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
type: 0,
|
||||
questionData: {
|
||||
title: '',
|
||||
typeString: '',
|
||||
options: [],
|
||||
answer: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
index() {
|
||||
return this.questionInfo.index
|
||||
},
|
||||
puId() {
|
||||
return this.questionInfo.puId
|
||||
},
|
||||
questionId() {
|
||||
return this.questionInfo.questionId
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
index() {
|
||||
if (this.questionId && this.questionInfo.puId) {
|
||||
this.loadQuestion()
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
doShow() {
|
||||
this.show = true
|
||||
},
|
||||
loadQuestion() {
|
||||
loadQuestion({ /* 理论题 */ type: 1, questionId: this.questionId, puId: this.questionInfo.puId }).then(
|
||||
resp => {
|
||||
const data = resp.data.common
|
||||
this.questionData = {
|
||||
title: data.question,
|
||||
typeString: types[data.type],
|
||||
options: data.optionList.map(opt => ({ label: opt.content, value: opt.id })),
|
||||
answer: data.type === 2 ? [] : NaN,
|
||||
}
|
||||
this.type = data.type
|
||||
if (resp.data.tmpAnswer) {
|
||||
const tmpAnswer = resp.data.tmpAnswer.split(',').map(s => Number(s))
|
||||
this.questionData.answer = data.type === 2 ? tmpAnswer : tmpAnswer[0]
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
doClose() {
|
||||
this.show = false
|
||||
},
|
||||
submit() {
|
||||
const data = {
|
||||
puId: this.puId,
|
||||
pqId: this.questionId,
|
||||
type: 1,
|
||||
subType: this.type,
|
||||
answer: this.type === 2 ? this.questionData.answer : [this.questionData.answer],
|
||||
}
|
||||
submitAnswer(data).then(resp => {
|
||||
// console.log(resp)
|
||||
})
|
||||
},
|
||||
navigate(direction) {
|
||||
const selected = this.type === 2 ? !!this.questionData.answer.length : !isNaN(this.questionData.answer)
|
||||
if (selected) {
|
||||
this.submit()
|
||||
this.$emit('submit', this.index, direction)
|
||||
}
|
||||
this.$emit('navigate', direction)
|
||||
if (!direction) this.doClose()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.questionTitle {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.options-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
& > .option {
|
||||
line-height: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
File diff suppressed because it is too large
Load Diff
@ -112,7 +112,7 @@ export default {
|
||||
let tags = [];
|
||||
if (row.abilityVOList) {
|
||||
row.abilityVOList.forEach(item => {
|
||||
tags.push(item.ability);
|
||||
tags.push(item.abilityName);
|
||||
});
|
||||
} else {
|
||||
tags = '';
|
||||
|
Loading…
Reference in New Issue
Block a user