parent
b6f3b1f3d6
commit
479aba93eb
20 changed files with 2277 additions and 30 deletions
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 884 B |
@ -0,0 +1,482 @@ |
||||
<template> |
||||
<div> |
||||
<Breadcrumb :data="crumbs" /> |
||||
<div class="page"> |
||||
<div class="side"> |
||||
<div class="m-b-20"> |
||||
<el-radio-group v-model="isNotJoin" @change="changeType"> |
||||
<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="addType">添加</el-button> |
||||
</div> |
||||
|
||||
<el-input class="m-b-10" placeholder="请输入知识点分类" prefix-icon="el-icon-search" size="small" clearable |
||||
v-model="keyword"></el-input> |
||||
<div style="overflow: auto"> |
||||
<el-tree v-loading="loading" :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 }"> |
||||
<span class="org-name">{{ data.name }}</span> |
||||
<span> |
||||
<el-button type="text" icon="el-icon-circle-plus-outline" @click="() => addType(node, data)"> |
||||
</el-button> |
||||
<el-button type="text" icon="el-icon-edit-outline" @click="() => editType(node, data)"> |
||||
</el-button> |
||||
<el-button type="text" icon="el-icon-delete" @click="() => delType(data)"> |
||||
</el-button> |
||||
</span> |
||||
</span> |
||||
</el-tree> |
||||
</div> |
||||
</div> |
||||
|
||||
<el-dialog :title="typeForm.id ? '编辑' : '新增' + '知识点分类'" :visible.sync="typeVisible" |
||||
:close-on-click-modal="false" width="400px"> |
||||
<el-form v-if="typeVisible" ref="typeForm" :model="typeForm" :rules="typeRules" label-width="130px"> |
||||
<el-form-item label="知识点分类名称" prop="name"> |
||||
<el-input v-model.trim="typeForm.name" placeholder="请输入知识点分类" maxlength="20"></el-input> |
||||
</el-form-item> |
||||
<el-form-item label="设置上一级"> |
||||
<el-cascader :options="types" v-model="cascaderValue" :props="cascaderProps" clearable |
||||
style="width: 100%"> |
||||
</el-cascader> |
||||
</el-form-item> |
||||
</el-form> |
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="closeType">取 消</el-button> |
||||
<el-button type="primary" @click="typeSubmit">确 定</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
</div> |
||||
|
||||
<div class="right"> |
||||
<h6 class="page-name">筛选</h6> |
||||
<div class="tool"> |
||||
<ul class="filter"> |
||||
<li> |
||||
<el-input style="width: 250px;" placeholder="请输入知识点名称" prefix-icon="el-icon-search" v-model="filter.name" |
||||
clearable></el-input> |
||||
</li> |
||||
</ul> |
||||
<div> |
||||
<el-button type="primary" @click="add">新增知识点</el-button> |
||||
<el-button type="primary" @click="delAllSelection">批量删除</el-button> |
||||
</div> |
||||
</div> |
||||
|
||||
<el-table :data="list" v-loading="listLoading" class="table" ref="table" stripe header-align="center" |
||||
@selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange"> |
||||
<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="name" label="知识点名称" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="knowledgePointsClassification" label="知识点分类" align="center" min-width="120" |
||||
show-overflow-tooltip></el-table-column> |
||||
<el-table-column prop="relatedQuestionsNum" label="已关联试题" align="center" width="90"></el-table-column> |
||||
<el-table-column prop="createTime" label="创建时间" align="center" width="160" |
||||
sortable="custom"></el-table-column> |
||||
<el-table-column prop="createUserName" label="创建人" align="center" width="100"></el-table-column> |
||||
<el-table-column label="操作" align="center" width="100"> |
||||
<template slot-scope="scope"> |
||||
<el-button type="text" @click="edit(scope.row)">编辑</el-button> |
||||
<!-- <el-button type="text" v-auth="'/system:后台账号:重置密码'" @click="resetPassword(scope.row)">转移</el-button> --> |
||||
<el-button type="text" @click="del(scope.row)">删除</el-button> |
||||
</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> |
||||
|
||||
<el-dialog :title="!form.id ? '添加知识点' : '编辑知识点'" :visible.sync="knowledgeVisible" width="400px" |
||||
:close-on-click-modal="false"> |
||||
<el-form :model="form" :rules="rules" label-width="100px"> |
||||
<el-form-item prop="parentId" label="知识点分类"> |
||||
<el-cascader placeholder="请选择题库分类" v-model="form.parentId" :options="types" |
||||
:props="{ value: 'id', label: 'name', checkStrictly: true }" clearable></el-cascader> |
||||
</el-form-item> |
||||
<el-form-item prop="name" label="知识点名称"> |
||||
<el-input placeholder="请输入知识点名称" v-model="form.name" maxlength="20"></el-input> |
||||
</el-form-item> |
||||
</el-form> |
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="knowledgeVisible = false">取 消</el-button> |
||||
<el-button type="primary" @click="knowledgeSubmit">确 定</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<el-dialog title="提示" :visible.sync="delVisible" width="400px" :close-on-click-modal="false" custom-class="del-dia"> |
||||
<div class="del-wrap"> |
||||
<div class="icon el-icon-warning"></div> |
||||
<div> |
||||
<p>确认要删除【{{ curName }}】吗?</p> |
||||
<p class="tips">删除后,其子级分类与知识点也将被删除。</p> |
||||
</div> |
||||
</div> |
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="delVisible = false">取消</el-button> |
||||
<el-button type="primary" @click="delTypeSubmit">确定</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import Util from '@/libs/util' |
||||
import _ from 'lodash' |
||||
import Breadcrumb from '@/components/breadcrumb' |
||||
export default { |
||||
components: { Breadcrumb }, |
||||
data () { |
||||
return { |
||||
typeId: this.$route.query.id, |
||||
createSource: 1, |
||||
loading: false, |
||||
keyword: '', |
||||
types: [], |
||||
isNotJoin: 0, |
||||
typeVisible: false, // 员工组织架对话框 |
||||
typeForm: { |
||||
id: '', |
||||
name: '' |
||||
}, |
||||
cascaderValue: [], |
||||
cascaderProps: { |
||||
checkStrictly: true, |
||||
label: "name", |
||||
value: "id" |
||||
}, |
||||
treeVisible: true, |
||||
isDetail: false, |
||||
name: '', |
||||
form: { |
||||
name: '', |
||||
parentId: [] |
||||
}, |
||||
typeRules: { |
||||
name: [ |
||||
{ required: true, message: '请输入知识点分类名称', trigger: 'blur' } |
||||
] |
||||
}, |
||||
rules: { |
||||
name: [ |
||||
{ required: true, message: '请输入知识点名称', trigger: 'blur' } |
||||
], |
||||
}, |
||||
filter: { |
||||
timeOrderBy: '', |
||||
name: '', |
||||
}, |
||||
listLoading: false, |
||||
list: [], |
||||
page: 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
multipleSelection: [], |
||||
|
||||
knowledgeVisible: false, |
||||
submiting: false, // 新增编辑防抖标识 |
||||
|
||||
|
||||
delVisible: false, |
||||
deleteQuestions: false, |
||||
curName: '', |
||||
curId: [], |
||||
}; |
||||
}, |
||||
watch: { |
||||
keyword: function () { |
||||
clearTimeout(this.searchTimer) |
||||
this.searchTimer = setTimeout(this.getType, 500) |
||||
}, |
||||
'filter.name': function () { |
||||
clearTimeout(this.searchTimer) |
||||
this.searchTimer = setTimeout(this.getList, 500) |
||||
}, |
||||
}, |
||||
mounted () { |
||||
this.crumbs = [ |
||||
{ |
||||
name: this.$route.query.name || '题库管理', |
||||
route: '/quesBank' |
||||
}, |
||||
{ |
||||
name: '试题列表', |
||||
route: '/ques', |
||||
query: { |
||||
id: this.typeId |
||||
} |
||||
}, |
||||
{ |
||||
name: '知识点列表' |
||||
}, |
||||
], |
||||
this.getType() |
||||
}, |
||||
methods: { |
||||
// 获取分类 |
||||
async getType () { |
||||
try { |
||||
this.loading = true |
||||
const { data } = await this.$post(this.api.classificationTreeStructure, { |
||||
createSource: this.createSource, |
||||
keyword: this.keyword, |
||||
questionBankId: this.typeId, |
||||
}) |
||||
this.handleType(data) |
||||
this.types = data |
||||
this.getList() |
||||
} finally { |
||||
this.loading = false |
||||
} |
||||
}, |
||||
// 分类筛选回调 |
||||
changeType () { |
||||
this.$refs.typeTree.setCurrentKey(null) |
||||
this.initData() |
||||
}, |
||||
// 添加分类 |
||||
addType (node, data) { |
||||
this.typeForm = { |
||||
id: '', |
||||
parentId: data ? data.id : '', |
||||
name: '', |
||||
} |
||||
this.typeVisible = true |
||||
this.cascaderValue = data.path.split('/').map(e => +e) |
||||
}, |
||||
// 编辑分类 |
||||
editType (node, data) { |
||||
this.typeForm = { |
||||
id: data.id, |
||||
name: data.name |
||||
} |
||||
this.typeVisible = true |
||||
const path = data.path.split('/').map(e => +e) |
||||
this.cascaderValue = path.length > 1 ? path.slice(0, path.length - 1) : [] |
||||
}, |
||||
// 处理树形 |
||||
handleType (list) { |
||||
list.map(e => { |
||||
if (e.children && e.children.length) { |
||||
this.handleType(e.children) |
||||
} else { |
||||
delete e.children |
||||
} |
||||
}) |
||||
}, |
||||
// 删除分类 |
||||
async delType (row) { |
||||
try { |
||||
await this.$confirm(`<p>确认要删除【${row.name}】吗?</p><p style="color: #f56c6c;">删除后,其子级分类与知识点都将被删除!</p>`, '提示', { |
||||
confirmButtonText: '确定', |
||||
cancelButtonText: '取消', |
||||
type: 'warning', |
||||
closeOnClickModal: false, |
||||
dangerouslyUseHTMLString: true, |
||||
}) |
||||
await this.$post(this.api.knowledgeHierarchyDel, [row.id]) |
||||
Util.successMsg('删除成功') |
||||
this.getType() |
||||
} catch (e) { } |
||||
}, |
||||
// 删除分类提交 |
||||
async delTypeSubmit () { |
||||
await this.$post(this.api.knowledgeHierarchyDel, this.curId) |
||||
Util.successMsg('删除成功') |
||||
this.delVisible = false |
||||
this.getType() |
||||
}, |
||||
// 分类新增/编辑 |
||||
typeSubmit () { |
||||
this.$refs.typeForm.validate(async (valid) => { |
||||
if (valid) { |
||||
const form = this.typeForm |
||||
const cas = this.cascaderValue |
||||
const len = cas.length |
||||
if (cas && len) { |
||||
this.typeForm.parentId = cas[len - 1] |
||||
} |
||||
form.createSource = this.createSource |
||||
form.questionBankId = this.typeId |
||||
form.type = 0 |
||||
await this.$post(this.api.knowledgeHierarchySave, form) |
||||
Util.successMsg('保存成功') |
||||
this.closeType() |
||||
} |
||||
}); |
||||
}, |
||||
// 点击树节点查询列表数据 |
||||
handleNodeClick (data) { |
||||
this.$refs.table.clearSelection() |
||||
this.isNotJoin = '' |
||||
this.getList() |
||||
}, |
||||
// 关闭组织新增编辑弹框 |
||||
closeType () { |
||||
this.typeVisible = false |
||||
this.cascaderValue = [] |
||||
this.getType() |
||||
}, |
||||
// 列表 |
||||
async getList () { |
||||
try { |
||||
this.listLoading = true |
||||
const res = await this.$post(this.api.knowledgeHierarchyList, { |
||||
...this.filter, |
||||
isNotJoin: this.isNotJoin || '', |
||||
pageNum: this.page, |
||||
pageSize: this.pageSize, |
||||
questionBankId: this.typeId, |
||||
knowledgePointCategoryId: this.$refs.typeTree.getCurrentKey() || '', |
||||
}) |
||||
this.list = res.message.records |
||||
this.total = res.message.total |
||||
} finally { |
||||
this.listLoading = false |
||||
} |
||||
}, |
||||
// 切换页码 |
||||
currentChange (val) { |
||||
this.page = val |
||||
this.getList() |
||||
}, |
||||
handleSelectionChange (val) { // 多选 |
||||
this.multipleSelection = val |
||||
}, |
||||
initData () { |
||||
this.$refs.table.clearSelection() |
||||
this.page = 1 |
||||
this.getList() |
||||
}, |
||||
// 排序回调 |
||||
sortChange (column) { |
||||
if (column.prop === 'createTime') this.filter.timeOrderBy = column.order ? column.order === 'ascending' ? 'asc' : 'desc' : '' |
||||
this.getList() |
||||
}, |
||||
// 删除 |
||||
async del (row) { |
||||
try { |
||||
await this.$confirm(`<p>确认要删除【${row.name}】吗?</p><p style="color: #f56c6c;">删除后,关联此知识点的试题将自动移除此知识点!</p>`, '提示', { |
||||
confirmButtonText: '确定', |
||||
cancelButtonText: '取消', |
||||
type: 'warning', |
||||
closeOnClickModal: false, |
||||
dangerouslyUseHTMLString: true, |
||||
}) |
||||
await this.$post(this.api.knowledgeHierarchyDel, [row.id]) |
||||
Util.successMsg('删除成功') |
||||
this.getList() |
||||
} catch (e) { } |
||||
}, |
||||
// 添加知识点 |
||||
add () { |
||||
const type = this.$refs.typeTree.getCurrentNode() |
||||
this.form = { |
||||
name: '', |
||||
parentId: type ? type.path.split('/').map(e => +e) : [], |
||||
} |
||||
this.knowledgeVisible = true |
||||
}, |
||||
// 编辑知识点 |
||||
async edit (row) { |
||||
const { data } = await this.$post(`${this.api.knowledgeHierarchyFind}?id=${row.id}`) |
||||
this.knowledgeVisible = true |
||||
const path = data.path.split('/').map(e => +e) |
||||
this.form = { |
||||
id: row.id, |
||||
name: row.name, |
||||
parentId: path.slice(0, path.length - 1), |
||||
} |
||||
console.log(11, this.form) |
||||
}, |
||||
// 知识点提交 |
||||
async knowledgeSubmit () { |
||||
if (this.submiting) return false |
||||
const form = _.cloneDeep(this.form) |
||||
if (!form.name) return Util.warningMsg('请输入题库名称') |
||||
this.submiting = true |
||||
form.parentId = form.parentId.length ? form.parentId[form.parentId.length - 1] : 0 |
||||
form.createSource = 1 |
||||
form.questionBankId = this.typeId |
||||
form.type = 1 |
||||
try { |
||||
await this.$post(this.api.knowledgeHierarchySave, form) |
||||
Util.successMsg('保存成功') |
||||
this.knowledgeVisible = false |
||||
this.submiting = false |
||||
this.getList() |
||||
} catch (e) { |
||||
this.submiting = false |
||||
} |
||||
}, |
||||
async delAllSelection () { |
||||
const list = this.multipleSelection |
||||
if (list.length) { |
||||
try { |
||||
await this.$confirm(`<p style="margin-bottom: 10px;">确认要删除已选定的${list.length}个知识点吗?</p><p style="color: #f56c6c;">删除后,关联这些知识点的试题将自动移除这些知识点!</p>`, '提示', { |
||||
confirmButtonText: '确定', |
||||
cancelButtonText: '取消', |
||||
type: 'warning', |
||||
closeOnClickModal: false, |
||||
dangerouslyUseHTMLString: true, |
||||
}) |
||||
await this.$post(this.api.knowledgeHierarchyDel, list.map(e => e.id)) |
||||
Util.successMsg('删除成功') |
||||
this.multipleSelection = [] |
||||
this.$refs.table.clearSelection() |
||||
this.getList() |
||||
} catch (e) { } |
||||
} else { |
||||
Util.warningMsg('请选择数据') |
||||
} |
||||
}, |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.m-b-20 { |
||||
margin-bottom: 20px; |
||||
} |
||||
|
||||
.org-name { |
||||
margin-right: 20px; |
||||
} |
||||
|
||||
.w-100 { |
||||
width: 100%; |
||||
} |
||||
|
||||
.page { |
||||
display: flex; |
||||
min-height: 100%; |
||||
margin-top: 20px; |
||||
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; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,332 @@ |
||||
<template> |
||||
<div class="page"> |
||||
<Breadcrumb :data="crumbs" /> |
||||
<p class="page-name mb">试卷</p> |
||||
<el-form :model="form" :rules="rules" class="input-form model" label-width="140px"> |
||||
<el-form-item prop="name" label="试卷名称"> |
||||
<el-input style="width: 940px" placeholder="请输入试卷名称" v-model="form.name" clearable maxlength="100" /> |
||||
</el-form-item> |
||||
<div class="item-line"> |
||||
<el-form-item prop="particularYear" label="年份"> |
||||
<el-date-picker v-model="form.particularYear" type="year" placeholder="请选择年份"> |
||||
</el-date-picker> |
||||
</el-form-item> |
||||
<el-form-item required label="所属试卷分类"> |
||||
<el-cascader placeholder="请选择所属试卷分类" :options="types" v-model="cascaderValue" :props="cascaderProps" clearable |
||||
style="width: 100%"> |
||||
</el-cascader> |
||||
</el-form-item> |
||||
</div> |
||||
<div class="item-line"> |
||||
<el-form-item prop="paperType" label="建议用途"> |
||||
<el-select v-model="form.paperType" clearable placeholder="请选择建议用途"> |
||||
<el-option v-for="(item, i) in paperTypes" :key="i" :label="item.name" :value="item.id"></el-option> |
||||
</el-select> |
||||
</el-form-item> |
||||
<el-form-item prop="suggestTime" label="估计用时"> |
||||
<el-input placeholder="请输入估计用时" v-model="form.suggestTime"> |
||||
<template slot="append">分钟</template> |
||||
</el-input> |
||||
</el-form-item> |
||||
</div> |
||||
<div class="item-line"> |
||||
<el-form-item prop="columnId" label="所属专业"> |
||||
<el-select v-model="form.professionalId" clearable 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="difficult" label="试卷难度"> |
||||
<el-select v-model="form.difficult" 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> |
||||
</div> |
||||
<el-form-item prop="userName" label="试卷说明"> |
||||
<Ueditor @ready="editorReady" /> |
||||
</el-form-item> |
||||
|
||||
<div class="line"></div> |
||||
|
||||
<div class="flex j-between m-b-20"> |
||||
<p>默认模板</p> |
||||
<p>目标总题数:30;目标总分:100</p> |
||||
<el-button type="primary" size="small" @click="showTemplate">选择大纲模板</el-button> |
||||
</div> |
||||
<el-table :data="form.paperOutline" stripe header-align="center" row-key="id"> |
||||
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
||||
<el-table-column prop="outlineName" label="大题" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="name" label="题型" align="center" min-width="120"> |
||||
<template slot-scope="scope"> |
||||
<el-select v-model="scope.row.questionType" placeholder="请选择题型"> |
||||
<el-option v-for="(item, i) in questionTypes" :key="i" :label="item.name" :value="item.id"></el-option> |
||||
</el-select> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="name" label="目标题数" align="center" min-width="120"> |
||||
<template slot-scope="scope"> |
||||
<el-input placeholder="请输入目标题数" v-model="scope.row.questionNum" type="number" /> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="name" label="目标分值" align="center" min-width="120"> |
||||
<template slot-scope="scope"> |
||||
<el-input placeholder="请输入目标分值" v-model="scope.row.targetScore" /> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" align="center" width="120"> |
||||
<template slot-scope="scope"> |
||||
<i class="el-icon-circle-plus-outline action-icon" @click="addLine(scope.$index)"></i> |
||||
<i class="el-icon-remove-outline action-icon" @click="delLine(scope.$index)"></i> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
|
||||
</el-form> |
||||
<div class="btns"> |
||||
<el-button @click="submit(0)">保存草稿</el-button> |
||||
<el-button type="primary" @click="submit(1)">发布</el-button> |
||||
<el-button v-if="$route.query.id" @click="preview">预览</el-button> |
||||
<el-button @click="back">取消</el-button> |
||||
</div> |
||||
|
||||
<Template :visible="templateVisible" /> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import Setting from '@/setting' |
||||
import Util from '@/libs/util' |
||||
import Ueditor from '@/components/ueditor' |
||||
import Breadcrumb from '@/components/breadcrumb' |
||||
import Template from './template' |
||||
export default { |
||||
components: { Ueditor, Breadcrumb, Template }, |
||||
data () { |
||||
return { |
||||
crumbs: [ |
||||
{ |
||||
name: '试卷管理', |
||||
route: 'list' |
||||
}, |
||||
{ |
||||
name: '创建试卷' |
||||
}, |
||||
], |
||||
libraryId: this.$route.query.libraryId, |
||||
headers: { |
||||
token: Util.local.get(Setting.tokenKey) |
||||
}, |
||||
types: [], |
||||
cascaderValue: [], |
||||
cascaderProps: { |
||||
checkStrictly: true, |
||||
label: "classificationName", |
||||
value: "classificationId" |
||||
}, |
||||
paperTypes: [ |
||||
{ |
||||
id: 0, |
||||
name: '练习' |
||||
}, |
||||
{ |
||||
id: 1, |
||||
name: '考核' |
||||
}, |
||||
{ |
||||
id: 2, |
||||
name: '竞赛' |
||||
}, |
||||
], |
||||
professionals: [], |
||||
difficults: [ |
||||
{ |
||||
id: 1, |
||||
name: '简单' |
||||
}, |
||||
{ |
||||
id: 2, |
||||
name: '普通' |
||||
}, |
||||
{ |
||||
id: 3, |
||||
name: '较难' |
||||
}, |
||||
{ |
||||
id: 4, |
||||
name: '难' |
||||
}, |
||||
], |
||||
questionTypes: [ |
||||
{ |
||||
name: '单选题' |
||||
}, |
||||
{ |
||||
name: '多选题' |
||||
}, |
||||
{ |
||||
name: '判断题' |
||||
}, |
||||
{ |
||||
name: '填空题' |
||||
}, |
||||
{ |
||||
name: '问答题' |
||||
}, |
||||
], |
||||
|
||||
richEditor: { |
||||
object: null, |
||||
parameterName: '', |
||||
instance: null |
||||
}, |
||||
form: { |
||||
classificationId: '', |
||||
difficult: '', |
||||
libraryId: '', |
||||
name: '', |
||||
paperMethod: '', |
||||
paperType: '', |
||||
particularYear: '', |
||||
professionalId: '', |
||||
questionCount: '', |
||||
remarks: '', |
||||
score: '', |
||||
suggestTime: '', |
||||
paperOutline: [ |
||||
{ |
||||
examQuestions: [], |
||||
outlineName: '单选题', |
||||
questionNum: '10', |
||||
questionType: '单选题', |
||||
targetScore: '20.0', |
||||
}, |
||||
{ |
||||
examQuestions: [], |
||||
outlineName: '多选题', |
||||
questionNum: '5', |
||||
questionType: '多选题', |
||||
targetScore: '15.0', |
||||
}, |
||||
{ |
||||
examQuestions: [], |
||||
outlineName: '判断题', |
||||
questionNum: '5', |
||||
questionType: '判断题', |
||||
targetScore: '10.0', |
||||
}, |
||||
{ |
||||
examQuestions: [], |
||||
outlineName: '填空题', |
||||
questionNum: '5', |
||||
questionType: '填空题', |
||||
targetScore: '15.0', |
||||
}, |
||||
{ |
||||
examQuestions: [], |
||||
outlineName: '问答题', |
||||
questionNum: '3', |
||||
questionType: '问答题', |
||||
targetScore: '40.0', |
||||
}, |
||||
], |
||||
}, |
||||
rules: { |
||||
name: [ |
||||
{ required: true, message: '请输入试卷名称', trigger: 'blur' } |
||||
], |
||||
particularYear: [ |
||||
{ required: true, message: '请选择年份', trigger: 'change' } |
||||
], |
||||
paperType: [ |
||||
{ required: true, message: '请选择建议用途', trigger: 'change' } |
||||
], |
||||
suggestTime: [ |
||||
{ required: true, message: '请输入估计用时', trigger: 'blur' } |
||||
], |
||||
name: [ |
||||
{ required: true, message: '请输入试卷名称', trigger: 'blur' } |
||||
], |
||||
}, |
||||
templateVisible: false, |
||||
}; |
||||
}, |
||||
mounted () { |
||||
this.getType() |
||||
this.getProfessional() |
||||
}, |
||||
methods: { |
||||
// 获取试卷分类 |
||||
async getType () { |
||||
try { |
||||
const res = await this.$post(this.api.examClassificationList, { |
||||
libraryId: this.libraryId, |
||||
}) |
||||
const data = res.treeList |
||||
this.handleType(data) |
||||
this.types = 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.children && e.children.length) { |
||||
this.handleType(e.children) |
||||
} else { |
||||
delete e.children |
||||
} |
||||
}) |
||||
}, |
||||
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) |
||||
}, |
||||
// 选择大纲模板 |
||||
showTemplate () { |
||||
this.templateVisible = true |
||||
}, |
||||
// 试卷大纲添加行 |
||||
addLine (i) { |
||||
this.form.paperOutline.splice(i + 1, 0, { |
||||
examQuestions: [], |
||||
outlineName: '', |
||||
questionNum: '', |
||||
questionType: '', |
||||
targetScore: '', |
||||
}) |
||||
}, |
||||
// 试卷大纲移除行 |
||||
delLine (i) { |
||||
this.form.paperOutline.splice(i, 1) |
||||
}, |
||||
// 提交 |
||||
submit () { |
||||
|
||||
}, |
||||
// 返回 |
||||
back () { |
||||
|
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.action-icon { |
||||
margin-right: 10px; |
||||
font-size: 18px; |
||||
color: $main-color; |
||||
cursor: pointer; |
||||
} |
||||
</style> |
@ -0,0 +1,189 @@ |
||||
<template> |
||||
<div> |
||||
<el-dialog title="选择试卷大纲模板" :visible.sync="listVisible" width="1000px" :close-on-click-modal="false"> |
||||
<div class="tool"> |
||||
<ul class="filter"> |
||||
<li> |
||||
<label>题型</label> |
||||
<el-select v-model="form.questionType" clearable placeholder="请选择题目类型" @change="initData"> |
||||
<el-option v-for="(item, i) in questionTypes" :key="i" :value="item.name"></el-option> |
||||
</el-select> |
||||
</li> |
||||
<li> |
||||
<label>搜索</label> |
||||
<el-input style="width: 250px;" placeholder="请输入模板名称" prefix-icon="el-icon-search" |
||||
v-model="form.templateName" clearable /> |
||||
</li> |
||||
</ul> |
||||
<div> |
||||
<el-button type="primary" @click="add">新增模板</el-button> |
||||
</div> |
||||
</div> |
||||
|
||||
<el-table :data="list" stripe header-align="center" row-key="libraryId"> |
||||
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
||||
<el-table-column prop="libraryName" label="模板名称" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="题型" label="题型" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="libraryClassificationName" label="大题数" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="examPaperNum" label="小题总数" align="center" width="100"></el-table-column> |
||||
<el-table-column prop="examPaperNum" label="总分" align="center" width="100"></el-table-column> |
||||
<el-table-column prop="createTime" label="创建时间" align="center" width="160" sortable="custom"></el-table-column> |
||||
<el-table-column prop="createUserName" label="创建人" align="center" width="100"></el-table-column> |
||||
<el-table-column label="操作" align="center" width="280"> |
||||
<template slot-scope="scope"> |
||||
<el-button type="text" @click="useTemplate(scope.row, 0)">使用模板</el-button> |
||||
<el-button type="text" @click="edit(scope.row, 1)">编辑</el-button> |
||||
<el-button type="text" @click="del(scope.row)">删除</el-button> |
||||
</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> |
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="listVisible = false">关闭</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
|
||||
<el-dialog title="新增模板" :visible.sync="detailVisible" width="600px" :close-on-click-modal="false"> |
||||
<el-form :model="form" :rules="rules" label-width="100px"> |
||||
<el-form-item prop="userName" label="模板名称"> |
||||
<el-input placeholder="请输入模板名称" prefix-icon="el-icon-search" |
||||
v-model="name" /> |
||||
</el-form-item> |
||||
</el-form> |
||||
|
||||
<el-table :data="list" stripe header-align="center" row-key="libraryId"> |
||||
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
||||
<el-table-column prop="libraryName" label="模板名称" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="题型" label="题型" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="libraryClassificationName" label="大题数" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="examPaperNum" label="小题总数" align="center" width="100"></el-table-column> |
||||
<el-table-column prop="examPaperNum" label="总分" align="center" width="100"></el-table-column> |
||||
<el-table-column prop="createTime" label="创建时间" align="center" width="160" sortable="custom"></el-table-column> |
||||
<el-table-column prop="createUserName" label="创建人" align="center" width="100"></el-table-column> |
||||
<el-table-column label="操作" align="center" width="280"> |
||||
<template slot-scope="scope"> |
||||
<el-button type="text" @click="useTemplate(scope.row, 0)">使用模板</el-button> |
||||
<el-button type="text" @click="edit(scope.row, 1)">编辑</el-button> |
||||
<el-button type="text" @click="del(scope.row)">删除</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="detailVisible = false">取消</el-button> |
||||
<el-button type="primary" @click="submit">保存模板</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import Setting from '@/setting' |
||||
import Util from '@/libs/util' |
||||
export default { |
||||
props: ['visible'], |
||||
data () { |
||||
return { |
||||
listVisible: false, |
||||
searchTimer: null, |
||||
questionTypes: [ |
||||
{ |
||||
name: '单选题' |
||||
}, |
||||
{ |
||||
name: '多选题' |
||||
}, |
||||
{ |
||||
name: '判断题' |
||||
}, |
||||
{ |
||||
name: '填空题' |
||||
}, |
||||
{ |
||||
name: '问答题' |
||||
}, |
||||
], |
||||
|
||||
form: { |
||||
templateName: '', |
||||
questionType: '', |
||||
}, |
||||
list: [], |
||||
page: 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
|
||||
detailVisible: false, |
||||
}; |
||||
}, |
||||
watch: { |
||||
'form.templateName': function (val) { |
||||
clearTimeout(this.searchTimer) |
||||
this.searchTimer = setTimeout(this.initData, 500) |
||||
}, |
||||
visible () { |
||||
this.listVisible = this.visible |
||||
} |
||||
}, |
||||
mounted () { |
||||
this.getList() |
||||
}, |
||||
methods: { |
||||
// 获取模板列表 |
||||
async getList () { |
||||
try { |
||||
const res = await this.$post(this.api.examPaperTemplateList, { |
||||
pageNum: this.page, |
||||
pageSize: this.pageSize, |
||||
...this.form |
||||
}) |
||||
this.types = res.pageList.records |
||||
this.total = res.pageList.total |
||||
} catch (e) { } |
||||
}, |
||||
// 切换页码 |
||||
currentChange (val) { |
||||
this.page = val |
||||
this.getList() |
||||
}, |
||||
initData () { |
||||
this.page = 1 |
||||
this.getList() |
||||
}, |
||||
// 新增 |
||||
add () { |
||||
this.detailVisible = true |
||||
}, |
||||
// 使用模板 |
||||
useTemplate (row) { |
||||
|
||||
}, |
||||
// 编辑 |
||||
edit (row) { |
||||
|
||||
}, |
||||
// 删除 |
||||
del (row) { |
||||
|
||||
}, |
||||
// 提交 |
||||
async submit () { |
||||
|
||||
}, |
||||
// 返回 |
||||
back () { |
||||
|
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.action-icon { |
||||
margin-right: 10px; |
||||
font-size: 18px; |
||||
color: $main-color; |
||||
cursor: pointer; |
||||
} |
||||
</style> |
@ -0,0 +1,498 @@ |
||||
<template> |
||||
<div> |
||||
<Breadcrumb :data="crumbs" /> |
||||
<div class="page"> |
||||
<div class="side"> |
||||
<div class="m-b-20"> |
||||
<el-radio-group v-model="isNotJoin" @change="changeType"> |
||||
<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="addType(0)">添加</el-button> |
||||
</div> |
||||
|
||||
<div style="overflow: auto"> |
||||
<el-tree v-loading="loading" :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 }"> |
||||
<span class="org-name">{{ data.classificationName }}</span> |
||||
<span> |
||||
<el-button type="text" icon="el-icon-circle-plus-outline" @click="() => addType(data)"> |
||||
</el-button> |
||||
<el-button type="text" icon="el-icon-edit-outline" @click="() => editType(data)"> |
||||
</el-button> |
||||
<el-button type="text" icon="el-icon-delete" @click="() => delType(node, data)"> |
||||
</el-button> |
||||
</span> |
||||
</span> |
||||
</el-tree> |
||||
</div> |
||||
</div> |
||||
|
||||
<el-dialog :title="typeForm.classificationId ? '编辑' : '新增' + '试卷分类'" :visible.sync="typeVisible" |
||||
:close-on-click-modal="false" width="400px"> |
||||
<el-form v-if="typeVisible" ref="typeForm" :model="typeForm" :rules="typeRules" label-width="130px"> |
||||
<el-form-item label="试卷分类名称" prop="classificationName"> |
||||
<el-input v-model.trim="typeForm.classificationName" placeholder="请输入试卷分类" maxlength="20"></el-input> |
||||
</el-form-item> |
||||
<el-form-item label="设置上一级"> |
||||
<el-cascader :options="types" v-model="cascaderValue" :props="cascaderProps" clearable |
||||
style="width: 100%"> |
||||
</el-cascader> |
||||
</el-form-item> |
||||
</el-form> |
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="closeType">取 消</el-button> |
||||
<el-button type="primary" @click="typeSubmit">确 定</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
</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-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: 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="add">批量移除 </el-button> |
||||
<el-button type="primary" @click="add">批量删除</el-button> |
||||
</div> |
||||
</ul> |
||||
</div> |
||||
|
||||
<el-table :data="list" v-loading="listLoading" class="table" ref="table" stripe header-align="center" |
||||
@selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange"> |
||||
<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="name" label="试卷名称" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="name" label="试题总数" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="name" label="总分" align="center" width="90"></el-table-column> |
||||
<el-table-column prop="name" label="中分位数" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="name" label="题型" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="name" label="试卷难度" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="name" label="建议用时" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="knowledgePointsClassification" label="试卷分类" align="center" min-width="120" |
||||
show-overflow-tooltip></el-table-column> |
||||
<el-table-column prop="relatedQuestionsNum" label="所属专业" align="center" width="90"></el-table-column> |
||||
<el-table-column prop="relatedQuestionsNum" label="年份" align="center" width="90"></el-table-column> |
||||
<el-table-column prop="relatedQuestionsNum" label="建议用途" align="center" width="90"></el-table-column> |
||||
<el-table-column prop="relatedQuestionsNum" label="状态" align="center" width="90"></el-table-column> |
||||
<el-table-column prop="createTime" label="创建时间" align="center" width="160" |
||||
sortable="custom"></el-table-column> |
||||
<el-table-column prop="createTime" label="最近编辑时间" align="center" width="160" |
||||
sortable="custom"></el-table-column> |
||||
<el-table-column prop="createUserName" label="最近编辑人" align="center" width="100"></el-table-column> |
||||
<el-table-column label="操作" align="center" width="240"> |
||||
<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> |
||||
</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="提示" :visible.sync="delVisible" width="400px" :close-on-click-modal="false" custom-class="del-dia"> |
||||
<div class="del-wrap"> |
||||
<div class="icon el-icon-warning"></div> |
||||
<div> |
||||
<p>确认要删除【{{ curName }}】吗?</p> |
||||
<p class="tips">删除后,其子级分类也将被删除。</p> |
||||
<el-checkbox v-model="deleteQuestions">同时删除此分类及其子分类的试卷,删除后数据无法恢复,请谨慎操作!</el-checkbox> |
||||
</div> |
||||
</div> |
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="delVisible = false">取消</el-button> |
||||
<el-button type="primary" @click="delTypeSubmit">确定</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import Util from '@/libs/util' |
||||
import _ from 'lodash' |
||||
import Breadcrumb from '@/components/breadcrumb' |
||||
export default { |
||||
components: { Breadcrumb }, |
||||
data () { |
||||
return { |
||||
typeId: this.$route.query.id, |
||||
createSource: 1, |
||||
loading: false, |
||||
keyword: '', |
||||
types: [], |
||||
isNotJoin: 1, |
||||
typeVisible: false, // 员工组织架对话框 |
||||
typeForm: { |
||||
classificationId: '', |
||||
classificationName: '' |
||||
}, |
||||
cascaderValue: [], |
||||
cascaderProps: { |
||||
checkStrictly: true, |
||||
label: "classificationName", |
||||
value: "classificationId" |
||||
}, |
||||
|
||||
status: [], |
||||
form: { |
||||
name: '', |
||||
parentId: [] |
||||
}, |
||||
typeRules: { |
||||
classificationName: [ |
||||
{ required: true, message: '请输入试卷分类名称', trigger: 'blur' } |
||||
] |
||||
}, |
||||
rules: { |
||||
name: [ |
||||
{ required: true, message: '请输入试卷名称', trigger: 'blur' } |
||||
], |
||||
}, |
||||
filter: { |
||||
difficultOrder: '', |
||||
yearOrder: '', |
||||
updateTimeOrder: '', |
||||
crateTimeOrder: '', |
||||
keyWord: '', |
||||
difficult: '', |
||||
particularYear: '', |
||||
keyWord: '', |
||||
}, |
||||
listLoading: false, |
||||
list: [], |
||||
page: 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
multipleSelection: [], |
||||
|
||||
submiting: false, // 新增编辑防抖标识 |
||||
|
||||
|
||||
delVisible: false, |
||||
deleteQuestions: false, |
||||
curName: '', |
||||
curId: [], |
||||
}; |
||||
}, |
||||
watch: { |
||||
keyword: function () { |
||||
clearTimeout(this.searchTimer) |
||||
this.searchTimer = setTimeout(this.getType, 500) |
||||
}, |
||||
'filter.keyWord': function () { |
||||
clearTimeout(this.searchTimer) |
||||
this.searchTimer = setTimeout(this.getList, 500) |
||||
}, |
||||
}, |
||||
mounted () { |
||||
this.crumbs = [ |
||||
{ |
||||
name: this.$route.query.name || '中台试卷库', |
||||
route: '/testPaperLibrary' |
||||
}, |
||||
{ |
||||
name: '试卷管理' |
||||
}, |
||||
], |
||||
this.getType() |
||||
}, |
||||
methods: { |
||||
// 获取分类 |
||||
async getType () { |
||||
try { |
||||
this.loading = true |
||||
const res = await this.$post(this.api.examClassificationList, { |
||||
createSource: this.createSource, |
||||
libraryId: this.typeId, |
||||
}) |
||||
const data = res.treeList |
||||
this.handleType(data) |
||||
this.types = data |
||||
this.getList() |
||||
} finally { |
||||
this.loading = false |
||||
} |
||||
}, |
||||
// 分类筛选回调 |
||||
changeType () { |
||||
this.$refs.typeTree.setCurrentKey(null) |
||||
this.initData() |
||||
}, |
||||
// 获取分类详情 |
||||
async getDetail (id) { |
||||
const res = await this.$get(this.api.examClassificationFind, { |
||||
id |
||||
}) |
||||
return res.examClassification |
||||
}, |
||||
// 添加分类 |
||||
async addType (row) { |
||||
this.typeForm = { |
||||
classificationId: '', |
||||
classificationName: '', |
||||
} |
||||
this.typeVisible = true |
||||
if (row) { |
||||
const data = await this.getDetail(row.classificationId) |
||||
const path = data.classificationPath.split('/').map(e => +e) |
||||
this.cascaderValue = data.classificationPath.split('/').map(e => +e) |
||||
} |
||||
}, |
||||
// 编辑分类 |
||||
async editType (row) { |
||||
this.typeForm = { |
||||
classificationId: row.classificationId, |
||||
classificationName: row.classificationName |
||||
} |
||||
this.typeVisible = true |
||||
const data = await this.getDetail(row.classificationId) |
||||
const path = data.classificationPath.split('/').map(e => +e) |
||||
this.cascaderValue = path.slice(0, path.length - 1) |
||||
}, |
||||
// 处理树形 |
||||
handleType (list) { |
||||
list.map(e => { |
||||
if (e.children && e.children.length) { |
||||
this.handleType(e.children) |
||||
} else { |
||||
delete e.children |
||||
} |
||||
}) |
||||
}, |
||||
// 删除分类 |
||||
delType (node, row) { |
||||
this.curName = row.classificationName |
||||
this.curId = [row.classificationId] |
||||
this.delVisible = true |
||||
}, |
||||
// 删除分类提交 |
||||
async delTypeSubmit () { |
||||
await this.$post(this.api.examClassificationDel, { |
||||
delete: this.deleteQuestions, |
||||
ids: this.curId |
||||
}) |
||||
Util.successMsg('删除成功') |
||||
this.delVisible = false |
||||
this.getType() |
||||
}, |
||||
// 分类新增/编辑 |
||||
typeSubmit () { |
||||
this.$refs.typeForm.validate(async (valid) => { |
||||
if (valid) { |
||||
const form = this.typeForm |
||||
const cas = this.cascaderValue |
||||
const len = cas.length |
||||
if (cas && len) { |
||||
form.parentId = cas[len - 1] |
||||
form.level = len + 1 |
||||
} else { |
||||
form.parentId = 0 |
||||
form.level = 1 |
||||
} |
||||
form.createSource = this.createSource |
||||
form.libraryId = this.typeId |
||||
await this.$post(this.api[form.classificationId ? 'examClassificationUpdate' : 'examClassificationSave'], form) |
||||
Util.successMsg('保存成功') |
||||
this.closeType() |
||||
} |
||||
}); |
||||
}, |
||||
// 点击树节点查询列表数据 |
||||
handleNodeClick (data) { |
||||
this.$refs.table.clearSelection() |
||||
this.isNotJoin = '' |
||||
this.getList() |
||||
}, |
||||
// 关闭组织新增编辑弹框 |
||||
closeType () { |
||||
this.typeVisible = false |
||||
this.cascaderValue = [] |
||||
this.getType() |
||||
}, |
||||
// 列表 |
||||
async getList () { |
||||
try { |
||||
this.listLoading = true |
||||
const res = await this.$post(this.api.examPaperList, { |
||||
...this.filter, |
||||
type: this.isNotJoin, |
||||
pageNum: this.page, |
||||
pageSize: this.pageSize, |
||||
classificationId: this.$refs.typeTree.getCurrentKey() || '', |
||||
}) |
||||
this.list = res.pageList.records |
||||
this.total = res.pageList.total |
||||
} finally { |
||||
this.listLoading = false |
||||
} |
||||
}, |
||||
// 切换页码 |
||||
currentChange (val) { |
||||
this.page = val |
||||
this.getList() |
||||
}, |
||||
handleSelectionChange (val) { // 多选 |
||||
this.multipleSelection = val |
||||
}, |
||||
initData () { |
||||
this.$refs.table.clearSelection() |
||||
this.page = 1 |
||||
this.getList() |
||||
}, |
||||
// 排序回调 |
||||
sortChange (column) { |
||||
if (column.prop === 'createTime') this.filter.timeOrderBy = column.order ? column.order === 'ascending' ? 'asc' : 'desc' : '' |
||||
this.getList() |
||||
}, |
||||
// 删除 |
||||
async del (row) { |
||||
try { |
||||
await this.$confirm(`<p>确认要删除【${row.name}】吗?</p><p style="color: #f56c6c;">删除后,关联此试卷的试题将自动移除此试卷!</p>`, '提示', { |
||||
confirmButtonText: '确定', |
||||
cancelButtonText: '取消', |
||||
type: 'warning', |
||||
closeOnClickModal: false, |
||||
dangerouslyUseHTMLString: true, |
||||
}) |
||||
await this.$post(this.api.knowledgeHierarchyDel, [row.id]) |
||||
Util.successMsg('删除成功') |
||||
this.getList() |
||||
} catch (e) { } |
||||
}, |
||||
// 添加试卷 |
||||
add () { |
||||
this.$router.push(`detail?libraryId=${this.typeId}`) |
||||
}, |
||||
// 编辑试卷 |
||||
async edit (row) { |
||||
const { data } = await this.$post(`${this.api.knowledgeHierarchyFind}?id=${row.id}`) |
||||
this.knowledgeVisible = true |
||||
const path = data.path.split('/').map(e => +e) |
||||
this.form = { |
||||
id: row.id, |
||||
name: row.name, |
||||
parentId: path.slice(0, path.length - 1), |
||||
} |
||||
console.log(11, this.form) |
||||
}, |
||||
async delAllSelection () { |
||||
const list = this.multipleSelection |
||||
if (list.length) { |
||||
try { |
||||
await this.$confirm(`<p style="margin-bottom: 10px;">确认要删除已选定的${list.length}个试卷吗?</p><p style="color: #f56c6c;">删除后,关联这些试卷的试题将自动移除这些试卷!</p>`, '提示', { |
||||
confirmButtonText: '确定', |
||||
cancelButtonText: '取消', |
||||
type: 'warning', |
||||
closeOnClickModal: false, |
||||
dangerouslyUseHTMLString: true, |
||||
}) |
||||
await this.$post(this.api.knowledgeHierarchyDel, list.map(e => e.id)) |
||||
Util.successMsg('删除成功') |
||||
this.multipleSelection = [] |
||||
this.$refs.table.clearSelection() |
||||
this.getList() |
||||
} catch (e) { } |
||||
} else { |
||||
Util.warningMsg('请选择数据') |
||||
} |
||||
}, |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.org-name { |
||||
margin-right: 20px; |
||||
} |
||||
|
||||
.page { |
||||
display: flex; |
||||
min-height: 100%; |
||||
margin-top: 20px; |
||||
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; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,363 @@ |
||||
<template> |
||||
<div class="page"> |
||||
<div class="side"> |
||||
<div class="m-b-20"> |
||||
<h6 class="page-name">试卷库分类</h6> |
||||
<el-radio-group v-model="isNotJoin" @change="typeChange"> |
||||
<div class="m-b-10"> |
||||
<el-radio :label="1">所有试卷库</el-radio> |
||||
</div> |
||||
<div> |
||||
<el-radio :label="2">未加入分类的试卷库</el-radio> |
||||
</div> |
||||
</el-radio-group> |
||||
</div> |
||||
<el-divider></el-divider> |
||||
<div> |
||||
<el-input class="m-b-10" placeholder="请输入试卷库分类" prefix-icon="el-icon-search" size="small" clearable |
||||
v-model="keyword"></el-input> |
||||
<div style="height: 504px; max-height: 504px; overflow: auto"> |
||||
<el-tree :data="types" default-expand-all ref="typeTree" node-key="libraryClassificationId" highlight-current |
||||
:expand-on-click-node="false" @node-click="handleNodeClick" |
||||
:props="{ id: 'libraryClassificationId', label: 'libraryClassificationName', isLeaf: 'leaf' }"></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.isDisable" clearable placeholder="请选择状态" @change="getList"> |
||||
<el-option v-for="(item, i) in isDisable" :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></el-input> |
||||
</li> |
||||
</ul> |
||||
<div> |
||||
<el-button type="primary" @click="add">创建试卷库</el-button> |
||||
</div> |
||||
</div> |
||||
|
||||
<el-table :data="list" class="table" ref="table" stripe header-align="center" |
||||
@selection-change="handleSelectionChange" row-key="libraryId" @sort-change="sortChange"> |
||||
<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="libraryName" label="试卷库名称" align="center" min-width="120"></el-table-column> |
||||
<el-table-column prop="remarks" label="描述" align="center" min-width="120" |
||||
show-overflow-tooltip></el-table-column> |
||||
<el-table-column prop="libraryClassificationName" label="试卷库分类" align="center" |
||||
min-width="120"></el-table-column> |
||||
<el-table-column prop="examPaperNum" label="试卷数量" align="center" width="100" |
||||
sortable="custom"></el-table-column> |
||||
<el-table-column prop="createTime" label="创建时间" align="center" width="160" sortable="custom"></el-table-column> |
||||
<el-table-column prop="createUserName" label="创建人" align="center" width="100"></el-table-column> |
||||
<el-table-column label="操作" align="center" width="280"> |
||||
<template slot-scope="scope"> |
||||
<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, 1)">复制</el-button> |
||||
<el-button type="text" @click="del(scope.row)">删除</el-button> |
||||
<el-switch v-model="scope.row.isDisable" :active-value="false" :inactive-value="true" |
||||
style="margin: 0 10px 0 5px" :active-text="scope.row.isDisable ? '关' : '开'" |
||||
@change="switchOff($event, scope.row)"></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> |
||||
|
||||
<el-dialog :title="isCopy ? '复制试卷库' : !form.libraryId ? '创建试卷库' : '编辑试卷库'" :visible.sync="quesBankVisible" |
||||
width="400px" :close-on-click-modal="false"> |
||||
<p v-if="isCopy" style="margin: -10px 0 20px;font-size: 12px;color: #f00;">您将复制当前试卷库中的所有题目到新试卷库,请输入新试卷库名称</p> |
||||
<el-form :model="form" :rules="rules" label-width="100px"> |
||||
<el-form-item prop="userName" label="分类"> |
||||
<el-cascader placeholder="请选择试卷库分类" v-model="libraryClassificationId" :options="enableTypes" |
||||
:props="{ value: 'libraryClassificationId', label: 'libraryClassificationName', checkStrictly: true }" |
||||
clearable></el-cascader> |
||||
</el-form-item> |
||||
<el-form-item prop="libraryName" label="试卷库名称"> |
||||
<el-input placeholder="请输入试卷库名称" v-model="form.libraryName"></el-input> |
||||
</el-form-item> |
||||
<el-form-item prop="remarks" label="试卷库描述"> |
||||
<el-input placeholder="请输入试卷库描述" type="textarea" :rows="3" v-model="form.remarks"></el-input> |
||||
</el-form-item> |
||||
</el-form> |
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="quesBankVisible = false">取 消</el-button> |
||||
<el-button type="primary" @click="quesBankSubmit">确 定</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import Util from "@/libs/util"; |
||||
import Setting from "@/setting"; |
||||
import _ from 'lodash' |
||||
export default { |
||||
data () { |
||||
return { |
||||
loading: false, |
||||
keyword: '', |
||||
isNotJoin: 1, |
||||
types: [], |
||||
isDisable: [ |
||||
{ |
||||
id: 0, |
||||
name: '启用' |
||||
}, |
||||
{ |
||||
id: 1, |
||||
name: '禁用' |
||||
}, |
||||
], |
||||
filter: { |
||||
numOrder: '', |
||||
timeOrder: '', |
||||
isDisable: '', |
||||
keyWord: '', |
||||
}, |
||||
list: [], |
||||
page: 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
multipleSelection: [], |
||||
|
||||
form: { |
||||
remarks: '', |
||||
libraryName: '', |
||||
}, |
||||
libraryClassificationId: [], |
||||
rules: { |
||||
libraryName: [ |
||||
{ required: true, message: '请输入试卷库名称', trigger: 'blur' } |
||||
] |
||||
}, |
||||
enableTypes: [], |
||||
quesBankVisible: false, |
||||
submiting: false, |
||||
isCopy: 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) |
||||
} |
||||
}, |
||||
mounted () { |
||||
this.getType() |
||||
}, |
||||
methods: { |
||||
// 获取试卷库分类 |
||||
async getType () { |
||||
try { |
||||
this.loading = true |
||||
const res = await this.$post(this.api.libraryClassificationList, { |
||||
keyword: this.keyword, |
||||
createSource: 1, |
||||
}) |
||||
const data = res.treeList |
||||
this.handleList(data) |
||||
this.types = data |
||||
this.getList() |
||||
} finally { |
||||
this.loading = false |
||||
} |
||||
}, |
||||
// 处理树形 |
||||
handleList (list) { |
||||
list.map(e => { |
||||
if (e.children && e.children.length) { |
||||
this.handleList(e.children) |
||||
} else { |
||||
delete e.children |
||||
} |
||||
}) |
||||
}, |
||||
|
||||
// 类型回调 |
||||
typeChange () { |
||||
this.$refs.typeTree.setCurrentKey(null) |
||||
this.initData() |
||||
}, |
||||
// 点击树节点查询列表数据 |
||||
handleNodeClick (data) { |
||||
this.isNotJoin = '' |
||||
this.initData() |
||||
this.$refs.table.clearSelection() |
||||
}, |
||||
// 试卷库列表 |
||||
async getList () { |
||||
const res = await this.$post(this.api.libraryList, { |
||||
...this.filter, |
||||
type: this.isNotJoin, |
||||
pageNum: this.page, |
||||
pageSize: this.pageSize, |
||||
libraryClassificationId: this.$refs.typeTree.getCurrentKey() || '', |
||||
}) |
||||
this.list = res.pageList.records |
||||
this.total = res.pageList.total |
||||
}, |
||||
// 切换页码 |
||||
currentChange (val) { |
||||
this.page = val |
||||
this.getList() |
||||
}, |
||||
// 多选 |
||||
handleSelectionChange (val) { |
||||
this.multipleSelection = val |
||||
}, |
||||
initData () { |
||||
this.$refs.table.clearSelection() |
||||
this.page = 1 |
||||
this.getList() |
||||
}, |
||||
// 排序回调 |
||||
sortChange (column) { |
||||
// 1上2下 |
||||
if (column.prop === 'examPaperNum') this.filter.numOrder = column.order ? column.order === 'ascending' ? 1 : 2 : '' |
||||
if (column.prop === 'createTime') this.filter.timeOrder = column.order ? column.order === 'ascending' ? 1 : 2 : '' |
||||
this.getList() |
||||
}, |
||||
// 删除 |
||||
async del (row) { |
||||
try { |
||||
await this.$confirm(`<p>确认要删除【${row.libraryName}】吗?</p><p style="color: #f56c6c;">删除后,试卷库中的试卷将会被删除,请谨慎操作!</p>`, '提示', { |
||||
confirmButtonText: '确定', |
||||
cancelButtonText: '取消', |
||||
type: 'warning', |
||||
closeOnClickModal: false, |
||||
dangerouslyUseHTMLString: true, |
||||
}) |
||||
await this.$post(this.api.paperLibraryDel, { |
||||
ids: [row.libraryId] |
||||
}) |
||||
Util.successMsg('删除成功') |
||||
this.getList() |
||||
} catch (e) { } |
||||
}, |
||||
async switchOff (val, row) { |
||||
await this.$post(this.api.paperLibraryDisable, { |
||||
id: row.libraryId, |
||||
isDisable: val |
||||
}) |
||||
Util.successMsg(val ? '禁用成功' : '启用成功') |
||||
this.getList() |
||||
}, |
||||
// 获取分类详情 |
||||
async getDetail (id) { |
||||
const res = await this.$get(this.api.libraryClassificationFind, { |
||||
id |
||||
}) |
||||
return res.libraryClassification |
||||
}, |
||||
// 添加 |
||||
async add () { |
||||
this.getEnableType() |
||||
this.isCopy = false |
||||
const type = this.$refs.typeTree.getCurrentNode() |
||||
this.form = { |
||||
remarks: '', |
||||
libraryName: '', |
||||
} |
||||
if (type) { |
||||
const data = await this.getDetail(type.libraryClassificationId) |
||||
this.libraryClassificationId = data.classificationPath.split('/').map(e => +e) |
||||
} else { |
||||
this.libraryClassificationId = [] |
||||
} |
||||
this.quesBankVisible = true |
||||
}, |
||||
// 试卷管理 |
||||
toTestPaper (row) { |
||||
this.$router.push(`/testPaper?id=${row.libraryId}&name=${row.libraryName}`) |
||||
}, |
||||
// 编辑/复制 |
||||
async edit (row, isCopy) { |
||||
this.getEnableType() |
||||
this.isCopy = isCopy |
||||
this.quesBankVisible = true |
||||
this.form = { |
||||
libraryId: row.libraryId, |
||||
libraryName: row.libraryName, |
||||
remarks: row.remarks, |
||||
} |
||||
let type = row.libraryClassificationId |
||||
if (type) { |
||||
type = type.split('/') |
||||
const data = await this.getDetail(type[type.length - 1]) |
||||
this.libraryClassificationId = data.classificationPath.split('/').map(e => +e) |
||||
} else { |
||||
this.libraryClassificationId = [] |
||||
} |
||||
}, |
||||
// 获取启用的试卷库分类 |
||||
async getEnableType () { |
||||
if (!this.enableTypes.length) { |
||||
try { |
||||
const res = await this.$post(this.api.libraryClassificationList, { |
||||
createSource: 1, |
||||
isDisable: false, |
||||
}) |
||||
const data = res.treeList |
||||
this.handleList(data) |
||||
this.enableTypes = data |
||||
} catch (e) { } |
||||
} |
||||
}, |
||||
// 试卷库提交 |
||||
async quesBankSubmit () { |
||||
if (this.submiting) return false |
||||
const form = _.cloneDeep(this.form) |
||||
if (!form.libraryName) return Util.warningMsg('请输入试卷库名称') |
||||
this.submiting = true |
||||
if (this.libraryClassificationId.length) form.libraryClassificationId = this.libraryClassificationId[this.libraryClassificationId.length - 1] |
||||
// form.systemId = this.systemId |
||||
form.createSource = 1 |
||||
try { |
||||
await this.$post(this.api[this.isCopy ? 'copyQuestionBank' : form.libraryId ? 'paperLibraryUpdate' : 'paperLibrarySave'], form) |
||||
Util.successMsg(this.isCopy ? '复制成功' : '保存成功') |
||||
this.quesBankVisible = false |
||||
this.submiting = false |
||||
this.getList() |
||||
} catch (e) { |
||||
this.submiting = 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; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,292 @@ |
||||
<template> |
||||
<div class="page"> |
||||
<div class="tool"> |
||||
<ul class="filter"> |
||||
<li> |
||||
<label>状态</label> |
||||
<el-select v-model="filter.isDisable" clearable placeholder="请选择状态" @change="getData"> |
||||
<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.libraryClassificationName" clearable></el-input> |
||||
</li> |
||||
</ul> |
||||
<div> |
||||
<el-button type="primary" @click="add(0)">新增</el-button> |
||||
<el-button type="primary" @click="delAllSelection">批量删除</el-button> |
||||
</div> |
||||
</div> |
||||
<el-table v-loading="loading" :data="list" class="table" ref="table" stripe header-align="center" |
||||
row-key="libraryClassificationId" default-expand-all |
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }" @selection-change="handleSelectionChange"> |
||||
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> |
||||
<el-table-column prop="libraryClassificationName" label="试卷库分类名称"></el-table-column> |
||||
<el-table-column prop="relatedLibraryNum" label="已关联试卷库" align="center"></el-table-column> |
||||
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column> |
||||
<el-table-column prop="createUser" label="创建人" align="center"></el-table-column> |
||||
<el-table-column label="操作" align="center" width="300"> |
||||
<template slot-scope="scope"> |
||||
<el-button type="text" @click="add(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-switch v-model="scope.row.isDisable" :active-value="false" :inactive-value="true" |
||||
style="margin: 0 10px 0 5px" :active-text="scope.row.isDisable ? '关' : '开'" |
||||
@change="switchOff($event, scope.row)"></el-switch> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
|
||||
|
||||
<el-dialog :title="(!form.libraryClassificationId ? '新增' : '编辑') + '试卷库分类'" :visible.sync="typeVisible" |
||||
width="400px" :close-on-click-modal="false"> |
||||
<el-form :model="form" :rules="rules" label-width="130px"> |
||||
<el-form-item prop="libraryClassificationName" label="试卷库分类名称"> |
||||
<el-input placeholder="请输入分类名称" v-model="form.libraryClassificationName" maxlength="20"></el-input> |
||||
</el-form-item> |
||||
<el-form-item label="设置上一级"> |
||||
<el-cascader v-model="parentId" :options="list" |
||||
:props="{ value: 'libraryClassificationId', label: 'libraryClassificationName', checkStrictly: true }" |
||||
clearable></el-cascader> |
||||
</el-form-item> |
||||
</el-form> |
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="typeVisible = false">取消</el-button> |
||||
<el-button type="primary" v-loading="submiting" @click="typeSubmit">确定</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
|
||||
|
||||
<el-dialog title="提示" :visible.sync="delVisible" width="400px" :close-on-click-modal="false" custom-class="del-dia"> |
||||
<div class="del-wrap"> |
||||
<div class="icon el-icon-warning"></div> |
||||
<div> |
||||
<p>确认要删除【{{ curName }}】吗?</p> |
||||
<p class="tips">删除后,此试卷库分类及其子分类将被删除,已关联的试卷库将无分类</p> |
||||
<el-checkbox v-model="deleteQuestions">同时删除此试卷库分类及其子分类的试卷库,删除后数据无法恢复,请谨慎操作!</el-checkbox> |
||||
</div> |
||||
</div> |
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="delVisible = false">取消</el-button> |
||||
<el-button type="primary" @click="delSubmit">确定</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import Util from '@/libs/util' |
||||
export default { |
||||
data () { |
||||
return { |
||||
systemId: '', |
||||
status: [ |
||||
{ |
||||
id: 0, |
||||
name: '启用' |
||||
}, |
||||
{ |
||||
id: 1, |
||||
name: '禁用' |
||||
}, |
||||
], |
||||
filter: { |
||||
isDisable: '', |
||||
libraryClassificationName: '', |
||||
}, |
||||
list: [], |
||||
multipleSelection: [], |
||||
parentId: [], |
||||
form: { |
||||
libraryClassificationName: '', |
||||
}, |
||||
rules: { |
||||
libraryClassificationName: [ |
||||
{ required: true, message: '请输入试卷库分类名称', trigger: 'blur' } |
||||
] |
||||
}, |
||||
typeVisible: false, |
||||
loading: false, |
||||
searchTimer: null, |
||||
|
||||
delVisible: false, |
||||
deleteQuestions: false, |
||||
curName: '', |
||||
curId: [], |
||||
submiting: false, |
||||
}; |
||||
}, |
||||
watch: { |
||||
'filter.libraryClassificationName': function (val) { |
||||
clearTimeout(this.searchTimer); |
||||
this.searchTimer = setTimeout(() => { |
||||
this.getData() |
||||
}, 500) |
||||
} |
||||
}, |
||||
mounted () { |
||||
this.getData() |
||||
}, |
||||
methods: { |
||||
async getData () { |
||||
try { |
||||
this.loading = true |
||||
const res = await this.$post(this.api.libraryClassificationList, { |
||||
...this.filter |
||||
}) |
||||
const data = res.treeList |
||||
this.handleList(data) |
||||
this.list = data |
||||
} finally { |
||||
this.loading = false |
||||
} |
||||
}, |
||||
// 处理树形 |
||||
handleList (list) { |
||||
list.map(e => { |
||||
if (e.children && e.children.length) { |
||||
this.handleList(e.children) |
||||
} else { |
||||
delete e.children |
||||
} |
||||
}) |
||||
}, |
||||
handleSelectionChange (val) { |
||||
this.multipleSelection = val |
||||
}, |
||||
// 获取分类详情 |
||||
async getDetail (id) { |
||||
const res = await this.$get(this.api.libraryClassificationFind, { |
||||
id |
||||
}) |
||||
return res.libraryClassification |
||||
}, |
||||
// 新建 |
||||
async add (row) { |
||||
this.form = { |
||||
libraryClassificationName: '', |
||||
parentId: 0, |
||||
} |
||||
this.typeVisible = true |
||||
|
||||
if (row) { |
||||
const data = await this.getDetail(row.libraryClassificationId) |
||||
const path = data.classificationPath |
||||
this.parentId = path.split('/').map(e => +e).slice(0, path.length - 1) |
||||
} else { |
||||
this.parentId = [] |
||||
} |
||||
}, |
||||
// 编辑 |
||||
async edit (row) { |
||||
this.typeVisible = true |
||||
const data = await this.getDetail(row.libraryClassificationId) |
||||
this.form = { |
||||
libraryClassificationId: data.libraryClassificationId, |
||||
libraryClassificationName: data.libraryClassificationName, |
||||
} |
||||
const path = data.classificationPath.split('/').map(e => +e) |
||||
this.parentId = path.slice(0, path.length - 1) |
||||
}, |
||||
// 分类提交 |
||||
async typeSubmit () { |
||||
if (this.submiting) return false |
||||
const { form, parentId } = this |
||||
if (!form.libraryClassificationName) return Util.warningMsg('请输入试卷库分类名称') |
||||
this.submiting = true |
||||
if (parentId.length) form.parentId = parentId[parentId.length - 1] |
||||
// form.systemId = this.systemId |
||||
form.createSource = 1 |
||||
await this.$post(this.api[form.libraryClassificationId ? 'libraryClassificationUpdate' : 'libraryClassificationSave'], form) |
||||
Util.successMsg('保存成功') |
||||
this.typeVisible = false |
||||
this.submiting = false |
||||
this.getData() |
||||
}, |
||||
// 删除 |
||||
del (row) { |
||||
this.curName = row.name |
||||
this.curId = [row.libraryClassificationId] |
||||
this.delVisible = true |
||||
}, |
||||
// 删除提交 |
||||
async delSubmit () { |
||||
await this.$post(this.api.libraryClassificationDel, { |
||||
ids: this.curId, |
||||
delete: this.deleteQuestions |
||||
}) |
||||
Util.successMsg('删除成功') |
||||
this.multipleSelection = [] |
||||
this.$refs.table.clearSelection() |
||||
this.delVisible = false |
||||
this.getData() |
||||
}, |
||||
// 批量删除 |
||||
delAllSelection () { |
||||
const list = this.multipleSelection |
||||
if (list.length) { |
||||
this.curName = list.map(e => e.libraryClassificationName).join() |
||||
this.curId = list.map(e => e.libraryClassificationId) |
||||
this.delVisible = true |
||||
} else { |
||||
Util.warningMsg('请选择数据') |
||||
} |
||||
}, |
||||
// 禁启用 |
||||
async switchOff (val, row) { |
||||
try { |
||||
row.isDisable = !val |
||||
if (val) { |
||||
await this.$confirm(`<p>确认要禁用【${row.libraryClassificationName}】吗?</p><p style="color: #f56c6c;">禁用后,此试卷库分类及其子分类将被禁用</p>`, '提示', { |
||||
confirmButtonText: '确定', |
||||
cancelButtonText: '取消', |
||||
type: 'warning', |
||||
closeOnClickModal: false, |
||||
dangerouslyUseHTMLString: true, |
||||
}) |
||||
} |
||||
const res = await this.$post(this.api.libraryClassificationDisable, { |
||||
id: row.libraryClassificationId, |
||||
isDisable: val |
||||
}) |
||||
if (res.status === 200) { |
||||
Util.successMsg(val ? '禁用成功' : '启用成功') |
||||
this.getData() |
||||
} |
||||
} catch (e) { |
||||
row.isDisable = !val |
||||
} |
||||
}, |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
/deep/.del-dia { |
||||
.el-dialog__body { |
||||
padding: 10px 30px; |
||||
} |
||||
|
||||
.del-wrap { |
||||
display: flex; |
||||
} |
||||
|
||||
.icon { |
||||
margin-right: 15px; |
||||
font-size: 24px; |
||||
color: #E6A23C; |
||||
} |
||||
|
||||
.tips { |
||||
margin: 5px 0 10px; |
||||
} |
||||
|
||||
.el-checkbox__label { |
||||
white-space: normal; |
||||
vertical-align: top; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,16 @@ |
||||
import BasicLayout from '@/layouts/home' |
||||
|
||||
const meta = {} |
||||
|
||||
export default { |
||||
path: '/knowledge', |
||||
meta, |
||||
component: BasicLayout, |
||||
children: [ |
||||
{ |
||||
path: '/knowledge', |
||||
component: () => import('@/pages/knowledge/index.vue'), |
||||
meta: { title: '知识点' } |
||||
}, |
||||
] |
||||
}; |
@ -0,0 +1,24 @@ |
||||
import BasicLayout from '@/layouts/home' |
||||
|
||||
const meta = {} |
||||
|
||||
export default { |
||||
path: '/testPaper', |
||||
redirect: { |
||||
path: `/testPaper/list` |
||||
}, |
||||
meta, |
||||
component: BasicLayout, |
||||
children: [ |
||||
{ |
||||
path: 'list', |
||||
component: () => import('@/pages/testPaper/list'), |
||||
meta: { title: '试卷管理' } |
||||
}, |
||||
{ |
||||
path: 'detail', |
||||
component: () => import('@/pages/testPaper/detail'), |
||||
meta: { title: '试卷管理' } |
||||
}, |
||||
] |
||||
}; |
@ -0,0 +1,16 @@ |
||||
import BasicLayout from '@/layouts/home' |
||||
|
||||
const meta = {} |
||||
|
||||
export default { |
||||
path: '/testPaperLibrary', |
||||
meta, |
||||
component: BasicLayout, |
||||
children: [ |
||||
{ |
||||
path: '/testPaperLibrary', |
||||
component: () => import('@/pages/testPaperLibrary'), |
||||
meta: { title: '试卷库分类' } |
||||
}, |
||||
] |
||||
}; |
@ -0,0 +1,16 @@ |
||||
import BasicLayout from '@/layouts/home' |
||||
|
||||
const meta = {} |
||||
|
||||
export default { |
||||
path: '/testPaperLibraryType', |
||||
meta, |
||||
component: BasicLayout, |
||||
children: [ |
||||
{ |
||||
path: '/testPaperLibraryType', |
||||
component: () => import('@/pages/testPaperLibraryType'), |
||||
meta: { title: '试卷库分类' } |
||||
}, |
||||
] |
||||
}; |
Loading…
Reference in new issue