<template>
|
<div class="app-container">
|
<el-form :model="form" ref="form" label-width="150px" v-loading="formLoading" :rules="rules">
|
<el-form-item label="学科:" prop="subjectId" required>
|
<el-select v-model="form.subjectId" placeholder="学科">
|
<el-option v-for="item in subjects" :key="item.id" :label="item.name" :value="item.id"/>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="试卷类型:" prop="paperType" required>
|
<el-select v-model="form.paperType" placeholder="试卷类型">
|
<el-option v-for="item in paperTypeEnum" :key="item.key" :value="item.key" :label="item.value"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="试卷名称:" prop="name" required>
|
<el-input style="width: 300px" v-model="form.name"/>
|
</el-form-item>
|
<el-form-item :key="index" :label="'标题'+(index+1)+':'" required
|
v-for="(titleItem,index) in form.questionTitleList" v-show="form.paperType===1">
|
<el-input v-model="titleItem.title" style="width: 50%"/>
|
<el-select @change="addQuestionType" v-model="titleItem.questionType" style="margin-left: 20px"
|
placeholder="请选择题目类型">
|
<el-option
|
v-for="item in questionTypeList"
|
:key="item.value"
|
:label="item.name"
|
:value="item.value"
|
:disabled="addedQuestionTypes.includes(item.value)"/><!-- 禁用已添加的选项 -->
|
</el-select>
|
<el-input-number v-show ="titleItem.questionList.length > 0" v-model="titleItem.eachScore" @change="updateScores(titleItem)" :min="0" :precision="1"
|
style="margin-left: 20px" placeholder="每题分数"></el-input-number>
|
<el-button type="text" class="link-left" style="margin-left: 20px" size="mini" @click="addQuestion(titleItem)">
|
添加题目
|
</el-button>
|
<el-button type="text" class="link-left" size="mini" @click="removeTitleItem(titleItem,index)">删除</el-button>
|
<el-card class="exampaper-item-box" v-if="titleItem.questionList.length!==0">
|
<el-form-item :key="questionIndex" :label="'题目'+(questionIndex+1)+':'"
|
v-for="(questionItem,questionIndex) in titleItem.questionList" style="margin-bottom: 15px">
|
<el-row>
|
<el-col :span="18">
|
<QuestionShow :qType="titleItem.questionType" :question="questionItem"/>
|
</el-col>
|
<el-col :span="3">
|
<el-input-number v-model="questionItem.score" size="mini" :min="0" :precision="1" placeholder="分数"
|
:controls="false" @change="updateTotalScore"/>
|
</el-col>
|
<el-col :span="3">
|
<el-button type="text" size="mini" @click="removeQuestion(titleItem,questionItem)">删除
|
</el-button>
|
</el-col>
|
</el-row>
|
</el-form-item>
|
</el-card>
|
</el-form-item>
|
<el-form-item label="多选题得分类型:" prop="deductType">
|
<div>
|
<el-select v-model="form.deductType" placeholder="请选择多选题得分类型" style="width: 200px;margin-right: 30px">
|
<el-option
|
v-for="item in deductTypeList"
|
:key="item.value"
|
:label="item.name"
|
:value="item.value"
|
/>
|
</el-select>
|
<el-input-number v-model="form.deductTypeScore" placeholder="请输入多选评分"
|
v-show="form.deductType === 2 || form.deductType === 3" :min="0"/>
|
</div>
|
</el-form-item>
|
<el-form-item label="建议时长(分钟):" prop="suggestTime" required>
|
<el-input-number v-model="form.suggestTime" placeholder="分钟" :min="0"/>
|
</el-form-item>
|
<el-form-item label="权限:" prop="visibility">
|
<el-radio v-model="form.visibility" :label="'1'">私有</el-radio>
|
<el-radio v-model="form.visibility" :label="'2'">公开</el-radio>
|
</el-form-item>
|
<el-form-item v-show="form.paperType ===2 ||form.paperType ===3" :key="index"
|
:label="translateQuestionType(item.questionType)+':'" v-for="(item,index) in form.questionSetting">
|
<div style="display: flex;">
|
<span style="margin-right: 10px">{{ '标题' }}</span>
|
<el-input v-model="item.title" style="margin-right: 50px;width: 500px"/>
|
<span style="margin-right: 10px">{{ '数量' }}</span>
|
<el-input-number v-model="item.num" :precision="0" :min="0" style="margin-right: 50px"/>
|
<span style="margin-right: 10px">{{ '每题分数' }}</span>
|
<el-input-number v-model="item.score" :min="0" :precision="1"/>
|
</div>
|
</el-form-item>
|
<el-form-item label="合计:">
|
<div style="display: flex;">
|
<span style="margin-right: 10px">{{ '数量:' }}</span>
|
<span v-if ="form.paperType ===2 || (form.paperType ===3 && !form.id)" style="margin-right: 50px;width: 100px">{{ totalNum }}</span>
|
<span v-if ="form.paperType ===1" style="margin-right: 50px;width: 100px">{{ form.num }}</span>
|
<span style="margin-right: 10px">{{ '总分:' }}</span>
|
<span v-if ="form.paperType ===2 || (form.paperType ===3 && !form.id)" style="width: 100px">{{ totalScore }}</span>
|
<span v-if ="form.paperType ===1" style="width: 100px">{{ form.score }}</span>
|
</div>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" @click="submitForm">提交</el-button>
|
<el-button @click="resetForm">重置</el-button>
|
<el-button type="success" @click="addTitle" v-show="form.paperType ===1">添加标题</el-button>
|
</el-form-item>
|
</el-form>
|
|
<el-dialog :visible.sync="questionPage.showDialog" width="70%">
|
<el-form :model="questionPage.queryParam" ref="queryForm" :inline="true">
|
<el-form-item label="ID:">
|
<el-input v-model="questionPage.queryParam.id" clearable></el-input>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" @click="queryForm">查询</el-button>
|
</el-form-item>
|
</el-form>
|
<el-table v-loading="questionPage.listLoading" :data="questionPage.tableData"
|
@selection-change="handleSelectionChange" border fit highlight-current-row style="width: 100%">
|
<el-table-column type="selection" width="35"></el-table-column>
|
<el-table-column prop="id" label="Id" width="60px"/>
|
<el-table-column prop="questionType" label="题型" width="70px">
|
<template slot-scope="scope">
|
<div> {{ translateQuestionType(scope.row.questionType) }}</div>
|
</template>
|
</el-table-column>
|
<el-table-column prop="shortTitle" label="题干" show-overflow-tooltip/>
|
</el-table>
|
<pagination v-show="questionPage.total>0" :total="questionPage.total"
|
:page.sync="questionPage.queryParam.pageIndex" :limit.sync="questionPage.queryParam.pageSize"
|
@pagination="search"/>
|
<span slot="footer" class="dialog-footer">
|
<el-button type="primary" @click="confirmQuestionSelect">确定</el-button>
|
<el-button @click="questionPage.showDialog = false">取 消</el-button>
|
</span>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
|
import { mapState, mapActions } from 'vuex'
|
import Pagination from '@/components/Pagination'
|
import subjectApi from '@/api/subject'
|
import QuestionShow from '../question/components/Show'
|
import examPaperApi from '@/api/examPaper'
|
import questionApi from '@/api/question'
|
|
export default {
|
components: { Pagination, QuestionShow },
|
data () {
|
return {
|
form: {
|
id: null,
|
subjectId: null,
|
paperType: 1,
|
name: '',
|
num: 0,
|
score: 0,
|
suggestTime: 0,
|
deductType: 1,
|
deductTypeScore: 0,
|
visibility: '1',
|
questionSetting: [
|
{ questionType: 1, title: '单选题', score: null, num: null },
|
{ questionType: 2, title: '多选题', score: null, num: null },
|
{ questionType: 3, title: '判断题', score: null, num: null },
|
{ questionType: 4, title: '填空题', score: null, num: null },
|
{ questionType: 5, title: '简答题', score: null, num: null },
|
{ questionType: 6, title: '语音题', score: null, num: null },
|
{ questionType: 7, title: '计算题', score: null, num: null },
|
{ questionType: 8, title: '分析题', score: null, num: null },
|
],
|
questionTitleList: []
|
},
|
deductTypeList: [
|
{ name: '答错不得分', value: 1 },
|
{ name: '漏选得固定分值,包含错误选项不得分', value: 2 },
|
{ name: '每对一题得相应分值,包含错误选项不得分', value: 3 },
|
],
|
questionTypeList: [
|
{ name: '单选题', value: 1 },
|
{ name: '多选题', value: 2 },
|
{ name: '判断题', value: 3 },
|
{ name: '填空题', value: 4 },
|
{ name: '简答题', value: 5 },
|
{ name: '语音题', value: 6 },
|
{ name: '计算题', value: 7 },
|
{ name: '分析题', value: 8 },
|
],
|
addedQuestionTypes: [], // 已添加的题目类型
|
subjects: [],
|
formLoading: false,
|
rules: {
|
level: [
|
{ required: true, message: '请选择年级', trigger: 'change' }
|
],
|
subjectId: [
|
{ required: true, message: '请选择学科', trigger: 'change' }
|
],
|
paperType: [
|
{ required: true, message: '请选择试卷类型', trigger: 'change' }
|
],
|
name: [
|
{ required: true, message: '请输入试卷名称', trigger: 'blur' }
|
],
|
suggestTime: [
|
{ required: true, message: '请输入建议时长', trigger: 'blur' }
|
]
|
},
|
questionPage: {
|
multipleSelection: [],
|
showDialog: false,
|
queryParam: {
|
id: null,
|
questionType: [],
|
subjectId: [],
|
pageIndex: 1,
|
pageSize: 5
|
},
|
listLoading: true,
|
tableData: [],
|
total: 0
|
},
|
currentTitleItem: null
|
}
|
},
|
created () {
|
let id = this.$route.query.id
|
let _this = this
|
this.getSubjects()
|
if (id && parseInt(id) !== 0) {
|
_this.formLoading = true
|
examPaperApi.select(id).then(re => {
|
_this.form = re.data
|
_this.formLoading = false
|
})
|
}
|
},
|
methods: {
|
updateTotalScore () {
|
this.form.score = 0
|
this.form.questionTitleList.forEach(titleItem => {
|
titleItem.questionList.forEach(questionItem => {
|
if (questionItem.score) {
|
this.form.score += questionItem.score
|
}
|
})
|
})
|
},
|
updateScores (titleItem) {
|
if (titleItem && titleItem.questionList) {
|
titleItem.questionList.forEach(questionItem => {
|
questionItem.score = titleItem.eachScore // 更新每个题目的分数
|
})
|
}
|
this.updateTotalScore()
|
},
|
// 添加题目类型
|
addQuestionType () {
|
if (this.form.questionTitleList.length > 0) {
|
this.addedQuestionTypes = []
|
// 遍历题目列表
|
this.form.questionTitleList.forEach((titleItem) => {
|
// 检查当前题目的类型是否还没有被添加到已添加的题目类型数组中
|
if (!this.addedQuestionTypes.includes(titleItem.questionType)) {
|
// 如果还没有被添加,则添加到数组中
|
this.addedQuestionTypes.push(titleItem.questionType)
|
}
|
})
|
}
|
},
|
// 获取科目
|
getSubjects () {
|
subjectApi.list().then(re => {
|
this.subjects = re.data
|
})
|
},
|
translateQuestionType (questionTypeId) {
|
const questionType = this.questionTypeList.find(questionType => questionType.value === questionTypeId)
|
return questionType ? questionType.name : '未知'
|
},
|
submitForm () {
|
let _this = this
|
this.$refs.form.validate((valid) => {
|
if (valid) {
|
this.formLoading = true
|
if (this.form.id) {
|
examPaperApi.edit(this.form).then(re => {
|
if (re.code === 1) {
|
_this.$message.success(re.message)
|
_this.delCurrentView(_this).then(() => {
|
_this.$router.push('/exam/paper/list')
|
})
|
} else {
|
_this.$message.error(re.message)
|
this.formLoading = false
|
}
|
}).catch(e => {
|
this.formLoading = false
|
})
|
} else {
|
examPaperApi.addPaper(this.form).then(re => {
|
if (re.code === 1) {
|
_this.$message.success(re.message)
|
_this.delCurrentView(_this).then(() => {
|
_this.$router.push('/exam/paper/list')
|
})
|
} else {
|
_this.$message.error(re.message)
|
this.formLoading = false
|
}
|
}).catch(e => {
|
this.formLoading = false
|
})
|
}
|
} else {
|
return false
|
}
|
})
|
},
|
addTitle () {
|
this.form.questionTitleList.push({
|
questionList: []
|
})
|
},
|
addQuestion (titleItem) {
|
this.currentTitleItem = titleItem
|
this.questionPage.queryParam.questionType = []
|
this.questionPage.queryParam.questionType.push(titleItem.questionType)
|
this.questionPage.showDialog = true
|
this.search()
|
},
|
removeTitleItem (titleItem ,index) {
|
this.form.questionTitleList.splice(index, 1)
|
this.form.num = this.form.num - titleItem.questionList.length
|
this.updateTotalScore();
|
if (!this.form.questionTitleList || this.form.questionTitleList.length === 0) {
|
this.addedQuestionTypes = []
|
} else {
|
this.addQuestionType()
|
}
|
},
|
removeQuestion (titleItem ,questionIndex) {
|
titleItem.questionList.splice(questionIndex ,1)
|
this.updateTotalScore();
|
this.form.num = this.form.num - 1
|
},
|
queryForm () {
|
this.questionPage.queryParam.pageIndex = 1
|
this.search()
|
},
|
confirmQuestionSelect () {
|
let _this = this
|
this.questionPage.multipleSelection.forEach(q => {
|
questionApi.select(q.id).then(re => {
|
_this.currentTitleItem.questionList.push(re.data)
|
this.form.num += 1
|
})
|
})
|
this.questionPage.showDialog = false
|
},
|
search () {
|
this.questionPage.queryParam.subjectId = []
|
this.questionPage.queryParam.subjectId.push(this.form.subjectId)
|
this.questionPage.listLoading = true
|
questionApi.pageList(this.questionPage.queryParam).then(data => {
|
const re = data.data
|
this.questionPage.tableData = re.list
|
this.questionPage.total = re.total
|
this.questionPage.queryParam.pageIndex = re.pageNum
|
this.questionPage.listLoading = false
|
})
|
},
|
handleSelectionChange (val) {
|
this.questionPage.multipleSelection = val
|
},
|
resetForm () {
|
let lastId = this.form.id
|
this.$refs['form'].resetFields()
|
this.form = {
|
subjectId: null,
|
paperType: 1,
|
name: '',
|
num: 0,
|
score: 0,
|
suggestTime: 0,
|
deductType: 1,
|
deductTypeScore: 0,
|
visibility: '1',
|
questionSetting: [
|
{ questionType: 1, title: '单选题', score: null, num: null },
|
{ questionType: 2, title: '多选题', score: null, num: null },
|
{ questionType: 3, title: '判断题', score: null, num: null },
|
{ questionType: 4, title: '填空题', score: null, num: null },
|
{ questionType: 5, title: '简答题', score: null, num: null },
|
{ questionType: 6, title: '计算题', score: null, num: null },
|
],
|
questionTitleList: []
|
}
|
this.form.id = lastId
|
},
|
...mapActions('tagsView', { delCurrentView: 'delCurrentView' })
|
},
|
computed: {
|
...mapState('enumItem', {
|
paperTypeEnum: state => state.exam.examPaper.paperTypeEnum,
|
}),
|
totalNum () {
|
if (this.form.paperType === 2 || this.form.paperType === 3) {
|
let total = 0
|
for (let item of this.form.questionSetting) {
|
total += parseInt(item.num || 0, 10)
|
}
|
this.form.num = total
|
return total
|
} else {
|
|
}
|
},
|
totalScore () {
|
if (this.form.paperType === 2 || this.form.paperType === 3) {
|
let total = 0
|
for (let item of this.form.questionSetting) {
|
const num = parseInt(item.num || 0, 10)
|
const score = parseFloat(item.score || 0)
|
total += num * score
|
}
|
this.form.score = total.toFixed(1)
|
return total.toFixed(1) // 保留一位小数
|
}
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss">
|
.exampaper-item-box {
|
.q-title {
|
margin: 0px 5px 0px 5px;
|
}
|
|
.q-item-content {
|
}
|
}
|
</style>
|