yujialong 3 months ago
parent 872a1f6514
commit f858f467b2
  1. 2
      src/components/breadcrumb/index.vue
  2. 2
      src/components/ueditorPlus/index.vue
  3. 26
      src/pages/knowledge/index.vue
  4. 135
      src/pages/ques/detail/index.vue
  5. 49
      src/pages/ques/list/index.vue
  6. 2
      src/pages/quesBank/index.vue
  7. 2
      src/pages/quesBankType/index.vue
  8. 33
      src/pages/testPaper/detail/auto.vue
  9. 46
      src/pages/testPaper/detail/index.vue
  10. 4
      src/pages/testPaper/detail/manual.vue
  11. 15
      src/pages/testPaper/detail/template.vue
  12. 10
      src/pages/testPaper/list/index.vue
  13. 6
      src/pages/testPaperLibrary/index.vue
  14. 5
      src/router/modules/ques.js

@ -42,7 +42,7 @@ export default {
.el-breadcrumb__inner, .el-breadcrumb__inner,
.el-breadcrumb__separator { .el-breadcrumb__separator {
font-weight: 400; font-weight: 400;
color: #333; color: $main-color;
} }
&:last-child:not(:first-child) { &:last-child:not(:first-child) {

@ -69,7 +69,7 @@ export default {
setText (con) { setText (con) {
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
this.instance = UE.getEditor(this.randomId) this.instance = UE.getEditor(this.randomId)
this.instance.setContent(con) this.instance && this.instance.setContent(con)
} }
} }
} }

