springboot后台管理动态菜单

一、目标介绍:

通常我们登录后台根据账号的拥有的角色不一样,每个角色拥有的权限,根据不同的角色登录显示不同的菜单。这样做可以更好的进行管理

二、设计表

我觉得想现实这个功能只靠代码无法实现,或者实现很困难,所以表需要设计的合理,功能做起来就简单很多了,

我这里设置了五张表

  • 第一张是用户表 :sys_user
  • 第二张是角色表 : sys_role
  • 第三站是用户表和角色表的关联表 : sys_user_role
  • 第四张是权限表:sys_permission
  • 第五张是角色和权限的关联表:sys_role_permission

在这里插入图片描述

三、编写代码

用户类

@Data
public class User implements Serializable {

    private Integer id;

    private String username;

    private String cname;
    
    private String password;
}

角色类

@Data
public class Role implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
	
    private String rolename;
    
     private String cname;

}

用户和角色关联类

@Data
public class UserRole implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    private Integer userId;

    private Integer roleId;

}

权限表

@Data
public class Permission implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 权限表
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 父节点id
     */
    private Long pid;

    /**
     * 名称
     */
    private String cname;

}

角色和权限关联类

@Data
public class RolePermission implements Serializable {

    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 角色id
     */
    private Long roleid;
    /**
     * 权限id
     */
    private Long permid;

}

在创建一个返回的类CNode

@Data
  @ApiModelProperty(value = "角色ID")
    private Long id;
    private Long pid;
    @ApiModelProperty(value = "角色昵称")
    private String cname;
    private String url;
    private String icon;
    private List<CNode> children;
}

直接看业务实现层,createNode方法在下面

 @Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService, BaseService {

  @Resource
    private PermissionDao permissionDao;
    @Override
    public R getMenu() {
   		 //getUserId()表示当前登录的用户id
        List<Permission> list = permissionDao.getMenu(getUserId());
        List<CNode> nodes = createNode(list, Constant.PID);
        return R.ok(nodes);

    }
}

PermissionDao 调用执行的方法和sql语句拿到菜单

public interface PermissionDao {
    @Select("SELECT * FROM `sys_permission` WHERE ctype=0 AND id IN (\n" +
            "SELECT permid FROM `sys_role_permission` WHERE roleid IN(\n" +
            "SELECT roleid FROM `sys_user_role` WHERE userid=#{userId}))")
    List<Permission> getMenu(@Param("userId") Long userId);
}

我把sql执行一遍结果如下:我给的参数是1,权限最大的一个,所以返回全部菜单
在这里插入图片描述
为了效果明显直接我把参数改成 2,在执行一次,可以明显看到用户2看到的菜单没有那么多了
在这里插入图片描述
在这里插入图片描述
角色id对应着权限id,也就是这个角色能看到的权限菜单
在这里插入图片描述

拿到数据后在把他变成树形结构返回去就行了
业务层的代码写在上面的,里面创建了一个私有方法,这一步就是做树形数据的

private List<CNode> createNode(List<Permission> list, Long pid) {
    return list.stream()
             .filter(p -> p.getPid().equals(pid))
             .map(p -> {
                CNode cNode = CopyBean.copyBean(p, CNode::new); //复制对象
                List<CNode> nodes = createNode(list, cNode.getId());
                    if (!CollectionUtils.isEmpty(nodes)) { 
                        cNode.setChildren(nodes);
                    }
                    return cNode;
            }).collect(Collectors.toList());
}

pid:代表根节点id,或者说是最外面那层菜单的id ,我的根节点是-1,所以pid就是-1
CopyBean:用来将源对象复制到目标对象,将Permission复制到CNode

测试说明:

从角色和权限的关联表就能看出,拥有角色id为1的用户可以看到全部菜单,拥有角色id为2的只能看到部分菜单,
在这里插入图片描述

测试结果:

登录账号:admin和lisi
在这里插入图片描述
先使用admin登录,拿到了全部菜单权限
在这里插入图片描述

在使用lisi进行登录,只有系统管理的权限
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值