parent
2ae0f95eaf
commit
d2a9e6721c
18 changed files with 1370 additions and 755 deletions
@ -1,3 +0,0 @@ |
|||||||
export default { |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,42 @@ |
|||||||
|
export default { |
||||||
|
difficults: [ |
||||||
|
{ |
||||||
|
id: 'basic', |
||||||
|
name: '基础' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'easy', |
||||||
|
name: '普通' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'medium', |
||||||
|
name: '较难' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'hard', |
||||||
|
name: '难' |
||||||
|
}, |
||||||
|
], |
||||||
|
questionTypes: [ |
||||||
|
{ |
||||||
|
id: 'single_choice', |
||||||
|
name: '单选题' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'multiple_choice', |
||||||
|
name: '多选题' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'judgement', |
||||||
|
name: '判断题' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'fill_blank', |
||||||
|
name: '填空题' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'essay', |
||||||
|
name: '问答题' |
||||||
|
}, |
||||||
|
], |
||||||
|
} |
@ -0,0 +1,551 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-dialog :title="readonly ? '查看试题' : !form.questionId ? '新增试题' : '编辑试题'" :visible.sync="quesVisible" |
||||||
|
width="1000px" :close-on-click-modal="false" @closed="closeDia"> |
||||||
|
<el-form :model="form" :rules="rules" ref="form" label-width="110px" :disabled="readonly"> |
||||||
|
<el-form-item label="题库分类"> |
||||||
|
<el-input v-model="questionBankCategory" disabled /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="题库"> |
||||||
|
<el-input v-model="questionBankName" disabled /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="specialtyIds" label="所属专业"> |
||||||
|
<el-select v-model="form.specialtyIds" clearable multiple placeholder="请选择所属专业"> |
||||||
|
<el-option v-for="(item, i) in professionals" :key="i" :label="item.professionalName" |
||||||
|
:value="item.professionalId" filter></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="knowledgePointIds" label="所属知识点"> |
||||||
|
<el-cascader placeholder="请选择所属知识点" v-model="form.knowledgePointIds" :options="knowledges" |
||||||
|
:props="{ value: 'id', label: 'name', multiple: true, checkStrictly: true }" clearable></el-cascader> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="givenYear" label="年份"> |
||||||
|
<el-date-picker v-model="form.givenYear" type="year" placeholder="请选择年份" format="yyyy" value-format="yyyy"> |
||||||
|
</el-date-picker> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="difficulty" label="难度"> |
||||||
|
<el-select v-model="form.difficulty" clearable placeholder="请选择试卷难度"> |
||||||
|
<el-option v-for="(item, i) in difficults" :key="i" :label="item.name" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="questionType" label="题型"> |
||||||
|
<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-group> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item class="is-required" prop="stem" label="题干"> |
||||||
|
<Ueditor ref="stem" @ready="stemReady" v-model="form.stem" /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item v-if="form.questionType !== 'fill_blank' && form.questionType !== 'essay'" label="正确答案" required> |
||||||
|
<div class="opts"> |
||||||
|
<div v-for="(item, i) in form.questionAnswerVersions" :key="i" class="line"> |
||||||
|
<el-checkbox v-if="form.questionType === 'multiple_choice'" class="correct-check" |
||||||
|
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)">选项{{ |
||||||
|
numToLetter(i) |
||||||
|
}}</el-radio> |
||||||
|
<el-input placeholder="请输入" v-model="item.optionText"></el-input> |
||||||
|
<template v-if="form.questionType !== 'judgement'"> |
||||||
|
<i class="icon el-icon-circle-plus-outline" @click="addOpt(i)"></i> |
||||||
|
<i class="icon el-icon-remove-outline" @click="delOpt(i)"></i> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
|
||||||
|
|
||||||
|
<!-- 填空题特有 --> |
||||||
|
<template v-if="form.questionType === 'fill_blank'"> |
||||||
|
<el-form-item label="正确答案" required> |
||||||
|
<div class="opts fill-blanks"> |
||||||
|
<div v-for="(item, i) in fillBlanks" :key="i" class="line j-between"> |
||||||
|
<div class="fills"> |
||||||
|
<span>填空{{ i + 1 }}:</span> |
||||||
|
<div v-for="(fill, j) in item.fills" :key="i" class="fill-item"> |
||||||
|
<el-input placeholder="请输入" v-model="fill.val" /> |
||||||
|
<i v-if="j" class="action-icon el-icon-remove-outline" @click="item.fills.splice(j, 1)"></i> |
||||||
|
<span v-if="j !== item.fills.length - 1">或</span> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-button class="add-fill" type="primary" size="small" @click="addFill(item)">新增答案</el-button> |
||||||
|
</div> |
||||||
|
<div class="score-wrap"> |
||||||
|
<span>分值占比</span> |
||||||
|
<el-input class="score" placeholder="请输入" size="small" v-model="item.scoreProportion" /> |
||||||
|
<span>%</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="gradingStandard" label="判分标准" required> |
||||||
|
<el-select :value="form.questionAnswerVersions[0].gradingStandard" placeholder="请选择判分标准" disabled> |
||||||
|
<el-option label="完全一致" value="exact_match"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="referenceAnswer" label="判分标准"> |
||||||
|
<div> |
||||||
|
<el-switch disabled active-text="判分时忽略答案中的字母大小写"></el-switch> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-switch disabled active-text="判分时忽略答案中的空格"></el-switch> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-switch disabled active-text="允许学生每个填空的答案与正确答案的顺序不一致"></el-switch> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-switch disabled active-text="判分时允许数值相等"></el-switch> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
</template> |
||||||
|
|
||||||
|
<!-- 问答题特有 --> |
||||||
|
<template v-if="form.questionType === 'essay'"> |
||||||
|
<el-form-item prop="userName" label="上传题干文件"> |
||||||
|
<el-input placeholder="请输入题库名称" v-model="form.name"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="allowAttachment" label="支持学生上传附件" label-width="130px"> |
||||||
|
<el-radio-group v-model="form.allowAttachment"> |
||||||
|
<el-radio :label="0">否</el-radio> |
||||||
|
<el-radio :label="1">是</el-radio> |
||||||
|
</el-radio-group> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="gradingStandard" label="判分标准"> |
||||||
|
<el-select :value="form.questionAnswerVersions[0].gradingStandard" placeholder="请选择判分标准" disabled> |
||||||
|
<el-option label="人工判分" value="manual"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="referenceAnswer" label="参考答案"> |
||||||
|
<Ueditor ref="referenceAnswer" @ready="referenceAnswerReady" |
||||||
|
v-model="form.questionAnswerVersions[0].referenceAnswer" /> |
||||||
|
</el-form-item> |
||||||
|
</template> |
||||||
|
|
||||||
|
<el-form-item prop="answerAnalysis" label="解析"> |
||||||
|
<Ueditor ref="answerAnalysis" @ready="answerAnalysisReady" v-model="answerAnalysis" /> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button type="primary" :loading="submiting && keep === 0" @click="submit(0)">保存</el-button> |
||||||
|
<el-button type="primary" :loading="submiting && keep === 1" @click="submit(1)">保存并继续新增</el-button> |
||||||
|
<el-button @click="quesVisible = false">取消</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
|
||||||
|
<el-dialog title="提示" :visible.sync="repeatVisible" width="800px" :close-on-click-modal="false"> |
||||||
|
<el-alert title="与当前题库中已有的试题重复(如下),是否继续保存?" type="warning" effect="dark" :closable="false"> |
||||||
|
</el-alert> |
||||||
|
<el-table class="m-t-10" :data="repeats" stripe header-align="center" row-key="id"> |
||||||
|
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="题型" align="center" min-width="120"> |
||||||
|
<template slot-scope="scope">{{ questionTypes.find(e => e.id === scope.row.questionType) ? |
||||||
|
questionTypes.find(e => e.id === scope.row.questionType).name : '' }}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="stem" label="题干" align="center" min-width="120" show-overflow-tooltip></el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="240"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text">详情</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
|
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="repeatVisible = false">取消</el-button> |
||||||
|
<el-button type="primary" @click="saveQues">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog :visible.sync="richEditor.dialogVisible" width="1000px" :show-close="false" center |
||||||
|
:close-on-click-modal="false"> |
||||||
|
<!-- <Ueditor ref="title2" @ready="editorReady" /> --> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button type="primary" @click="editorSubmit">确定</el-button> |
||||||
|
<el-button @click="richEditor.dialogVisible = false">取消</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import Setting from '@/setting' |
||||||
|
import Util from '@/libs/util' |
||||||
|
import Ueditor from '@/components/ueditor' |
||||||
|
import dayjs from 'dayjs' |
||||||
|
import _ from 'lodash' |
||||||
|
import Const from '@/const/ques' |
||||||
|
export default { |
||||||
|
props: ['visible', 'row', 'readonly'], |
||||||
|
components: { Ueditor }, |
||||||
|
data () { |
||||||
|
return { |
||||||
|
typeId: this.$route.query.id, |
||||||
|
questionBankName: this.$route.query.questionBankName, |
||||||
|
questionBankCategory: this.$route.query.questionBankCategory, |
||||||
|
numToLetter: Util.numToLetter, |
||||||
|
radio: '', |
||||||
|
types: [], |
||||||
|
cascaderValue: [], |
||||||
|
cascaderProps: { |
||||||
|
checkStrictly: true, |
||||||
|
label: "classificationName", |
||||||
|
value: "classificationId" |
||||||
|
}, |
||||||
|
professionals: [], |
||||||
|
difficults: Const.difficults, |
||||||
|
questionTypes: Const.questionTypes, |
||||||
|
knowledges: [], |
||||||
|
|
||||||
|
richEditor: { |
||||||
|
object: null, |
||||||
|
parameterName: '', |
||||||
|
instance: null |
||||||
|
}, |
||||||
|
originForm: {}, |
||||||
|
originOpt: { |
||||||
|
answerAnalysis: '', |
||||||
|
answerIsCorrect: '', |
||||||
|
optionNumber: '', |
||||||
|
optionText: '', |
||||||
|
}, |
||||||
|
answerAnalysis: '', |
||||||
|
fillBlanks: [ |
||||||
|
{ |
||||||
|
serial: 1, |
||||||
|
fills: [{ |
||||||
|
val: '' |
||||||
|
}], |
||||||
|
scoreProportion: '' |
||||||
|
} |
||||||
|
], |
||||||
|
form: { |
||||||
|
difficulty: '', |
||||||
|
givenYear: new Date(), |
||||||
|
knowledgePointIds: [], |
||||||
|
questionAnswerVersions: [], |
||||||
|
questionBankId: '', |
||||||
|
questionType: 'single_choice', |
||||||
|
specialtyIds: [1], |
||||||
|
stem: '', |
||||||
|
allowAttachment: 0, |
||||||
|
stemAttachment: '', |
||||||
|
uploadInstructions: '', |
||||||
|
}, |
||||||
|
rules: { |
||||||
|
knowledgePointIds: [ |
||||||
|
{ required: true, message: '请选择知识点', trigger: 'change' } |
||||||
|
], |
||||||
|
difficulty: [ |
||||||
|
{ required: true, message: '请选择难度', trigger: 'change' } |
||||||
|
], |
||||||
|
questionType: [ |
||||||
|
{ required: true, message: '请选择题型', trigger: 'change' } |
||||||
|
], |
||||||
|
}, |
||||||
|
templateVisible: false, |
||||||
|
quesVisible: false, |
||||||
|
submiting: false, |
||||||
|
tempForm: {}, |
||||||
|
keep: 0, |
||||||
|
|
||||||
|
repeatVisible: false, |
||||||
|
repeats: [] |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
visible () { |
||||||
|
this.quesVisible = this.visible |
||||||
|
this.visible && this.init() |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted () { |
||||||
|
this.originForm = _.cloneDeep(this.form) |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
init () { |
||||||
|
this.form = _.cloneDeep(this.originForm) |
||||||
|
// 选项默认 |
||||||
|
for (let i = 1; i < 5; i++) { |
||||||
|
const opt = _.cloneDeep(this.originOpt) |
||||||
|
opt.optionNumber = i |
||||||
|
this.form.questionAnswerVersions.push(opt) |
||||||
|
} |
||||||
|
this.form.questionAnswerVersions[0].answerIsCorrect = 1 |
||||||
|
|
||||||
|
this.$refs.stem.setText('') |
||||||
|
this.$refs.answerAnalysis.setText('') |
||||||
|
|
||||||
|
this.getDetail() |
||||||
|
this.getKnowledge() |
||||||
|
this.getProfessional() |
||||||
|
}, |
||||||
|
// 获取题目详情 |
||||||
|
async getDetail () { |
||||||
|
try { |
||||||
|
const { row } = this |
||||||
|
if (row.questionId) { |
||||||
|
const res = await this.$post(`${this.api.findQuestion}?questionId=${this.row.questionId}&version=${this.row.version}`) |
||||||
|
const r = res.message |
||||||
|
const opts = r.questionAnswerVersionsList |
||||||
|
this.form = { |
||||||
|
questionId: r.questionId, |
||||||
|
questionType: r.questionType, |
||||||
|
questionVersionId: r.questionVersionId, |
||||||
|
version: r.version, |
||||||
|
givenYear: r.givenYear, |
||||||
|
difficulty: r.difficulty, |
||||||
|
stem: r.stem, |
||||||
|
knowledgePointIds: r.knowledgePointList.map(e => { |
||||||
|
return e.path.split('/').map(n => +n) |
||||||
|
}), |
||||||
|
specialtyIds: r.professionalList.map(e => e.specialtyId), |
||||||
|
questionAnswerVersions: opts, |
||||||
|
} |
||||||
|
this.answerAnalysis = opts[0].answerAnalysis |
||||||
|
} |
||||||
|
} catch (e) { } |
||||||
|
}, |
||||||
|
// 获取知识点 |
||||||
|
async getKnowledge () { |
||||||
|
try { |
||||||
|
const { data } = await this.$post(this.api.TreeStructure, { |
||||||
|
createSource: 1, |
||||||
|
questionBankId: this.typeId, |
||||||
|
keyword: '' |
||||||
|
}) |
||||||
|
this.handleType(data) |
||||||
|
this.knowledges = data |
||||||
|
} catch (e) { } |
||||||
|
}, |
||||||
|
// 获取所属专业 |
||||||
|
async getProfessional () { |
||||||
|
try { |
||||||
|
const res = await this.$post(this.api.queryProfessional, { |
||||||
|
pageNum: 1, |
||||||
|
pageSize: 1000, |
||||||
|
}) |
||||||
|
this.professionals = res.pageList.records |
||||||
|
} catch (e) { } |
||||||
|
}, |
||||||
|
// 处理树形 |
||||||
|
handleType (list) { |
||||||
|
list.map(e => { |
||||||
|
if (!e.type) e.disabled = true |
||||||
|
if (e.children && e.children.length) { |
||||||
|
this.handleType(e.children) |
||||||
|
} else { |
||||||
|
delete e.children |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 题型选择回调 |
||||||
|
questionTypeChange (val) { |
||||||
|
// 判断题 |
||||||
|
if (val === 'judgement') { |
||||||
|
const opts = [] |
||||||
|
for (let i = 1; i < 3; i++) { |
||||||
|
const opt = _.cloneDeep(this.originOpt) |
||||||
|
opt.optionNumber = i |
||||||
|
opts.push(opt) |
||||||
|
} |
||||||
|
opts[0].answerIsCorrect = 1 |
||||||
|
opts[0].optionText = '正确' |
||||||
|
opts[1].optionText = '错误' |
||||||
|
this.form.questionAnswerVersions = opts |
||||||
|
} else if (val === 'essay') { |
||||||
|
// 简答题 |
||||||
|
const opt = _.cloneDeep(this.originOpt) |
||||||
|
opt.gradingStandard = 'manual' |
||||||
|
opt.referenceAnswer = '' |
||||||
|
this.form.questionAnswerVersions = [opt] |
||||||
|
} |
||||||
|
}, |
||||||
|
// 题干富文本加载完毕回调 |
||||||
|
stemReady (editor) { |
||||||
|
this.form.stem && editor.setContent(this.form.stem) |
||||||
|
}, |
||||||
|
// 解析富文本加载完毕回调 |
||||||
|
answerAnalysisReady (editor) { |
||||||
|
this.form.answerAnalysis && editor.setContent(this.answerAnalysis) |
||||||
|
}, |
||||||
|
// 正确答案选择回调 |
||||||
|
correctChange (i) { |
||||||
|
this.form.questionAnswerVersions.map(e => { |
||||||
|
e.answerIsCorrect = 0 |
||||||
|
}) |
||||||
|
this.form.questionAnswerVersions[i].answerIsCorrect = 1 |
||||||
|
}, |
||||||
|
// 新增选项 |
||||||
|
addOpt (i) { |
||||||
|
const opt = _.cloneDeep(this.originOpt) |
||||||
|
opt.optionNumber = i + 2 |
||||||
|
this.form.questionAnswerVersions.splice(i + 1, 0, opt) |
||||||
|
}, |
||||||
|
// 移除选项 |
||||||
|
delOpt (i) { |
||||||
|
this.form.questionAnswerVersions.length > 2 && this.form.questionAnswerVersions.splice(i, 1) |
||||||
|
}, |
||||||
|
|
||||||
|
editorReady (instance) { |
||||||
|
console.log("🚀 ~ editorReady ~ instance:", instance) |
||||||
|
|
||||||
|
// this.richEditor.instance = instance |
||||||
|
// let currentContent = this.richEditor.object[this.richEditor.parameterName] |
||||||
|
// this.richEditor.instance.setContent(currentContent) |
||||||
|
// // 光标定位到Ueditor |
||||||
|
// this.richEditor.instance.focus(true) |
||||||
|
}, |
||||||
|
inputClick (object, parameterName) { |
||||||
|
this.richEditor.object = object |
||||||
|
this.richEditor.parameterName = parameterName |
||||||
|
this.richEditor.dialogVisible = true |
||||||
|
}, |
||||||
|
editorSubmit () { |
||||||
|
let content = this.richEditor.instance.getContent() |
||||||
|
if (this.richEditor.parameterName === 'title') { // 题干的正确答案重置 |
||||||
|
// if (this.questionItemReset(content)) { |
||||||
|
// this.richEditor.object[this.richEditor.parameterName] = content |
||||||
|
// this.richEditor.dialogVisible = false |
||||||
|
// } |
||||||
|
} else { |
||||||
|
this.richEditor.object[this.richEditor.parameterName] = content |
||||||
|
this.richEditor.dialogVisible = false |
||||||
|
} |
||||||
|
}, |
||||||
|
questionItemReset (content) { |
||||||
|
let spanRegex = new RegExp('<span class="gapfilling-span (.*?)">(.*?)<\\/span>', 'g') |
||||||
|
let _this = this |
||||||
|
let newFormItem = [] |
||||||
|
let gapfillingItems = content.match(spanRegex) |
||||||
|
if (gapfillingItems === null) { |
||||||
|
this.$message.error('请插入填空') |
||||||
|
return false |
||||||
|
} |
||||||
|
gapfillingItems.forEach(function (span, index) { |
||||||
|
let pairRegex = /<span class="gapfilling-span (.*?)">(.*?)<\/span>/ |
||||||
|
pairRegex.test(span) |
||||||
|
newFormItem.push({ id: null, itemUuid: RegExp.$1, prefix: RegExp.$2, content: '', score: '0' }) |
||||||
|
}) |
||||||
|
|
||||||
|
newFormItem.forEach(function (item) { |
||||||
|
_this.form.items.some((oldItem, index) => { |
||||||
|
if (oldItem.itemUuid === item.itemUuid) { |
||||||
|
item.content = oldItem.content |
||||||
|
item.id = oldItem.id |
||||||
|
item.score = oldItem.score |
||||||
|
return true |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
_this.form.items = newFormItem |
||||||
|
return true |
||||||
|
}, |
||||||
|
// 填空题新增填空项 |
||||||
|
addFill (item) { |
||||||
|
item.fills.push({ val: '' }) |
||||||
|
}, |
||||||
|
// 题目提交 |
||||||
|
submit (keep) { |
||||||
|
if (this.submiting) return false |
||||||
|
this.$refs.form.validate(async (valid) => { |
||||||
|
if (valid) { |
||||||
|
const form = _.cloneDeep(this.form) |
||||||
|
const stem = this.$refs.stem.getUEContent() |
||||||
|
const answerAnalysis = this.$refs.answerAnalysis.getUEContent() |
||||||
|
const opt = form.questionAnswerVersions |
||||||
|
if (!stem) return Util.warningMsg('请输入题干') |
||||||
|
let invalid = 0 |
||||||
|
for (const e of opt) { |
||||||
|
if (!e.optionText) { |
||||||
|
Util.warningMsg('选项请输入完整') |
||||||
|
invalid = 1 |
||||||
|
break |
||||||
|
} |
||||||
|
} |
||||||
|
// debugger |
||||||
|
if (invalid) return false |
||||||
|
if (!opt.find(e => e.answerIsCorrect)) return Util.warningMsg('请设置正确答案') |
||||||
|
this.submiting = true |
||||||
|
try { |
||||||
|
form.stem = stem |
||||||
|
form.questionBankId = this.typeId |
||||||
|
form.knowledgePointIds = form.knowledgePointIds.map(e => { |
||||||
|
return e[e.length - 1] |
||||||
|
}) |
||||||
|
form.givenYear = dayjs(form.givenYear).format('YYYY') |
||||||
|
if (answerAnalysis) form.questionAnswerVersions[0].answerAnalysis = answerAnalysis // 解析保存在选项里第一个对象里 |
||||||
|
|
||||||
|
|
||||||
|
// 判断是否有重复试题,如果有,则弹出重复的试题 |
||||||
|
this.tempForm = form |
||||||
|
this.keep = keep |
||||||
|
const res = await this.$post(this.api.checkQuestion, form) |
||||||
|
// 没有重复的试题,直接保存 |
||||||
|
if (res.status === 200) { |
||||||
|
this.saveQues() |
||||||
|
} |
||||||
|
} catch (e) { |
||||||
|
// 有重复的 |
||||||
|
setTimeout(() => { |
||||||
|
this.repeatVisible = true |
||||||
|
this.repeats = Util.removeTag(e) |
||||||
|
this.submiting = false |
||||||
|
}, 1500) |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 保存题目 |
||||||
|
async saveQues () { |
||||||
|
const form = this.tempForm |
||||||
|
await this.$post(this.api[form.id ? 'updateQuestion' : 'addQuestion'], form) |
||||||
|
Util.successMsg('保存成功') |
||||||
|
this.submiting = false |
||||||
|
this.keep ? this.init() : (this.quesVisible = false) |
||||||
|
this.repeatVisible = false |
||||||
|
}, |
||||||
|
// 弹框关闭回调 |
||||||
|
closeDia () { |
||||||
|
this.$emit('update:visible', false) |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.action-icon { |
||||||
|
margin-right: 10px; |
||||||
|
font-size: 18px; |
||||||
|
color: $main-color; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
.ques { |
||||||
|
li { |
||||||
|
padding: 15px; |
||||||
|
margin: 20px 0 10px; |
||||||
|
border: 1px solid #dbdbdb; |
||||||
|
} |
||||||
|
|
||||||
|
.top { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
|
||||||
|
.serial { |
||||||
|
margin-right: 10px; |
||||||
|
font-size: 13px; |
||||||
|
} |
||||||
|
|
||||||
|
.sum { |
||||||
|
margin: 15px 0; |
||||||
|
font-size: 13px; |
||||||
|
color: $main-color; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/deep/.correct-check { |
||||||
|
margin-right: 15px; |
||||||
|
} |
||||||
|
</style> |
@ -1,694 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<Breadcrumb :data="crumbs" /> |
|
||||||
<div class="page"> |
|
||||||
<div class="side"> |
|
||||||
<div class="m-b-20"> |
|
||||||
<el-radio-group v-model="type" @change="typeChange"> |
|
||||||
<div class="m-b-20"> |
|
||||||
<el-radio :label="1">所有试题</el-radio> |
|
||||||
</div> |
|
||||||
<div> |
|
||||||
<el-radio :label="2">未分配知识点的试题</el-radio> |
|
||||||
</div> |
|
||||||
</el-radio-group> |
|
||||||
</div> |
|
||||||
<el-divider></el-divider> |
|
||||||
<div> |
|
||||||
<div class="flex-between m-b-10"> |
|
||||||
<h6 class="page-name" style="margin-bottom: 0">知识点框架</h6> |
|
||||||
<el-button type="text" @click="toSet">设置</el-button> |
|
||||||
</div> |
|
||||||
<el-input class="m-b-10" placeholder="请输入知识点分类、知识点名称" prefix-icon="el-icon-search" size="small" |
|
||||||
v-model="keyword" clearable></el-input> |
|
||||||
<div style="height: 504px; max-height: 504px; overflow: auto"> |
|
||||||
<el-tree :data="types" default-expand-all ref="orgTree" node-key="id" highlight-current |
|
||||||
:expand-on-click-node="false" @node-click="handleNodeClick" :props="{ label: 'name', isLeaf: 'leaf' }"> |
|
||||||
<span class="custom-tree-node" slot-scope="{ node, data }"> |
|
||||||
<img v-if="data.type" class="m-r-5" src="@/assets/images/knowledge.svg" alt=""> |
|
||||||
<span class="org-name">{{ data.name }}</span> |
|
||||||
</span> |
|
||||||
</el-tree> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="right"> |
|
||||||
<h6 class="page-name">筛选</h6> |
|
||||||
<div class="tool"> |
|
||||||
<ul class="filter"> |
|
||||||
<li> |
|
||||||
<label>题目类型</label> |
|
||||||
<el-select v-model="filter.status" clearable placeholder="请选择题目类型" @change="getList"> |
|
||||||
<el-option v-for="(item, i) in status" :key="i" :label="item.name" :value="item.id"></el-option> |
|
||||||
</el-select> |
|
||||||
</li> |
|
||||||
<li> |
|
||||||
<label>专业</label> |
|
||||||
<el-select v-model="filter.status" clearable placeholder="请选择专业" @change="getList"> |
|
||||||
<el-option v-for="(item, i) in status" :key="i" :label="item.name" :value="item.id"></el-option> |
|
||||||
</el-select> |
|
||||||
</li> |
|
||||||
<li> |
|
||||||
<label>试题难度</label> |
|
||||||
<el-select v-model="filter.status" clearable placeholder="请选择试题难度" @change="getList"> |
|
||||||
<el-option v-for="(item, i) in status" :key="i" :label="item.name" :value="item.id"></el-option> |
|
||||||
</el-select> |
|
||||||
</li> |
|
||||||
<li> |
|
||||||
<label>知识点</label> |
|
||||||
<el-select v-model="filter.status" clearable placeholder="请选择知识点" @change="getList"> |
|
||||||
<el-option v-for="(item, i) in status" :key="i" :label="item.name" :value="item.id"></el-option> |
|
||||||
</el-select> |
|
||||||
</li> |
|
||||||
<li> |
|
||||||
<label>正确率</label> |
|
||||||
<el-input style="width: 80px;" placeholder="请输入" v-model="filter.keyWord" clearable /> |
|
||||||
<span style="margin: 0 10px;">% -- </span> |
|
||||||
<el-input style="width: 80px;" placeholder="请输入" v-model="filter.keyWord" clearable /> |
|
||||||
<span style="margin-left: 10px;">%</span> |
|
||||||
</li> |
|
||||||
<li> |
|
||||||
<label>状态</label> |
|
||||||
<el-select v-model="filter.status" clearable placeholder="请选择状态" @change="getList"> |
|
||||||
<el-option v-for="(item, i) in status" :key="i" :label="item.name" :value="item.id"></el-option> |
|
||||||
</el-select> |
|
||||||
</li> |
|
||||||
<li> |
|
||||||
<label>搜索</label> |
|
||||||
<el-input style="width: 250px;" placeholder="请输入题干" prefix-icon="el-icon-search" v-model="filter.keyWord" |
|
||||||
clearable /> |
|
||||||
</li> |
|
||||||
<div style="margin-bottom: 15px;"> |
|
||||||
<el-button type="primary" @click="add">新增试题</el-button> |
|
||||||
<el-button type="primary" @click="batchImport">批量导入</el-button> |
|
||||||
<!-- <el-button type="primary" @click="add">批量转移</el-button> --> |
|
||||||
<el-button type="primary" @click="add">批量移除 </el-button> |
|
||||||
<el-button type="primary" @click="add">批量删除</el-button> |
|
||||||
</div> |
|
||||||
</ul> |
|
||||||
</div> |
|
||||||
|
|
||||||
<el-table :data="list" class="table" ref="table" stripe header-align="center" |
|
||||||
@selection-change="handleSelectionChange" row-key="id"> |
|
||||||
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
|
||||||
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
|
||||||
<el-table-column prop="userName" label="题干" align="center" min-width="100"></el-table-column> |
|
||||||
<el-table-column prop="account" label="题型" align="center" min-width="100"></el-table-column> |
|
||||||
<el-table-column prop="phone" label="专业" align="center" min-width="120"></el-table-column> |
|
||||||
<el-table-column prop="invitationAccount" label="知识点" align="center" min-width="120"></el-table-column> |
|
||||||
<el-table-column prop="invitationAccount" label="年份" align="center" min-width="120"></el-table-column> |
|
||||||
<el-table-column prop="invitationAccount" label="难度" align="center" min-width="120"></el-table-column> |
|
||||||
<el-table-column prop="invitationAccount" label="正确率" align="center" min-width="120"></el-table-column> |
|
||||||
<el-table-column prop="loginNumber" label="更新时间" align="center" width="120"></el-table-column> |
|
||||||
<el-table-column prop="lastLoginTime" label="最近编辑人" align="center" width="120"></el-table-column> |
|
||||||
<el-table-column prop="lastLoginTime" label="已引用试卷(套)" align="center" width="120"></el-table-column> |
|
||||||
<el-table-column label="操作" align="center" width="300"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<el-button type="text" @click="edit(scope.row)">复制</el-button> |
|
||||||
<el-button type="text" @click="edit(scope.row)">查看</el-button> |
|
||||||
<el-button type="text" @click="edit(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-model="scope.row.ztOpen" :active-value="0" :inactive-value="1" style="margin: 0 10px 0 5px" |
|
||||||
:active-text="scope.row.ztOpen ? '关' : '开'" |
|
||||||
@change="switchOff($event, scope.row, scope.$index)"></el-switch> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
</el-table> |
|
||||||
<div class="pagination"> |
|
||||||
<el-pagination background @current-change="currentChange" :current-page="page" |
|
||||||
layout="total, prev, pager, next" :total="total"></el-pagination> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
<el-dialog :title="!form.id ? '创建题目' : '编辑题目'" :visible.sync="quesVisible" width="1000px" |
|
||||||
:close-on-click-modal="false"> |
|
||||||
<el-form label-width="110px"> |
|
||||||
<el-form-item prop="userName" label="题库分类"> |
|
||||||
<el-select style="width: 100%" v-model="form.provinceId" placeholder="请选择题库分类"> |
|
||||||
<el-option v-for="(item, i) in types" :key="i" :label="item.provinceName" |
|
||||||
:value="item.provinceId"></el-option> |
|
||||||
</el-select> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="题库"> |
|
||||||
<el-input placeholder="请输入题库名称" v-model="form.name" disabled></el-input> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="所属专业"> |
|
||||||
<el-input placeholder="请输入题库名称" v-model="form.name"></el-input> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="所属知识点"> |
|
||||||
<el-input placeholder="请输入题库名称" v-model="form.name"></el-input> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="年份"> |
|
||||||
<el-input placeholder="请输入题库名称" v-model="form.name"></el-input> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="难度"> |
|
||||||
<el-input placeholder="请输入题库名称" v-model="form.name"></el-input> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="题型"> |
|
||||||
<el-input placeholder="请输入题库名称" v-model="form.name"></el-input> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="题干"> |
|
||||||
<Ueditor ref="title" /> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item label="正确答案" required> |
|
||||||
<div class="opts"> |
|
||||||
<div class="line"> |
|
||||||
<el-radio v-model="radio" label="1">选项A</el-radio> |
|
||||||
<el-input placeholder="请输入" v-model="form.name"></el-input> |
|
||||||
<i class="icon el-icon-circle-plus-outline" @click="addOpt"></i> |
|
||||||
<i class="icon el-icon-remove-outline" @click="delOpt"></i> |
|
||||||
</div> |
|
||||||
<div class="line"> |
|
||||||
<el-radio v-model="radio" label="1">选项B</el-radio> |
|
||||||
<el-input placeholder="请输入" v-model="form.name"></el-input> |
|
||||||
<i class="icon el-icon-circle-plus-outline"></i> |
|
||||||
<i class="icon el-icon-remove-outline"></i> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="解析"> |
|
||||||
<Ueditor ref="title1" @ready="editorReady" /> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="上传题干文件"> |
|
||||||
<el-input placeholder="请输入题库名称" v-model="form.name"></el-input> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="支持学生上传附件"> |
|
||||||
<el-radio-group v-model="radio"> |
|
||||||
<el-radio :label="3">否</el-radio> |
|
||||||
<el-radio :label="6">是</el-radio> |
|
||||||
</el-radio-group> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="判分标准"> |
|
||||||
<el-select style="width: 100%" v-model="form.provinceId" placeholder="请选择判分标准"> |
|
||||||
<el-option v-for="(item, i) in types" :key="i" :label="item.provinceName" |
|
||||||
:value="item.provinceId"></el-option> |
|
||||||
</el-select> |
|
||||||
</el-form-item> |
|
||||||
</el-form> |
|
||||||
<span slot="footer" class="dialog-footer"> |
|
||||||
<el-button type="primary" @click="quesSubmit(0)">保存</el-button> |
|
||||||
<el-button type="primary" @click="quesSubmit(1)">保存并继续新增</el-button> |
|
||||||
<el-button @click="quesVisible = false">取消</el-button> |
|
||||||
</span> |
|
||||||
</el-dialog> |
|
||||||
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="richEditor.dialogVisible" width="1000px" :show-close="false" center |
|
||||||
:close-on-click-modal="false"> |
|
||||||
<Ueditor ref="title2" @ready="editorReady" /> |
|
||||||
<span slot="footer" class="dialog-footer"> |
|
||||||
<el-button type="primary" @click="editorSubmit">确定</el-button> |
|
||||||
<el-button @click="richEditor.dialogVisible = false">取消</el-button> |
|
||||||
</span> |
|
||||||
</el-dialog> |
|
||||||
|
|
||||||
|
|
||||||
<el-dialog title="批量导入试题" :visible.sync="importVisible" width="520px" :close-on-click-modal="false" |
|
||||||
:modal-append-to-body="false"> |
|
||||||
<el-form label-width="110px"> |
|
||||||
<el-form-item prop="userName" label="题库分类"> |
|
||||||
<el-select style="width: 100%" v-model="form.provinceId" placeholder="请选择题库分类"> |
|
||||||
<el-option v-for="(item, i) in types" :key="i" :label="item.provinceName" |
|
||||||
:value="item.provinceId"></el-option> |
|
||||||
</el-select> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="当前题库"> |
|
||||||
<el-input placeholder="请输入题库名称" v-model="form.name" disabled></el-input> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="模板文件"> |
|
||||||
<el-button type="primary" @click="download">模板下载<i class="el-icon-download el-icon--right"></i></el-button> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="userName" label="选择文件上传"> |
|
||||||
<el-upload name="file" accept=".xls,.xlsx" ref="upload" class="import-file" drag :before-upload="beforeUpload" |
|
||||||
:on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove" |
|
||||||
:limit="1" :data="{ |
|
||||||
// competitionId: id, |
|
||||||
platformId: 2 |
|
||||||
}" :disabled="uploading" :on-exceed="handleExceed" :action="this.api.batchImportPersonalData" |
|
||||||
:file-list="uploadList" :headers="headers"> |
|
||||||
<i class="el-icon-upload"></i> |
|
||||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> |
|
||||||
<div class="el-upload__tip" slot="tip" style="line-height: 1.8;"> |
|
||||||
<p>上传说明:</p> |
|
||||||
<p>1.请按照模板要求,正确填写后上传</p> |
|
||||||
<p>2.上传文件大小限制50M</p> |
|
||||||
<p>3.仅支持上传.xls、 .xlsx文件格式</p> |
|
||||||
</div> |
|
||||||
</el-upload> |
|
||||||
</el-form-item> |
|
||||||
</el-form> |
|
||||||
<span slot="footer" class="dialog-footer"> |
|
||||||
<el-button @click="importVisible = false">关闭</el-button> |
|
||||||
</span> |
|
||||||
</el-dialog> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import Util from '@/libs/util' |
|
||||||
import Setting from '@/setting' |
|
||||||
import Ueditor from '@/components/ueditor' |
|
||||||
import Breadcrumb from '@/components/breadcrumb' |
|
||||||
export default { |
|
||||||
components: { Ueditor, Breadcrumb }, |
|
||||||
data () { |
|
||||||
return { |
|
||||||
crumbs: [ |
|
||||||
{ |
|
||||||
name: this.$route.query.name || '题库管理', |
|
||||||
route: '/quesBank' |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '试题管理' |
|
||||||
}, |
|
||||||
], |
|
||||||
typeId: this.$route.query.id, |
|
||||||
loading: false, |
|
||||||
createSource: 1, |
|
||||||
keyword: '', |
|
||||||
radio: '', |
|
||||||
type: 1, |
|
||||||
types: [], |
|
||||||
status: [ |
|
||||||
{ |
|
||||||
id: 1, |
|
||||||
name: '启用' |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 2, |
|
||||||
name: '禁用' |
|
||||||
}, |
|
||||||
], |
|
||||||
filter: { |
|
||||||
status: '', |
|
||||||
keyWord: '', |
|
||||||
}, |
|
||||||
list: [], |
|
||||||
page: 1, |
|
||||||
pageSize: 10, |
|
||||||
total: 0, |
|
||||||
multipleSelection: [], |
|
||||||
|
|
||||||
form: { |
|
||||||
userName: '', |
|
||||||
provinceId: '', |
|
||||||
cityId: '', |
|
||||||
roleList: [] |
|
||||||
}, |
|
||||||
richEditor: { |
|
||||||
dialogVisible: false, |
|
||||||
object: null, |
|
||||||
parameterName: '', |
|
||||||
instance: null |
|
||||||
}, |
|
||||||
rules: { |
|
||||||
userName: [ |
|
||||||
{ required: true, message: "请输入姓名", trigger: "blur" } |
|
||||||
], |
|
||||||
provinceId: [ |
|
||||||
{ required: true, message: '请选择省份', trigger: "change" } |
|
||||||
], |
|
||||||
cityId: [ |
|
||||||
{ required: true, message: '请选择城市', trigger: "change" } |
|
||||||
], |
|
||||||
roleList: [ |
|
||||||
{ required: true, message: '请选择角色', trigger: "change" } |
|
||||||
], |
|
||||||
}, |
|
||||||
quesVisible: false, |
|
||||||
|
|
||||||
|
|
||||||
submiting: false, // 新增编辑防抖标识 |
|
||||||
setKey: '', |
|
||||||
transferVisible: false, |
|
||||||
chooseVisible: false, |
|
||||||
members: [], |
|
||||||
choosePartnerId: '', |
|
||||||
curRow: '', |
|
||||||
provinces: [], |
|
||||||
cities: [], |
|
||||||
editVisible: false, |
|
||||||
|
|
||||||
importVisible: false, |
|
||||||
uploadList: [], |
|
||||||
uploadFaild: false, |
|
||||||
uploadTips: '', |
|
||||||
exportCode: '', |
|
||||||
headers: { |
|
||||||
token: Util.local.get(Setting.tokenKey) |
|
||||||
}, |
|
||||||
uploading: false, |
|
||||||
}; |
|
||||||
}, |
|
||||||
watch: { |
|
||||||
keyword: function (val) { |
|
||||||
clearTimeout(this.searchTimer); |
|
||||||
this.searchTimer = setTimeout(this.getType, 500); |
|
||||||
}, |
|
||||||
keyWord: function (val) { |
|
||||||
clearTimeout(this.searchTimer); |
|
||||||
this.searchTimer = setTimeout(this.initData, 500); |
|
||||||
} |
|
||||||
}, |
|
||||||
mounted () { |
|
||||||
this.getType() |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
// 获取知识点 |
|
||||||
async getType () { |
|
||||||
try { |
|
||||||
this.loading = true |
|
||||||
const { data } = await this.$post(this.api.TreeStructure, { |
|
||||||
createSource: 1, |
|
||||||
questionBankId: this.typeId, |
|
||||||
keyword: this.keyword, |
|
||||||
}) |
|
||||||
this.types = data |
|
||||||
// this.getList() |
|
||||||
} finally { |
|
||||||
this.loading = false |
|
||||||
} |
|
||||||
}, |
|
||||||
// 前往知识点 |
|
||||||
toSet () { |
|
||||||
this.$router.push(`/knowledge?id=${this.typeId}`) |
|
||||||
}, |
|
||||||
// 类型回调 |
|
||||||
typeChange () { |
|
||||||
this.$refs.orgTree.setCurrentKey(null) |
|
||||||
this.curTeamId = '' |
|
||||||
this.initData() |
|
||||||
}, |
|
||||||
// 获得点击层级里的第一个城市合伙人id |
|
||||||
getTeamId (list) { |
|
||||||
for (const i in list) { |
|
||||||
const e = list[i] |
|
||||||
if (e.isTeam && !this.curTeamId) { |
|
||||||
this.curTeamId = e.id |
|
||||||
break |
|
||||||
} else { |
|
||||||
this.getTeamId(e.children) |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
// 点击树节点查询列表数据 |
|
||||||
handleNodeClick (data) { |
|
||||||
this.type = '' |
|
||||||
this.curTeamId = '' |
|
||||||
if (data.isTeam) { |
|
||||||
this.curTeamId = data.id |
|
||||||
} else { |
|
||||||
// this.getTeamId(data.children) |
|
||||||
} |
|
||||||
if (!this.curTeamId) this.curTeamId = data.id |
|
||||||
this.initData() |
|
||||||
this.$refs.table.clearSelection() |
|
||||||
}, |
|
||||||
// 查询全部 |
|
||||||
getAll () { |
|
||||||
this.curTeamId = '' |
|
||||||
this.getList() |
|
||||||
}, |
|
||||||
// 员工列表 |
|
||||||
getList () { |
|
||||||
this.$post(this.api[this.type ? 'partnerAccountMergeList' : 'partnerAccountList'], { |
|
||||||
type: this.type || 1, |
|
||||||
partnerClassificationId: this.curTeamId, |
|
||||||
pageNum: this.page, |
|
||||||
pageSize: this.pageSize |
|
||||||
}).then(({ pageList }) => { |
|
||||||
pageList.records.forEach((e, i) => { |
|
||||||
e.id = i |
|
||||||
}) |
|
||||||
this.list = pageList.records |
|
||||||
this.total = pageList.total |
|
||||||
}).catch(err => { }) |
|
||||||
}, |
|
||||||
// 切换页码 |
|
||||||
currentChange (val) { |
|
||||||
this.page = val |
|
||||||
this.getList() |
|
||||||
}, |
|
||||||
handleSelectionChange (val) { // 多选 |
|
||||||
this.multipleSelection = val |
|
||||||
}, |
|
||||||
initData () { |
|
||||||
this.$refs.table.clearSelection() |
|
||||||
this.page = 1 |
|
||||||
this.getList() |
|
||||||
}, |
|
||||||
// 删除 |
|
||||||
del (row) { |
|
||||||
this.$confirm("确定要删除吗?", "提示", { |
|
||||||
type: "warning" |
|
||||||
}).then(() => { |
|
||||||
this.$post(`${this.api.delPartnerAccount}?accountId=${row.accountId}`).then(res => { |
|
||||||
Util.successMsg("删除成功") |
|
||||||
this.getList() |
|
||||||
}).catch(res => { }) |
|
||||||
}).catch(() => { }) |
|
||||||
}, |
|
||||||
async switchOff (val, row) { |
|
||||||
this.$post(this.api.disabledEventsCompetition, { |
|
||||||
competitionId: row.id, |
|
||||||
isOpen: val, |
|
||||||
type: 0 // 禁用平台来源(0中台,1职站) |
|
||||||
}).then(res => { |
|
||||||
Util.successMsg(val == 1 ? '禁用成功' : '启用成功') |
|
||||||
}).catch(err => { }) |
|
||||||
|
|
||||||
await this.$post(`${this.api.refreshPageNotification}?content=1`) |
|
||||||
}, |
|
||||||
// 编辑 |
|
||||||
edit (row) { |
|
||||||
if (!row.provinceId) row.provinceId = '' |
|
||||||
if (!row.cityId) row.cityId = '' |
|
||||||
row.roleList = row.roleId.split(',').map(e => +e) |
|
||||||
this.editVisible = true |
|
||||||
this.form = JSON.parse(JSON.stringify(row)) |
|
||||||
}, |
|
||||||
// 新增选项 |
|
||||||
addOpt (i) { |
|
||||||
|
|
||||||
}, |
|
||||||
// 移除选项 |
|
||||||
delOpt (i) { |
|
||||||
|
|
||||||
}, |
|
||||||
|
|
||||||
inputClick (object, parameterName) { |
|
||||||
this.richEditor.object = object |
|
||||||
this.richEditor.parameterName = parameterName |
|
||||||
this.richEditor.dialogVisible = true |
|
||||||
}, |
|
||||||
editorSubmit () { |
|
||||||
let content = this.richEditor.instance.getContent() |
|
||||||
if (this.richEditor.parameterName === 'title') { // 题干的正确答案重置 |
|
||||||
// if (this.questionItemReset(content)) { |
|
||||||
// this.richEditor.object[this.richEditor.parameterName] = content |
|
||||||
// this.richEditor.dialogVisible = false |
|
||||||
// } |
|
||||||
} else { |
|
||||||
this.richEditor.object[this.richEditor.parameterName] = content |
|
||||||
this.richEditor.dialogVisible = false |
|
||||||
} |
|
||||||
}, |
|
||||||
questionItemReset (content) { |
|
||||||
let spanRegex = new RegExp('<span class="gapfilling-span (.*?)">(.*?)<\\/span>', 'g') |
|
||||||
let _this = this |
|
||||||
let newFormItem = [] |
|
||||||
let gapfillingItems = content.match(spanRegex) |
|
||||||
if (gapfillingItems === null) { |
|
||||||
this.$message.error('请插入填空') |
|
||||||
return false |
|
||||||
} |
|
||||||
gapfillingItems.forEach(function (span, index) { |
|
||||||
let pairRegex = /<span class="gapfilling-span (.*?)">(.*?)<\/span>/ |
|
||||||
pairRegex.test(span) |
|
||||||
newFormItem.push({ id: null, itemUuid: RegExp.$1, prefix: RegExp.$2, content: '', score: '0' }) |
|
||||||
}) |
|
||||||
|
|
||||||
newFormItem.forEach(function (item) { |
|
||||||
_this.form.items.some((oldItem, index) => { |
|
||||||
if (oldItem.itemUuid === item.itemUuid) { |
|
||||||
item.content = oldItem.content |
|
||||||
item.id = oldItem.id |
|
||||||
item.score = oldItem.score |
|
||||||
return true |
|
||||||
} |
|
||||||
}) |
|
||||||
}) |
|
||||||
_this.form.items = newFormItem |
|
||||||
return true |
|
||||||
}, |
|
||||||
|
|
||||||
// 编辑提交 |
|
||||||
submitEdit () { |
|
||||||
this.$refs.form.validate((valid) => { |
|
||||||
if (valid) { |
|
||||||
if (this.submiting) return false |
|
||||||
this.submiting = true |
|
||||||
const form = JSON.parse(JSON.stringify(this.form)) |
|
||||||
form.classificationId = form.partnerClassificationId |
|
||||||
this.$post(this.api.editProvinceCity, form).then(res => { |
|
||||||
this.getList() |
|
||||||
Util.successMsg("编辑成功!") |
|
||||||
this.editVisible = false |
|
||||||
setTimeout(() => { |
|
||||||
this.submiting = false |
|
||||||
}, 2000) |
|
||||||
}).catch(res => { |
|
||||||
setTimeout(() => { |
|
||||||
this.submiting = false |
|
||||||
}, 2000) |
|
||||||
}) |
|
||||||
} |
|
||||||
}) |
|
||||||
}, |
|
||||||
// 添加 |
|
||||||
add () { |
|
||||||
this.quesVisible = true |
|
||||||
}, |
|
||||||
editorReady (instance) { |
|
||||||
// this.richEditor.instance = instance |
|
||||||
// let currentContent = this.richEditor.object[this.richEditor.parameterName] |
|
||||||
// this.richEditor.instance.setContent(currentContent) |
|
||||||
// // 光标定位到Ueditor |
|
||||||
// this.richEditor.instance.focus(true) |
|
||||||
}, |
|
||||||
// 题目提交 |
|
||||||
quesSubmit () { |
|
||||||
console.log(55, this.richEditor, this.$refs.title.getUEContent(), this.$refs.title1.getUEContent()) |
|
||||||
}, |
|
||||||
|
|
||||||
// 批量导入 |
|
||||||
batchImport () { |
|
||||||
this.importVisible = true |
|
||||||
this.uploadList = [] |
|
||||||
this.uploadFaild = false |
|
||||||
}, |
|
||||||
// 模板下载 |
|
||||||
download () { |
|
||||||
location.href = this.api[this.info.completeCompetitionSetup.competitionType ? 'competionTeamTemplate' : 'competionPersonTemplate'] |
|
||||||
}, |
|
||||||
// 上传文件 |
|
||||||
handleExceed (files, fileList) { |
|
||||||
Util.warningMsg( |
|
||||||
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` |
|
||||||
) |
|
||||||
}, |
|
||||||
// 下载失败文件 |
|
||||||
showFaild () { |
|
||||||
axios.get(`${this.api.TeamDataExportFailure}?exportCode=${this.exportCode}&platformId=2&type=${this.info.completeCompetitionSetup.competitionType ? 1 : 2}`, { |
|
||||||
headers: this.headers, |
|
||||||
responseType: 'blob' |
|
||||||
}).then((res) => { |
|
||||||
const name = res.headers['content-disposition'] |
|
||||||
Util.downloadFileDirect(name ? decodeURI(name) : '批量导入报名人员失败数据导出.xlsx', new Blob([res.data])) |
|
||||||
}).catch(res => { }) |
|
||||||
}, |
|
||||||
uploadSuccess ({ data, status }) { |
|
||||||
this.uploading = false |
|
||||||
this.uploadFaild = false |
|
||||||
this.uploadTips = '' |
|
||||||
if (status === 200) { |
|
||||||
this.init() |
|
||||||
const { tip } = data |
|
||||||
if (data.exportCode) { |
|
||||||
this.exportCode = data.exportCode |
|
||||||
this.uploadFaild = true |
|
||||||
this.uploadTips = tip |
|
||||||
} else { |
|
||||||
Util[tip.includes('5000') ? 'errorMsg' : 'successMsg'](tip, 3000) |
|
||||||
this.importVisible = false |
|
||||||
} |
|
||||||
} else { |
|
||||||
Util.errorMsg(res.message || '上传失败,请检查数据', 3000) |
|
||||||
} |
|
||||||
}, |
|
||||||
uploadError (err, file, fileList) { |
|
||||||
this.uploading = false |
|
||||||
this.$message({ |
|
||||||
message: "上传出错,请重试!", |
|
||||||
type: "error", |
|
||||||
center: true |
|
||||||
}) |
|
||||||
}, |
|
||||||
beforeUpload (file) { |
|
||||||
this.uploading = true |
|
||||||
}, |
|
||||||
beforeRemove (file, fileList) { |
|
||||||
return this.$confirm(`确定移除 ${file.name}?`) |
|
||||||
}, |
|
||||||
handleRemove (file, fileList) { |
|
||||||
this.uploadList = fileList |
|
||||||
this.uploadFaild = false |
|
||||||
}, |
|
||||||
cancelUpload () { |
|
||||||
this.uploading = false |
|
||||||
this.$refs.upload.abort() |
|
||||||
this.keyword = '' |
|
||||||
this.init() |
|
||||||
this.importVisible = false |
|
||||||
}, |
|
||||||
// 后台上传 |
|
||||||
backstageUpload () { |
|
||||||
this.isBackstage = 1 |
|
||||||
this.importVisible = false |
|
||||||
}, |
|
||||||
} |
|
||||||
}; |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss" scoped> |
|
||||||
.page { |
|
||||||
display: flex; |
|
||||||
padding: 0 24px; |
|
||||||
|
|
||||||
.side { |
|
||||||
width: 300px; |
|
||||||
padding: 24px 10px 24px 0; |
|
||||||
margin-right: 24px; |
|
||||||
border-right: 1px solid rgba(0, 0, 0, 0.06); |
|
||||||
} |
|
||||||
|
|
||||||
.right { |
|
||||||
width: calc(100% - 324px); |
|
||||||
padding: 24px 0; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.tool { |
|
||||||
margin-bottom: 0; |
|
||||||
|
|
||||||
.filter { |
|
||||||
flex-wrap: wrap; |
|
||||||
justify-content: space-between; |
|
||||||
|
|
||||||
li { |
|
||||||
margin-bottom: 15px; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/deep/.opts { |
|
||||||
.line { |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
margin-bottom: 15px; |
|
||||||
} |
|
||||||
|
|
||||||
.el-radio { |
|
||||||
margin-right: 15px; |
|
||||||
} |
|
||||||
|
|
||||||
.icon { |
|
||||||
margin-left: 10px; |
|
||||||
font-size: 18px; |
|
||||||
cursor: pointer; |
|
||||||
} |
|
||||||
} |
|
||||||
</style> |
|
@ -0,0 +1,560 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<Breadcrumb :data="crumbs" /> |
||||||
|
<div class="page"> |
||||||
|
<div class="side"> |
||||||
|
<div class="m-b-20"> |
||||||
|
<el-radio-group v-model="isNotJoin" @change="typeChange"> |
||||||
|
<div class="m-b-20"> |
||||||
|
<el-radio :label="0">所有试题</el-radio> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-radio :label="1">未分配知识点的试题</el-radio> |
||||||
|
</div> |
||||||
|
</el-radio-group> |
||||||
|
</div> |
||||||
|
<el-divider></el-divider> |
||||||
|
<div> |
||||||
|
<div class="flex-between m-b-10"> |
||||||
|
<h6 class="page-name" style="margin-bottom: 0">知识点框架</h6> |
||||||
|
<el-button type="text" @click="toSet">设置</el-button> |
||||||
|
</div> |
||||||
|
<el-input class="m-b-10" placeholder="请输入知识点分类、知识点名称" prefix-icon="el-icon-search" size="small" |
||||||
|
v-model="keyword" clearable></el-input> |
||||||
|
<div style="height: 504px; max-height: 504px; overflow: auto"> |
||||||
|
<el-tree :data="types" default-expand-all ref="typeTree" node-key="id" highlight-current |
||||||
|
:expand-on-click-node="false" @node-click="handleNodeClick" :props="{ label: 'name', isLeaf: 'leaf' }"> |
||||||
|
<span class="custom-tree-node" slot-scope="{ node, data }"> |
||||||
|
<img v-if="data.type" class="m-r-5" src="@/assets/images/knowledge.svg" alt=""> |
||||||
|
<span class="org-name">{{ data.name }}</span> |
||||||
|
</span> |
||||||
|
</el-tree> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="right"> |
||||||
|
<h6 class="page-name">筛选</h6> |
||||||
|
<div class="tool"> |
||||||
|
<ul class="filter"> |
||||||
|
<li> |
||||||
|
<label>题目类型</label> |
||||||
|
<el-select v-model="filter.questionTypes" clearable placeholder="请选择题目类型" multiple @change="initData"> |
||||||
|
<el-option v-for="(item, i) in questionTypes" :key="i" :label="item.name" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>专业</label> |
||||||
|
<el-select v-model="filter.specialtyIds" clearable placeholder="请选择专业" multiple @change="initData"> |
||||||
|
<el-option v-for="(item, i) in status" :key="i" :label="item.name" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>年份</label> |
||||||
|
<el-date-picker v-model="givenYears" type="year" placeholder="请选择年份" format="yyyy" value-format="yyyy" |
||||||
|
multiple @change="initData"> |
||||||
|
</el-date-picker> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>试题难度</label> |
||||||
|
<el-select v-model="filter.difficultys" clearable placeholder="请选择试题难度" multiple @change="initData"> |
||||||
|
<el-option v-for="(item, i) in difficults" :key="i" :label="item.name" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>知识点</label> |
||||||
|
<el-cascader :disabled="isNotJoin !== 0" placeholder="请选择知识点" v-model="knowledgePointIds" |
||||||
|
:options="knowledges" :props="{ value: 'id', label: 'name', multiple: true }" clearable collapse-tags |
||||||
|
@change="initData"></el-cascader> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>正确率</label> |
||||||
|
<el-input style="width: 90px;" placeholder="请输入" v-model="filter.correctRateStart" clearable /> |
||||||
|
<span style="margin: 0 10px;">% -- </span> |
||||||
|
<el-input style="width: 90px;" placeholder="请输入" v-model="filter.correctRateEnd" clearable /> |
||||||
|
<span style="margin-left: 10px;">%</span> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>状态</label> |
||||||
|
<el-select v-model="filter.status" clearable placeholder="请选择状态" @change="initData"> |
||||||
|
<el-option v-for="(item, i) in status" :key="i" :label="item.name" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>搜索</label> |
||||||
|
<el-input style="width: 250px;" placeholder="请输入题干" prefix-icon="el-icon-search" v-model="filter.keyword" |
||||||
|
clearable /> |
||||||
|
</li> |
||||||
|
<div style="margin-bottom: 15px;"> |
||||||
|
<el-button type="primary" @click="add">新增试题</el-button> |
||||||
|
<el-button type="primary" @click="batchImport">批量导入</el-button> |
||||||
|
<!-- <el-button type="primary" @click="add">批量转移</el-button> --> |
||||||
|
<el-button type="primary" @click="add">批量移除 </el-button> |
||||||
|
<el-button type="primary" @click="add">批量删除</el-button> |
||||||
|
</div> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table :data="list" class="table" ref="table" stripe header-align="center" |
||||||
|
@selection-change="handleSelectionChange" row-key="id"> |
||||||
|
<el-table-column type="selection" width="45" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="50" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="stem" label="题干" align="center" min-width="120" show-overflow-tooltip></el-table-column> |
||||||
|
<el-table-column prop="account" label="题型" align="center" width="100"> |
||||||
|
<template slot-scope="scope">{{ questionTypes.find(e => e.id === scope.row.questionType) ? |
||||||
|
questionTypes.find(e => e.id === scope.row.questionType).name : '' }}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="professionalName" label="专业" align="center" min-width="120"></el-table-column> |
||||||
|
<el-table-column prop="knowledgePointName" label="知识点" align="center" min-width="120"></el-table-column> |
||||||
|
<el-table-column prop="givenYear" label="年份" align="center" width="50"></el-table-column> |
||||||
|
<el-table-column prop="difficulty" label="难度" align="center" width="50"> |
||||||
|
<template slot-scope="scope">{{ difficults.find(e => e.id === scope.row.difficulty) ? difficults.find(e => |
||||||
|
e.id === scope.row.difficulty).name : '' }}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="correctRate" label="正确率" align="center" width="60"></el-table-column> |
||||||
|
<el-table-column prop="updateTime" label="更新时间" align="center" width="140"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="最近编辑人" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="referenceCount" label="已引用试卷(套)" align="center" width="100"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="300"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="copy(scope.row)">复制</el-button> |
||||||
|
<el-button type="text" @click="toDetail(scope.row, 1)">查看</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-model="scope.row.status" :active-value="1" :inactive-value="0" style="margin: 0 10px 0 5px" |
||||||
|
:active-text="scope.row.status ? '开' : '关'" |
||||||
|
@change="switchOff($event, scope.row, scope.$index)"></el-switch> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination background @current-change="currentChange" :current-page="page" |
||||||
|
layout="total, prev, pager, next" :total="total"></el-pagination> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<Detail :visible.sync="quesVisible" :row.sync="curRow" :readonly.sync="readonly" /> |
||||||
|
|
||||||
|
<el-dialog title="批量导入试题" :visible.sync="importVisible" width="520px" :close-on-click-modal="false" |
||||||
|
:modal-append-to-body="false"> |
||||||
|
<el-form label-width="110px"> |
||||||
|
<el-form-item prop="userName" label="题库分类"> |
||||||
|
<el-select style="width: 100%" v-model="form.provinceId" placeholder="请选择题库分类"> |
||||||
|
<el-option v-for="(item, i) in types" :key="i" :label="item.provinceName" |
||||||
|
:value="item.provinceId"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="userName" label="当前题库"> |
||||||
|
<el-input placeholder="请输入题库名称" v-model="form.name" disabled></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="userName" label="模板文件"> |
||||||
|
<el-button type="primary" @click="download">模板下载<i class="el-icon-download el-icon--right"></i></el-button> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="userName" label="选择文件上传"> |
||||||
|
<el-upload name="file" accept=".xls,.xlsx" ref="upload" class="import-file" drag :before-upload="beforeUpload" |
||||||
|
:on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove" |
||||||
|
:limit="1" :data="{ |
||||||
|
// competitionId: id, |
||||||
|
platformId: 2 |
||||||
|
}" :disabled="uploading" :on-exceed="handleExceed" :action="this.api.batchImportPersonalData" |
||||||
|
:file-list="uploadList" :headers="headers"> |
||||||
|
<i class="el-icon-upload"></i> |
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> |
||||||
|
<div class="el-upload__tip" slot="tip" style="line-height: 1.8;"> |
||||||
|
<p>上传说明:</p> |
||||||
|
<p>1.请按照模板要求,正确填写后上传</p> |
||||||
|
<p>2.上传文件大小限制50M</p> |
||||||
|
<p>3.仅支持上传.xls、 .xlsx文件格式</p> |
||||||
|
</div> |
||||||
|
</el-upload> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="importVisible = false">关闭</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Util from '@/libs/util' |
||||||
|
import Setting from '@/setting' |
||||||
|
import Ueditor from '@/components/ueditor' |
||||||
|
import Breadcrumb from '@/components/breadcrumb' |
||||||
|
import Detail from '../detail' |
||||||
|
import Const from '@/const/ques' |
||||||
|
export default { |
||||||
|
components: { Ueditor, Breadcrumb, Detail }, |
||||||
|
data () { |
||||||
|
return { |
||||||
|
crumbs: [ |
||||||
|
{ |
||||||
|
name: this.$route.query.questionBankName || '题库管理', |
||||||
|
route: '/quesBank' |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '试题管理' |
||||||
|
}, |
||||||
|
], |
||||||
|
difficults: Const.difficults, |
||||||
|
questionTypes: Const.questionTypes, |
||||||
|
typeId: this.$route.query.id, |
||||||
|
loading: false, |
||||||
|
isNotJoin: 0, |
||||||
|
createSource: 1, |
||||||
|
keyword: '', |
||||||
|
type: 1, |
||||||
|
types: [], |
||||||
|
status: [ |
||||||
|
{ |
||||||
|
id: 1, |
||||||
|
name: '启用' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 0, |
||||||
|
name: '禁用' |
||||||
|
}, |
||||||
|
], |
||||||
|
knowledges: [], |
||||||
|
givenYears: '', |
||||||
|
knowledgePointIds: [], |
||||||
|
filter: { |
||||||
|
questionTypes: [], |
||||||
|
correctRateEnd: '', |
||||||
|
correctRateStart: '', |
||||||
|
difficultys: [], |
||||||
|
specialtyIds: [], |
||||||
|
status: '', |
||||||
|
keyword: '', |
||||||
|
}, |
||||||
|
list: [], |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
multipleSelection: [], |
||||||
|
|
||||||
|
quesVisible: false, |
||||||
|
curRow: {}, |
||||||
|
readonly: false, |
||||||
|
|
||||||
|
form: {}, |
||||||
|
importVisible: false, |
||||||
|
uploadList: [], |
||||||
|
uploadFaild: false, |
||||||
|
uploadTips: '', |
||||||
|
exportCode: '', |
||||||
|
headers: { |
||||||
|
token: Util.local.get(Setting.tokenKey) |
||||||
|
}, |
||||||
|
uploading: false, |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function (val) { |
||||||
|
clearTimeout(this.searchTimer); |
||||||
|
this.searchTimer = setTimeout(this.getType, 500); |
||||||
|
}, |
||||||
|
'filter.keyword': function (val) { |
||||||
|
clearTimeout(this.searchTimer); |
||||||
|
this.searchTimer = setTimeout(this.initData, 500); |
||||||
|
}, |
||||||
|
quesVisible () { |
||||||
|
this.quesVisible || this.getList() |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted () { |
||||||
|
this.getType() |
||||||
|
this.getKnowledge() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 获取知识点 |
||||||
|
async getType () { |
||||||
|
try { |
||||||
|
this.loading = true |
||||||
|
const { data } = await this.$post(this.api.TreeStructure, { |
||||||
|
createSource: 1, |
||||||
|
questionBankId: this.typeId, |
||||||
|
keyword: this.keyword, |
||||||
|
}) |
||||||
|
this.types = data |
||||||
|
this.getList() |
||||||
|
} finally { |
||||||
|
this.loading = false |
||||||
|
} |
||||||
|
}, |
||||||
|
// 前往知识点 |
||||||
|
toSet () { |
||||||
|
this.$router.push(`/knowledge?id=${this.typeId}`) |
||||||
|
}, |
||||||
|
// 类型回调 |
||||||
|
typeChange () { |
||||||
|
this.$refs.typeTree.setCurrentKey(null) |
||||||
|
this.initData() |
||||||
|
}, |
||||||
|
// 点击树节点查询列表数据 |
||||||
|
handleNodeClick () { |
||||||
|
this.isNotJoin = '' |
||||||
|
this.initData() |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
}, |
||||||
|
// 处理树形 |
||||||
|
handleType (list) { |
||||||
|
list.map(e => { |
||||||
|
if (e.children && e.children.length) { |
||||||
|
this.handleType(e.children) |
||||||
|
} else { |
||||||
|
delete e.children |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 获取知识点 |
||||||
|
async getKnowledge () { |
||||||
|
try { |
||||||
|
const { data } = await this.$post(this.api.TreeStructure, { |
||||||
|
createSource: 1, |
||||||
|
questionBankId: this.typeId, |
||||||
|
keyword: '' |
||||||
|
}) |
||||||
|
this.handleType(data) |
||||||
|
this.knowledges = data |
||||||
|
} catch (e) { } |
||||||
|
}, |
||||||
|
// 列表 |
||||||
|
async getList () { |
||||||
|
let type = this.$refs.typeTree.getCurrentKey() |
||||||
|
const k = this.knowledgePointIds |
||||||
|
if (k.length) { // 右边筛选里的知识点 |
||||||
|
type = k.map(e => { |
||||||
|
return e[e.length - 1] |
||||||
|
}) |
||||||
|
} else if (type) { |
||||||
|
type = [type] |
||||||
|
} |
||||||
|
const { message } = await this.$post(this.api.listQuestion, { |
||||||
|
...this.filter, |
||||||
|
givenYears: this.givenYears ? [this.givenYears] : [], |
||||||
|
isNotJoin: this.isNotJoin || '', |
||||||
|
pageNum: this.page, |
||||||
|
pageSize: this.pageSize, |
||||||
|
questionBankId: this.typeId, |
||||||
|
knowledgePointIds: type || [], |
||||||
|
}) |
||||||
|
this.list = Util.removeTag(message.records) |
||||||
|
this.total = message.total |
||||||
|
}, |
||||||
|
// 切换页码 |
||||||
|
currentChange (val) { |
||||||
|
this.page = val |
||||||
|
this.getList() |
||||||
|
}, |
||||||
|
handleSelectionChange (val) { // 多选 |
||||||
|
this.multipleSelection = val |
||||||
|
}, |
||||||
|
initData () { |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
this.page = 1 |
||||||
|
this.getList() |
||||||
|
}, |
||||||
|
|
||||||
|
// 添加 |
||||||
|
add () { |
||||||
|
this.quesVisible = true |
||||||
|
this.curRow = {} |
||||||
|
this.readonly = false |
||||||
|
}, |
||||||
|
// 复制 |
||||||
|
copy (row) { |
||||||
|
|
||||||
|
}, |
||||||
|
// 编辑/查看 |
||||||
|
toDetail (row, readonly = false) { |
||||||
|
this.quesVisible = true |
||||||
|
this.curRow = row |
||||||
|
this.readonly = readonly |
||||||
|
}, |
||||||
|
// 删除 |
||||||
|
del (row) { |
||||||
|
this.$confirm("确定要删除吗?", "提示", { |
||||||
|
type: "warning" |
||||||
|
}).then(() => { |
||||||
|
this.$post(`${this.api.delPartnerAccount}?accountId=${row.accountId}`).then(res => { |
||||||
|
Util.successMsg("删除成功") |
||||||
|
this.getList() |
||||||
|
}).catch(res => { }) |
||||||
|
}).catch(() => { }) |
||||||
|
}, |
||||||
|
async switchOff (val, row) { |
||||||
|
this.$post(this.api.disabledEventsCompetition, { |
||||||
|
competitionId: row.id, |
||||||
|
isOpen: val, |
||||||
|
type: 0 // 禁用平台来源(0中台,1职站) |
||||||
|
}).then(res => { |
||||||
|
Util.successMsg(val == 1 ? '禁用成功' : '启用成功') |
||||||
|
}).catch(err => { }) |
||||||
|
|
||||||
|
await this.$post(`${this.api.refreshPageNotification}?content=1`) |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
// 批量导入 |
||||||
|
batchImport () { |
||||||
|
this.importVisible = true |
||||||
|
this.uploadList = [] |
||||||
|
this.uploadFaild = false |
||||||
|
}, |
||||||
|
// 模板下载 |
||||||
|
download () { |
||||||
|
location.href = this.api[this.info.completeCompetitionSetup.competitionType ? 'competionTeamTemplate' : 'competionPersonTemplate'] |
||||||
|
}, |
||||||
|
// 上传文件 |
||||||
|
handleExceed (files, fileList) { |
||||||
|
Util.warningMsg( |
||||||
|
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` |
||||||
|
) |
||||||
|
}, |
||||||
|
// 下载失败文件 |
||||||
|
showFaild () { |
||||||
|
axios.get(`${this.api.TeamDataExportFailure}?exportCode=${this.exportCode}&platformId=2&type=${this.info.completeCompetitionSetup.competitionType ? 1 : 2}`, { |
||||||
|
headers: this.headers, |
||||||
|
responseType: 'blob' |
||||||
|
}).then((res) => { |
||||||
|
const name = res.headers['content-disposition'] |
||||||
|
Util.downloadFileDirect(name ? decodeURI(name) : '批量导入报名人员失败数据导出.xlsx', new Blob([res.data])) |
||||||
|
}).catch(res => { }) |
||||||
|
}, |
||||||
|
uploadSuccess ({ data, status }) { |
||||||
|
this.uploading = false |
||||||
|
this.uploadFaild = false |
||||||
|
this.uploadTips = '' |
||||||
|
if (status === 200) { |
||||||
|
this.init() |
||||||
|
const { tip } = data |
||||||
|
if (data.exportCode) { |
||||||
|
this.exportCode = data.exportCode |
||||||
|
this.uploadFaild = true |
||||||
|
this.uploadTips = tip |
||||||
|
} else { |
||||||
|
Util[tip.includes('5000') ? 'errorMsg' : 'successMsg'](tip, 3000) |
||||||
|
this.importVisible = false |
||||||
|
} |
||||||
|
} else { |
||||||
|
Util.errorMsg(res.message || '上传失败,请检查数据', 3000) |
||||||
|
} |
||||||
|
}, |
||||||
|
uploadError (err, file, fileList) { |
||||||
|
this.uploading = false |
||||||
|
this.$message({ |
||||||
|
message: "上传出错,请重试!", |
||||||
|
type: "error", |
||||||
|
center: true |
||||||
|
}) |
||||||
|
}, |
||||||
|
beforeUpload (file) { |
||||||
|
this.uploading = true |
||||||
|
}, |
||||||
|
beforeRemove (file, fileList) { |
||||||
|
return this.$confirm(`确定移除 ${file.name}?`) |
||||||
|
}, |
||||||
|
handleRemove (file, fileList) { |
||||||
|
this.uploadList = fileList |
||||||
|
this.uploadFaild = false |
||||||
|
}, |
||||||
|
cancelUpload () { |
||||||
|
this.uploading = false |
||||||
|
this.$refs.upload.abort() |
||||||
|
this.keyword = '' |
||||||
|
this.init() |
||||||
|
this.importVisible = false |
||||||
|
}, |
||||||
|
// 后台上传 |
||||||
|
backstageUpload () { |
||||||
|
this.isBackstage = 1 |
||||||
|
this.importVisible = false |
||||||
|
}, |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.page { |
||||||
|
display: flex; |
||||||
|
padding: 0 24px; |
||||||
|
|
||||||
|
.side { |
||||||
|
width: 300px; |
||||||
|
padding: 24px 10px 24px 0; |
||||||
|
margin-right: 24px; |
||||||
|
border-right: 1px solid rgba(0, 0, 0, 0.06); |
||||||
|
} |
||||||
|
|
||||||
|
.right { |
||||||
|
width: calc(100% - 324px); |
||||||
|
padding: 24px 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.tool { |
||||||
|
margin-bottom: 0; |
||||||
|
|
||||||
|
.filter { |
||||||
|
flex-wrap: wrap; |
||||||
|
justify-content: space-between; |
||||||
|
|
||||||
|
li { |
||||||
|
margin-bottom: 15px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/deep/.opts { |
||||||
|
.line { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 15px; |
||||||
|
} |
||||||
|
|
||||||
|
.el-radio { |
||||||
|
margin-right: 15px; |
||||||
|
} |
||||||
|
|
||||||
|
.icon { |
||||||
|
margin-left: 10px; |
||||||
|
font-size: 18px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/deep/.fill-blanks { |
||||||
|
.fills { |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
|
||||||
|
.fill-item { |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
margin-right: 10px; |
||||||
|
|
||||||
|
.el-input { |
||||||
|
width: 100px; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.add-fill { |
||||||
|
margin-left: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.score-wrap { |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
|
||||||
|
.el-input { |
||||||
|
width: 80px; |
||||||
|
margin: 0 10px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
Loading…
Reference in new issue