一、获取全部菜单
1、controller
//获取全部菜单
@ApiOperation(value = "查询所有菜单")
@GetMapping
public R indexAllPermission() {
List<Permission> list = permissionService.queryAllMenuGuli();
return R.ok().data("children",list);
}
2、serviceImpl
//获取全部菜单
@Override
public List<Permission> queryAllMenuGuli() {
//1 查询菜单表所有数据
LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
wrapper.orderByDesc(Permission::getId);
List<Permission> permissionList = baseMapper.selectList(wrapper);
//2 把查询所有菜单list集合按照要求进行封装
List<Permission> resultList = bulidPermission(permissionList);
return resultList;
}
// 找到递归调用的起始节点:即顶层菜单
//把返回所有菜单list集合进行封装的方法
public static List<Permission> bulidPermission(List<Permission> permissionList) {
//创建list集合,用于数据最终封装
List<Permission> finalNode = new ArrayList<>();
//把所有菜单list集合遍历,得到顶层菜单 pid=0菜单,设置level是1
permissionList.forEach(e -> {
//得到顶层菜单 pid=0菜单
if("0".equals(e.getPid())){
//设置顶层菜单的level是1
e.setLevel(1);
//根据顶层菜单,向里面进行查询子菜单,封装到finalNode里面
finalNode.add(selectChildren(e,permissionList));
}
});
return finalNode;
}
/**
*
* @param permissionNode 父菜单
* @param permissionList 所有的菜单
* @return
*/
private static Permission selectChildren(Permission permissionNode, List<Permission> permissionList) {
//1 因为向一层菜单里面放二层菜单,二层里面还要放三层,把子菜单对象初始化
permissionNode.setChildren(new ArrayList<Permission>());
//2 遍历所有菜单list集合,进行判断比较,比较父菜单id和子菜单pid值是否相同
permissionList.forEach(permission -> {
//判断父菜单id和子菜单pid值是否相同
if(permission.getPid().equals(permissionNode.getId())){
//把父菜单的level值+1,赋值给子菜单
int level = permissionNode.getLevel() + 1;
permission.setLevel(level);
//如果children为空,进行初始化操作
if(permission.getChildren() == null){
permission.setChildren(new ArrayList<Permission>());
}
//把查询出来的子菜单放到父菜单里面
permissionNode.getChildren().add(selectChildren(permission,permissionList));
// permissionNode.setChildren(new ArrayList<Permission>(){
// {
// add(selectChildren(permission,permissionList));
// }
// });
}
});
return permissionNode;
}
二、递归删除菜单
1、controller
@ApiOperation(value = "递归删除菜单")
@DeleteMapping("remove/{id}")
public R remove(@PathVariable String id) {
permissionService.removeChildByIdGuli(id);
return R.ok();
}
2、serviceImpl
@Override
public void removeChildByIdGuli(String id) {
//1 创建list集合,用于封装所有删除菜单id值
List<String> idList = new ArrayList<>();
//2 向idList集合设置删除菜单id
this.selectPermissionChildById(id,idList);
//把当前id封装到list里面
idList.add(id);
//执行删除操作
baseMapper.deleteBatchIds(idList);
}
//2 根据当前菜单id,查询菜单里面子菜单id,封装到list集合
private void selectPermissionChildById(String id, List<String> idList) {
//查询菜单里面子菜单id
LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Permission::getPid,id);
List<Permission> childIdList = baseMapper.selectList(wrapper);
if(!CollectionUtils.isEmpty(childIdList)){
//把childIdList里面菜单id值获取出来,封装idList里面,做递归查询
childIdList.stream().forEach(item -> {
//封装idList里面
idList.add(item.getId());
//递归查询
this.selectPermissionChildById(item.getId(), idList);
});
}
}
三、给角色分配菜单
1、controller
@ApiOperation(value = "给角色分配菜单")
@PostMapping("/doAssign")
public R doAssign(String roleId,String[] permissionId) {
permissionService.saveRolePermissionRealtionShipGuli(roleId,permissionId);
return R.ok();
}
2、serviceImpl
@Override
public void saveRolePermissionRealtionShipGuli(String roleId, String[] permissionIds) {
//roleId角色id
//permissionId菜单id 数组形式
// 删除已分配的菜单
LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(RolePermission::getRoleId,roleId);
rolePermissionService.remove(wrapper);
// 创建list集合,用于封装添加数据
List<RolePermission> rolePermissionList = new ArrayList<>();
//遍历所有菜单数组
for(String perId : permissionIds) {
//RolePermission对象
RolePermission rolePermission = new RolePermission();
rolePermission.setRoleId(roleId);
rolePermission.setPermissionId(perId);
//封装到list集合
rolePermissionList.add(rolePermission);
}
//添加到角色菜单关系表
rolePermissionService.saveBatch(rolePermissionList);
}
四、根据角色获取菜单
1、controller
@ApiOperation(value = "根据角色获取菜单")
@GetMapping("toAssign/{roleId}")
public R toAssign(@PathVariable String roleId) {
List<Permission> list = permissionService.selectAllMenu(roleId);
return R.ok().data("children", list);
}
2、serviceImpl
//根据角色获取菜单
@Override
public List<Permission> selectAllMenu(String roleId) {
//获取所有菜单
// CAST(id AS SIGNED),将id转换成int类型
// List<Permission> allPermissionList = baseMapper.selectList(new QueryWrapper<Permission>().orderByAsc("CAST(id AS SIGNED)"));
LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
wrapper.orderByDesc(Permission::getId);
List<Permission> allPermissionList = baseMapper.selectList(wrapper);
// 根据角色id获取角色权限
// List<RolePermission> rolePermissionList = rolePermissionService.list(new QueryWrapper<RolePermission>().eq("role_id",roleId));
LambdaQueryWrapper<RolePermission> wrapper1 = new LambdaQueryWrapper<>();
wrapper1.eq(RolePermission::getRoleId,roleId);
List<RolePermission> rolePermissionList = rolePermissionService.list(wrapper1);
// 获取角色对应的权限id
List<String> permissionIdList = rolePermissionList.stream().map(RolePermission::getPermissionId).collect(Collectors.toList());
// 设置权限列表的select字段
allPermissionList.forEach(p -> {
if(permissionIdList.contains(p.getId())){
p.setSelect(true);
}else {
p.setSelect(false);
}
});
//转换给角色id与角色权限对应Map对象
// List<String> permissionIdList = rolePermissionList.stream().map(e -> e.getPermissionId()).collect(Collectors.toList());
// allPermissionList.forEach(permission -> {
// if(permissionIdList.contains(permission.getId())) {
// permission.setSelect(true);
// } else {
// permission.setSelect(false);
// }
// });
// for (int i = 0; i < allPermissionList.size(); i++) {
// Permission permission = allPermissionList.get(i);
// for (int m = 0; m < rolePermissionList.size(); m++) {
// RolePermission rolePermission = rolePermissionList.get(m);
// if(rolePermission.getPermissionId().equals(permission.getId())) {
// permission.setSelect(true);
// }
// }
// }
List<Permission> permissionList = bulid(allPermissionList);
return permissionList;
}
/**
* 使用递归方法建菜单
* @param treeNodes
* @return
*/
private static List<Permission> bulid(List<Permission> treeNodes) {
List<Permission> trees = new ArrayList<>();
for (Permission treeNode : treeNodes) {
if ("0".equals(treeNode.getPid())) {
treeNode.setLevel(1);
trees.add(findChildren(treeNode,treeNodes));
}
}
return trees;
}
/**
* 递归查找子节点
* @param treeNodes
* @return
*/
private static Permission findChildren(Permission treeNode,List<Permission> treeNodes) {
treeNode.setChildren(new ArrayList<Permission>());
for (Permission it : treeNodes) {
if(treeNode.getId().equals(it.getPid())) {
int level = treeNode.getLevel() + 1;
it.setLevel(level);
if (treeNode.getChildren() == null) {
treeNode.setChildren(new ArrayList<>());
}
treeNode.getChildren().add(findChildren(it,treeNodes));
}
}
return treeNode;
}
五、根据用户id获取用户菜单
1、PermissionService
public interface PermissionService extends IService<Permission> {
//根据用户id获取用户菜单
List<String> selectPermissionValueByUserId(String id);
}
2、PermissionServiceImpl
//根据用户id获取用户菜单
@Override
public List<String> selectPermissionValueByUserId(String id) {
List<String> selectPermissionValueList = null;
if(this.isSysAdmin(id)) {
// 如果是系统管理员,获取所有权限
selectPermissionValueList = baseMapper.selectAllPermissionValue();
} else {
selectPermissionValueList = baseMapper.selectPermissionValueByUserId(id);
}
return selectPermissionValueList;
}
3、PermissionMapper
public interface PermissionMapper extends BaseMapper<Permission> {
// 系统管理员,获取所有权限
List<String> selectAllPermissionValue();
// 非系统管理员,根据用户id获取用户菜单
List<String> selectPermissionValueByUserId(String id);
}
4、PermissionMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.aclservice.mapper.PermissionMapper">
<resultMap id="permissionMap" type="com.atguigu.aclservice.entity.Permission">
<result property="id" column="id"/>
<result property="pid" column="pid"/>
<result property="name" column="name"/>
<result property="type" column="type"/>
<result property="permissionValue" column="permission_value"/>
<result property="path" column="path"/>
<result property="component" column="component"/>
<result property="icon" column="icon"/>
<result property="status" column="status"/>
<result property="isDeleted" column="is_deleted"/>
<result property="gmtCreate" column="gmt_create"/>
<result property="gmtModified" column="gmt_modified"/>
</resultMap>
<!-- 用于select查询公用抽取的列 -->
<sql id="columns">
p.id,p.pid,p.name,p.type,p.permission_value,path,p.component,p.icon,p.status,p.is_deleted,p.gmt_create,p.gmt_modified
</sql>
// 非系统管理员,根据用户id获取用户菜单
<select id="selectPermissionValueByUserId" resultType="String">
select
p.permission_value
from acl_user_role ur
inner join acl_role_permission rp on rp.role_id = ur.role_id
inner join acl_permission p on p.id = rp.permission_id
where ur.user_id = #{userId}
and p.type = 2
and ur.is_deleted = 0
and rp.is_deleted = 0
and p.is_deleted = 0
</select>
// 系统管理员,获取所有权限
<select id="selectAllPermissionValue" resultType="String">
select
permission_value
from
acl_permission
where
type = 2
and is_deleted = 0
</select>
</mapper>
5、IndexServiceImpl
/**
* 根据用户名获取用户登录信息
*
* @param username
* @return
*/
public Map<String, Object> getUserInfo(String username) {
Map<String, Object> result = new HashMap<>();
User user = userService.selectByUsername(username);
if (null == user) {
//throw new GuliException(ResultCodeEnum.FETCH_USERINFO_ERROR);
}
//根据用户id获取角色
List<Role> roleList = roleService.selectRoleByUserId(user.getId());
List<String> roleNameList = roleList.stream().map(item -> item.getRoleName()).collect(Collectors.toList());
if(roleNameList.size() == 0) {
//前端框架必须返回一个角色,否则报错,如果没有角色,返回一个空角色
roleNameList.add("");
}
//根据用户id获取操作权限值
List<String> permissionValueList = permissionService.selectPermissionValueByUserId(user.getId());
redisTemplate.opsForValue().set(username, permissionValueList);
result.put("name", user.getUsername());
result.put("avatar", "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
result.put("roles", roleNameList);
result.put("permissionValueList", permissionValueList);
return result;
}
6、IndexController
/**
* 根据token获取用户信息
*/
@GetMapping("info")
public R info(){
//获取当前登录用户用户名
String username = SecurityContextHolder.getContext().getAuthentication().getName();
Map<String, Object> userInfo = indexService.getUserInfo(username);
return R.ok().data(userInfo);
}
六、根据用户id获取用户菜单权限
1、PermissionService
public interface PermissionService extends IService<Permission> {
//根据用户id获取用户菜单权限
List<JSONObject> selectPermissionByUserId(String id);
}
2、PermissionServiceImpl
/**
* 根据用户id获取用户菜单权限
* @param userId
* @return
*/
@Override
public List<JSONObject> selectPermissionByUserId(String userId) {
List<Permission> selectPermissionList = null;
if(this.isSysAdmin(userId)) {
// 如果是超级管理员,获取所有菜单
selectPermissionList = baseMapper.selectList(null);
} else {
selectPermissionList = baseMapper.selectPermissionByUserId(userId);
}
// 根据权限数据构建菜单数据
List<Permission> permissionList = PermissionHelper.bulid(selectPermissionList);
// 根据权限数据构建登录用户左侧菜单数据
List<JSONObject> result = MemuHelper.bulid(permissionList);
return result;
}
1)PermissionHelper
/**
* 根据权限数据构建菜单数据
*/
public class PermissionHelper {
/**
* 使用递归方法建菜单
* @param treeNodes
* @return
*/
public static List<Permission> bulid(List<Permission> treeNodes) {
List<Permission> trees = new ArrayList<>();
for (Permission treeNode : treeNodes) {
if ("0".equals(treeNode.getPid())) {
treeNode.setLevel(1);
trees.add(findChildren(treeNode,treeNodes));
}
}
return trees;
}
/**
* 递归查找子节点
* @param treeNodes
* @return
*/
public static Permission findChildren(Permission treeNode,List<Permission> treeNodes) {
treeNode.setChildren(new ArrayList<Permission>());
for (Permission it : treeNodes) {
if(treeNode.getId().equals(it.getPid())) {
int level = treeNode.getLevel() + 1;
it.setLevel(level);
if (treeNode.getChildren() == null) {
treeNode.setChildren(new ArrayList<>());
}
treeNode.getChildren().add(findChildren(it,treeNodes));
}
}
return treeNode;
}
}
2)MemuHelper
/**
* 根据权限数据构建登录用户左侧菜单数据
*/
public class MemuHelper {
/**
* 构建菜单
* @param treeNodes
* @return
*/
public static List<JSONObject> bulid(List<Permission> treeNodes) {
List<JSONObject> meuns = new ArrayList<>();
if(treeNodes.size() == 1) {
Permission topNode = treeNodes.get(0);
//左侧一级菜单
List<Permission> oneMeunList = topNode.getChildren();
for(Permission one :oneMeunList) {
JSONObject oneMeun = new JSONObject();
oneMeun.put("path", one.getPath());
oneMeun.put("component", one.getComponent());
oneMeun.put("redirect", "noredirect");
oneMeun.put("name", "name_"+one.getId());
oneMeun.put("hidden", false);
JSONObject oneMeta = new JSONObject();
oneMeta.put("title", one.getName());
oneMeta.put("icon", one.getIcon());
oneMeun.put("meta", oneMeta);
List<JSONObject> children = new ArrayList<>();
List<Permission> twoMeunList = one.getChildren();
for(Permission two :twoMeunList) {
JSONObject twoMeun = new JSONObject();
twoMeun.put("path", two.getPath());
twoMeun.put("component", two.getComponent());
twoMeun.put("name", "name_"+two.getId());
twoMeun.put("hidden", false);
JSONObject twoMeta = new JSONObject();
twoMeta.put("title", two.getName());
twoMeun.put("meta", twoMeta);
children.add(twoMeun);
List<Permission> threeMeunList = two.getChildren();
for(Permission three :threeMeunList) {
if(StringUtils.isEmpty(three.getPath())) continue;
JSONObject threeMeun = new JSONObject();
threeMeun.put("path", three.getPath());
threeMeun.put("component", three.getComponent());
threeMeun.put("name", "name_"+three.getId());
threeMeun.put("hidden", true);
JSONObject threeMeta = new JSONObject();
threeMeta.put("title", three.getName());
threeMeun.put("meta", threeMeta);
children.add(threeMeun);
}
}
oneMeun.put("children", children);
meuns.add(oneMeun);
}
}
return meuns;
}
}
3、PermissionMapper
public interface PermissionMapper extends BaseMapper<Permission> {
// 非超级管理员,根据用户id获取用户菜单权限
List<Permission> selectPermissionByUserId(String userId);
}
4、PermissionMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.aclservice.mapper.PermissionMapper">
<resultMap id="permissionMap" type="com.atguigu.aclservice.entity.Permission">
<result property="id" column="id"/>
<result property="pid" column="pid"/>
<result property="name" column="name"/>
<result property="type" column="type"/>
<result property="permissionValue" column="permission_value"/>
<result property="path" column="path"/>
<result property="component" column="component"/>
<result property="icon" column="icon"/>
<result property="status" column="status"/>
<result property="isDeleted" column="is_deleted"/>
<result property="gmtCreate" column="gmt_create"/>
<result property="gmtModified" column="gmt_modified"/>
</resultMap>
<!-- 用于select查询公用抽取的列 -->
<sql id="columns">
p.id,p.pid,p.name,p.type,p.permission_value,path,p.component,p.icon,p.status,p.is_deleted,p.gmt_create,p.gmt_modified
</sql>
// 非超级管理员,根据用户id获取用户菜单权限
<select id="selectPermissionByUserId" resultMap="permissionMap">
select
<include refid="columns" />
from acl_user_role ur
inner join acl_role_permission rp on rp.role_id = ur.role_id
inner join acl_permission p on p.id = rp.permission_id
where ur.user_id = #{userId}
and ur.is_deleted = 0
and rp.is_deleted = 0
and p.is_deleted = 0
</select>
</mapper>
5、IndexServiceImpl
/**
* 根据用户名获取动态菜单
* @param username
* @return
*/
public List<JSONObject> getMenu(String username) {
User user = userService.selectByUsername(username);
//根据用户id获取用户菜单权限
List<JSONObject> permissionList = permissionService.selectPermissionByUserId(user.getId());
return permissionList;
}
6、IndexController
/**
* 获取菜单
* @return
*/
@GetMapping("menu")
public R getMenu(){
//获取当前登录用户用户名
String username = SecurityContextHolder.getContext().getAuthentication().getName();
List<JSONObject> permissionList = indexService.getMenu(username);
return R.ok().data("permissionList", permissionList);
}