提交 75c40775 authored 作者: 王鹏飞's avatar 王鹏飞

chore: 组卷模式新增自由组卷

上级 1673d3f9
......@@ -28,9 +28,9 @@
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-vue": "^8.7.1",
"sass": "1.51.0",
"vite": "^2.9.8",
"vite": "^2.9.10",
"vite-plugin-checker": "^0.4.6",
"vite-plugin-vue2": "^2.0.0",
"vite-plugin-vue2": "^2.0.1",
"vue-template-compiler": "^2.6.14"
}
},
......@@ -4419,9 +4419,10 @@
}
},
"node_modules/qs": {
"version": "6.10.1",
"version": "6.10.5",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.5.tgz",
"integrity": "sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.0.4"
},
......@@ -5154,9 +5155,9 @@
"license": "MIT"
},
"node_modules/vite": {
"version": "2.9.8",
"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.8.tgz",
"integrity": "sha512-zsBGwn5UT3YS0NLSJ7hnR54+vUKfgzMUh/Z9CxF1YKEBVIe213+63jrFLmZphgGI5zXwQCSmqIdbPuE8NJywPw==",
"version": "2.9.10",
"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.10.tgz",
"integrity": "sha512-TwZRuSMYjpTurLqXspct+HZE7ONiW9d+wSWgvADGxhDPPyoIcNywY+RX4ng+QpK30DCa1l/oZgi2PLZDibhzbQ==",
"dev": true,
"dependencies": {
"esbuild": "^0.14.27",
......@@ -5220,9 +5221,9 @@
}
},
"node_modules/vite-plugin-vue2": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/vite-plugin-vue2/-/vite-plugin-vue2-2.0.0.tgz",
"integrity": "sha512-6+CfhsPgQoZnkBbMMb/pxX3gYLD3k10QljjVlUa2lL8160UmVotLuEaN+U2eSyCEnn+uBj7YMSmBPWXqqTEpsw==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/vite-plugin-vue2/-/vite-plugin-vue2-2.0.1.tgz",
"integrity": "sha512-8ixcIDZwk3PSbdaqKrPFYDot044lPLIqpjjuRXUDHdRhml87Kbc6JqLq6uwHERlPovwfI3DpluWRMVgn/Llmag==",
"dev": true,
"dependencies": {
"@babel/core": "^7.17.9",
......@@ -8452,7 +8453,9 @@
"dev": true
},
"qs": {
"version": "6.10.1",
"version": "6.10.5",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.5.tgz",
"integrity": "sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ==",
"dev": true,
"requires": {
"side-channel": "^1.0.4"
......@@ -8928,9 +8931,9 @@
"dev": true
},
"vite": {
"version": "2.9.8",
"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.8.tgz",
"integrity": "sha512-zsBGwn5UT3YS0NLSJ7hnR54+vUKfgzMUh/Z9CxF1YKEBVIe213+63jrFLmZphgGI5zXwQCSmqIdbPuE8NJywPw==",
"version": "2.9.10",
"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.10.tgz",
"integrity": "sha512-TwZRuSMYjpTurLqXspct+HZE7ONiW9d+wSWgvADGxhDPPyoIcNywY+RX4ng+QpK30DCa1l/oZgi2PLZDibhzbQ==",
"dev": true,
"requires": {
"esbuild": "^0.14.27",
......@@ -8964,9 +8967,9 @@
}
},
"vite-plugin-vue2": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/vite-plugin-vue2/-/vite-plugin-vue2-2.0.0.tgz",
"integrity": "sha512-6+CfhsPgQoZnkBbMMb/pxX3gYLD3k10QljjVlUa2lL8160UmVotLuEaN+U2eSyCEnn+uBj7YMSmBPWXqqTEpsw==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/vite-plugin-vue2/-/vite-plugin-vue2-2.0.1.tgz",
"integrity": "sha512-8ixcIDZwk3PSbdaqKrPFYDot044lPLIqpjjuRXUDHdRhml87Kbc6JqLq6uwHERlPovwfI3DpluWRMVgn/Llmag==",
"dev": true,
"requires": {
"@babel/core": "^7.17.9",
......
......@@ -31,9 +31,9 @@
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-vue": "^8.7.1",
"sass": "1.51.0",
"vite": "^2.9.8",
"vite": "^2.9.10",
"vite-plugin-checker": "^0.4.6",
"vite-plugin-vue2": "^2.0.0",
"vite-plugin-vue2": "^2.0.1",
"vue-template-compiler": "^2.6.14"
}
}
......@@ -76,3 +76,17 @@ export function getPaperCategory(params) {
export function getKnowledge(params) {
return httpRequest.get('/api/admin/v1/knowledge-point/search/x1', { params })
}
/**
* 一次性自动组卷——搜索试题数量 (通过主题目检索)
*/
export function getParentQuestionCount(data) {
return httpRequest.post('/api/qbs/admin/v1/question/search/parent-count', data)
}
/**
* 一次性自动组卷——通过一次性自动选题规则获取题目
*/
export function getOnceAutoQuestionList(data) {
return httpRequest.post('/api/qbs/admin/v1/question/search/once-auto-questions', data)
}
......@@ -15,12 +15,7 @@
<el-table-column align="center" label="题目类型" width="140">
<template slot-scope="{ row, $index }">
<el-select v-model="row.question_type" @change="getQuestionMaxCount($index, row)">
<el-option
v-for="item in questionTypeMap"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
<el-option v-for="item in questionTypeMap" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</template>
</el-table-column>
......@@ -28,12 +23,7 @@
<el-table-column align="center" label="难度" width="140">
<template slot-scope="{ row, $index }">
<el-select v-model="row.question_difficulty" @change="getQuestionMaxCount($index, row)">
<el-option
v-for="item in questionDifficultyMap"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
<el-option v-for="item in questionDifficultyMap" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</template>
</el-table-column>
......@@ -53,13 +43,7 @@
<el-table-column align="center" label="数量" width="140">
<template slot-scope="{ row }">
<el-input-number
v-model="row.question_num"
:min="0"
:max="row.max_question_num"
step-strictly
style="width: 100%"
></el-input-number>
<el-input-number v-model="row.question_num" :min="0" :max="row.max_question_num" step-strictly style="width: 100%"></el-input-number>
</template>
</el-table-column>
......@@ -71,15 +55,7 @@
<el-table-column align="center" label="操作" width="140">
<template slot-scope="scope">
<el-button
style="margin-left: 10px"
circle
icon="el-icon-plus"
size="mini"
:plain="true"
type="danger"
@click="handleAdd(scope.$index, scope.row)"
></el-button>
<el-button style="margin-left: 10px" circle icon="el-icon-plus" size="mini" :plain="true" type="danger" @click="handleAdd(scope.$index, scope.row)"></el-button>
<el-button
style="margin-left: 10px"
......@@ -106,9 +82,7 @@
<el-table-column align="center" label="题目类型" prop="question_type_name"></el-table-column>
<el-table-column align="center" label="难度 / 数量 / 分值">
<template slot-scope="{ row }">
<div v-for="(item, index) in row.children" :key="index">
{{ item.question_difficulty_name }} / {{ item.question_num }} / {{ item.question_score }}
</div>
<div v-for="(item, index) in row.children" :key="index">{{ item.question_difficulty_name }} / {{ item.question_num }} / {{ item.question_score }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="小计(数量 / 分值)">
......@@ -193,20 +167,14 @@ export default {
totalQuestionList() {
const result = []
this.questionList.forEach(item => {
if (
item.question_type &&
item.question_num &&
!result.find(item2 => item2.question_type === item.question_type)
) {
if (item.question_type && item.question_num && !result.find(item2 => item2.question_type === item.question_type)) {
// 当前类型的试题列表
const currentTypeQuestionList = this.questionList.filter(item2 => item2.question_type === item.question_type)
// 难度列表
const questionDifficultyList = this.questionDifficultyMap.map(item => {
// 当前难度的试题列表
const currentDifficultyQuestionList = currentTypeQuestionList.filter(
item2 => item2.question_difficulty === item.value
)
const currentDifficultyQuestionList = currentTypeQuestionList.filter(item2 => item2.question_difficulty === item.value)
return {
question_difficulty: item.value,
question_difficulty_name: item.label,
......@@ -272,8 +240,8 @@ export default {
return
}
}
const parmas = { id: this.data.id, permission: this.form.permission, rules }
updatePaperRules(parmas).then(res => {
const params = { id: this.data.id, permission: this.form.permission, rules }
updatePaperRules(params).then(res => {
this.$message.success('保存成功')
this.$emit('update')
this.$emit('update:visible', false)
......
<template>
<el-drawer title="自动组卷" size="80%" v-bind="$attrs" v-on="$listeners">
<div style="margin: 0 20px">
<el-form :model="form">
<!-- 组卷题库 -->
<el-form-item label="组卷题库:">
<el-radio-group v-model="form.permission" @change="onChangePermission">
<el-radio label="1">我的题库</el-radio>
<el-radio label="2">公共题库</el-radio>
</el-radio-group>
</el-form-item>
<!-- 自动组卷规则 -->
<el-form-item label="自动组卷规则:">
<el-table ref="mytable" :data="questionList" style="width: 100%">
<el-table-column align="center" label="题目类型" width="140">
<template slot-scope="{ row, $index }">
<el-select v-model="row.question_type" @change="getQuestionMaxCount($index, row)">
<el-option v-for="item in questionTypeMap" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column align="center" label="难度" width="140">
<template slot-scope="{ row, $index }">
<el-select v-model="row.question_difficulty" @change="getQuestionMaxCount($index, row)">
<el-option v-for="item in questionDifficultyMap" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column align="center" label="题目类别">
<template slot-scope="{ row, $index }">
<question-type-treeselect
multiple
:checkStrictly="false"
:isRequestRemote="false"
v-model="row.question_categories"
@change="getQuestionMaxCount($index, row)"
style="width: 100%"
></question-type-treeselect>
</template>
</el-table-column>
<el-table-column align="center" label="数量" width="140">
<template slot-scope="{ row }">
<el-input-number v-model="row.question_num" :min="0" :max="row.max_question_num" step-strictly style="width: 100%"></el-input-number>
</template>
</el-table-column>
<el-table-column align="center" label="每题分值" width="140">
<template slot-scope="{ row }">
<el-input-number v-model="row.question_score" :min="0" :max="30" :disabled="['7', '8'].includes(row.question_type)" style="width: 100%"></el-input-number>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="140">
<template slot-scope="scope">
<el-button style="margin-left: 10px" circle icon="el-icon-plus" size="mini" :plain="true" type="danger" @click="handleAdd(scope.$index, scope.row)"></el-button>
<el-button
style="margin-left: 10px"
circle
icon="el-icon-minus"
size="mini"
:plain="true"
type="danger"
@click="handleDelete(scope.$index, scope.row)"
v-if="questionList.length > 1"
></el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
<!-- 您计划自动组卷的试题情况: -->
<el-form-item label="您计划自动组卷的试题情况:">
<!-- 您计划自动组卷的试题情况 -->
<div class="automatic">
<div class="automatic_questionNum">试题数量总数:{{ questionTotalNum }}</div>
<div class="automatic_totalScore">试卷总分:{{ questionTotalScore }}</div>
</div>
<el-table ref="mytable" :data="totalQuestionList" style="width: 100%">
<el-table-column align="center" label="题目类型" prop="question_type_name"></el-table-column>
<el-table-column align="center" label="难度 / 数量 / 分值">
<template slot-scope="{ row }">
<div v-for="(item, index) in row.children" :key="index">{{ item.question_difficulty_name }} / {{ item.question_num }} / {{ item.question_score }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="小计(数量 / 分值)">
<template slot-scope="{ row }"> {{ row.question_num }} / {{ row.question_score }} </template>
</el-table-column>
</el-table>
</el-form-item>
<div style="text-align: center">
<el-button type="primary" @click="handleSubmit">自动组卷</el-button>
</div>
</el-form>
</div>
</el-drawer>
</template>
<script>
import { cloneDeep } from 'lodash'
import QuestionTypeTreeselect from '@/components/base/QuestionTypeTreeselect.vue'
import { getParentQuestionCount, getOnceAutoQuestionList } from '../api.js'
export default {
props: {
data: { type: Object, default: () => ({}) }
},
components: { QuestionTypeTreeselect },
data() {
const questionTypeMap = [
{ value: '1', label: '单选题' },
{ value: '2', label: '多选题' },
{ value: '3', label: '问答题' },
{ value: '5', label: '案例题' },
{ value: '6', label: '判断题' },
{ value: '7', label: '实操题' },
{ value: '8', label: '情景题' }
]
const questionDifficultyMap = [
{ value: '1', label: '易' },
{ value: '2', label: '中' },
{ value: '3', label: '难' },
{ value: '0', label: '无' }
]
const defaultItem = {
question_type: '',
question_difficulty: '',
question_num: '',
question_score: '',
question_categories: [],
max_question_num: 0
}
const permission = localStorage.getItem('paper_permission') || '1'
return {
questionTypeMap,
questionDifficultyMap,
defaultItem,
// 组卷题库
form: { permission },
questionList: [{ ...defaultItem }]
}
},
watch: {
data: {
immediate: true,
handler(data) {
if (data.paper_contents) {
this.form = Object.assign({}, this.form, data.paper_contents)
}
if (data.paper_contents && data.paper_contents.rules) {
this.questionList = cloneDeep(data.paper_contents.rules)
}
}
}
},
computed: {
// 试题数量总数
questionTotalNum() {
return this.getQuestionTotalNumber(this.questionList)
},
// 试题总分
questionTotalScore() {
return this.getQuestionTotalScoreNumber(this.questionList)
},
// 试题情况
totalQuestionList() {
const result = []
this.questionList.forEach(item => {
if (item.question_type && item.question_num && !result.find(item2 => item2.question_type === item.question_type)) {
// 当前类型的试题列表
const currentTypeQuestionList = this.questionList.filter(item2 => item2.question_type === item.question_type)
// 难度列表
const questionDifficultyList = this.questionDifficultyMap.map(item => {
// 当前难度的试题列表
const currentDifficultyQuestionList = currentTypeQuestionList.filter(item2 => item2.question_difficulty === item.value)
return {
question_difficulty: item.value,
question_difficulty_name: item.label,
question_num: this.getQuestionTotalNumber(currentDifficultyQuestionList),
question_score: this.getQuestionTotalScoreNumber(currentDifficultyQuestionList)
}
})
const temp = {
question_type: item.question_type,
question_type_name: this.questionTypeMap.find(type => type.value === item.question_type)?.label,
question_num: this.getQuestionTotalNumber(currentTypeQuestionList),
question_score: this.getQuestionTotalScoreNumber(currentTypeQuestionList),
children: questionDifficultyList.filter(item => item.question_num) // 难度列表
}
result.push(temp)
}
})
return result
}
},
methods: {
// 获取试题数量
getQuestionTotalNumber(list = this.questionList) {
return list.reduce((result, item) => {
return result + parseFloat(item.question_num || 0)
}, 0)
},
// 获取试题分数
getQuestionTotalScoreNumber(list = this.questionList) {
return list.reduce((result, item) => {
return result + parseFloat(item.question_score || 0) * parseFloat(item.question_num || 0)
}, 0)
},
// 新增
handleAdd(index, row) {
if (!row.question_categories.length || !row.question_difficulty || !row.question_type) {
this.$message({
message: '试题规则不能为空!',
type: 'warning'
})
} else {
this.questionList.splice(index + 1, 0, { ...this.defaultItem })
}
},
// 删除
handleDelete(index) {
this.questionList.splice(index, 1) // 前端删除
},
// 保存
handleSave(index, row) {
row.edit = false
},
// 自动组卷
handleSubmit() {
const rules = []
this.questionList.forEach(question => {
rules.push(Object.assign({}, question, { question_count: question.question_num }))
})
for (let i = 0; i < rules.length; i++) {
const item = rules[i]
if ((!['7', '8'].includes(item.question_type) && !item.question_score) || !item.question_num) {
this.$message.error(`第${i + 1}行规则配置错误,请检查后重试`)
return
}
}
const params = { id: this.data.id, permission: this.form.permission, rules }
getOnceAutoQuestionList(params).then(res => {
this.$emit('update', res.data.items)
this.$emit('update:visible', false)
})
},
// 获取试题最大数量
getQuestionMaxCount(index, row) {
const params = Object.assign({}, this.form, row)
if (!row.question_categories.length || !row.question_difficulty || !row.question_type) {
row.max_question_num = 0
row.question_num = row.max_question_num
return
}
getParentQuestionCount(params).then(res => {
row.max_question_num = res.data.count
if (row.question_num > row.max_question_num) {
row.question_num = row.max_question_num
}
})
},
onChangePermission(value) {
localStorage.setItem('paper_permission', value)
}
}
}
</script>
<style lang="scss" scoped>
.automatic {
display: flex;
align-items: center;
justify-content: center;
margin: 50px 0 50px;
div {
margin: 0 20px;
}
}
</style>
......@@ -5,27 +5,24 @@
<el-col :span="18">
<app-card title="试题列表">
<template #header-aside>
<!-- 选题组卷 -->
<template v-if="data.paper_type === 1">
<el-button type="primary" @click="showSelectQuestion" v-permission="'admin_v1_question_paper_rules'"
>添加试题</el-button
>
<el-button type="primary" :disabled="!multipleSelection.length" @click="handleRemove"
>删除选中试题</el-button
>
<el-button type="primary" @click="showSelectQuestion" v-permission="'admin_v1_question_paper_rules'">添加试题</el-button>
<el-button type="primary" :disabled="!multipleSelection.length" @click="handleRemove">删除选中试题</el-button>
</template>
<!-- 自动组卷 -->
<template v-if="data.paper_type === 2">
<el-button type="primary" @click="handleAutoPaper" v-permission="'admin_v1_question_paper_rules'"
>自动组卷</el-button
>
<el-button type="primary" @click="handleAutoPaper" v-permission="'admin_v1_question_paper_rules'">自动组卷</el-button>
</template>
<!-- 自由组卷 -->
<template v-if="data.paper_type === 3">
<el-button type="primary" @click="handleAutoPaper" v-permission="'admin_v1_question_paper_rules'">自动组卷</el-button>
<el-button type="primary" @click="paperVisible = true" v-permission="'admin_v1_question_paper_rules'">添加试题</el-button>
<el-button type="primary" :disabled="!multipleSelection.length" @click="handleRemove">删除选中试题</el-button>
</template>
</template>
<question-list
:list="currentQuestions"
:disableScore="data.paper_type === 2"
style="margin-top: 20px"
v-if="currentQuestions.length"
>
<template v-slot:selection="item" v-if="data.paper_type === 1">
<question-list :list="currentQuestions" :disableScore="data.paper_type === 2" style="margin-top: 20px" v-if="currentQuestions.length">
<template v-slot:selection="item" v-if="hasSelection">
<el-checkbox @change="handleSelectionChange(arguments[0], item)"></el-checkbox>
</template>
</question-list>
......@@ -50,10 +47,8 @@
</div>
</template>
<template #footer>
<template v-if="data.paper_type === 1">
<el-button type="primary" @click="handleSubmit" v-permission="'admin_v1_question_paper_rules'"
>保存试卷</el-button
>
<template v-if="hasSelection">
<el-button type="primary" @click="handleSubmit" v-permission="'admin_v1_question_paper_rules'">保存试卷</el-button>
</template>
</template>
</question-num>
......@@ -67,6 +62,13 @@
<template v-if="data.paper_type === 2">
<AutomaticPaper :visible.sync="visible" :data="data" @update="$emit('update')" v-if="visible" />
</template>
<!-- 自由组卷 -->
<template v-if="data.paper_type === 3">
<!-- 自由组卷-自动组卷 -->
<OnceAutomaticPaper :visible.sync="visible" :data="data" @update="handleUpdate" v-if="visible" />
<!-- 自由组卷-选题组卷 -->
<addPaper :visible.sync="paperVisible" :data="data" :list="questions" @update="handleUpdate" v-if="paperVisible" />
</template>
</div>
</template>
......@@ -75,15 +77,17 @@ import QuestionList from './QuestionList.vue'
import QuestionNum from './QuestionNum.vue'
import AddPaper from './AddPaper.vue'
import AutomaticPaper from './AutomaticPaper.vue'
import OnceAutomaticPaper from './OnceAutomaticPaper.vue'
import { updatePaperRules } from '../api.js'
export default {
props: {
data: { type: Object, default: () => ({}) }
},
components: { QuestionList, QuestionNum, AddPaper, AutomaticPaper },
components: { QuestionList, QuestionNum, AddPaper, AutomaticPaper, OnceAutomaticPaper },
data() {
return {
visible: false,
paperVisible: false, // 选题组卷弹窗
questions: [],
multipleSelection: [], // 选择项
top: 0
......@@ -119,6 +123,10 @@ export default {
return total + parseFloat(item.score || 0)
}, 0)
return Math.floor(result)
},
// 是否可选
hasSelection() {
return [1, 3].includes(this.data.paper_type)
}
},
methods: {
......@@ -183,8 +191,8 @@ export default {
return
}
}
const parmas = { id: this.data.id, rules }
updatePaperRules(parmas).then(res => {
const params = { id: this.data.id, rules }
updatePaperRules(params).then(res => {
this.$message.success('保存成功')
this.$emit('update')
})
......
......@@ -31,6 +31,8 @@
<script>
import PaperQuestions from '../components/PaperQuestions.vue'
import { getPaper } from '../api.js'
import { paperType } from '@/utils/dictionary'
export default {
props: { id: { type: String } },
components: { PaperQuestions },
......@@ -54,8 +56,7 @@ export default {
const data = res.data
const temp = {}
// 组卷模式
const paperTypeMap = { 1: '选题组卷', 2: '自动组卷' }
temp.paper_type_name = paperTypeMap[data.paper_type] || data.paper_type
temp.paper_type_name = paperType[data.paper_type] || data.paper_type
// 试题顺序
const questionOrderMap = { 1: '固定', 2: '随机' }
temp.paper_question_order_name = questionOrderMap[data.paper_question_order] || data.paper_question_order
......@@ -64,8 +65,7 @@ export default {
temp.is_multiple_exams_name = isMultipleExamsMap[data.is_multiple_exams] || data.is_multiple_exams
// 多次考试成绩计算规则
const multipleTestScoreRuleMap = { 1: '平均计算法', 2: '最高得分法' }
temp.multiple_test_score_rule_name =
multipleTestScoreRuleMap[data.multiple_test_score_rule] || data.multiple_test_score_rule
temp.multiple_test_score_rule_name = multipleTestScoreRuleMap[data.multiple_test_score_rule] || data.multiple_test_score_rule
this.detail = Object.assign({}, this.detail, res.data, temp)
})
.finally(() => {
......
......@@ -2,38 +2,17 @@
<app-card>
<app-list v-bind="tableOptions" ref="list" @selection-change="handleSelectionChange">
<div class="btn_operate">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate" v-permission="'admin_v1_paper_create'"
>新建试卷</el-button
>
<el-button
type="primary"
icon="el-icon-delete"
:disabled="!multipleSelection.length"
@click="handleBatchDelete"
v-permission="'admin_v1_paper_batch_delete'"
>批量删除</el-button
>
<el-button type="primary" icon="el-icon-plus" @click="handleCreate" v-permission="'admin_v1_paper_create'">新建试卷</el-button>
<el-button type="primary" icon="el-icon-delete" :disabled="!multipleSelection.length" @click="handleBatchDelete" v-permission="'admin_v1_paper_batch_delete'">批量删除</el-button>
</div>
<template v-slot:filter-category="{ params }">
<question-type-treeselect
multiple
v-model="params.paper_categories"
@change="refetchList"
></question-type-treeselect>
<question-type-treeselect multiple v-model="params.paper_categories" @change="refetchList"></question-type-treeselect>
</template>
<template v-slot:table-x="{ row }">
<router-link
:to="{ name: 'editPaper', params: { id: row.id } }"
target="_blank"
v-permission="'admin_v1_paper_update'"
>
<router-link :to="{ name: 'editPaper', params: { id: row.id } }" target="_blank" v-permission="'admin_v1_paper_update'">
<el-button type="text">编辑</el-button>
</router-link>
<router-link
:to="{ name: 'viewPaper', params: { id: row.id } }"
target="_blank"
v-permission="'admin_v1_paper_detail'"
>
<router-link :to="{ name: 'viewPaper', params: { id: row.id } }" target="_blank" v-permission="'admin_v1_paper_detail'">
<el-button type="text">查看详情</el-button>
</router-link>
<el-button type="text" @click="handleDelete(row)" v-permission="'admin_v1_paper_batch_delete'">删除</el-button>
......@@ -45,11 +24,7 @@
<script>
import { getPaperList, batchDeletePaper } from '../api'
import QuestionTypeTreeselect from '@/components/base/QuestionTypeTreeselect.vue'
const paperType = [
{ label: '选题组卷', value: 1 },
{ label: '自动组卷', value: 2 }
]
import { paperType, paperTypeList } from '@/utils/dictionary'
export default {
components: { QuestionTypeTreeselect },
......@@ -86,9 +61,7 @@ export default {
type: 'select',
prop: 'paper_type',
placeholder: '请选择组卷模式',
options: paperType,
labelKey: 'label',
valueKey: 'value',
options: paperTypeList,
label: '组卷模式:'
},
{
......@@ -110,8 +83,7 @@ export default {
label: '组卷模式',
prop: 'paper_type',
computed: ({ row }) => {
const map = { 1: '选题组卷', 2: '自动组卷' }
return map[row.paper_type] || row.paper_type
return paperType[row.paper_type] || row.paper_type
}
},
{
......
......@@ -35,8 +35,7 @@
<el-col :span="12">
<el-form-item label="组卷模式" prop="paper_type">
<el-select v-model="form.paper_type" placeholder="请选择组卷模式" style="width: 100%">
<el-option label="选题组卷" :value="1"></el-option>
<el-option label="自动组卷" :value="2"></el-option>
<el-option v-for="item in paperTypeList" :label="item.label" :value="item.value" :key="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
......@@ -52,15 +51,7 @@
<el-row>
<el-col :span="12">
<el-form-item label="试卷总分" prop="paper_total_score">
<el-input-number
:controls="false"
v-model="form.paper_total_score"
:min="0"
:max="200"
placeholder="请输入试卷总分"
style="width: 100%"
:precision="0"
></el-input-number>
<el-input-number :controls="false" v-model="form.paper_total_score" :min="0" :max="200" placeholder="请输入试卷总分" style="width: 100%" :precision="0"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="10">
......@@ -80,28 +71,12 @@
<el-row>
<el-col :span="12">
<el-form-item label="考试时长" prop="paper_times">
<el-input-number
v-model="form.paper_times"
:controls="false"
:min="1"
:max="150"
placeholder="请输入考试时长"
:precision="0"
></el-input-number
>&nbsp;分钟
<el-input-number v-model="form.paper_times" :controls="false" :min="1" :max="150" placeholder="请输入考试时长" :precision="0"></el-input-number>&nbsp;分钟
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="最短交卷时长" prop="minimum_paper_handing_time">
<el-input-number
v-model="form.minimum_paper_handing_time"
:controls="false"
:min="1"
:max="150"
placeholder="请输入考试时长"
:precision="0"
></el-input-number
>&nbsp;分钟
<el-input-number v-model="form.minimum_paper_handing_time" :controls="false" :min="1" :max="150" placeholder="请输入考试时长" :precision="0"></el-input-number>&nbsp;分钟
</el-form-item>
</el-col>
</el-row>
......@@ -135,6 +110,7 @@
<script>
import { getPaper, createPaper, updatePaper } from '../api'
import QuestionTypeTreeselect from '@/components/base/QuestionTypeTreeselect.vue'
import { paperTypeList } from '@/utils/dictionary'
export default {
props: { id: { type: String } },
......@@ -148,6 +124,7 @@ export default {
}
}
return {
paperTypeList,
form: {
paper_title: '', // 试卷名称
paper_uses: 1, // 试卷用途
......
// json to array
export const json2Array = function (data, isValueToNumber = true) {
return Object.keys(data).map(value => ({ label: data[value], value: isValueToNumber ? parseInt(value) : value }))
}
// 组卷模式
export const paperType = {
1: '选题组卷',
2: '自动组卷',
3: '自由组卷'
}
// 组卷模式列表
export const paperTypeList = json2Array(paperType)
// 试题类型
export const questionType = {
1: '单选题',
2: '多选题',
3: '问答题',
5: '案例题',
6: '判断题',
7: '实操题',
8: '情景题'
}
// 试题类型列表
export const questionTypeList = json2Array(questionType, false)
// 试题难度
export const questionDifficulty = {
1: '易',
2: '中',
3: '难',
0: '无'
}
// 试题难度列表
export const questionDifficultyList = json2Array(questionDifficulty, false)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论