forked from github/dataease
feat: 角色管理完善
This commit is contained in:
parent
7056db3b53
commit
2ba005db3d
@ -1,6 +1,8 @@
|
||||
package io.dataease.base.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@ -42,4 +44,30 @@ public class SysMenu implements Serializable {
|
||||
private Long updateTime;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/**
|
||||
* 由于该类型作为HashSet key所以必须重写以下方法
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SysMenu menu = (SysMenu) o;
|
||||
return Objects.equals(menuId, menu.menuId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(menuId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -5,10 +5,15 @@ import io.dataease.controller.sys.response.RoleNodeResponse;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public interface ExtSysRoleMapper {
|
||||
|
||||
|
||||
List<RoleNodeResponse> query(@Param("request")RoleGridRequest request);
|
||||
|
||||
int deleteRoleMenu(@Param("roleId") Long roleId);
|
||||
|
||||
int batchInsertRoleMenu(@Param("maps") List<Map<String, Long>> maps);
|
||||
}
|
||||
|
@ -23,4 +23,16 @@
|
||||
</select>
|
||||
|
||||
|
||||
<delete id="deleteRoleMenu">
|
||||
delete from sys_roles_menus where role_id = #{roleId}
|
||||
</delete>
|
||||
|
||||
<insert id="batchInsertRoleMenu">
|
||||
insert into sys_roles_menus (role_id, menu_id) values
|
||||
<foreach collection="maps" item="map" separator=",">
|
||||
(#{map.roleId},#{map.menuId})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
@ -14,6 +14,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@ -29,15 +30,11 @@ public class SysMenuController {
|
||||
@PostMapping("/childNodes/{pid}")
|
||||
public List<MenuNodeResponse> childNodes(@PathVariable("pid") Long pid){
|
||||
List<SysMenu> nodes = menuService.nodesByPid(pid);
|
||||
List<MenuNodeResponse> nodeResponses = nodes.stream().map(node -> {
|
||||
MenuNodeResponse menuNodeResponse = BeanUtils.copyBean(new MenuNodeResponse(), node);
|
||||
menuNodeResponse.setHasChildren(node.getSubCount() > 0);
|
||||
menuNodeResponse.setTop(node.getPid() == menuService.MENU_ROOT_PID);
|
||||
return menuNodeResponse;
|
||||
}).collect(Collectors.toList());
|
||||
return nodeResponses;
|
||||
return menuService.convert(nodes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ApiOperation("新增菜单")
|
||||
@PostMapping("/create")
|
||||
public void create(@RequestBody MenuCreateRequest request){
|
||||
@ -49,6 +46,7 @@ public class SysMenuController {
|
||||
public void delete(@RequestBody MenuDeleteRequest request){
|
||||
menuService.delete(request);
|
||||
}
|
||||
|
||||
@ApiOperation("更新菜单")
|
||||
@PostMapping("/update")
|
||||
public void update(@RequestBody MenuCreateRequest menu){
|
||||
@ -56,4 +54,14 @@ public class SysMenuController {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@PostMapping("/childMenus/{pid}")
|
||||
public Set<Long> childMenus(@PathVariable Long pid){
|
||||
List<MenuNodeResponse> childs = menuService.childs(pid);
|
||||
Set<Long> sets = childs.stream().map(MenuNodeResponse::getMenuId).collect(Collectors.toSet());
|
||||
sets.add(pid);
|
||||
return sets;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import io.dataease.base.domain.SysRole;
|
||||
import io.dataease.commons.utils.PageUtils;
|
||||
import io.dataease.commons.utils.Pager;
|
||||
import io.dataease.controller.sys.request.RoleGridRequest;
|
||||
import io.dataease.controller.sys.request.RoleMenusRequest;
|
||||
import io.dataease.controller.sys.response.RoleNodeResponse;
|
||||
import io.dataease.service.sys.SysRoleService;
|
||||
import io.swagger.annotations.Api;
|
||||
@ -34,8 +35,8 @@ public class SysRoleController {
|
||||
|
||||
|
||||
@ApiOperation("删除角色")
|
||||
@PostMapping("/delete")
|
||||
public void delete(Long roleId){
|
||||
@PostMapping("/delete/{roleId}")
|
||||
public void delete(@PathVariable("roleId") Long roleId){
|
||||
sysRoleService.delete(roleId);
|
||||
}
|
||||
|
||||
@ -52,4 +53,10 @@ public class SysRoleController {
|
||||
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||
return PageUtils.setPageInfo(page, sysRoleService.query(request));
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/saveRolesMenus")
|
||||
public void saveRolesMenus(@RequestBody RoleMenusRequest request){
|
||||
sysRoleService.batchSaveRolesMenus(request);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
package io.dataease.controller.sys.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class RoleMenusRequest {
|
||||
|
||||
private Long roleId;
|
||||
|
||||
private List<Long> menuIds;
|
||||
}
|
@ -7,11 +7,16 @@ import io.dataease.base.mapper.ext.ExtMenuMapper;
|
||||
import io.dataease.commons.utils.BeanUtils;
|
||||
import io.dataease.controller.sys.request.MenuCreateRequest;
|
||||
import io.dataease.controller.sys.request.MenuDeleteRequest;
|
||||
import io.dataease.controller.sys.response.MenuNodeResponse;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class MenuService {
|
||||
@ -108,5 +113,32 @@ public class MenuService {
|
||||
return sysMenuMapper.updateByPrimaryKeySelective(sysMenu);
|
||||
}
|
||||
|
||||
public List<MenuNodeResponse> childs(Long pid){
|
||||
Set<SysMenu> childs = getChilds(nodesByPid(pid), new HashSet());
|
||||
List<SysMenu> menus = childs.stream().collect(Collectors.toList());
|
||||
List<MenuNodeResponse> responses = convert(menus);
|
||||
return responses;
|
||||
}
|
||||
|
||||
private Set<SysMenu> getChilds(List<SysMenu> lists, Set<SysMenu> sets){
|
||||
lists.forEach(menu -> {
|
||||
sets.add(menu);
|
||||
List<SysMenu> kidMenus = nodesByPid(menu.getMenuId());
|
||||
if (CollectionUtils.isNotEmpty(kidMenus)){
|
||||
getChilds(kidMenus, sets);
|
||||
}
|
||||
});
|
||||
return sets;
|
||||
}
|
||||
|
||||
public List<MenuNodeResponse> convert(List<SysMenu> menus){
|
||||
return menus.stream().map(node -> {
|
||||
MenuNodeResponse menuNodeResponse = BeanUtils.copyBean(new MenuNodeResponse(), node);
|
||||
menuNodeResponse.setHasChildren(node.getSubCount() > 0);
|
||||
menuNodeResponse.setTop(node.getPid() == MENU_ROOT_PID);
|
||||
return menuNodeResponse;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -5,11 +5,16 @@ import io.dataease.base.domain.SysRole;
|
||||
import io.dataease.base.mapper.SysRoleMapper;
|
||||
import io.dataease.base.mapper.ext.ExtSysRoleMapper;
|
||||
import io.dataease.controller.sys.request.RoleGridRequest;
|
||||
import io.dataease.controller.sys.request.RoleMenusRequest;
|
||||
import io.dataease.controller.sys.response.RoleNodeResponse;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class SysRoleService {
|
||||
@ -45,4 +50,19 @@ public class SysRoleService {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public int batchSaveRolesMenus(RoleMenusRequest request){
|
||||
extSysRoleMapper.deleteRoleMenu(request.getRoleId());
|
||||
List<Map<String, Long>> maps = request.getMenuIds().stream().map(menuId -> {
|
||||
Map<String, Long> map = new HashMap<>();
|
||||
map.put("roleId", request.getRoleId());
|
||||
map.put("menuId", menuId);
|
||||
return map;
|
||||
}).collect(Collectors.toList());
|
||||
return extSysRoleMapper.batchInsertRoleMenu(maps);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -4,12 +4,12 @@
|
||||
<el-aside width="70%" style="border: 1px solid #eee">
|
||||
<el-card class="table-card">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="search" @create="create" :create-tip="$t('user.create')" :title="$t('commons.user')"/>
|
||||
<ms-table-header :condition.sync="condition" @search="search" @create="create" :create-tip="$t('role.add')" :title="$t('commons.role')"/>
|
||||
</template>
|
||||
<el-table border class="adjust-table" :data="tableData" style="width: 100%;">
|
||||
<el-table border highlight-current-row class="adjust-table" :data="tableData" style="width: 100%;" @row-click="rowClick">
|
||||
|
||||
<el-table-column prop="name" label="名称" />
|
||||
<el-table-column :show-overflow-tooltip="true" width="135px" prop="createTime" label="创建日期">
|
||||
<el-table-column :show-overflow-tooltip="true" prop="createTime" label="创建日期">
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
@ -35,9 +35,8 @@
|
||||
:load="getMenuDatas"
|
||||
:props="defaultProps"
|
||||
check-strictly
|
||||
accordion
|
||||
show-checkbox
|
||||
node-key="menuId"
|
||||
node-key="id"
|
||||
@check="menuChange"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
@ -45,6 +44,26 @@
|
||||
</el-tabs>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<el-dialog :close-on-click-modal="false" :title="formType=='add' ? $t('role.add') : $t('role.modify')" :visible.sync="dialogVisible" width="580px" @closed="closeFunc"
|
||||
:destroy-on-close="true">
|
||||
<el-form ref="roleForm" inline :model="form" :rules="rule" size="small" label-width="80px">
|
||||
|
||||
<el-form-item label="角色名称" prop="name">
|
||||
<el-input v-model="form.name" style="width: 380px;" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="描述信息" prop="description">
|
||||
<el-input v-model="form.description" style="width: 380px;" rows="5" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template v-slot:footer>
|
||||
<ms-dialog-footer
|
||||
@cancel="dialogVisible = false"
|
||||
@confirm="saveRole('roleForm')"/>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
@ -55,7 +74,10 @@ import MsTableHeader from "../../common/components/MsTableHeader";
|
||||
import MsTableOperator from "../../common/components/MsTableOperator";
|
||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||
|
||||
import {
|
||||
listenGoBack,
|
||||
removeGoBackListener
|
||||
} from "@/common/js/utils";
|
||||
export default {
|
||||
name: 'role',
|
||||
components: {
|
||||
@ -70,9 +92,12 @@ export default {
|
||||
return {
|
||||
result: {},
|
||||
queryPath: '/api/role/roleGrid',
|
||||
deletePath: '/user/special/delete/',
|
||||
createPath: '/user/special/add',
|
||||
updatePath: '/user/special/update',
|
||||
deletePath: '/api/role/delete/',
|
||||
createPath: '/api/role/create',
|
||||
updatePath: '/api/role/update',
|
||||
queryMenusPath: '/api/menu/childNodes/',
|
||||
childMenusPath: '/api/menu/childMenus/',
|
||||
saveRoleMenusPath: '/api/role/saveRolesMenus',
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
@ -80,37 +105,147 @@ export default {
|
||||
tableData: [],
|
||||
menus: [],
|
||||
menuIds: [],
|
||||
defaultProps: {},
|
||||
activeName: 'second'
|
||||
defaultProps: { children: 'children', label: 'label' ,isLeaf: 'isLeaf'},
|
||||
activeName: 'first',
|
||||
dialogVisible: false,
|
||||
formType: 'add',
|
||||
form: {},
|
||||
rule: {
|
||||
name: [
|
||||
{ required: true, message: '请输入名称', trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
currentRow: null
|
||||
};
|
||||
},
|
||||
activated() {
|
||||
this.search();
|
||||
},
|
||||
watch: {
|
||||
currentRow: 'currentRowChange'
|
||||
},
|
||||
methods: {
|
||||
handleClick(tab, event) {
|
||||
console.log(tab, event);
|
||||
},
|
||||
create(){},
|
||||
create(){
|
||||
this.form = {}
|
||||
this.formType = "add";
|
||||
this.dialogVisible = true
|
||||
listenGoBack(this.closeFunc)
|
||||
},
|
||||
search(){
|
||||
this.result = this.$post(this.queryPath+ "/" + this.currentPage + "/" + this.pageSize, this.condition, response => {
|
||||
let data = response.data;
|
||||
this.total = data.itemCount;
|
||||
this.tableData = data.listObject;
|
||||
let data = response.data
|
||||
this.total = data.itemCount
|
||||
this.tableData = data.listObject
|
||||
})
|
||||
},
|
||||
|
||||
edit(row){
|
||||
|
||||
this.formType = 'modify'
|
||||
this.dialogVisible = true
|
||||
this.form = Object.assign({}, row)
|
||||
listenGoBack(this.closeFunc)
|
||||
},
|
||||
getMenuDatas(node, resolve){
|
||||
|
||||
saveRole(roleForm){
|
||||
this.$refs[roleForm].validate(valid => {
|
||||
if (valid) {
|
||||
const url = this.formType=='add' ? this.createPath : this.updatePath
|
||||
this.result = this.$post(url, this.form, () => {
|
||||
this.$success(this.$t('commons.save_success'))
|
||||
this.search();
|
||||
this.dialogVisible = false
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
closeFunc() {
|
||||
this.dialogVisible = false
|
||||
removeGoBackListener(this.closeFunc);
|
||||
},
|
||||
|
||||
getMenuDatas(node, resolve){
|
||||
this.$post(this.queryMenusPath+(node.data.id ? node.data.id : 0), null, (res) => {
|
||||
const datas = res.data
|
||||
const nodes = datas.map(data => this.formatNode(data))
|
||||
resolve && resolve(nodes)
|
||||
})
|
||||
},
|
||||
formatNode(node) {
|
||||
const result = {
|
||||
id: node.menuId,
|
||||
label: node.title,
|
||||
isLeaf: !node.hasChildren,
|
||||
children: node.children
|
||||
}
|
||||
return result
|
||||
},
|
||||
menuChange(menu){
|
||||
this.$post(this.childMenusPath + menu.id, null, res => {
|
||||
const childIds = res.data
|
||||
if (this.menuIds.indexOf(menu.id) !== -1) {
|
||||
for (let i = 0; i < childIds.length; i++) {
|
||||
const index = this.menuIds.indexOf(childIds[i])
|
||||
if (index !== -1) {
|
||||
this.menuIds.splice(index, 1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < childIds.length; i++) {
|
||||
const index = this.menuIds.indexOf(childIds[i])
|
||||
if (index === -1) {
|
||||
this.menuIds.push(childIds[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(this.menuIds)
|
||||
this.$refs.menu.setCheckedKeys(this.menuIds)
|
||||
this.saveMenus()
|
||||
})
|
||||
},
|
||||
saveMenus(){
|
||||
if (!this.currentRow) {
|
||||
return
|
||||
}
|
||||
const param = {roleId: this.currentRow.roleId, menuIds: this.menuIds}
|
||||
this.$post(this.saveRoleMenusPath, param, res => {
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
rowClick(row,column, event){
|
||||
this.currentRow = row
|
||||
},
|
||||
currentRowChange(newVal, oldVal){
|
||||
if (newVal == oldVal) {
|
||||
return
|
||||
}
|
||||
if (!newVal) {
|
||||
this.menuIds = []
|
||||
return
|
||||
}
|
||||
|
||||
this.menuIds = newVal.menuIds;
|
||||
this.$refs.menu.setCheckedKeys(this.menuIds)
|
||||
},
|
||||
handleDelete(row){
|
||||
this.$confirm('确认删除角色['+row.name+']?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const url = this.deletePath+row.roleId
|
||||
this.$post(url, null, () => {
|
||||
this.$success(this.$t('commons.modify_success'))
|
||||
this.search()
|
||||
});
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,6 +385,8 @@ export default {
|
||||
test_user: '测试人员',
|
||||
test_viewer: '只读用户',
|
||||
add: '添加角色',
|
||||
delete: '删除角色',
|
||||
modify: '修改角色',
|
||||
},
|
||||
report: {
|
||||
api_test_report: '接口测试报告',
|
||||
|
Loading…
Reference in New Issue
Block a user