最新消息:文章中包含代码时,请遵守代码高亮规范!

关于项目中权限模块的一些思考【原创】

Java 施, 建 260浏览 0评论

最近在做项目管理后台时遇到一个场景,管理后台中有很多个模块,比如说查看用户模块,订单管理模块财务管理模块等等,每个用户登录管理后台后可能只有一部分权限,比如说总经理有所有的权限,业务员登录之后只有订单管理的权限,这个时候需要记录每个用户的权限存到表当中,这是背景.

1.最开始设计的时候有个最简单的想法,就是用户表中加一个varchar类型的权限字段,然后每个模块对应一个模块id,权限字段存储这个用户拥有权限的所有模块id,id之间用逗号隔开(类似这种1,3,4,6),存表的时候就把用户的拥有权限的id使用StringUtils.join(idList,”,”)拼接成字符串,取的时候就是把这个字符串通过字符串的split方法转数组然后遍历,得到中这个用户的权限信息.后来想想这种太low了,有么有逼格高一点的,于是就有了下面的想法.

2.首先用户表中的权限字段设计成int,然后记录模块的增加一个字段,表示这个模块对应的显示在用户表中的值,id为1的模块,value就设计成1(对应2进制的1),id为2的模块value设计成2(对应2进制的10),id为3的模块value设计成4(对应2进制的100),以此类推.当用户的拥有模块1和模块3的权限的时候,用户表中的权限字段就存模块1和模块3的value的和.但是实际上你会发现,这个模块对应的value是有规律的,1,2,4,8,16…….,对应的二进制就是1,10,100,1000,10000…..,所以实际上value不需要存库,直接用使用 Java中的左移操作就能得到,模块1对应的value是1<<(1-1),模块2对应的value是1<<(2-1),模块n对应的value是1<<(n-1).当这个用户有模块1和模块3的权限的时候,表中存的就是5(对应的2进制就是101)

 

这些就是存库的时候逻辑,下面说说取出来的时候怎么操作,比如用户表中取出来的数是5,怎么转换成对应的模块id呢,5对应的2进制就是101,很容易发现,第一位和第三位是1,其他位都是0,很明显了,就是有模块1和模块三的权限了,简单的说就是看用户的值转2进制后,对应id位是0还是1,是0,这个模块就没有权限,是有就有权限.这个可以使用java中与运算得出,比如用户数据是5,我要看id为3的模块是否有权限,直接5&3==3判断即可.

以上就是存取时的大概思路,写的可能有点乱,下面把存和取的核心代码贴出来,

//前端页面传过来一个模块id的数组表示这个用户有这些模块的id
int[] ids = {1, 5, 6, 7, 8};

//存的时候核心代码
int access = Arrays.stream(ids).map(id -> 1 << (id - 1)).sum();
System.out.println("数据库中用户权限的值存:   " + access);
//取的时候假如想看模块4有没有权限 核心代码
boolean isAccessInModule4 = (access & (1 << (4 - 1))) == (1 << (4 - 1));
System.out.println("是否有模块4的权限: " + isAccessInModule4);
boolean isAccessInModule5 = (access & (1 << (5 - 1))) == (1 << (5 - 1));
System.out.println("是否有模块5的权限: " + isAccessInModule5);

//一共有10个模块,看这个用户有哪些模块的权限 核心代码
int[] allIds = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
System.out.print("拥有权限的模块是:   ");
Arrays.stream(allIds).filter(id -> (access & (1 << (id - 1))) == (1 << id - 1))
                     .forEach(id -> System.out.print(id + "  "));

有兴趣的可以一起探讨一下.

转载时请注明出处及相应链接,本文永久地址:https://blog.yayuanzi.com/24442.html


pay_weixin
pay_weixin
微信打赏
pay_weixin
支付宝打赏
感谢您对作者joy1的打赏,我们会更加努力!    如果您想成为作者,请点我

您必须 登录 才能发表评论!