@ -1,7 +1,7 @@
<template> <template>
<div>
<Breadcrumb :data="crumbs" />
<div class="page"> <div class="page">
<Breadcrumb style="margin-bottom: 0;" :data="crumbs" />
<div class="wrap">
<div class="side"> <div class="side">
<div class="m-b-20"> <div class="m-b-20">
<el-radio-group v-model="isNotJoin" @change="changeType"> <el-radio-group v-model="isNotJoin" @change="changeType">
@ -142,7 +142,7 @@ export default {
components: { Breadcrumb }, components: { Breadcrumb },
data () { data () {
return { return {
typeId: this.$route.query.id, questionBankId: this.$route.query.questionBankId,
createSource: 1, createSource: 1,
loading: false, loading: false,
keyword: '', keyword: '',
@ -208,16 +208,19 @@ export default {
}, },
}, },
mounted () { mounted () {
const { query } = this.$route
this.crumbs = [ this.crumbs = [
{ {
name: this.$route.query.name || '题库管理', name: query.questionBankName || '题库管理',
route: '/quesBank' route: '/quesBank'
}, },
{ {
name: '试题列表', name: '试题列表',
route: '/ques', route: '/ques',
query: { query: {
id: this.typeId questionBankId: query.questionBankId,
questionBankName: query.questionBankName,
questionBankCategory: query.questionBankCategory
} }
}, },
{ {
@ -234,7 +237,7 @@ export default {
const { data } = await this.$post(this.api.classificationTreeStructure, { const { data } = await this.$post(this.api.classificationTreeStructure, {
createSource: this.createSource, createSource: this.createSource,
keyword: this.keyword, keyword: this.keyword,
questionBankId: this.typeId, questionBankId: this.questionBankId,
}) })
this.handleType(data) this.handleType(data)
this.types = data this.types = data
@ -311,7 +314,7 @@ export default {
this.typeForm.parentId = cas[len - 1] this.typeForm.parentId = cas[len - 1]
} }
form.createSource = this.createSource form.createSource = this.createSource
form.questionBankId = this.typeId form.questionBankId = this.questionBankId
form.type = 0 form.type = 0
await this.$post(this.api.knowledgeHierarchySave, form) await this.$post(this.api.knowledgeHierarchySave, form)
Util.successMsg('保存成功') Util.successMsg('保存成功')
@ -340,7 +343,7 @@ export default {
isNotJoin: this.isNotJoin || '', isNotJoin: this.isNotJoin || '',
pageNum: this.page, pageNum: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
questionBankId: this.typeId, questionBankId: this.questionBankId,
knowledgePointCategoryId: this.$refs.typeTree.getCurrentKey() || '', knowledgePointCategoryId: this.$refs.typeTree.getCurrentKey() || '',
}) })
this.list = res.message.records this.list = res.message.records
@ -411,7 +414,7 @@ export default {
this.submiting = true this.submiting = true
form.parentId = form.parentId.length ? form.parentId[form.parentId.length - 1] : 0 form.parentId = form.parentId.length ? form.parentId[form.parentId.length - 1] : 0
form.createSource = 1 form.createSource = 1
form.questionBankId = this.typeId form.questionBankId = this.questionBankId
form.type = 1 form.type = 1
try { try {
await this.$post(this.api.knowledgeHierarchySave, form) await this.$post(this.api.knowledgeHierarchySave, form)
@ -461,11 +464,8 @@ export default {
width: 100%; width: 100%;
} }
.page { .wrap {
display: flex; display: flex;
min-height: 100%;
margin-top: 20px;
padding: 0 24px;
.side { .side {
width: 300px; width: 300px;

@ -1,24 +1,31 @@
<template> <template>
<div> <div class="page">
<el-dialog :title="diaTitle" :visible.sync="quesVisible" :modal-append-to-body="false" width="1000px" <Breadcrumb :data="crumbs" />
:close-on-click-modal="false" custom-class="ques-dia" @closed="closeDia"> <p class="page-name mb">试题</p>
<el-form :model="form" :rules="rules" ref="form" label-width="110px" :disabled="detailType === 2"> <el-form :model="form" :rules="rules" class="input-form model" ref="form" label-width="110px"
:disabled="detailType === 2">
<div class="item-line">
<el-form-item label="题库分类"> <el-form-item label="题库分类">
<el-input v-model="questionBankCategory" disabled /> <el-input v-model="questionBankCategory" disabled />
</el-form-item> </el-form-item>
<el-form-item label="题库"> <el-form-item label="题库">
<el-input v-model="questionBankName" disabled /> <el-input v-model="questionBankName" disabled />
</el-form-item> </el-form-item>
</div>
<div class="item-line">
<el-form-item prop="specialtyIds" label="所属专业"> <el-form-item prop="specialtyIds" label="所属专业">
<el-select v-model="form.specialtyIds" clearable multiple placeholder="请选择所属专业"> <el-select v-model="form.specialtyIds" clearable multiple filterable placeholder="请选择所属专业">
<el-option v-for="(item, i) in professionals" :key="i" :label="item.professionalName" <el-option v-for="(item, i) in professionals" :key="i" :label="item.professionalName"
:value="item.professionalId" filter></el-option> :value="item.professionalId" filter></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="knowledgePointIds" label="所属知识点"> <el-form-item prop="knowledgePointIds" label="所属知识点">
<el-cascader placeholder="请选择所属知识点" v-model="form.knowledgePointIds" :options="knowledges" <el-cascader placeholder="请选择所属知识点" v-model="form.knowledgePointIds" :options="knowledges"
:props="{ value: 'id', label: 'name', multiple: true, checkStrictly: true }" clearable></el-cascader> :props="{ value: 'id', label: 'name', multiple: true, checkStrictly: true }" :show-all-levels="false"
clearable></el-cascader>
</el-form-item> </el-form-item>
</div>
<div class="item-line">
<el-form-item prop="givenYear" label="年份"> <el-form-item prop="givenYear" label="年份">
<el-date-picker v-model="form.givenYear" type="year" placeholder="请选择年份" format="yyyy" value-format="yyyy"> <el-date-picker v-model="form.givenYear" type="year" placeholder="请选择年份" format="yyyy" value-format="yyyy">
</el-date-picker> </el-date-picker>
@ -28,6 +35,7 @@
<el-option v-for="(item, i) in difficults" :key="i" :label="item.name" :value="item.id"></el-option> <el-option v-for="(item, i) in difficults" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</div>
<el-form-item prop="questionType" label="题型"> <el-form-item prop="questionType" label="题型">
<el-radio-group v-model="form.questionType" @change="questionTypeChange"> <el-radio-group v-model="form.questionType" @change="questionTypeChange">
<el-radio v-for="(item, i) in questionTypes" :key="i" :label="item.id">{{ item.name }}</el-radio> <el-radio v-for="(item, i) in questionTypes" :key="i" :label="item.id">{{ item.name }}</el-radio>
@ -51,7 +59,7 @@
<!-- 单选多选判断特有 --> <!-- 单选多选判断特有 -->
<el-form-item v-if="form.questionType !== 'fill_blank' && form.questionType !== 'essay'" label="正确答案" required> <el-form-item v-if="form.questionType !== 'fill_blank' && form.questionType !== 'essay'" label="正确答案" required>
<div class="opts"> <div class="opts">
<div v-for="(item, i) in form.questionAnswerVersions" :key="i" class="line"> <div v-for="(item, i) in form.questionAnswerVersions" :key="i" class="opt">
<el-checkbox v-if="form.questionType === 'multiple_choice'" class="correct-check" <el-checkbox v-if="form.questionType === 'multiple_choice'" class="correct-check"
v-model="item.answerIsCorrect" :true-label="1">选项{{ numToLetter(i) }}</el-checkbox> v-model="item.answerIsCorrect" :true-label="1">选项{{ numToLetter(i) }}</el-checkbox>
<el-radio v-else v-model="item.answerIsCorrect" :true-label="1" :label="1" @change="correctChange(i)">选项{{ <el-radio v-else v-model="item.answerIsCorrect" :true-label="1" :label="1" @change="correctChange(i)">选项{{
@ -75,7 +83,7 @@
<template v-if="form.questionType === 'fill_blank'"> <template v-if="form.questionType === 'fill_blank'">
<el-form-item label="正确答案" required> <el-form-item label="正确答案" required>
<div class="opts fill-blanks"> <div class="opts fill-blanks">
<div v-for="(item, i) in fillBlanks" :key="i" class="line j-between"> <div v-for="(item, i) in fillBlanks" :key="i" class="opt j-between">
<div class="fills"> <div class="fills">
<span>填空{{ i + 1 }}</span> <span>填空{{ i + 1 }}</span>
<div v-for="(fill, j) in item.fills" :key="j" class="fill-item"> <div v-for="(fill, j) in item.fills" :key="j" class="fill-item">
@ -117,7 +125,7 @@
<!-- 问答题特有 --> <!-- 问答题特有 -->
<template v-if="form.questionType === 'essay'"> <template v-if="form.questionType === 'essay'">
<el-form-item prop="allowAttachment" label="支持学生上传附件" label-width="130px"> <el-form-item prop="allowAttachment" label="支持学生上传附件" label-width="140px">
<el-radio-group v-model="form.allowAttachment"> <el-radio-group v-model="form.allowAttachment">
<el-radio :label="0"></el-radio> <el-radio :label="0"></el-radio>
<el-radio :label="1"></el-radio> <el-radio :label="1"></el-radio>
@ -143,21 +151,19 @@
v-model="answerAnalysis" /> v-model="answerAnalysis" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<span v-if="detailType !== 2" slot="footer" class="dialog-footer"> <div v-if="detailType !== 2" class="btns">
<el-button v-if="detailType === 1" type="primary" :loading="submiting && keep === 0" <el-button v-if="detailType === 1" type="primary" :loading="submiting && keep === 0"
@click="submit(1)">保存</el-button> @click="submit(1)">保存</el-button>
<template v-else> <template v-else>
<el-button type="primary" :loading="submiting && keep === 0" @click="submit(0)">{{ row.questionId ? '仅更新此题' : <el-button type="primary" :loading="submiting && keep === 0" @click="submit(0)">{{ questionId ? '仅更新此题' :
'保存' '保存'
}}</el-button> }}</el-button>
<el-button type="primary" :loading="submiting && keep === 1" @click="submit(1)">{{ row.questionId ? '同步更新相似题' <el-button type="primary" :loading="submiting && keep === 1" @click="submit(1)">{{ questionId ? '同步更新相似题'
: :
'保存并继续新增' }}</el-button> '保存并继续新增' }}</el-button>
</template> </template>
<el-button @click="quesVisible = false">取消</el-button> <el-button @click="back">取消</el-button>
</span> </div>
</el-dialog>
<el-dialog title="提示" :visible.sync="repeatVisible" width="800px" :close-on-click-modal="false"> <el-dialog title="提示" :visible.sync="repeatVisible" width="800px" :close-on-click-modal="false">
<el-alert title="与当前题库中已有的试题重复(如下),是否继续保存?" type="warning" effect="dark" :closable="false" /> <el-alert title="与当前题库中已有的试题重复(如下),是否继续保存?" type="warning" effect="dark" :closable="false" />
@ -194,6 +200,7 @@
<script> <script>
import Setting from '@/setting' import Setting from '@/setting'
import Util from '@/libs/util' import Util from '@/libs/util'
import Breadcrumb from '@/components/breadcrumb'
import UeditorPlus from '@/components/ueditorPlus' import UeditorPlus from '@/components/ueditorPlus'
import Upload from '@/components/upload' import Upload from '@/components/upload'
import Oss from '@/components/upload/upload.js' import Oss from '@/components/upload/upload.js'
@ -201,13 +208,16 @@ import dayjs from 'dayjs'
import _ from 'lodash' import _ from 'lodash'
import Const from '@/const/ques' import Const from '@/const/ques'
export default { export default {
props: ['visible', 'row', 'detailType'], components: { Breadcrumb, UeditorPlus, Upload },
components: { UeditorPlus, Upload },
data () { data () {
return { return {
typeId: this.$route.query.id, // id crumbs: [],
questionId: this.$route.query.questionId, // id
version: this.$route.query.version, // id
questionBankId: this.$route.query.questionBankId, // id
questionBankName: this.$route.query.questionBankName, questionBankName: this.$route.query.questionBankName,
questionBankCategory: this.$route.query.questionBankCategory, questionBankCategory: this.$route.query.questionBankCategory,
detailType: this.$route.query.detailType,
numToLetter: Util.numToLetter, numToLetter: Util.numToLetter,
detailTypes: ['', '复制', '查看', '编辑', '编辑'], detailTypes: ['', '复制', '查看', '编辑', '编辑'],
types: [], types: [],
@ -222,9 +232,7 @@ export default {
questionTypes: Const.questionTypes, questionTypes: Const.questionTypes,
knowledges: [], knowledges: [],
editorConfig: { editorConfig: {},
zIndex: 2500,
},
richEditor: { richEditor: {
object: null, object: null,
parameterName: '', parameterName: '',
@ -249,7 +257,7 @@ export default {
questionAnswerVersions: [], questionAnswerVersions: [],
questionBankId: '', questionBankId: '',
questionType: 'single_choice', questionType: 'single_choice',
specialtyIds: [1], specialtyIds: [],
stem: '', stem: '',
allowAttachment: 0, allowAttachment: 0,
stemAttachment: '', stemAttachment: '',
@ -267,7 +275,6 @@ export default {
], ],
}, },
templateVisible: false, templateVisible: false,
quesVisible: false,
submiting: false, submiting: false,
tempForm: {}, tempForm: {},
keep: 0, keep: 0,
@ -291,15 +298,24 @@ export default {
'') + '试题' '') + '试题'
}, },
}, },
watch: { mounted () {
visible () { this.crumbs = [
this.quesVisible = this.visible {
this.visible && this.init() name: '试题管理',
route: 'list',
query: {
id: this.questionBankId
} }
}, },
mounted () { {
name: this.diaTitle
},
]
this.originForm = _.cloneDeep(this.form) this.originForm = _.cloneDeep(this.form)
// this.originFillBlank = _.cloneDeep(this.fillBlanks[0]) // this.originFillBlank = _.cloneDeep(this.fillBlanks[0])
this.init()
}, },
methods: { methods: {
// //
@ -309,18 +325,16 @@ export default {
const type = this.detailType const type = this.detailType
// //
if (type < 4) { if (!type) {
const knowledgeCheck = this.$parent.$refs.typeTree.getCurrentNode() const { path } = this.$route.query
if (knowledgeCheck && knowledgeCheck.type) this.form.knowledgePointIds = [knowledgeCheck.path.split('/').map(e => +e)] if (path) this.form.knowledgePointIds = [path.split('/').map(e => +e)]
} else if (type === 4) { } else if (type === 4) {
this.typeId = this.row.questionBankId // this.questionBankId = this.row.questionBankId
} }
const { stem, answerAnalysis } = this.$refs
// stem && stem.instance && stem.setText('')
this.$refs.stem && this.$refs.stem.setText('') answerAnalysis && answerAnalysis.instance && answerAnalysis.setText('')
this.$refs.answerAnalysis && this.$refs.answerAnalysis.setText('') this.answerAnalysis = ''
this.$refs.uploadInstructions && this.$refs.uploadInstructions.setText('')
this.$refs.referenceAnswer && this.$refs.referenceAnswer.setText('')
this.getDetail() this.getDetail()
this.getKnowledge() this.getKnowledge()
@ -329,9 +343,9 @@ export default {
// //
async getDetail () { async getDetail () {
try { try {
const { row } = this const { questionId, version } = this
if (row.questionId) { if (questionId) {
const res = await this.$post(`${this.api.findQuestion}?questionId=${this.row.questionId}&version=${this.row.version}`) const res = await this.$post(`${this.api.findQuestion}?questionId=${questionId}&version=${version}`)
const r = res.message const r = res.message
const opts = r.questionAnswerVersionsList const opts = r.questionAnswerVersionsList
@ -352,7 +366,7 @@ export default {
knowledgePointIds: r.knowledgePointList ? r.knowledgePointList.map(e => { knowledgePointIds: r.knowledgePointList ? r.knowledgePointList.map(e => {
return e.path.split('/').map(n => +n) return e.path.split('/').map(n => +n)
}) : [], }) : [],
specialtyIds: r.professionalList.map(e => e.specialtyId), specialtyIds: r.professionalList ? r.professionalList.map(e => e.specialtyId) : [],
allowAttachment: r.allowAttachment, allowAttachment: r.allowAttachment,
stemAttachment: r.stemAttachment, stemAttachment: r.stemAttachment,
uploadInstructions: r.uploadInstructions, uploadInstructions: r.uploadInstructions,
@ -374,11 +388,11 @@ export default {
}, },
// //
async getKnowledge () { async getKnowledge () {
if (this.typeId) { if (this.questionBankId) {
try { try {
const { data } = await this.$post(this.api.TreeStructure, { const { data } = await this.$post(this.api.TreeStructure, {
createSource: 1, createSource: 1,
questionBankId: this.typeId, questionBankId: this.questionBankId,
keyword: '', keyword: '',
}) })
this.handleType(data) this.handleType(data)
@ -394,6 +408,7 @@ export default {
pageSize: 1000, pageSize: 1000,
}) })
this.professionals = res.pageList.records this.professionals = res.pageList.records
if (!this.questionId) this.form.specialtyIds = [1]
} catch (e) { } } catch (e) { }
}, },
// //
@ -456,19 +471,19 @@ export default {
editor.addListener('contentChange', () => { editor.addListener('contentChange', () => {
this.questionItemReset(editor.getContent()) this.questionItemReset(editor.getContent())
}) })
this.form.stem && editor.setContent(this.form.stem) editor.setContent(this.form.stem)
}, },
// //
answerAnalysisReady (editor) { answerAnalysisReady (editor) {
this.answerAnalysis && editor.setContent(this.answerAnalysis) editor.setContent(this.answerAnalysis)
}, },
// //
uploadInstructionsReady (editor) { uploadInstructionsReady (editor) {
this.form.uploadInstructions && editor.setContent(this.form.uploadInstructions) editor.setContent(this.form.uploadInstructions)
}, },
// //
referenceAnswerReady (editor) { referenceAnswerReady (editor) {
this.form.questionAnswerVersions[0].referenceAnswer && editor.setContent(this.form.questionAnswerVersions[0].referenceAnswer) editor.setContent(this.form.questionAnswerVersions[0].referenceAnswer)
}, },
// //
correctChange (i) { correctChange (i) {
@ -588,7 +603,7 @@ export default {
this.submiting = true this.submiting = true
try { try {
form.stem = stem form.stem = stem
form.questionBankId = this.typeId form.questionBankId = this.questionBankId
form.knowledgePointIds = form.knowledgePointIds.map(e => { form.knowledgePointIds = form.knowledgePointIds.map(e => {
return e[e.length - 1] return e[e.length - 1]
}) })
@ -654,16 +669,15 @@ export default {
type === 4 && this.$emit('updateQues', this.tempForm, res.questionVersionId) type === 4 && this.$emit('updateQues', this.tempForm, res.questionVersionId)
Util.successMsg('保存成功') Util.successMsg('保存成功')
!form.questionId && this.keep ? this.init() : (this.quesVisible = false) !form.questionId && this.keep ? this.init() : this.back()
this.repeatVisible = false this.repeatVisible = false
} finally { } finally {
this.submiting = false this.submiting = false
} }
}, },
// back () {
closeDia () { this.$router.back()
this.$emit('update:visible', false) },
}
} }
}; };
</script> </script>
@ -698,12 +712,6 @@ export default {
} }
} }
/deep/.ques-dia {
z-index: 500;
.fill-blanks { .fill-blanks {
.fills { .fills {
display: inline-flex; display: inline-flex;
@ -737,7 +745,7 @@ export default {
} }
.opts { .opts {
.line { .opt {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 15px; margin-bottom: 15px;
@ -773,8 +781,7 @@ export default {
} }
} }
/deep/.correct-check { .correct-check {
margin-right: 15px; margin-right: 15px;
} }
}
</style> </style>

@ -139,8 +139,6 @@
</div> </div>
</div> </div>
<Detail :visible.sync="quesVisible" :row.sync="curRow" :detailType.sync="detailType" />
<el-dialog title="提示" :visible.sync="delVisible" width="400px" :close-on-click-modal="false" custom-class="del-dia"> <el-dialog title="提示" :visible.sync="delVisible" width="400px" :close-on-click-modal="false" custom-class="del-dia">
<div class="del-wrap"> <div class="del-wrap">
<div class="icon el-icon-warning"></div> <div class="icon el-icon-warning"></div>
@ -211,18 +209,12 @@ export default {
components: { Breadcrumb, Detail }, components: { Breadcrumb, Detail },
data () { data () {
return { return {
crumbs: [ crumbs: [],
{ questionBankId: this.$route.query.questionBankId,
name: this.$route.query.questionBankName || '题库管理', questionBankName: this.$route.query.questionBankName,
route: '/quesBank' questionBankCategory: this.$route.query.questionBankCategory,
},
{
name: '试题管理'
},
],
difficults: Const.difficults, difficults: Const.difficults,
questionTypes: Const.questionTypes, questionTypes: Const.questionTypes,
typeId: this.$route.query.id,
loading: false, loading: false,
isNotJoin: 0, isNotJoin: 0,
createSource: 1, createSource: 1,
@ -264,10 +256,6 @@ export default {
total: 0, total: 0,
multipleSelection: [], multipleSelection: [],
quesVisible: false,
curRow: {},
detailType: '',
delVisible: false, delVisible: false,
curUsePapers: [], curUsePapers: [],
curRow: {}, curRow: {},
@ -303,11 +291,17 @@ export default {
clearTimeout(this.searchTimer) clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(this.initData, 500) this.searchTimer = setTimeout(this.initData, 500)
}, },
quesVisible () {
this.quesVisible || this.getList()
},
}, },
mounted () { mounted () {
this.crumbs = [
{
name: this.questionBankName || '题库管理',
route: '/quesBank'
},
{
name: '试题管理'
},
]
this.getType() this.getType()
this.getProfessional() this.getProfessional()
this.getKnowledge() this.getKnowledge()
@ -319,7 +313,7 @@ export default {
this.loading = true this.loading = true
const { data } = await this.$post(this.api.TreeStructure, { const { data } = await this.$post(this.api.TreeStructure, {
createSource: 1, createSource: 1,
questionBankId: this.typeId, questionBankId: this.questionBankId,
keyword: this.keyword, keyword: this.keyword,
}) })
this.types = data this.types = data
@ -330,7 +324,7 @@ export default {
}, },
// //
toSet () { toSet () {
this.$router.push(`/knowledge?id=${this.typeId}`) this.$router.push(`/knowledge?questionBankId=${this.questionBankId}&questionBankName=${this.questionBankName}`)
}, },
// //
typeChange () { typeChange () {
@ -358,7 +352,7 @@ export default {
try { try {
const { data } = await this.$post(this.api.TreeStructure, { const { data } = await this.$post(this.api.TreeStructure, {
createSource: 1, createSource: 1,
questionBankId: this.typeId, questionBankId: this.questionBankId,
keyword: '' keyword: ''
}) })
this.handleType(data) this.handleType(data)
@ -392,7 +386,7 @@ export default {
isNotJoin: this.isNotJoin || '', isNotJoin: this.isNotJoin || '',
pageNum: this.page, pageNum: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
questionBankId: this.typeId, questionBankId: this.questionBankId,
knowledgePointIds: type || [], knowledgePointIds: type || [],
}) })
this.list = Util.removeTag(message.records) this.list = Util.removeTag(message.records)
@ -424,15 +418,12 @@ export default {
// //
add () { add () {
this.quesVisible = true const knowledgeCheck = this.$refs.typeTree.getCurrentNode()
this.curRow = {} this.$router.push(`detail?questionBankId=${this.questionBankId}&questionBankName=${this.questionBankName}&questionBankCategory=${this.questionBankCategory}&path=${knowledgeCheck && knowledgeCheck.type ? knowledgeCheck.path : ''}`)
this.detailType = ''
}, },
// / type: 123 // / type: 123
toDetail (row, type) { toDetail (row, type) {
this.quesVisible = true this.$router.push(`detail?questionId=${row.questionId}&version=${row.version}&questionBankId=${this.questionBankId}&questionBankName=${this.questionBankName}&questionBankCategory=${this.questionBankCategory}&detailType=${type}`)
this.curRow = row
this.detailType = type
}, },
// //
async remove (row) { async remove (row) {

@ -270,7 +270,7 @@ export default {
}, },
// //
toQues (row) { toQues (row) {
this.$router.push(`/ques?id=${row.id}&questionBankName=${row.questionBankName}&questionBankCategory=${row.questionBankCategory}`) this.$router.push(`/ques?questionBankId=${row.id}&questionBankName=${row.questionBankName}&questionBankCategory=${row.questionBankCategory}`)
}, },
// / // /
async edit (row, isCopy) { async edit (row, isCopy) {

@ -219,7 +219,7 @@ export default {
async switchOff (val, row) { async switchOff (val, row) {
try { try {
row.status = val ? 0 : 1 // row.status = val ? 0 : 1 //
if (!val) { if (!val && row.children && row.children.length) {
await this.$confirm(`<p>确认要禁用【${row.name}】吗?</p><p style="color: #f56c6c;">禁用后,此题库分类及其子分类将被禁用</p>`, '提示', { await this.$confirm(`<p>确认要禁用【${row.name}】吗?</p><p style="color: #f56c6c;">禁用后,此题库分类及其子分类将被禁用</p>`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',

@ -1,6 +1,8 @@
<template> <template>
<div> <div>
<el-dialog title="自动选题" :visible.sync="quesVisible" width="1200px" :close-on-click-modal="false" @closed="closeDia"> <el-drawer title="自动选题" :visible.sync="quesVisible" size="1200px" :close-on-click-modal="false"
custom-class="ques-dia" @closed="closeDia">
<div class="overflow">
<h6 class="page-name">难度设置</h6> <h6 class="page-name">难度设置</h6>
<div class="tool"> <div class="tool">
<ul class="filter"> <ul class="filter">
@ -64,8 +66,8 @@
<!-- 知识点 --> <!-- 知识点 -->
<div class="item"> <div class="item">
<p class="total m-b-10">知识点框架</p> <p class="total m-b-10">知识点框架</p>
<el-input class="m-b-10" placeholder="请输入知识点分类/知识点名称" prefix-icon="el-icon-search" v-model="knowledgeKeyword" <el-input class="m-b-10" placeholder="请输入知识点分类/知识点名称" prefix-icon="el-icon-search"
clearable /> v-model="knowledgeKeyword" clearable />
<el-tree :data="knowledges" default-expand-all ref="knowledge" node-key="id" highlight-current <el-tree :data="knowledges" default-expand-all ref="knowledge" node-key="id" highlight-current
:expand-on-click-node="false" show-checkbox @check-change="knowledgeCheck" :props="{ label: 'name' }"> :expand-on-click-node="false" show-checkbox @check-change="knowledgeCheck" :props="{ label: 'name' }">
<span class="custom-tree-node" slot-scope="{ node, data }"> <span class="custom-tree-node" slot-scope="{ node, data }">
@ -106,13 +108,13 @@
<el-checkbox v-for="(item, i) in years" :key="i" :label="item"></el-checkbox> <el-checkbox v-for="(item, i) in years" :key="i" :label="item"></el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</div> </div>
</div>
<div class="btns">
<span slot="footer" class="dialog-footer">
<el-button @click="quesVisible = false">取消</el-button> <el-button @click="quesVisible = false">取消</el-button>
<el-button type="primary" :loading="submiting" @click="submit">自动选题</el-button> <el-button type="primary" :loading="submiting" @click="submit">自动选题</el-button>
</span> </div>
</el-dialog> </el-drawer>
</div> </div>
</template> </template>
<script> <script>
@ -145,6 +147,7 @@ export default {
yearAll: true, yearAll: true,
yearCheck: [], yearCheck: [],
submiting: false, submiting: false,
diaTop: 0,
}; };
}, },
computed: { computed: {
@ -171,7 +174,9 @@ export default {
} }
}, },
mounted () { mounted () {
console.log(5555, window.innerHeight)
const height = (window.innerHeight - 600) / 2
this.diaTop = (height > 0 ? height : 0) + 'px'
}, },
methods: { methods: {
// //
@ -419,6 +424,18 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
/deep/.ques-dia {
.el-drawer__header {
margin-bottom: 20px;
}
}
.overflow {
height: calc(100vh - 147px);
padding: 0 20px;
overflow: auto;
}
.wrap { .wrap {
display: flex; display: flex;
margin-top: 20px; margin-top: 20px;

@ -32,7 +32,7 @@
</div> </div>
<div class="item-line"> <div class="item-line">
<el-form-item prop="professionals" label="所属专业"> <el-form-item prop="professionals" label="所属专业">
<el-select v-model="form.professionalId" clearable placeholder="请选择所属专业"> <el-select v-model="form.professionalId" multiple clearable placeholder="请选择所属专业">
<el-option v-for="(item, i) in professionals" :key="i" :label="item.professionalName" <el-option v-for="(item, i) in professionals" :key="i" :label="item.professionalName"
:value="item.professionalId" filter></el-option> :value="item.professionalId" filter></el-option>
</el-select> </el-select>
@ -122,7 +122,7 @@
<div> <div>
<el-button type="primary" @click="allocation(item)">一键分配分值</el-button> <el-button type="primary" @click="allocation(item)">一键分配分值</el-button>
<el-button type="primary" @click="showManualDia(item)">批量添加</el-button> <el-button type="primary" @click="showManualDia(item)">批量添加</el-button>
<el-button type="danger" @click="batchDelQues(item)">批量除试题</el-button> <el-button type="danger" @click="batchDelQues(item)">批量除试题</el-button>
<img :class="['shrink', { active: item.shrink }]" src="@/assets/images/shrink.svg" alt="" <img :class="['shrink', { active: item.shrink }]" src="@/assets/images/shrink.svg" alt=""
@click="item.shrink = !item.shrink"> @click="item.shrink = !item.shrink">
</div> </div>
@ -137,12 +137,14 @@
{{ ques.repeat }} {{ ques.repeat }}
<div :class="['ques-info', { disabled: !ques.status, del: ques.isDel, repeat: ques.repeat }]"> <div :class="['ques-info', { disabled: !ques.status, del: ques.isDel, repeat: ques.repeat }]">
<div class="top-line"> <div class="top-line">
<div class="stem-info">
<div class="labels"> <div class="labels">
<span class="label">{{ j + 1 }} / {{ item.examQuestions.length }}</span> <span class="label">{{ j + 1 }} / {{ item.examQuestions.length }}</span>
<span class="label">{{ questionTypes.find(e => e.id === item.questionType).name }}</span> <span class="label">{{ questionTypes.find(e => e.id === item.questionType).name }}</span>
</div> </div>
<div class="stem" :id="'stem' + ques.questionVersionId" v-html="getQuesStem(ques)"></div> <div class="stem" :id="'stem' + ques.questionVersionId" v-html="getQuesStem(ques)"></div>
<p v-if="item.questionType !== 'fill_blank'"><el-input class="score" placeholder="请输入分值" </div>
<p v-if="item.questionType !== 'fill_blank'"><el-input class="l-input" placeholder="请输入分值"
v-model="ques.score" /></p> v-model="ques.score" /></p>
</div> </div>
@ -163,7 +165,7 @@
<div class="actions"> <div class="actions">
<div class="sort"> <div class="sort">
<span>排序</span> <span>排序</span>
<el-input class="score" v-model="ques.serialNumber" /> <el-input class="l-input sort-input" v-model="ques.serialNumber" />
</div> </div>
<el-button type="text" @click="toQues(item, j, ques)">编辑试题</el-button> <el-button type="text" @click="toQues(item, j, ques)">编辑试题</el-button>
<el-button type="text" @click="showManualDia(item, j, ques)">更换试题</el-button> <el-button type="text" @click="showManualDia(item, j, ques)">更换试题</el-button>
@ -177,7 +179,6 @@
</div> </div>
</li> </li>
</ul> </ul>
</el-form> </el-form>
<div class="btns"> <div class="btns">
<el-button @click="submit(1)">保存草稿</el-button> <el-button @click="submit(1)">保存草稿</el-button>
@ -189,7 +190,6 @@
<Template :visible.sync="templateVisible" /> <Template :visible.sync="templateVisible" />
<Manual :visible.sync="manualVisible" :questionType.sync="curType.questionType" /> <Manual :visible.sync="manualVisible" :questionType.sync="curType.questionType" />
<Auto :visible.sync="autoVisible" /> <Auto :visible.sync="autoVisible" />
<Detail :visible.sync="quesVisible" :row.sync="curRow" :detailType.sync="detailType" @updateQues="updateQues" />
<RepeatQues :visible.sync="repeatVisible" :list.sync="repeatQues" /> <RepeatQues :visible.sync="repeatVisible" :list.sync="repeatQues" />
</div> </div>
</template> </template>
@ -201,7 +201,6 @@ import Template from './template'
import Manual from './manual' import Manual from './manual'
import Auto from './auto' import Auto from './auto'
import RepeatQues from './repeatQues' import RepeatQues from './repeatQues'
import Detail from '@/pages/ques/detail'
import Setting from '@/setting' import Setting from '@/setting'
import Util from '@/libs/util' import Util from '@/libs/util'
import dayjs from 'dayjs' import dayjs from 'dayjs'
@ -210,7 +209,7 @@ import TestPaperConst from '@/const/testPaper'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
export default { export default {
components: { UeditorPlus, Breadcrumb, Template, Manual, Auto, RepeatQues, Detail, Draggable }, components: { UeditorPlus, Breadcrumb, Template, Manual, Auto, RepeatQues, Draggable },
data () { data () {
return { return {
crumbs: [], crumbs: [],
@ -244,7 +243,7 @@ export default {
paperMethod: '', paperMethod: '',
paperType: '', paperType: '',
particularYear: new Date(), particularYear: new Date(),
professionalId: '', professionalId: [],
remarks: '', remarks: '',
score: '', score: '',
questionCount: 0, questionCount: 0,
@ -377,6 +376,7 @@ export default {
}) })
if (r.particularYear) r.particularYear = r.particularYear + '' if (r.particularYear) r.particularYear = r.particularYear + ''
if (r.professionalId) r.professionalId = r.professionalId.split(',').map(e => +e)
this.form = r this.form = r
} }
} catch (e) { } } catch (e) { }
@ -615,7 +615,7 @@ export default {
try { try {
const checked = item.examQuestions.filter(e => e.check) const checked = item.examQuestions.filter(e => e.check)
if (checked.length) { if (checked.length) {
await this.$confirm(`确认要除吗?`, '提示', { await this.$confirm(`确认要除吗?`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
@ -639,9 +639,17 @@ export default {
}) })
}, },
// //
delQues (item, i) { async delQues (item, i) {
try {
await this.$confirm(`确认要移除吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
closeOnClickModal: false,
})
item.examQuestions.splice(i, 1) item.examQuestions.splice(i, 1)
this.calcDifficult() this.calcDifficult()
} catch (e) { }
}, },
// //
hasRepeatQues (list) { hasRepeatQues (list) {
@ -796,6 +804,7 @@ export default {
} }
this.submiting = true this.submiting = true
form.professionalId = form.professionalId.join()
form.particularYear = +(dayjs(form.particularYear).format('YYYY')) form.particularYear = +(dayjs(form.particularYear).format('YYYY'))
form.libraryId = this.libraryId form.libraryId = this.libraryId
form.questionCount = this.questionCount form.questionCount = this.questionCount
@ -962,11 +971,18 @@ export default {
.top-line { .top-line {
display: flex; display: flex;
justify-content: space-between;
align-items: baseline; align-items: baseline;
margin-bottom: 10px; margin-bottom: 10px;
line-height: 28px; line-height: 28px;
} }
.stem-info {
display: inline-flex;
align-items: baseline;
flex: 1;
}
.labels { .labels {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
@ -984,13 +1000,17 @@ export default {
} }
.stem { .stem {
max-width: calc(100% - 236px); max-width: calc(100% - 120px);
} }
/deep/.score { /deep/.l-input {
width: 100px; width: 100px;
margin: 0 10px; margin: 0 10px;
&.sort-input {
width: 56px;
}
.el-input__inner { .el-input__inner {
height: 28px; height: 28px;
line-height: 28px; line-height: 28px;

@ -90,8 +90,6 @@
<el-button type="primary" :loading="submiting" @click="submit">确定</el-button> <el-button type="primary" :loading="submiting" @click="submit">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<Detail :visible.sync="quesVisible" :row.sync="curRow" :detailType.sync="detailType" @updateQues="updateQues" />
</div> </div>
</template> </template>
<script> <script>
@ -99,9 +97,7 @@ import Setting from '@/setting'
import Util from '@/libs/util' import Util from '@/libs/util'
import _ from 'lodash' import _ from 'lodash'
import QuesConst from '@/const/ques' import QuesConst from '@/const/ques'
import Detail from '@/pages/ques/detail'
export default { export default {
components: { Detail },
props: ['visible', 'questionType'], props: ['visible', 'questionType'],
data () { data () {
return { return {

@ -6,14 +6,14 @@
<ul class="filter"> <ul class="filter">
<li> <li>
<label>题型</label> <label>题型</label>
<el-select v-model="filter.questionType" clearable placeholder="请选择题目类型" @change="initData"> <el-select v-model="questionType" multiple clearable placeholder="请选择题目类型" @change="initData">
<el-option v-for="(item, i) in questionTypes" :key="i" :value="item.id" :label="item.name"></el-option> <el-option v-for="(item, i) in questionTypes" :key="i" :value="item.id" :label="item.name"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>搜索</label> <label>搜索</label>
<el-input style="width: 250px;" placeholder="请输入模板名称" prefix-icon="el-icon-search" <el-input style="width: 250px;" placeholder="请输入模板名称" prefix-icon="el-icon-search" v-model="templateName"
v-model="filter.templateName" clearable /> clearable />
</li> </li>
</ul> </ul>
<div> <div>
@ -105,10 +105,8 @@ export default {
listVisible: false, listVisible: false,
searchTimer: null, searchTimer: null,
filter: {
templateName: '', templateName: '',
questionType: '', questionType: [],
},
list: [], list: [],
page: 1, page: 1,
pageSize: 10, pageSize: 10,
@ -174,7 +172,7 @@ export default {
} }
}, },
watch: { watch: {
'filter.templateName': function (val) { templateName: function (val) {
clearTimeout(this.searchTimer) clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(this.initData, 500) this.searchTimer = setTimeout(this.initData, 500)
}, },
@ -193,7 +191,8 @@ export default {
const res = await this.$post(this.api.examPaperTemplateList, { const res = await this.$post(this.api.examPaperTemplateList, {
pageNum: this.page, pageNum: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
...this.filter questionType: this.questionType.join(),
templateName: this.templateName
}) })
const list = res.pageList.records const list = res.pageList.records
const types = QuesConst.questionTypes const types = QuesConst.questionTypes

@ -150,7 +150,7 @@
<el-table-column label="操作" align="center" width="240"> <el-table-column label="操作" align="center" width="240">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="toDetail(scope.row, 1)">复制</el-button> <el-button type="text" @click="toDetail(scope.row, 1)">复制</el-button>
<!-- <el-button type="text" @click="edit(scope.row)">预览</el-button> --> <el-button type="text" @click="preview(scope.row)">预览</el-button>
<el-button type="text" @click="toDetail(scope.row)">编辑</el-button> <el-button type="text" @click="toDetail(scope.row)">编辑</el-button>
<el-button type="text" @click="del(scope.row)">删除</el-button> <el-button type="text" @click="del(scope.row)">删除</el-button>
<el-switch v-if="!scope.row.status" v-model="scope.row.isDisable" :active-value="false" <el-switch v-if="!scope.row.status" v-model="scope.row.isDisable" :active-value="false"
@ -474,11 +474,15 @@ export default {
}, },
// //
add () { add () {
this.$router.push(`detail?libraryId=${this.typeId}&classificationId=${this.$refs.typeTree.getCurrentKey() || ''}`) this.$router.push(`/testPaper/detail?libraryId=${this.typeId}&classificationId=${this.$refs.typeTree.getCurrentKey() || ''}`)
}, },
// //
async toDetail (row, isCopy = '') { async toDetail (row, isCopy = '') {
this.$router.push(`detail?paperId=${row.paperId}&libraryId=${this.typeId}&classificationId=${this.$refs.typeTree.getCurrentKey() || ''}&isCopy=${isCopy}`) this.$router.push(`/testPaper/detail?paperId=${row.paperId}&libraryId=${this.typeId}&classificationId=${this.$refs.typeTree.getCurrentKey() || ''}&isCopy=${isCopy}`)
},
//
preview (row) {
window.open(this.$router.resolve(`preview?id=${row.paperId}`).href)
}, },
async delAllSelection () { async delAllSelection () {
const list = this.multipleSelection const list = this.multipleSelection

@ -61,7 +61,7 @@
<el-table-column prop="createUserName" label="创建人" align="center" width="100"></el-table-column> <el-table-column prop="createUserName" label="创建人" align="center" width="100"></el-table-column>
<el-table-column label="操作" align="center" width="280"> <el-table-column label="操作" align="center" width="280">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="toTestPaper(scope.row)">管理</el-button> <el-button type="text" @click="toTestPaper(scope.row)">管理</el-button>
<el-button type="text" @click="edit(scope.row, 0)">编辑</el-button> <el-button type="text" @click="edit(scope.row, 0)">编辑</el-button>
<el-button type="text" @click="edit(scope.row, 1)">复制</el-button> <el-button type="text" @click="edit(scope.row, 1)">复制</el-button>
<el-button type="text" @click="del(scope.row)">删除</el-button> <el-button type="text" @click="del(scope.row)">删除</el-button>
@ -126,7 +126,7 @@ export default {
], ],
filter: { filter: {
numOrder: '', numOrder: '',
timeOrder: '', timeOrder: 2,
isDisable: '', isDisable: '',
keyWord: '', keyWord: '',
}, },
@ -171,7 +171,7 @@ export default {
try { try {
this.loading = true this.loading = true
const res = await this.$post(this.api.libraryClassificationList, { const res = await this.$post(this.api.libraryClassificationList, {
keyword: this.keyword, libraryClassificationName: this.keyword,
createSource: 1, createSource: 1,
}) })
const data = res.treeList const data = res.treeList

@ -15,5 +15,10 @@ export default {
component: () => import('@/pages/ques/list'), component: () => import('@/pages/ques/list'),
meta: { title: '试题管理' } meta: { title: '试题管理' }
}, },
{
path: 'detail',
component: () => import('@/pages/ques/detail'),
meta: { title: '试题详情' }
},
] ]
}; };

Loading…
Cancel
Save