欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

参数和宏的极致使用

程序员文章站 2022-03-12 08:20:39
...

本文通过一个使用参数和宏结合实现复杂数据权限需求的案例,分享给大家一个经验:不管多么复杂的数据权限业务逻辑,集智数据平台报表系统都可以实现。
应用场景说明
   
某医疗用品制造商使用了润乾集智数据平台来搭建报表管理系统,集智数据平台中用户、组织机构和角色数据保持与客户原有EOS系统数据同步。报表数据从以EOS数据为基础的视图库中抽取。
   
权限控制涉及到了系统权限和较为复杂的数据权限。系统权限中除了基本的组织机构授权和角色权限以处,还衍生出多种角色权限。比如每一用户都关联了一个权限标志位,而权限标志位又分为普通、部门和全部三种。其中普通权限用户只能看到本人及下级人员数据信息,部门权限用户可以看到本部门内容的数据信息,全部权限用户可以看到全部数据信息,无权限过滤。
   
但是该单位的销售职位中存在RSMTSMTSR三种角色,它们存在上下级关系,职位由高到低依次是RSMTSMTSR。并且,TSM有权力跟代理商签订代理协议。TSM可以选择自己跟踪代理协议、分配给TSR跟踪代理协议和自己与TSR同时跟踪代理协议这种跟踪方法。
   
鉴于以上业务事实,客户提出在相关报表中(设为R)要求实现如下业务逻辑:将R分配给用户后,要求根据权限标志位判断出用户能访问的数据范围。同时,当用户登录后,在参数模板中还要求根据sys_UserID筛选出该用户能访问的代理商以及该用户的RSMRSM的显示规则是:当用户权限标志位为普通时,若登录用户为TSR,则显示其上级TSM;若若登录用户为TSM,则显示为自己;若登录用户为RSM,则显示为其下属的所有TSM。当用户权限标志位为部门全部时,则按权限标志位判断规则显示数据。
实现过程
框架
    本实现过程先搭框架,再具体实现,以使读者能够更清晰地理解整个实现过程。
�/SPAN> 查询权限标志位
   
增加一个参数“mapKey”,使用query()查询并返回权限标志位
�/SPAN> 搭建权限标志位逻辑
    Case(mapKey,”
普通权限”,”操作1”,”部门权限”,”操作2”,”全部权限操作3”)
�/SPAN> 实现普通权限时操作1
   
若操作1是查询代理商,则通过sysDistributorsyslicencetsmsharesyspersont_user表之间的关联关系查出代理商并返回。
   
若操作1是查询RSM,则通过syslicencetsmsharsyslicencetsrsharesyspersont_user表之间的关联关系查出RSM并返回。
�/SPAN> 实现部门权限时操作2
   
若操作2是查询代理商,则先通过DistributorAgreementDistributorProductKindsysperson表之间的关联关系构造出一个含有代理商名称、TSM以及TSM所属部门的视图“DistributorAgreement”。然后从DistributorAgreement查出登录人员所在部门的所有代理商并返回。
   
若操作2是查询RSM,则通过sysagreementproductdeptrt_roleuser表之间的关联关系查出RSM并返回。
�/SPAN> 实现全部权限时操作3
   
不进行数据过滤,直接取全量数据即可。
�/SPAN> 将权限标志位逻辑封闭到宏中
 
将宏结果交给数据集�/SPAN>
实例
    在框架基础上,实现实例。
�/SPAN> 查询权限标志位
参数名称 参数类型 值表达式 参数说明
sys_UserID
字符串   集智数据平台传入参数模板的登录用户ID
mapKey
字符串 query2(”mis2datasource”,”select role_id from RT_ROLEUSER where user_id=? and role_id in (3,4,5)”,@sys_UserID) 权限标志位

�/SPAN> 搭建权限标志位逻辑
Case(mapKey,”
普通权限”,”操作1”,”部门权限”,”操作2”,”全部权限操作3”)

�/SPAN> 实现普通权限时操作1
   
