题库分类及题库联调

master
yujialong 4 months ago
parent 3e9b0a4a52
commit 15897f24e5
  1. 6
      public/index.html
  2. 3
      public/static/ueditor/ueditor.config.js
  3. 13
      src/api/index.js
  4. 13
      src/components/ueditor/index.vue
  5. 2
      src/layouts/home/index.vue
  6. 13
      src/pages/ques/index.vue
  7. 357
      src/pages/quesBank/index.vue
  8. 110
      src/pages/quesBankType/index.vue
  9. 104
      src/plugins/requests/index.js
  10. 2
      src/setting.js

@ -16,8 +16,8 @@
<script src='./static/ueditor/ueditor.config.js?v=3'></script>
<script src='./static/ueditor/ueditor.all.js?v=3'></script>
<script src='./static/ueditor/lang/zh-cn/zh-cn.js'></script>
<script src='./static/ueditor/kityformula-plugin/addKityFormulaDialog.js'></script>
<script src='./static/ueditor/kityformula-plugin/getKfContent.js'></script>
<script src='./static/ueditor/kityformula-plugin/defaultFilterFix.js'></script>
<!-- <script src='./static/ueditor1/kityformula-plugin/addKityFormulaDialog.js'></script>
<script src='./static/ueditor1/kityformula-plugin/getKfContent.js'></script>
<script src='./static/ueditor1/kityformula-plugin/defaultFilterFix.js'></script> -->
</body>
</html>

