提交 0bf90677 authored 作者: fit2cloud-chenyw's avatar fit2cloud-chenyw

feat: 完善权限管理

上级 3a592137
...@@ -8,6 +8,7 @@ import io.dataease.controller.sys.request.DeptCreateRequest; ...@@ -8,6 +8,7 @@ import io.dataease.controller.sys.request.DeptCreateRequest;
import io.dataease.controller.sys.request.DeptDeleteRequest; import io.dataease.controller.sys.request.DeptDeleteRequest;
import io.dataease.controller.sys.request.DeptStatusRequest; import io.dataease.controller.sys.request.DeptStatusRequest;
import io.dataease.controller.sys.response.DeptNodeResponse; import io.dataease.controller.sys.response.DeptNodeResponse;
import io.dataease.controller.sys.response.DeptTreeNode;
import io.dataease.service.sys.DeptService; import io.dataease.service.sys.DeptService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
...@@ -82,4 +83,9 @@ public class SysDeptController extends ResultHolder { ...@@ -82,4 +83,9 @@ public class SysDeptController extends ResultHolder {
deptService.updateStatus(request); deptService.updateStatus(request);
} }
@PostMapping("/nodesByDeptId/{deptId}")
public List<DeptTreeNode> nodesByDeptId(@PathVariable("deptId") Long deptId){
return deptService.searchTree(deptId);
}
} }
package io.dataease.controller.sys.response;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DeptTreeNode implements Serializable {
private Long id;
private String label;
private Boolean hasChildren;
private List<DeptTreeNode> children;
public List<DeptTreeNode> toList(){
List<DeptTreeNode> lists = new ArrayList<>();
lists.add(this);
return lists;
}
}
...@@ -8,10 +8,12 @@ import io.dataease.base.mapper.ext.query.GridExample; ...@@ -8,10 +8,12 @@ import io.dataease.base.mapper.ext.query.GridExample;
import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.CommonBeanFactory; import io.dataease.commons.utils.CommonBeanFactory;
import io.dataease.controller.sys.base.BaseGridRequest; import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.base.ConditionEntity;
import io.dataease.controller.sys.request.DeptCreateRequest; import io.dataease.controller.sys.request.DeptCreateRequest;
import io.dataease.controller.sys.request.DeptDeleteRequest; import io.dataease.controller.sys.request.DeptDeleteRequest;
import io.dataease.controller.sys.request.DeptStatusRequest; import io.dataease.controller.sys.request.DeptStatusRequest;
import io.dataease.controller.sys.request.SimpleTreeNode; import io.dataease.controller.sys.request.SimpleTreeNode;
import io.dataease.controller.sys.response.DeptTreeNode;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -139,6 +141,33 @@ public class DeptService { ...@@ -139,6 +141,33 @@ public class DeptService {
return sysDepts; return sysDepts;
} }
public List<DeptTreeNode> searchTree(Long deptId){
List<SysDept> roots = nodesByPid(0L);
if (deptId == DEPT_ROOT_PID) return roots.stream().map(this::format).collect(Collectors.toList());
SysDept sysDept = sysDeptMapper.selectByPrimaryKey(deptId);
if (roots.stream().anyMatch(node -> node.getDeptId() == deptId)) return roots.stream().map(this::format).collect(Collectors.toList());
SysDept current = sysDept;
DeptTreeNode currentNode = format(sysDept);
while (current.getPid() != DEPT_ROOT_PID){
SysDept parent = sysDeptMapper.selectByPrimaryKey(current.getPid()); //pid上有索引 所以效率不会太差
DeptTreeNode parentNode = format(parent);
parentNode.setChildren(currentNode.toList());
current = parent;
currentNode = parentNode;
}
DeptTreeNode targetRootNode = currentNode;
return roots.stream().map(node -> node.getDeptId() == targetRootNode.getId() ? targetRootNode : format(node)).collect(Collectors.toList());
}
private DeptTreeNode format(SysDept sysDept){
DeptTreeNode deptTreeNode = new DeptTreeNode();
deptTreeNode.setId(sysDept.getDeptId());
deptTreeNode.setLabel(sysDept.getName());
deptTreeNode.setHasChildren(sysDept.getSubCount() > 0);
return deptTreeNode;
}
private DeptService proxy(){ private DeptService proxy(){
return CommonBeanFactory.getBean(DeptService.class); return CommonBeanFactory.getBean(DeptService.class);
} }
......
...@@ -41,4 +41,11 @@ export function editDept(data) { ...@@ -41,4 +41,11 @@ export function editDept(data) {
}) })
} }
export default { addDept, delDept, editDept, getDeptTree, loadTable } export function treeByDeptId(deptId) {
return request({
url: '/api/dept/nodesByDeptId/' + deptId,
method: 'post'
})
}
export default { addDept, delDept, editDept, getDeptTree, loadTable, treeByDeptId }
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
@search="search" @search="search"
> >
<template #buttons> <template #buttons>
<fu-table-button icon="el-icon-circle-plus-outline" :label="$t('organization.create')" @click="create" /> <fu-table-button v-permission="['dept:add']" icon="el-icon-circle-plus-outline" :label="$t('organization.create')" @click="create" />
</template> </template>
<el-table <el-table
ref="table" ref="table"
...@@ -129,7 +129,7 @@ import Treeselect from '@riophae/vue-treeselect' ...@@ -129,7 +129,7 @@ import Treeselect from '@riophae/vue-treeselect'
import { formatCondition } from '@/utils/index' import { formatCondition } from '@/utils/index'
import '@riophae/vue-treeselect/dist/vue-treeselect.css' import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS, LOAD_ROOT_OPTIONS } from '@riophae/vue-treeselect' import { LOAD_CHILDREN_OPTIONS, LOAD_ROOT_OPTIONS } from '@riophae/vue-treeselect'
import { checkPermission } from '@/utils/permission'
import { getDeptTree, addDept, editDept, delDept, loadTable } from '@/api/system/dept' import { getDeptTree, addDept, editDept, delDept, loadTable } from '@/api/system/dept'
export default { export default {
...@@ -173,9 +173,11 @@ export default { ...@@ -173,9 +173,11 @@ export default {
columns: [], columns: [],
buttons: [ buttons: [
{ {
label: this.$t('commons.edit'), icon: 'el-icon-edit', click: this.edit label: this.$t('commons.edit'), icon: 'el-icon-edit', click: this.edit,
show: checkPermission(['dept:edit'])
}, { }, {
label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this._handleDelete label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this._handleDelete,
show: checkPermission(['dept:del'])
} }
], ],
searchConfig: { searchConfig: {
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
:search-config="searchConfig" :search-config="searchConfig"
@search="initTableData" @search="initTableData"
> >
<template #buttons> <template v-permission="['menu:add']" #buttons>
<fu-table-button icon="el-icon-circle-plus-outline" :label="$t('menu.create')" @click="create" /> <fu-table-button v-permission="['menu:add']" icon="el-icon-circle-plus-outline" :label="$t('menu.create')" @click="create" />
</template> </template>
<el-table <el-table
...@@ -124,7 +124,7 @@ import IconSelect from '@/components/IconSelect' ...@@ -124,7 +124,7 @@ import IconSelect from '@/components/IconSelect'
import Treeselect from '@riophae/vue-treeselect' import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css' import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS, LOAD_ROOT_OPTIONS } from '@riophae/vue-treeselect' import { LOAD_CHILDREN_OPTIONS, LOAD_ROOT_OPTIONS } from '@riophae/vue-treeselect'
import { checkPermission } from '@/utils/permission'
import { addMenu, editMenu, delMenu, getMenusTree } from '@/api/system/menu' import { addMenu, editMenu, delMenu, getMenusTree } from '@/api/system/menu'
export default { export default {
...@@ -137,7 +137,7 @@ export default { ...@@ -137,7 +137,7 @@ export default {
data() { data() {
return { return {
menus: [], menus: [],
topMunu: { id: 0, label: '顶级类目', children: null }, topMunu: { id: 0, label: '顶级目录', children: null },
formType: 'add', formType: 'add',
dialogVisible: false, dialogVisible: false,
condition: {}, condition: {},
...@@ -165,9 +165,11 @@ export default { ...@@ -165,9 +165,11 @@ export default {
columns: [], columns: [],
buttons: [ buttons: [
{ {
label: this.$t('commons.edit'), icon: 'el-icon-edit', click: this.edit label: this.$t('commons.edit'), icon: 'el-icon-edit', click: this.edit,
show: checkPermission(['menu:edit'])
}, { }, {
label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this._handleDelete label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this._handleDelete,
show: checkPermission(['menu:del'])
} }
], ],
searchConfig: { searchConfig: {
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
@search="search" @search="search"
> >
<template #buttons> <template #buttons>
<fu-table-button icon="el-icon-circle-plus-outline" :label="$t('user.create')" @click="create" /> <fu-table-button v-permission="['user:add']" icon="el-icon-circle-plus-outline" :label="$t('user.create')" @click="create" />
</template> </template>
<el-table-column type="selection" fix /> <el-table-column type="selection" fix />
...@@ -157,7 +157,7 @@ import '@riophae/vue-treeselect/dist/vue-treeselect.css' ...@@ -157,7 +157,7 @@ import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { userLists, addUser, editUser, delUser, editPassword, editStatus } from '@/api/system/user' import { userLists, addUser, editUser, delUser, editPassword, editStatus } from '@/api/system/user'
import { allRoles } from '@/api/system/role' import { allRoles } from '@/api/system/role'
import { getDeptTree } from '@/api/system/dept' import { getDeptTree, treeByDeptId } from '@/api/system/dept'
export default { export default {
...@@ -168,9 +168,11 @@ export default { ...@@ -168,9 +168,11 @@ export default {
columns: [], columns: [],
buttons: [ buttons: [
{ {
label: this.$t('commons.edit'), icon: 'el-icon-edit', click: this.edit label: this.$t('commons.edit'), icon: 'el-icon-edit', click: this.edit,
show: checkPermission(['user:edit'])
}, { }, {
label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this.del label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this.del,
show: checkPermission(['user:del'])
}, { }, {
label: this.$t('member.edit_password'), icon: 'el-icon-s-tools', type: 'danger', click: this.editPassword, label: this.$t('member.edit_password'), icon: 'el-icon-s-tools', type: 'danger', click: this.editPassword,
show: checkPermission(['user:editPwd']) show: checkPermission(['user:editPwd'])
...@@ -306,14 +308,20 @@ export default { ...@@ -306,14 +308,20 @@ export default {
}, },
create() { create() {
this.depts = null
this.formType = 'add' this.formType = 'add'
this.form = Object.assign({}, this.defaultForm) this.form = Object.assign({}, this.defaultForm)
this.dialogVisible = true this.dialogVisible = true
}, },
edit(row) { edit(row) {
this.depts = null
this.formType = 'modify' this.formType = 'modify'
this.dialogVisible = true this.dialogVisible = true
this.form = Object.assign({}, row) this.form = Object.assign({}, row)
if (this.form.deptId === 0) {
this.form.deptId = null
}
this.initDeptTree()
}, },
editPassword(row) { editPassword(row) {
this.editPasswordVisible = true this.editPasswordVisible = true
...@@ -364,6 +372,7 @@ export default { ...@@ -364,6 +372,7 @@ export default {
}) })
}, },
handleClose() { handleClose() {
this.depts = null
this.formType = 'add' this.formType = 'add'
this.form = {} this.form = {}
this.editPasswordVisible = false this.editPasswordVisible = false
...@@ -376,12 +385,30 @@ export default { ...@@ -376,12 +385,30 @@ export default {
this.$success(this.$t('commons.modify_success')) this.$success(this.$t('commons.modify_success'))
}) })
}, },
initDeptTree() {
treeByDeptId(this.form.deptId || 0).then(res => {
const results = res.data.map(node => {
if (node.hasChildren && !node.children) {
node.children = null
}
return node
})
this.depts = results
})
},
// 获取弹窗内部门数据 // 获取弹窗内部门数据
loadDepts({ action, parentNode, callback }) { loadDepts({ action, parentNode, callback }) {
if (action === LOAD_ROOT_OPTIONS) { if (action === LOAD_ROOT_OPTIONS && !this.form.deptId) {
const _self = this const _self = this
!this.depts && getDeptTree('0').then(res => { treeByDeptId(0).then(res => {
_self.depts = res.data.map(node => _self.normalizer(node)) const results = res.data.map(node => {
if (node.hasChildren && !node.children) {
node.children = null
}
return node
})
_self.depts = results
callback() callback()
}) })
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论