目前权限管理系统不少,但通用、灵活、符合现代企事业单位实际工作需要的不多。现有的权限系统绝大多数都是以模块为核心,而本权限模型将摒弃此类普遍的做 法,将以组织机构为核心来进行权限系统的设计,因为这更符合实际的业务需求,也具有很多无法比拟的优点。首先来看以组织机构为核心的权限模型的逻辑结构 图:
通过上图你可轻松的设计出相应的数据库结构,而此权限模型体系所具有的优点如下:
1、以组织机构为核心进行权限的管理和分配等,更加符合现代企事业的实际需要,包括多机构、组织、部门、岗位、人员等。
2、实现一人对应多个组织实体、岗位的同时,还能对帐号进行统一的登录、验证和授权。
3、支持功能权限、动作权限、数据权限、管理权限等。
4、权限继承,某个组织的所有下属组织均能继承本组织的权限。
5、实现分级授权,某个组织可对下属组织实现权限范围内的分级权限管理,对于组织机构层次很多的企业或政府机构来说特别适用,这可通过上图中的权限继承来实现。
6、通常情况下通过角色对组织进行权限分配,在这里,组织本身其实也同时充当了“用户组”的职责,而且在操作上还更加方便;当然,还可直接对某个特定组织绕开角色单独进行权限的分配,例如可对某个组织追加或禁用具有的角色权限范围之外的一些特定权限。
7、实现组织回收站功能,必要时可进行物理删除和恢复,做到系统中有后悔药可用。
8、美观的界面,出色的性能与多系统、多数据库的支持。
上述的权限模型体系,还应有如下考量:
1、组织机构按特定的规则创建,例如组织下可包含组织、机构、 部门、岗位、人员,但部门下只能包含子部门、岗位和人员,而岗位下只能是人员等等;同时需对数据库表进行优化并适当冗余,保证每个组织可快速查询所包含的下属组织及类型。
2、通过人员成员和用户相关联,人员成员可分配至组织下的任意节点,这在实现了一人多岗的同时,也实现了统一的用户基本资料管理和权限分配。每个用户有且只能有一个主要岗位,其他岗位均为从属岗位,对人员成员的信息管理将自动更新到人员成员管理的用户上。
3、在组织下进行角色的关联, 通过路径就可快速查询到某个组织所属的角色及继承的角色,管理权限和数据权限的实现思想和此类似。
4、通过人员成员和权限的管理,可在角色范围外对用户的权限进行分配和管理,这有助于大大增加系统在权限控制上的灵活性,也有助于实现真正意义上的分级授权。
5、管理权限,本质上是一种数据权限,指的是某个组织下的人员成员可以管理的组织的业务数据,管理权限的目标是实现跨部门协作,管理权限可脱离本组织所对 应的组织机构树节点。通过在业务系统中增加人员成员的完整路径字段,这样每个用户登录后均能通过自身管理的组织完整路径查询到所管理的下属组织的业务数 据。同时完整路径字段应由一系列唯一的ID值组合而成,需要保证这个完整路径的唯一性并尽量做到不变性;同时提供相应的事件机制,保证即使完整路径有修改 时,也能通知业务系统进行相应的处理,有效保证业务数据和权限模型数据之间的一致性。
6、至于数据权限,可通过指定自定义的查询过滤条件等,为每个角色和人员指定特殊的数据权限;动作权限和数据权限只能对应到具体的功能权限而不能独立存在。
7、本权限模型实现了多个业务系统共用一个数据库数据,并保证管理上互不交叉;同时可配置表的个性化名称;支持扩展字段等个性化功能,为二次开发用户提供必要的灵活性和个性化支持接口。
8、在性能上,首先需要考虑的是数据库设计的适当冗余,例如对组织机构增加了路径字段,这个字段的值需要根据组织所在的上下级关系生成,业务系统中可通过 存储该字段的值实现高性能的数据权限和管理权限功能;其次在界面上对树形结构、网格数据等尽量使用服务器端的延迟查询和分页处理,在大数据量下可大大提高 系统的响应速度;最后还要对不经常变化的数据进行适当的缓存处理。
9、本权限模型的实现难点主要在业务规则的标准化和冗余字段数据进行一致性的维护上。例如前面提到的路径数据,以及状态字段等(如当禁用了某个组织后,毫无疑问也需要禁用所有下属的组织)。对于多数据库支持,还需考虑不同数据库之间SQL语法和特性上的差异。
10、本权限模型应能提供必要的权限控制表达式解析组件,这有助于提供终端用户使用本系统时的灵活性和易用性。例如可在界面配置只能查询自身数据、或父组 织数据、或指定完整路径的业务数据过滤表达式等,而后台能自动把这些表达式解析成 SQL 表达式或 LINQ 表达式,对特定的业务数据进行过滤查询。
11、本权限模型还应提供功能完备、简单易用的 API 接口和必要的界面组件,例如可显示指定ID的所有下属组织机构树等界面组件,这样只需简单配置下ID就能显示所有下属组织,开发人员无需关心底层的数据结构,可大大提高业务系统的开发速度。
个人思路:
方案一、
(1)参考多维分析中的维度设计
1.1 建立维度级别信息,对应一般业务系统就是 省、市、县行政级别,
维度表结构如下(Level):
id | 省级代码 | 市级代码 | 县级代码 |
1 | 200 | 201 | 100 |
2 | 200 | 202 | 101 |
业务表结构如下:
业务表A
id | 机构代码 | 操作人员 | 其他业务字段... |
1 | level.1 | admin | uuu |
2 | level.2 | admin | ooo |
另一种方式,不需要维度表的情况下
业务表B
id | 机构代码 | 操作人员 | 其他业务字段... |
1 | 200201100 | admin | uuu |
2 | 200202101 | admin | ooo |
此种方式无法满足机构代码无规律的情况,优点是可以通过数据库的locate函数方便、快捷实现。
1.2 代码中留有占位符来动态替换规则sql,如下
针对业务表A的设计:
select * from A a, level b where 1=1 and a.机构代码 = level.id and ${rules}
${rules} 由后台配置会生成类似 b.省级代码 = 登录用户机构省级代码 and b.省级代码 = 登录用户机构市级代码 and 操作人员 = 登录用户ID
针对业务表B的设计:
select * from B where 1=1 and ${rules:field} -->filed 用于 locate 中替换的字段
${rules} 由后台配置会生成类似 locate(机构代码,'200201') > 0 and 操作人员 = 登录用户ID
1.3 系统SQL执行前加一层代理,替换掉SQL中的占位符即可。
另一种方式直接拼接SQL不使用占位符,缺点是复杂SQL不好处理及拼接的SQL可能存在性能问题,另外部分功能需要部分功能不需要时不好处理。
功能补充:
(1)权限级别定义功能
(2)角色数据权限配置 + 权限级别配置
(3)机构补充权限代码字段