578 lines
18 KiB
Vue
578 lines
18 KiB
Vue
<template>
|
||
<ai-detail class="AppExaminationManage-add">
|
||
<template slot="title">
|
||
<ai-title :title="params.id ? '编辑' + '考试' : '添加' + '考试'" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title>
|
||
</template>
|
||
<template slot="content">
|
||
<ai-card title="基本信息">
|
||
<template #content>
|
||
<el-form class="ai-form" :model="form" label-width="120px" ref="form">
|
||
<el-form-item label="考试名称" prop="examinationName" :rules="[{required: true, message: '请输入考试名称', trigger: 'blur'}]">
|
||
<el-input size="small" v-model="form.examinationName" clearable placeholder="请输入考试名称" :maxlength="50" :show-word-limit="true"></el-input>
|
||
</el-form-item>
|
||
<el-form-item prop="showIndex" label="排序" :rules="[{required: true, message: '请选择排序', trigger: 'change'}]">
|
||
<el-input-number size="small" v-model="form.showIndex" :min="0"></el-input-number>
|
||
</el-form-item>
|
||
<el-form-item prop="examinationType" label="考试类型" :rules="[{required: true, message: '请选择考试类型', trigger: 'change'}]">
|
||
<ai-select
|
||
v-model="form.examinationType"
|
||
clearable
|
||
placeholder="请选择"
|
||
:selectList="dict.getDict('qjExaminationType')">
|
||
</ai-select>
|
||
</el-form-item>
|
||
<el-form-item prop="examinationDuration" v-if="form.examinationType === '1'" label="考试学时" style="width: 100%" :rules="[{required: true, message: '请输入', trigger: 'change'}]">
|
||
<el-input-number size="small" v-model="form.examinationDuration" :min="1"></el-input-number>(分钟)
|
||
</el-form-item>
|
||
<el-form-item prop="certificateId" v-if="form.examinationType === '1'" label="关联证书" :rules="[{required: true, message: '请选择关联证书', trigger: 'change'}]">
|
||
<ai-select
|
||
v-model="form.certificateId"
|
||
clearable
|
||
placeholder="请选择"
|
||
:selectList="certificateList">
|
||
</ai-select>
|
||
</el-form-item>
|
||
<el-form-item prop="chooseType" style="width: 100%" label="成绩评核" :rules="[{required: true, message: '请选择成绩评核', trigger: 'change'}]">
|
||
<div class="type-list">
|
||
<div class="type-item" v-for="(item, index) in form.assessments" :key="index">
|
||
<span class="type-name">{{ dict.getLabel('qjEAType', item.assessmentType) }}</span>
|
||
<ai-select
|
||
style="width: 180px;"
|
||
v-model="item.upCondition"
|
||
clearable
|
||
placeholder="请选择"
|
||
:selectList="dict.getDict('qjEACondition')">
|
||
</ai-select>
|
||
<el-input size="small" style="width: 180px;" v-model="item.upScore" placeholder="请输入"></el-input>
|
||
</div>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item prop="chooseType" label="选题方式" :rules="[{required: true, message: '请选择选题方式', trigger: 'change'}]">
|
||
<el-radio-group v-model="form.chooseType" @change="form.questions = []">
|
||
<el-radio :label="item.dictValue" :key="item.dictValue" v-for="item in dict.getDict('qjEIChooseType')">{{ item.dictName }}</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<el-form-item prop="subjectConfigs" style="width: 100%;" label="题目设置" :rules="[{required: true, message: '请选择题目设置', trigger: 'change'}]">
|
||
<div class="type-list">
|
||
<div class="choose-item" v-for="(item, index) in form.subjectConfigs" :key="index">
|
||
<span class="type-name">{{ dict.getLabel('qjQBType', item.subjectType) }}题:</span>
|
||
<div class="form-wrapper">
|
||
<div class="form-item">
|
||
<span>总题数</span>
|
||
<el-input-number size="small" v-model="item.subjectNumber" :min="0"></el-input-number>
|
||
</div>
|
||
<div class="form-item">
|
||
<span>每题分数</span>
|
||
<el-input-number size="small" v-model="item.eachScore" :min="0"></el-input-number>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item style="width: 100%;" label="">
|
||
<el-button size="small" type="primary" style="width: 100px;" @click="toAdd">确定设置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
<ai-dialog
|
||
:visible.sync="isShow"
|
||
@onConfirm="onConfirm"
|
||
width="890px"
|
||
title="选择试题">
|
||
<ai-search-bar class="search-bar">
|
||
<template #left>
|
||
<ai-select
|
||
style="width: 180px;"
|
||
v-model="search.type"
|
||
clearable
|
||
placeholder="请选择试题类型"
|
||
:selectList="dict.getDict('qjQBType')"
|
||
@change="search.current = 1, getList()">
|
||
</ai-select>
|
||
</template>
|
||
<template #right>
|
||
<el-input
|
||
v-model="search.title"
|
||
class="search-input"
|
||
size="small"
|
||
v-throttle="() => {search.current = 1, getList()}"
|
||
placeholder="请输入标题"
|
||
clearable
|
||
@clear="search.current = 1, getList()"
|
||
suffix-icon="iconfont iconSearch">
|
||
</el-input>
|
||
</template>
|
||
</ai-search-bar>
|
||
<el-checkbox-group v-model="ids">
|
||
<el-checkbox style="width: 100%;" :label="item.id" v-for="(item, index) in tableData" :key="index">
|
||
<span>{{ dict.getLabel('qjQBType', item.type) }}题</span>
|
||
<span :title="item.title">{{ item.title }}</span>
|
||
</el-checkbox>
|
||
</el-checkbox-group>
|
||
<el-pagination
|
||
style="margin-top: 20px;"
|
||
background
|
||
:current-page.sync="search.current"
|
||
:total="total"
|
||
:page-size.sync="search.size"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
layout="slot,->, prev, pager, next, sizes, jumper"
|
||
:pager-count="7"
|
||
@size-change="getList"
|
||
@current-change="getList">
|
||
</el-pagination>
|
||
</ai-dialog>
|
||
</template>
|
||
</ai-card>
|
||
|
||
<ai-card title="试题" v-if="form.questions.length">
|
||
<template #content>
|
||
<ai-wrapper
|
||
class="topic-item"
|
||
v-for="(item, index) in form.questions"
|
||
:key="index"
|
||
label-width="120px">
|
||
<ai-info-item label="题目描述" isLine :value="item.title"></ai-info-item>
|
||
<ai-info-item label="题目类型" :value="dict.getLabel('qjQBType', item.type)"></ai-info-item>
|
||
<ai-info-item label="正确答案" :value="item.answer"></ai-info-item>
|
||
<ai-info-item label="题目选项" isLine>
|
||
<div class="">
|
||
<div class="options" v-for="(e, index) in item.items" :key="index">
|
||
<span>{{ e.sort }}:</span>
|
||
<span>{{ e.content }}</span>
|
||
</div>
|
||
</div>
|
||
</ai-info-item>
|
||
<ai-info-item label="答案解析" isLine>
|
||
<AiArticle :value="item.analysis"></AiArticle>
|
||
</ai-info-item>
|
||
</ai-wrapper>
|
||
</template>
|
||
</ai-card>
|
||
</template>
|
||
<template #footer>
|
||
<el-button @click="cancel">取消</el-button>
|
||
<el-button type="primary" @click="confirm">提交</el-button>
|
||
</template>
|
||
</ai-detail>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: 'Add',
|
||
|
||
props: {
|
||
instance: Function,
|
||
dict: Object,
|
||
params: Object
|
||
},
|
||
data () {
|
||
return {
|
||
info: {},
|
||
form: {
|
||
examinationName: '',
|
||
title: '',
|
||
examinationDuration : '',
|
||
certificateId: '',
|
||
certificateName: '',
|
||
examinationType: '',
|
||
showIndex: '',
|
||
chooseType: '0',
|
||
questions: [],
|
||
assessments: [{
|
||
assessmentType: '0',
|
||
status: '',
|
||
upCondition: '',
|
||
upScore: ''
|
||
}, {
|
||
assessmentType: '1',
|
||
status: '',
|
||
upCondition: '',
|
||
upScore: ''
|
||
}, {
|
||
assessmentType: '2',
|
||
status: '',
|
||
upCondition: '',
|
||
upScore: ''
|
||
}, {
|
||
assessmentType: '3',
|
||
status: '',
|
||
upCondition: '',
|
||
upScore: ''
|
||
}],
|
||
subjectConfigs: [{
|
||
eachScore: '',
|
||
subjectNumber: '',
|
||
subjectType: '0'
|
||
}, {
|
||
eachScore: '',
|
||
subjectNumber: '',
|
||
subjectType: '1'
|
||
}, {
|
||
eachScore: '',
|
||
subjectNumber: '',
|
||
subjectType: '2'
|
||
}]
|
||
},
|
||
search: {
|
||
current: 1,
|
||
size: 10,
|
||
title: '',
|
||
type: ''
|
||
},
|
||
total: 10,
|
||
colConfigs: [
|
||
{ type: 'selection' },
|
||
{ prop: 'type', label: '题目类型', align: 'left', format: v => this.dict.getLabel('qjQBType', v) + '题' },
|
||
{ prop: 'title', label: '题目', align: 'center' },
|
||
],
|
||
tableData: [],
|
||
isShow: false,
|
||
ids: [],
|
||
sort: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],
|
||
certificateList: []
|
||
}
|
||
},
|
||
|
||
computed: {
|
||
answerTotal () {
|
||
let subjectNumber = 0
|
||
this.form.subjectConfigs.forEach(v => {
|
||
subjectNumber = Number(v.subjectNumber) + subjectNumber
|
||
})
|
||
|
||
return subjectNumber
|
||
}
|
||
},
|
||
|
||
created () {
|
||
this.getList()
|
||
this.getCertificateList()
|
||
this.dict.load(['qjQBType', 'qjEIChooseType', 'qjEACondition', 'qjEAType', 'qjExaminationType']).then(() => {
|
||
if (this.params && this.params.id) {
|
||
this.id = this.params.id
|
||
this.getInfo(this.params.id)
|
||
}
|
||
})
|
||
},
|
||
|
||
methods: {
|
||
getInfo (id) {
|
||
this.instance.post(`/app/appexaminationinfo/queryDetailById?id=${id}`).then(res => {
|
||
if (res.code === 0) {
|
||
this.form = {
|
||
...res.data,
|
||
questions: res.data.questions.map(v => {
|
||
let answer = []
|
||
v.items.forEach((e, index) => {
|
||
if (e.checked === '1') {
|
||
answer.push(this.sort[index])
|
||
}
|
||
})
|
||
return {
|
||
...v,
|
||
answer: answer.join(',')
|
||
}
|
||
})
|
||
}
|
||
}
|
||
})
|
||
},
|
||
|
||
getCertificateList() {
|
||
this.instance.post(`/app/appcertificateinfo/list`, null, {
|
||
params: {
|
||
...this.search,
|
||
size: 1000
|
||
}
|
||
}).then(res => {
|
||
if (res.code == 0) {
|
||
this.certificateList = res.data.records.map(v => {
|
||
return {
|
||
dictName: v.certificateName,
|
||
dictValue: v.id
|
||
}
|
||
})
|
||
}
|
||
})
|
||
},
|
||
onChange () {
|
||
this.getList()
|
||
},
|
||
|
||
onConfirm () {
|
||
if (this.ids.length !== this.answerTotal) {
|
||
return this.$message.error(`请选择${this.answerTotal}道题目`)
|
||
}
|
||
|
||
this.instance.post(`/app/appquestionbank/queryDetailByIds`, this.ids).then(res => {
|
||
if (res.code == 0) {
|
||
this.form.questions = res.data.map(v => {
|
||
let answer = []
|
||
v.items.forEach((e, index) => {
|
||
if (e.checked === '1') {
|
||
answer.push(this.sort[index])
|
||
}
|
||
})
|
||
return {
|
||
...v,
|
||
answer: answer.join(',')
|
||
}
|
||
})
|
||
|
||
this.isShow = false
|
||
}
|
||
})
|
||
},
|
||
|
||
getList() {
|
||
this.instance.post(`/app/appquestionbank/list`, null, {
|
||
params: {
|
||
...this.search
|
||
}
|
||
}).then(res => {
|
||
if (res.code == 0) {
|
||
this.tableData = res.data.records
|
||
this.total = res.data.total
|
||
}
|
||
})
|
||
},
|
||
|
||
toAdd () {
|
||
if (this.form.chooseType === '0') {
|
||
this.getRandomChoose()
|
||
} else {
|
||
this.isShow = true
|
||
}
|
||
},
|
||
|
||
getRandomChoose() {
|
||
let subjectNumber = 0
|
||
let eachScore = 0
|
||
this.form.subjectConfigs.forEach(v => {
|
||
eachScore = Number(v.eachScore) + eachScore
|
||
subjectNumber = Number(v.subjectNumber) + subjectNumber
|
||
})
|
||
|
||
if (subjectNumber === 0 || eachScore === 0) {
|
||
return this.$message.error('请进行题目设置')
|
||
}
|
||
|
||
this.instance.post(`/app/appquestionbank/randomChoose`, this.form.subjectConfigs).then(res => {
|
||
if (res.code == 0) {
|
||
this.form.questions = res.data.map(v => {
|
||
let answer = []
|
||
v.items.forEach((e, index) => {
|
||
if (e.checked === '1') {
|
||
answer.push(this.sort[index])
|
||
}
|
||
})
|
||
return {
|
||
...v,
|
||
answer: answer.join(',')
|
||
}
|
||
})
|
||
}
|
||
})
|
||
},
|
||
|
||
confirm () {
|
||
this.$refs.form.validate((valid) => {
|
||
if (valid) {
|
||
let subjectNumber = 0
|
||
let eachScore = 0
|
||
|
||
for (let i = 0; i < this.form.assessments.length; i++) {
|
||
if (!this.form.assessments[i].upCondition) {
|
||
return this.$message.error(`${this.dict.getLabel('qjEAType', this.form.assessments[i].assessmentType)}不能为空`)
|
||
}
|
||
if (!this.form.assessments[i].upScore && this.form.assessments[i].upScore !== '0') {
|
||
return this.$message.error(`${this.dict.getLabel('qjEAType', this.form.assessments[i].assessmentType)}分值不能为空`)
|
||
}
|
||
}
|
||
|
||
this.form.subjectConfigs.forEach(v => {
|
||
eachScore = Number(v.eachScore) + eachScore
|
||
subjectNumber = Number(v.subjectNumber) + subjectNumber
|
||
})
|
||
if (subjectNumber === 0 || eachScore === 0) {
|
||
return this.$message.error('请进行题目设置')
|
||
}
|
||
|
||
if (!this.form.questions.length) {
|
||
return this.$message.error('请选择试题')
|
||
}
|
||
|
||
this.instance.post(`/app/appexaminationinfo/addOrUpdate`, {
|
||
...this.form,
|
||
id: this.params.id || '',
|
||
certificateName: this.form.examinationType === '1' ? this.certificateList.filter(v => v.dictValue === this.form.certificateId)[0].dictName : ''
|
||
}).then(res => {
|
||
if (res.code == 0) {
|
||
this.$message.success('提交成功')
|
||
setTimeout(() => {
|
||
this.cancel(true)
|
||
}, 600)
|
||
}
|
||
})
|
||
}
|
||
})
|
||
},
|
||
|
||
cancel (isRefresh) {
|
||
this.$emit('change', {
|
||
type: 'List',
|
||
isRefresh: !!isRefresh
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.AppExaminationManage {
|
||
.topic-item {
|
||
padding: 40px 0 0;
|
||
border-bottom: 1px solid #eee;
|
||
|
||
&:first-child {
|
||
padding-top: 0;
|
||
}
|
||
|
||
&:last-child {
|
||
border: none;
|
||
}
|
||
}
|
||
|
||
.el-checkbox-group {
|
||
width: 100%;
|
||
|
||
:deep( .el-checkbox__label ) {
|
||
display: flex;
|
||
align-items: center;
|
||
width: 100%;
|
||
}
|
||
}
|
||
|
||
:deep( .el-pagination ){
|
||
position: absolute;
|
||
bottom: 0px;
|
||
left: 0;
|
||
z-index: 11;
|
||
width: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
flex-direction: row-reverse;
|
||
justify-content: flex-end;
|
||
background: #fcfcfc;
|
||
padding: 10px 10px;
|
||
.paginationPre {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.el-pagination__rightwrapper {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
flex: 1;
|
||
|
||
.el-pagination__sizes {
|
||
margin: 0;
|
||
|
||
input {
|
||
height: 22px;
|
||
line-height: 22px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.el-checkbox {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.el-checkbox__input, .el-checkbox__inner {
|
||
width: 14px;
|
||
height: 14px;
|
||
min-width: 0 !important;
|
||
line-height: 1 !important;
|
||
}
|
||
|
||
.el-checkbox__label {
|
||
font-size: 12px;
|
||
color: #222222;
|
||
height: auto !important;
|
||
line-height: 1 !important;
|
||
padding-left: 3px !important;
|
||
}
|
||
}
|
||
}
|
||
.el-checkbox {
|
||
display: flex;
|
||
align-items: center;
|
||
width: 100%;
|
||
padding: 10px 20px;
|
||
|
||
&:nth-of-type(2n - 1) {
|
||
background: #F5F6F9;
|
||
}
|
||
|
||
span:first-child {
|
||
margin-right: 80px;
|
||
}
|
||
|
||
span:last-child {
|
||
flex: 1;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
text-align: center;
|
||
}
|
||
}
|
||
|
||
.choose-item {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.type-name {
|
||
width: 80px;
|
||
color: #666;
|
||
}
|
||
.form-wrapper {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.form-item:first-child {
|
||
margin-right: 40px;
|
||
}
|
||
|
||
.el-input-number {
|
||
margin: 0 10px;
|
||
}
|
||
|
||
span {
|
||
margin-right: 10px;
|
||
color: #999;
|
||
}
|
||
}
|
||
}
|
||
|
||
.type-item {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.el-input {
|
||
margin: 0 10px;
|
||
}
|
||
|
||
.type-name {
|
||
width: 80px;
|
||
}
|
||
|
||
span {
|
||
margin-right: 10px;
|
||
color: #666;
|
||
}
|
||
}
|
||
}
|
||
</style>
|