diff --git a/src/api/system/dept.js b/src/api/system/dept.js index 59998ba..8877b53 100644 --- a/src/api/system/dept.js +++ b/src/api/system/dept.js @@ -1,4 +1,5 @@ import request from '@/utils/request' +import qs from 'qs' export function getDepts(params) { return request({ @@ -8,6 +9,16 @@ export function getDepts(params) { }) } +export function getSuperior(ids) { + const params = { + ids: ids + } + return request({ + url: 'api/dept/superior?' + qs.stringify(params, { indices: false }), + method: 'get' + }) +} + export function add(data) { return request({ url: 'api/dept', @@ -32,4 +43,4 @@ export function edit(data) { }) } -export default { add, edit, del, getDepts } +export default { add, edit, del, getDepts, getSuperior } diff --git a/src/api/system/job.js b/src/api/system/job.js index 1029ce9..a00630e 100644 --- a/src/api/system/job.js +++ b/src/api/system/job.js @@ -3,7 +3,8 @@ import request from '@/utils/request' export function getAllJob() { const params = { page: 0, - size: 9999 + size: 9999, + enabled: true } return request({ url: 'api/job', diff --git a/src/api/system/menu.js b/src/api/system/menu.js index 4e8ac90..f9888a7 100644 --- a/src/api/system/menu.js +++ b/src/api/system/menu.js @@ -1,8 +1,23 @@ import request from '@/utils/request' -export function getMenusTree() { +export function getMenusTree(pid) { return request({ - url: 'api/menus/tree', + url: 'api/menus/lazy?pid=' + pid, + method: 'get' + }) +} + +export function getMenus(params) { + return request({ + url: 'api/menus', + method: 'get', + params + }) +} + +export function getSuperior(id) { + return request({ + url: 'api/menus/superior?id=' + id, method: 'get' }) } @@ -38,4 +53,4 @@ export function edit(data) { }) } -export default { add, edit, del, getMenusTree } +export default { add, edit, del, getMenusTree, getSuperior, getMenus } diff --git a/src/components/Crud/crud.js b/src/components/Crud/crud.js index 03a035c..466f0b0 100644 --- a/src/components/Crud/crud.js +++ b/src/components/Crud/crud.js @@ -132,6 +132,11 @@ function CRUD(options) { crud.loading = true // 请求数据 initData(crud.url, crud.getQueryParams()).then(data => { + const table = crud.getTable() + if (table.lazy) { // 懒加载子节点数据,清掉已加载的数据 + table.store.states.treeData = {} + table.store.states.lazyTreeNodeMap = {} + } crud.page.total = data.totalElements crud.data = data.content crud.resetDataStatus() @@ -437,7 +442,7 @@ function CRUD(options) { crud.selectChange(selection, val) }) } else { - crud.findVM('presenter').$refs['table'].clearSelection() + crud.getTable().clearSelection() } }, /** @@ -447,10 +452,10 @@ function CRUD(options) { */ selectChange(selection, row) { // 如果selection中存在row代表是选中,否则是取消选中 - if (selection.find(val => { return this.getDataId(val) === this.getDataId(row) })) { + if (selection.find(val => { return crud.getDataId(val) === crud.getDataId(row) })) { if (row.children) { row.children.forEach(val => { - crud.findVM('presenter').$refs['table'].toggleRowSelection(val, true) + crud.getTable().toggleRowSelection(val, true) selection.push(val) if (val.children) { crud.selectChange(selection, val) @@ -469,7 +474,7 @@ function CRUD(options) { toggleRowSelection(selection, data) { if (data.children) { data.children.forEach(val => { - crud.findVM('presenter').$refs['table'].toggleRowSelection(val, false) + crud.getTable().toggleRowSelection(val, false) if (val.children) { crud.toggleRowSelection(selection, val) } @@ -492,8 +497,11 @@ function CRUD(options) { getDataId(data) { return data[this.idField] }, + getTable() { + return this.findVM('presenter').$refs.table + }, attchTable() { - const table = this.findVM('presenter').$refs.table + const table = this.getTable() const columns = [] table.columns.forEach((e, index) => { if (!e.property || e.type !== 'default') { @@ -509,6 +517,25 @@ function CRUD(options) { }) this.updateProp('tableColumns', columns) this.updateProp('table', table) + + const that = this + table.$on('expand-change', (row, expanded) => { + if (!expanded) { + return + } + const lazyTreeNodeMap = table.store.states.lazyTreeNodeMap + const children = lazyTreeNodeMap[row.id] + row.children = children + children.forEach(ele => { + const id = crud.getDataId(ele) + if (that.dataStatus[id] === undefined) { + that.dataStatus[id] = { + delete: 0, + edit: 0 + } + } + }) + }) } } const crud = Object.assign({}, data) diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue index 3fdd313..9cbc25e 100644 --- a/src/views/system/dept/index.vue +++ b/src/views/system/dept/index.vue @@ -25,15 +25,36 @@ - - + + - + + + + + + + + + + {{ item.label }} - - + + - + + - @@ -150,6 +166,7 @@ import crudMenu from '@/api/system/menu' import IconSelect from '@/components/IconSelect' import Treeselect from '@riophae/vue-treeselect' import '@riophae/vue-treeselect/dist/vue-treeselect.css' +import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' import CRUD, { presenter, header, form, crud } from '@crud/crud' import rrOperation from '@crud/RR.operation' import crudOperation from '@crud/CRUD.operation' @@ -185,13 +202,50 @@ export default { methods: { // 新增与编辑前做的操作 [CRUD.HOOK.afterToCU](crud, form) { - crudMenu.getMenusTree().then(res => { - this.menus = [] - const menu = { id: 0, label: '顶级类目', children: [] } - menu.children = res - this.menus.push(menu) + this.menus = [] + if (form.id != null) { + if (form.pid === null) { + form.pid = 0 + } + this.getSupDepts(form.id) + } else { + this.menus.push({ id: 0, label: '顶级类目', children: null }) + } + }, + getMenus(tree, treeNode, resolve) { + const params = { pid: tree.id } + setTimeout(() => { + crudMenu.getMenus(params).then(res => { + resolve(res.content) + }) + }, 100) + }, + getSupDepts(id) { + crudMenu.getSuperior(id).then(res => { + const children = res.content.map(function(obj) { + if (!obj.leaf && !obj.children) { + obj.children = null + } + return obj + }) + this.menus = [{ id: 0, label: '顶级类目', children: children }] }) }, + loadMenus({ action, parentNode, callback }) { + if (action === LOAD_CHILDREN_OPTIONS) { + crudMenu.getMenusTree(parentNode.id).then(res => { + parentNode.children = res.map(function(obj) { + if (!obj.leaf) { + obj.children = null + } + return obj + }) + setTimeout(() => { + callback() + }, 100) + }) + } + }, // 选中图标 selected(name) { this.form.icon = name @@ -204,4 +258,8 @@ export default { /deep/ .el-input-number .el-input__inner { text-align: left; } + /deep/ .vue-treeselect__control, /deep/ .vue-treeselect__placeholder, /deep/ .vue-treeselect__single-value { + height: 30px; + line-height: 30px; + } diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index ba02507..e6acb00 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -40,7 +40,14 @@ - + @@ -103,8 +110,10 @@ import crudRoles from '@/api/system/role' -import { getDepts } from '@/api/system/dept' +import { getDepts, getSuperior } from '@/api/system/dept' import { getMenusTree } from '@/api/system/menu' import CRUD, { presenter, header, form, crud } from '@crud/crud' import rrOperation from '@crud/RR.operation' @@ -128,6 +137,7 @@ import udOperation from '@crud/UD.operation' import pagination from '@crud/Pagination' import Treeselect from '@riophae/vue-treeselect' import '@riophae/vue-treeselect/dist/vue-treeselect.css' +import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' const defaultForm = { id: null, name: null, depts: [], description: null, dataScope: '全部', level: 3 } export default { @@ -139,7 +149,7 @@ export default { mixins: [presenter(), header(), form(defaultForm), crud()], data() { return { - defaultProps: { children: 'children', label: 'label' }, + defaultProps: { children: 'children', label: 'label', isLeaf: 'leaf' }, dateScopes: ['全部', '本级', '自定义'], level: 3, currentId: 0, menuLoading: false, showButton: false, menus: [], menuIds: [], depts: [], @@ -159,19 +169,29 @@ export default { } }, created() { - this.getMenus() crudRoles.getLevel().then(data => { this.level = data.level }) }, methods: { + getMenuDatas(node, resolve) { + setTimeout(() => { + getMenusTree(node.data.id ? node.data.id : 0).then(res => { + resolve(res) + }) + }, 100) + }, [CRUD.HOOK.afterRefresh]() { this.$refs.menu.setCheckedKeys([]) }, // 编辑前 [CRUD.HOOK.beforeToEdit](crud, form) { if (form.dataScope === '自定义') { - this.getDepts() + if (form.id == null) { + this.getDepts() + } else { + this.getSupDepts(form.depts) + } } const depts = [] form.depts.forEach(function(dept, index) { @@ -212,12 +232,6 @@ export default { }) crud.form.depts = depts }, - // 获取所有菜单 - getMenus() { - getMenusTree().then(res => { - this.menus = res - }) - }, // 触发单选 handleCurrentChange(val) { if (val) { @@ -273,9 +287,44 @@ export default { // 获取部门数据 getDepts() { getDepts({ enabled: true }).then(res => { - this.depts = res.content + this.depts = res.content.map(function(obj) { + if (obj.hasChildren) { + obj.children = null + } + return obj + }) }) }, + getSupDepts(depts) { + const ids = [] + depts.forEach(dept => { + ids.push(dept.id) + }) + getSuperior(ids).then(res => { + this.depts = res.content.map(function(obj) { + if (obj.hasChildren && !obj.children) { + obj.children = null + } + return obj + }) + }) + }, + // 获取弹窗内部门数据 + loadDepts({ action, parentNode, callback }) { + if (action === LOAD_CHILDREN_OPTIONS) { + getDepts({ enabled: true, pid: parentNode.id }).then(res => { + parentNode.children = res.content.map(function(obj) { + if (obj.hasChildren) { + obj.children = null + } + return obj + }) + setTimeout(() => { + callback() + }, 200) + }) + } + }, // 如果数据权限为自定义则获取部门数据 changeScope() { if (this.form.dataScope === '自定义') { @@ -300,4 +349,11 @@ export default { /deep/ .el-input-number .el-input__inner { text-align: left; } + /deep/ .vue-treeselect__multi-value{ + margin-bottom: 0; + } + /deep/ .vue-treeselect__multi-value-item{ + border: 0; + padding: 0; + } diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index e47d461..a599ed6 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -2,7 +2,7 @@
- +
- +
@@ -87,6 +88,7 @@ @@ -171,7 +173,7 @@ /> - + @@ -179,7 +181,7 @@ @@ -202,7 +204,7 @@ -