<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">
|
<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">
|
<el-select v-model="form.paperType" placeholder="试卷类型" disabled>
|
<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">
|
<el-input style="width: 300px" v-model="form.name" />
|
</el-form-item>
|
<el-form-item label="文件导入:" prop="file">
|
<el-upload :on-change="handleChange" action="none" drag accept=".xlsx, .xls" :limit="1" :auto-upload="false">
|
<i class="el-icon-upload"></i>
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
</el-upload>
|
</el-form-item>
|
<!-- 题目详细信息 -->
|
<el-form-item :key="index" :label="'标题' + (index + 1) + ':'"
|
v-for="(titleItem, index) in form.questionTitleList"
|
v-show="form.paperType === 1 || (form.paperType === 3 && form.id)">
|
<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, questionIndex)">删除
|
</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">
|
<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 && !form.id)" :key="index"
|
:label="translateQuestionType(item.questionType) + ':'" v-for="(item, index) in form.questionSetting">
|
<div>
|
<span style="margin-right: 10px">{{ '标题' }}</span>
|
<el-input v-model="item.title" style="margin-bottom: 20px;margin-right: 30px;width: 800px" />
|
<el-button type="primary" @click=addToQuestionSetting(item.questionType)>添加</el-button>
|
|
<div style="display: flex;" :key="index" v-for="(setting, index) in item.settingList">
|
<span style="margin-right: 10px;margin-bottom: 10px;">{{ '难度' }}</span>
|
<el-rate v-model="setting.difficult" :precision="0" :min="0" style="margin-right: 25px;padding: 5px 0" />
|
<span style="margin-right: 10px">{{ '科目' }}</span>
|
<el-select v-model="setting.subjectId" placeholder="学科" style="margin-right: 25px">
|
<el-option v-for="item in subjects" :key="item.id" :label="item.name" :value="item.id" />
|
</el-select>
|
<span style="margin-right: 10px">{{ '数量' }}</span>
|
<el-input-number v-model="setting.num" :precision="0" :min="0" style="margin-right: 25px" />
|
<span style="margin-right: 10px">{{ '每题分数' }}</span>
|
<el-input-number v-model="setting.score" :min="0" :precision="1" />
|
</div>
|
|
</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 || (form.paperType === 3 && form.id)"
|
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 || (form.paperType === 3 && form.id)" 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 ||(form.paperType ===3 && form.id)">
|
添加标题
|
</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: {
|
file: '',
|
id: null,
|
subjectId: null,
|
paperType: 1,
|
name: '',
|
num: 0,
|
score: 0,
|
suggestTime: 0,
|
deductType: 1,
|
deductTypeScore: 0,
|
visibility: '1',
|
questionSetting: [
|
{
|
title: '单选题',
|
questionType: 1,
|
settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
|
},
|
{
|
title: '多选题',
|
questionType: 2,
|
settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
|
},
|
{
|
title: '判断题',
|
questionType: 3,
|
settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
|
},
|
{
|
title: '填空题',
|
questionType: 4,
|
settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
|
},
|
{
|
title: '简答题',
|
questionType: 5,
|
settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
|
},
|
{
|
title: '语音题',
|
questionType: 6,
|
settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
|
},
|
{
|
title: '计算题',
|
questionType: 7,
|
settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
|
},
|
{
|
title: '分析题',
|
questionType: 8,
|
settingList: [{ difficult: null, score: null, num: null, subjectId: 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
|
this.addQuestionType()
|
})
|
}
|
},
|
methods: {
|
handleChange(file) {
|
this.form.file = file.raw;
|
},
|
addToQuestionSetting(questionType) {
|
this.form.questionSetting.forEach(item => {
|
if (item.questionType === questionType) {
|
item.settingList.push({ difficult: null, score: null, num: null, subjectId: null })
|
}
|
})
|
},
|
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() {
|
console.log("form:", this.form);
|
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 {
|
let formData = new FormData();
|
formData.append('file', this.form.file);
|
formData.append('examPaper', JSON.stringify(this.form));
|
examPaperApi.import(formData).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 = {
|
file: '',
|
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: []
|
}
|
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>
|