二、设计表通常我们登录后台根据账号的拥有的角色不一样,每个角色拥有的权限,根据不同的角色登录显示不同的菜单。这样做可以更好的进行管理
我觉得想现实这个功能只靠代码无法实现,或者实现很困难,所以表需要设计的合理,功能做起来就简单很多了,
我这里设置了五张表
- 第一张是用户表 :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;
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;
private Long roleid;
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 children;
}
直接看业务实现层,createNode方法在下面
@Service public class PermissionServiceImpl extends ServiceImplimplements PermissionService, BaseService { @Resource private PermissionDao permissionDao; @Override public R getMenu() { //getUserId()表示当前登录的用户id List list = permissionDao.getMenu(getUserId()); List 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 getMenu(@Param("userId") Long userId);
}
我把sql执行一遍结果如下:我给的参数是1,权限最大的一个,所以返回全部菜单
为了效果明显直接我把参数改成 2,在执行一次,可以明显看到用户2看到的菜单没有那么多了
角色id对应着权限id,也就是这个角色能看到的权限菜单
拿到数据后在把他变成树形结构返回去就行了
业务层的代码写在上面的,里面创建了一个私有方法,这一步就是做树形数据的
private ListcreateNode(List list, Long pid) { return list.stream() .filter(p -> p.getPid().equals(pid)) .map(p -> { CNode cNode = CopyBean.copyBean(p, CNode::new); //复制对象 List 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进行登录,只有系统管理的权限