若操作1是查询代理商,则:
select DistributorName_C as
代理商中文名称 from sysDistributor where DistributorID in (select distinct DistributorID from syslicencetsmshare where personid in (select personid from sysperson where personname in (select user_name from sjmreport.dbo.t_user where user_id = ‘”+sys_UserID+”‘))) order by DistributorName_C

   
若操作1是查询RSM,则增加一个参数dmgr,以判断登录用户是否是TSM,若返回值为0,说明是TSR,否则为TSM。参数及相关业务逻辑如下:
参数名称 参数类型 值表达式 参数说明
dmgr
整数 query2(”eosreport”,”select count(*) from syslicencetsmshare where personid in (select personid from sysperson where personname in (select user_name from sjmreport.dbo.t_user where user_id = ?))”,@sys_UserID) 判断登录用户是否是TSM,若返回值为0,说明是TSR,否则为TSM
if(dmgr>=1,”select user_name as
经理名 from sjmreport.dbo.t_user where user_id = ‘”+sys_UserID+”‘”,”select personname as 经理名 from sysperson where personid in(select personid from syslicencetsmshare where pk_lictsmshare in(select pk_lictsmshare from syslicencetsrshare where personid in(select personid from sysperson where personname in(select user_name from sjmreport.dbo.t_user where user_id = ‘”+sys_UserID+”‘))))”)

�/SPAN> 实现部门权限时操作2
   
若操作2是查询代理商,则:
SELECT
代理商中文名称 FROM sysagreement where 部门 in(select role_name from sjmreport.dbo.t_role where role_id in(select role_id from sjmreport.dbo.rt_roleuser where user_id=’”+sys_UserID+”‘ and role_id in (22,23,24,25,26,27)))

   
若操作2是查询RSM,则:
select distinct
区域销售经理 as 经理名 from sysagreement where 部门 in(SELECT 部门代码 FROM productdept where 部门ID in(select role_id-21 from sjmreport.dbo.rt_roleuser where user_id=’”+sys_UserID+”‘ and role_id in (22,23,24,25,26,27)))

�/SPAN> 实现全部权限时操作3
   
若操作2是查询代理商,则:
select DistributorName_C as
代理商中文名称 from sysDistributor where DistributorID in (select distinct DistributorID from syslicencetsmshare) order by DistributorName_C
   
若操作2是查询RSM,则:
select distinct
区域销售经理 as 经理名 from sysagreement
�/SPAN> 将权限标志位逻辑封闭到宏中
宏名称 类型 值表达式
代理商 动态宏 case(mapKey, “3″,”select DistributorName_C as 代理商中文名称 from sysDistributor where DistributorID in (select distinct DistributorID from syslicencetsmshare where personid in (select personid from sysperson where personname in (select user_name from sjmreport.dbo.t_user where user_id = ‘”+sys_UserID+”‘))) order by DistributorName_C”,”4″,”SELECT 代理商中文名称 FROM sysagreement where 部门 in(select role_name from sjmreport.dbo.t_role where role_id in(select role_id from sjmreport.dbo.rt_roleuser where user_id=’”+sys_UserID+”‘ and role_id in (22,23,24,25,26,27)))”,”select DistributorName_C as 代理商中文名称 from sysDistributor where DistributorID in (select distinct DistributorID from syslicencetsmshare) order by DistributorName_C”)
TSM
动态宏 case(mapKey, “3″,if(dmgr>=1,”select user_name as 经理名 from sjmreport.dbo.t_user where user_id = ‘”+sys_UserID+”‘”,”select personname as 经理名 from sysperson where personid in(select personid from syslicencetsmshare where pk_lictsmshare in(select pk_lictsmshare from syslicencetsrshare where personid in(select personid from sysperson where personname in(select user_name from sjmreport.dbo.t_user where user_id = ‘”+sys_UserID+”‘))))”),”4″,”select distinct 区域销售经理 as 经理名 from sysagreement where 部门 in(SELECT 部门代码 FROM productdept where 部门ID in(select role_id-21 from sjmreport.dbo.rt_roleuser where user_id=’”+sys_UserID+”‘ and role_id in (22,23,24,25,26,27)))”,”select distinct 区域销售经理 as 经理名 from sysagreement”)

�/SPAN> 将宏结果交给数据集
代理商“TSM”使用复杂SQL数据集封闭即可。

总结
    以上实现案例仅是针对在参数模板中进行数据权限控制的情况。当参数模板中数据传递到报表模板时还需要针对入参匹配数据,真正实现数据权限控制。不过,相对此过程参数模板中的控制就简单多了,不此不再实现。
   
实现以上业务逻辑也实属无奈。当集智数据平台与其它系统共享库表,集智数据平台业务数据结构必须依赖于共享库表时,该案例还是有一定的借鉴意义。
   
这种实现方案能避免就尽量避免,不能避免时,也要相信集智数据平台报表系统能够很好地解决的。

更多了解各种复杂问题的处理,可以参考:让业务用户随时可以自己定义查询报表多级部门角色按不同权限查看不同数据