@ -1,6 +1,6 @@
!function () {
window.UEDITOR_HOME_URL = "./static/ueditor/"; var s = window.UEDITOR_HOME_URL || l(); function l (s, l) { return function (s, l) { var t = l; /^(\/|\\\\)/.test(l) ? t = /^.+?\w(\/|\\\\)/.exec(s)[0] + l.replace(/^(\/|\\\\)/, "") : /^[a-z]+:/i.test(l) || (s = s.split("#")[0].split("?")[0].replace(/[^\\\/]+$/, ""), t = s + "" + l); return function (s) { var l = /^[a-z]+:\/\//.exec(s)[0], t = null, e = []; (s = (s = s.replace(l, "").split("?")[0].split("#")[0]).replace(/\\/g, "/").split(/\//))[s.length - 1] = ""; for (; s.length;)".." === (t = s.shift()) ? e.pop() : "." !== t && e.push(t); return l + e.join("/") }(t) }(s || self.document.URL || self.location.href, l || (t = document.getElementsByTagName("script"))[t.length - 1].src); var t } window.UEDITOR_CONFIG = {
UEDITOR_HOME_URL: s, serverUrl: "http://192.168.31.51:9000/exam/upload/configAndUpload", toolbars: [[
UEDITOR_HOME_URL: s, serverHeaders: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS' }, serverUrl: "http://192.168.31.51:9000/exam/exam/upload/configAndUpload", toolbars: [[
"fullscreen",
"source",
"|",
@ -57,7 +57,6 @@
"imageright",
"imagecenter",
"|",
"simpleupload",
"insertimage",
"emotion",
"scrawl",

@ -1,6 +1,17 @@
import Setting from '@/setting'
const { apiBaseURL: host } = Setting
// const host = 'http://192.168.31.217:9000/'
export default {
upload: `${host}/iasf/sysFiles/upload`,
categoriesDel: `/exam/question/bank/categories/batchDeletion`,
categoriesFind: `/exam/question/bank/categories/findById`,
getAllQuestionBankCategories: `/exam/question/bank/categories/getAllQuestionBankCategories`,
categoriesSave: `/exam/question/bank/categories/saveOrUpdate`,
categoriesDisable: `/exam/question/bank/categories/updateStatus`,
questionBankDel: `/exam/questionBank/batchDeletion`,
questionBankFind: `/exam/questionBank/findById`,
questionBankList: `/exam/questionBank/pagingQuery`,
questionBankSave: `/exam/questionBank/saveOrUpdate`,
questionBankDisable: `/exam/questionBank/updateStatus`,
}

@ -43,10 +43,23 @@ export default {
},
methods: {
initEditor () {
console.log(44, UE.Editor.prototype.getActionUrl)
this.$nextTick(() => {
// eslint-disable-next-line no-undef
this.instance = UE.getEditor(this.randomId)
this.instance.addListener('ready', () => {
// UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;
// UE.Editor.prototype.getActionUrl = function (action) {
// console.log("🚀 ~ initEditor ~ action:", action)
// if (action == 'uploadimage' || action == 'uploadscrawl' || action == 'uploadimage') {
// return 'http://192.168.31.51:9000/nakadai/nakadai/oss/fileUpload';
// } else {
// return this._bkGetActionUrl.call(this, action);
// }
// }
this.ready = true
this.$emit('ready', this.instance)
})

@ -31,7 +31,7 @@ export default {
},
mounted () {
const { token } = this.$route.query
Util.local.set(Setting.tokenKey, token, Setting.tokenExpires)
token && Util.local.set(Setting.tokenKey, token, Setting.tokenExpires)
},
};
</script>

@ -202,7 +202,7 @@
<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,
// competitionId: id,
platformId: 2
}" :disabled="uploading" :on-exceed="handleExceed" :action="this.api.batchImportPersonalData"
:file-list="uploadList" :headers="headers">
@ -232,6 +232,7 @@ export default {
components: { Ueditor },
data () {
return {
radio: '',
type: 1,
orgList: [],
status: [
@ -524,11 +525,11 @@ export default {
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)
// this.richEditor.instance = instance
// let currentContent = this.richEditor.object[this.richEditor.parameterName]
// this.richEditor.instance.setContent(currentContent)
// // Ueditor
// this.richEditor.instance.focus(true)
},
//
quesSubmit () {

@ -3,23 +3,24 @@
<div class="side">
<div class="m-b-20">
<h6 class="page-name">题库分类</h6>
<el-radio-group v-model="type" @change="typeChange">
<el-radio-group v-model="isNotJoin" @change="typeChange">
<div class="m-b-10">
<el-radio :label="1">所有题库</el-radio>
<el-radio :label="0">所有题库</el-radio>
</div>
<div>
<el-radio :label="2">未加入分类的题库</el-radio>
<el-radio :label="1">未加入分类的题库</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></el-input>
<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="orgList" default-expand-all ref="orgTree" node-key="id" highlight-current
<el-tree :data="types" default-expand-all ref="typeTree" node-key="id" highlight-current
:expand-on-click-node="false" @node-click="handleNodeClick"
:props="{ children: 'children', label: 'partnerClassificationName', isLeaf: 'leaf' }"></el-tree>
:props="{ children: 'children', label: 'name', isLeaf: 'leaf' }"></el-tree>
</div>
</div>
</div>
@ -36,7 +37,7 @@
</li>
<li>
<label>搜索</label>
<el-input style="width: 250px;" placeholder="请输入题库名称" prefix-icon="el-icon-search" v-model="filter.keyWord"
<el-input style="width: 250px;" placeholder="请输入题库名称" prefix-icon="el-icon-search" v-model="filter.name"
clearable></el-input>
</li>
</ul>
@ -46,23 +47,25 @@
</div>
<el-table :data="list" class="table" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange" row-key="id">
@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="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="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 label="操作" align="center" width="300">
<el-table-column prop="questionBankName" label="题库名称" align="center" min-width="120"></el-table-column>
<el-table-column prop="questionBankDescription" label="描述" align="center" min-width="120"
show-overflow-tooltip></el-table-column>
<el-table-column prop="questionBankCategory" label="题库分类" align="center" min-width="120"></el-table-column>
<el-table-column prop="questionsNum" 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="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="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.ztOpen" :active-value="0" :inactive-value="1" style="margin: 0 10px 0 5px"
:active-text="scope.row.ztOpen ? '关' : '开'"
<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>
@ -72,20 +75,19 @@
:total="total"></el-pagination>
</div>
<el-dialog :title="!form.id ? '创建题库' : '编辑题库'" :visible.sync="quesBankVisible" width="400px"
<el-dialog :title="isCopy ? '复制题库' : !form.id ? '创建题库' : '编辑题库'" :visible.sync="quesBankVisible" width="400px"
:close-on-click-modal="false">
<el-form label-width="80px">
<p v-if="isCopy" style="margin: -10px 0 20px;font-size: 12px;color: #f00;">您将复制当前题库中的所有题目到新题库请输入新题库名称</p>
<el-form :model="form" :rules="rules" label-width="80px">
<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-cascader placeholder="请选择题库分类" v-model="form.categoryIds" :options="enableTypes"
:props="{ value: 'id', label: 'name', checkStrictly: true }" clearable></el-cascader>
</el-form-item>
<el-form-item prop="userName" label="题库名称">
<el-input placeholder="请输入题库名称" v-model="form.name"></el-input>
<el-form-item prop="questionBankName" label="题库名称">
<el-input placeholder="请输入题库名称" v-model="form.questionBankName"></el-input>
</el-form-item>
<el-form-item prop="userName" label="题库描述">
<el-input placeholder="请输入题库描述" type="textarea" :rows="3" v-model="form.name"></el-input>
<el-form-item prop="questionBankDescription" label="题库描述">
<el-input placeholder="请输入题库描述" type="textarea" :rows="3" v-model="form.questionBankDescription"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
@ -103,21 +105,25 @@ import Setting from "@/setting";
export default {
data () {
return {
type: 1,
orgList: [],
loading: false,
keyword: '',
isNotJoin: 0,
types: [],
status: [
{
id: 1,
name: '启用'
},
{
id: 2,
id: 0,
name: '禁用'
},
],
filter: {
questionNumOrderBy: '',
timeOrderBy: '',
status: '',
keyWord: '',
name: '',
},
list: [],
page: 1,
@ -125,136 +131,96 @@ export default {
total: 0,
multipleSelection: [],
types: [],
form: {
userName: '',
provinceId: '',
cityId: '',
roleList: []
questionBankDescription: '',
questionBankName: '',
categoryIds: [],
},
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" }
],
questionBankName: [
{ required: true, message: '请输入题库名称', trigger: 'blur' }
]
},
enableTypes: [],
quesBankVisible: false,
submiting: false, //
setKey: '',
transferVisible: false,
chooseVisible: false,
members: [],
choosePartnerId: '',
curRow: '',
provinces: [],
cities: [],
editVisible: false
submiting: false,
isCopy: false,
};
},
watch: {
keyWord: function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(this.initData, 500);
keyword: function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(this.getType, 500)
},
'filter.name': function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(this.initData, 500)
}
},
mounted () {
this.getOrg()
this.getType()
},
methods: {
//
async getOrg () {
const res = await this.$post(this.api.listParner)
const list = res.treeList
// children
const handleLeaf = (list, ids) => {
list.map(e => {
e.ids = ids ? [...ids, e.id] : [e.id]
if (e.children.length) {
if (e.isTeam) {
delete e.children
} else {
handleLeaf(e.children, e.ids)
}
} else {
delete e.children
}
//
async getType () {
try {
this.loading = true
const { data } = await this.$post(this.api.getAllQuestionBankCategories, {
keyword: this.keyword,
createSource: 1,
})
this.handleList(data)
this.types = data
//
this.setKey && this.$nextTick(() => {
this.$refs.typeTree.setCurrentKey(this.setKey)
})
this.getList()
} finally {
this.loading = false
}
handleLeaf(list)
this.orgList = list
//
this.setKey && this.$nextTick(() => {
this.$refs.orgTree.setCurrentKey(this.setKey)
},
//
handleList (list) {
list.map(e => {
if (e.children && e.children.length) {
this.handleList(e.children)
} else {
delete e.children
}
})
this.getList()
},
//
typeChange () {
this.$refs.orgTree.setCurrentKey(null)
this.curTeamId = ''
this.$refs.typeTree.setCurrentKey(null)
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.isNotJoin = ''
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,
//
async getList () {
const res = await this.$post(this.api.questionBankList, {
...this.filter,
isNotJoin: this.isNotJoin || '',
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 => { })
pageSize: this.pageSize,
questionCategoryId: this.$refs.typeTree.getCurrentKey() || '',
})
this.list = res.message.records
this.total = res.message.total
},
//
currentChange (val) {
this.page = val
this.getList()
},
handleSelectionChange (val) { //
//
handleSelectionChange (val) {
this.multipleSelection = val
},
initData () {
@ -262,80 +228,93 @@ export default {
this.page = 1
this.getList()
},
//
sortChange (column) {
// 12
if (column.prop === 'questionNumOrderBy') this.filter.questionNumOrderBy = column.order ? column.order === 'ascending' ? 'asc' : 'desc' : ''
if (column.prop === 'createTime') this.filter.timeOrderBy = column.order ? column.order === 'ascending' ? 'asc' : 'desc' : ''
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 del (row) {
try {
await this.$confirm(`<p>确认要删除【${row.questionBankName}】吗?</p><p style="color: #f56c6c;">删除后,题库中的知识点框架与题目将会被删除,请谨慎操作!</p>`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
})
await this.$post(this.api.questionBankDel, [row.id])
Util.successMsg('删除成功')
this.getList()
} catch (e) { }
},
async switchOff (val, row) {
this.$post(this.api.disabledEventsCompetition, {
competitionId: row.id,
isOpen: val,
type: 0 // (01)
}).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))
},
//
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)
})
}
})
await this.$post(`${this.api.questionBankDisable}?id=${row.id}&status=${val}`)
Util.successMsg(val ? '启用成功' : '禁用成功')
this.getList()
},
//
add () {
this.getEnableType()
this.isCopy = false
const type = this.$refs.typeTree.getCurrentNode()
this.form = {
questionBankDescription: '',
questionBankName: '',
categoryIds: type ? type.path.split('/').map(e => +e) : [],
}
this.quesBankVisible = true
},
// /
async edit (row, isCopy) {
this.getEnableType()
this.isCopy = isCopy
const res = await this.$post(`${this.api.questionBankFind}?id=${row.id}`)
const type = res.message.questionBankCategoryRelations
this.quesBankVisible = true
this.form = {
id: row.id,
questionBankName: row.questionBankName,
questionBankDescription: row.questionBankDescription,
categoryIds: type && type.length ? type[0].path.split('/').map(e => +e) : [],
}
},
//
async getEnableType () {
if (!this.enableTypes.length) {
try {
const { data } = await this.$post(this.api.getAllQuestionBankCategories, {
createSource: 1,
status: 1,
})
this.handleList(data)
this.enableTypes = data
} catch (e) { }
}
},
//
quesBankSubmit () {
async quesBankSubmit () {
if (this.submiting) return false
const { form } = this
if (!form.categoryIds.length) return Util.warningMsg('请选择分类')
if (!form.questionBankName) return Util.warningMsg('请输入题库名称')
this.submiting = true
if (form.categoryIds.length) form.categoryIds = [form.categoryIds[form.categoryIds.length - 1]]
// form.systemId = this.systemId
form.createSource = 1
await this.$post(this.api.questionBankSave, form)
Util.successMsg('保存成功')
this.quesBankVisible = false
this.submiting = false
this.getList()
},
}
};
</script>
<style lang="scss" scoped>
.org-name {
margin-right: 20px;
}
.w-100 {
width: 100%;
}
.page {
display: flex;
padding: 0 24px;

@ -10,7 +10,7 @@
</li>
<li>
<label>搜索</label>
<el-input style="width: 250px;" placeholder="请输入题库分类名称" prefix-icon="el-icon-search" v-model="filter.keyWord"
<el-input style="width: 250px;" placeholder="请输入题库分类名称" prefix-icon="el-icon-search" v-model="filter.keyword"
clearable></el-input>
</li>
</ul>
@ -20,19 +20,21 @@
</div>
</div>
<el-table v-loading="loading" :data="list" class="table" ref="table" stripe header-align="center" row-key="id"
default-expand-all :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
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="name" label="题库分类名称" align="center"></el-table-column>
<el-table-column prop="name" label="题库分类名称"></el-table-column>
<el-table-column prop="orderNum" label="已关联题库" align="center"></el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
<el-table-column prop="orderVolume" label="创建人" align="center"></el-table-column>
<el-table-column prop="createUserName" 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.status" :active-value="0" :inactive-value="1" style="margin: 0 10px 0 5px"
:active-text="scope.row.ztOpen ? '关' : '开'" @change="switchOff($event, scope.row)"></el-switch>
<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)"></el-switch>
</template>
</el-table-column>
</el-table>
@ -40,18 +42,18 @@
<el-dialog :title="(!form.id ? '新增' : '编辑') + '题库分类'" :visible.sync="typeVisible" width="400px"
:close-on-click-modal="false">
<el-form label-width="110px">
<el-form-item prop="name" label="题库分类名称" required>
<el-form :model="form" :rules="rules" label-width="110px">
<el-form-item prop="name" label="题库分类名称">
<el-input placeholder="请输入分类名称" v-model="form.name" maxlength="20"></el-input>
</el-form-item>
<el-form-item prop="userName" label="设置上一级">
<el-form-item label="设置上一级">
<el-cascader v-model="parentId" :options="list" :props="{ value: 'id', label: 'name', 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" @click="typeSubmit">确定</el-button>
<el-button type="primary" v-loading="submiting" @click="typeSubmit">确定</el-button>
</span>
</el-dialog>
@ -62,7 +64,7 @@
<div>
<p>确认要删除{{ curName }}</p>
<p class="tips">删除后此题库分类及其子分类将被删除关联题库将无分类</p>
<el-checkbox v-model="delCheck">同时删除此分类及其子分类的题库删除后数据无法恢复请谨慎操作</el-checkbox>
<el-checkbox v-model="deleteQuestions">同时删除此分类及其子分类的题库删除后数据无法恢复请谨慎操作</el-checkbox>
</div>
</div>
<span slot="footer" class="dialog-footer">
@ -78,75 +80,113 @@ import Util from '@/libs/util'
export default {
data () {
return {
systemId: '',
status: [
{
id: 1,
name: '启用'
},
{
id: 2,
id: 0,
name: '禁用'
},
],
filter: {
createSource: 1,
status: '',
keyWord: '',
keyword: '',
},
list: [],
multipleSelection: [],
parentId: [],
form: {
name: '',
},
rules: {
name: [
{ required: true, message: '请输入题库分类名称', trigger: 'blur' }
]
},
typeVisible: false,
loading: false,
searchTimer: null,
delVisible: false,
delCheck: false,
deleteQuestions: false,
curName: '',
curId: [],
submiting: false,
};
},
watch: {
"form.curriculumName": function (val) {
'filter.keyword': function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.initData();
}, 500);
this.getData()
}, 500)
}
},
mounted () {
// this.getData()
this.getData()
},
methods: {
async getData () {
this.loading = true
const { data } = await this.$post(this.api.getAllCategories)
this.list = data
this.loading = false
try {
this.loading = true
const { data } = await this.$post(this.api.getAllQuestionBankCategories, {
...this.filter
})
this.handleList(data)
this.list = data
} finally {
this.loading = false
}
},
initData () {
this.page = 1
this.getData()
//
handleList (list) {
list.map(e => {
if (e.children && e.children.length) {
this.handleList(e.children)
} else {
delete e.children
}
})
},
handleSelectionChange (val) {
this.multipleSelection = val
},
//
add () {
add (row) {
this.form = {
name: '',
}
if (row) this.parentId = row.path.split('/').map(e => +e)
this.typeVisible = true
},
//
edit (row) {
this.$router.push(`/addcurriculum?cid=${row.cid}`);
async edit (row) {
const { data } = await this.$post(`${this.api.categoriesFind}?id=${row.id}`)
this.typeVisible = true
this.form = {
id: data.id,
name: data.name,
}
this.parentId = data.path.split('/').map(e => +e)
},
//
async typeSubmit () {
const { form } = this
if (this.submiting) return false
const { form, parentId } = this
if (!form.name) 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.categoriesSave, form)
Util.successMsg('保存成功')
this.typeVisible = false
this.submiting = false
this.getData()
},
//
del (row) {
@ -156,9 +196,12 @@ export default {
},
//
async delSubmit () {
await this.$post(this.api.categoriesDel, this.curId)
await this.$post(`${this.api.categoriesDel}?deleteQuestions=${this.deleteQuestions}`, this.curId)
Util.successMsg('删除成功')
this.multipleSelection = []
this.$refs.table.clearSelection()
this.delVisible = false
this.getData()
},
//
delAllSelection () {
@ -175,16 +218,19 @@ export default {
async switchOff (val, row) {
try {
if (!val) {
await this.$confirm(`<p>确认要禁用${row.name}吗?</p><p style="color: #f56c6c;">禁用后,此题库分类及其子分类将被禁用</p>`, '提示', {
row.status = 1
await this.$confirm(`<p>确认要禁用【${row.name}】吗?</p><p style="color: #f56c6c;">禁用后,此题库分类及其子分类将被禁用</p>`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
})
row.status = 0
}
await this.$post(`${this.api.categoriesDisable}?categoryId=${row.id}&status=${row.status}`)
Util.successMsg(val == 1 ? '禁用成功' : '启用成功')
Util.successMsg(val ? '启用成功' : '禁用成功')
this.getData()
} catch (e) { }
},
}

@ -1,21 +1,20 @@
import axios from 'axios'
import Util from '@/libs/util'
import Setting from '@/setting'
import axios from "axios";
import Util from "@/libs/util";
import router from "@/router/index";
import Setting from "@/setting";
import store from '@/store'
import Router from '@/router'
const service = axios.create({
baseURL: Setting.apiBaseURL,
timeout: 1000 * 60 * 60 * 6
timeout: 10000000
});
// post请求头
service.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
service.defaults.headers['X-Content-Type-Options'] = 'nosniff'
service.defaults.headers['Content-Security-Policy'] = 'script-src "self"; object-src "none";style-src cdn.example.org third-party.org; child-src https:'
service.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8";
// 请求拦截器
service.interceptors.request.use(config => {
let token = Util.local.get(Setting.tokenKey);
if (token) config.headers.token = token
if (token) config.headers.token = token;
return config;
}, err => {
Util.errorMsg({
@ -27,67 +26,74 @@ service.interceptors.request.use(config => {
return Promise.reject(err);
});
let logouted = 0;
// 响应拦截器
service.interceptors.response.use(
response => {
const res = response.data
const { code, status } = res
if (code == 200 || status === 200) {
const res = response.data;
if (res.status == 200 || res.status == 10000 || res.status == 30001) {
return Promise.resolve(res).catch(e => { });
} else if (code === 401) {
Util.errorMsg(res.msg)
setTimeout(() => {
store.dispatch('user/logout')
}, 1000)
return Promise.reject(res)
} else if (code == 300) {
// 悬浮栏管理里的禁用启用返回300要弹询问框选择是否继续
} else if (res.code === 401) {
// 账号互踢
if (!logouted) {
Util.local.remove(Setting.storeKey)
Util.local.remove(Setting.tokenKey)
Util.errorMsg(res.msg.includes('顶') ? '您的账号已在其他设备登录,您已被迫下线!' : '登录过期,请重新登录!')
setTimeout(() => {
store.dispatch('user/logout')
logouted = 0
}, 2000)
logouted = 1
}
} else if (!res.status) {
return Promise.resolve(res).catch(e => { });
} else {
Util.errorMsg(res.msg);
Util.errorMsg(res.message);
return Promise.reject(res)
// return Promise.resolve(res).catch(e => {});
}
},
// 服务器状态码不是200的情况
error => {
if (error.response.status) {
const { msg, code } = error.response.data
// 站点id为空
if (error.response.status === 405) {
Router.replace('/site')
} else {
switch (code) {
// 401: 未登录
case 401:
Util.errorMsg("登录过期,请重新登录")
switch (error.response.status) {
// 401: 未登录
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
if (!logouted) {
Util.local.remove(Setting.storeKey);
Util.local.remove(Setting.tokenKey);
Util.errorMsg("登录过期,请重新登录");
setTimeout(() => {
store.dispatch('user/logout')
}, 1000)
break
// 403 token过期
case 403:
Util.errorMsg("登录过期,请重新登录")
setTimeout(() => {
store.dispatch('user/logout')
}, 1000)
break
// 其他错误,直接抛出错误提示
default:
Util.errorMsg(msg)
Promise.reject(error.response.data)
}
return Promise.reject(error.response)
}, 1000);
logouted = 1
}
break;
case 500:
Util.errorMsg("网络错误");
break;
// 404请求不存在
case 404:
Util.errorMsg("网络请求不存在!");
break;
// 其他错误,直接抛出错误提示
default:
Util.errorMsg(error.response.data.message);
Promise.reject(res);
}
return Promise.reject(error.response);
}
}
)
);
function get (url, params) {
return new Promise((resolve, reject) => {
service.get(url, { params: params }).then(res => {
resolve(res)
resolve(res);
}).catch(err => {
reject(err)
reject(err);
});
});
}
@ -105,7 +111,7 @@ function post (url, params) {
function del (url, params) {
return new Promise((resolve, reject) => {
service.delete(url, {
data: params
params
}).then(res => {
resolve(res);
}).catch(err => {

@ -4,7 +4,7 @@
const isDev = process.env.NODE_ENV === 'development' // 开发环境
let host = location.origin
if (isDev) {
host = 'http://192.168.31.51:10000'
host = 'http://192.168.31.217:9000'
}
const Setting = {

Loading…
Cancel
Save