赞
踩
通常我们登录后台根据账号的拥有的角色不一样,每个角色拥有的权限,根据不同的角色登录显示不同的菜单。这样做可以更好的进行管理
我觉得想现实这个功能只靠代码无法实现,或者实现很困难,所以表需要设计的合理,功能做起来就简单很多了,
我这里设置了五张表
用户类
@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进行登录,只有系统管理的权限
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。