博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
走火入魔.NET权限组件在公司的网络版温湿度监控系统中进行实战-用列表资源权限(数据集权限)思想来解决实际问题...
阅读量:6853 次
发布时间:2019-06-26

本文共 6608 字,大约阅读时间需要 22 分钟。

  hot3.png

前些日子公司有一个温湿度控制的监控类软件产品在开发,刚开始定位是单机版软件,后来重新被定位为多用户的、有权限控制的网络版温湿度监控系统,大家都觉得每个软件都有个性化的权限设置,无法进行通用,还是每个软件都开发自己的权限控制比较实在。

 

我的对策是如下:

 

1:一天一个人能开发几个稳定的页面?一整套完善的权限控制少说需要10来个页面、往多了说有几十个页面,那需要开发多久?代码检查多久?测试多久?将来又由谁维护?跟公司的其他产品是否有一定的兼容性?

     其实真正平均起来,1正常的开发人员,1天连1个页面也做不出来的,就算是做出来了,有没完没了的错误、测试、修正、完善,到最后完善说不定平均几天才是1个页面,很多人不相信,觉得没这么恐怖,那我就说:“现在我们工作几年了?有几个做的页面真正能拿得出手的?那在算算平均产值是多少?”要么就从来公司开始算有多久时间了?总共做了几个铜墙铁壁的可以用的页面?平均1天能有一个页面吗?难道做权限?1天就能做10个页面了飞快不成?

 

2:只有少数几个功能是需求不一样的,例如登录、用户管理、添加用户、修改用户、修改密码、设置密码、角色管理、添加角色、编辑角色。。。。等等一大堆页面都是通用的,只是设置用户权限时?设置角色权限时?这2个页面的个性化需求有些不一样,就算需求不一样,底层的数据存储结构、调用的权限判断函数都一样才对。何必从新搞一套呢?就把这2个页面能个性化定制,然后其他页面都共用,数据库结构共用、底层函数功能不就可以了吗?这里权限组件需要有能个性化定制才可以。

 

3:我们拿论坛来讲,现在有几个人自己做论坛了?都不是用现成的?现成的论坛能满足我们的个性化需要吗?自己完全从新开发一个论坛需要付出多少代价?要花费多少时间精力?人力物力?权限这玩意儿也不是一样的道理吗?说说都简单,但是真的做得精,做得可持续维护,可持续改进,跟业务无关?而且是效率高的?那我们还自己开发不?还是用现成的?

 

4:我本身就是本公司的,我的权限系统又免费给公司用,又不要公司的钱,而且你自己开发了,责任是你自己承担,开发那么多功能,何必跟自己过不去呢?直接拿过来用,你的工作,还别人给你分担,一方面更细化工作分工,另一方面还促进团结,就算花费500元购买,省事、省心,老板会差这么500元吗?有个稳定的组件可以用,而且可以重复用,又有源码? 不是很开心的事情吗?

 

5:网络版温湿度监控软件,对权限需求的差别在于,用户可以查看管理哪个仓库?角色可以产看管理哪个仓库?其他的需求与通用权限是完全一致的,那如何能做到个性化自定义权限呢?那接下来我们细致得讲解一下思路。

 

我们以类似项目管理的抓图来讲解,晚上在家里没有公司的温湿度数据库(以项目来代替仓库)

 

5.1 首先权限项定义里,应该有个“项目管理权限=ProjectAdmin”

 

 

5.2 需要有存储项目的表,应该有个“Base_Project表”

 

5.3 原有的权限设置窗体效果是什么?跟现在的有啥区别?就是希望点权限时,弹出的页面是,另外的个性化的页面,而不是原来的页面。

 

 

5.4 我们期望的效果图是如下:

 

5.5 那我们就继承一下原先的用户权限管理窗体,然后把权限设置按钮里的代码进行个性化改造:

 

5.6 覆盖原窗体中的权限设置按钮里的代码:

 

5.7 这个是原窗体中的权限设置按钮里的代码:

 

5.8 这个是新窗体中的权限设置按钮里的代码后的运行效果:

 

 

6:资源权限(数据集权限)的讲解如下图。

 

6.1:资源权限(数据集权限的表结构)的讲解如下图。

 

6.2:资源权限(数据集权限的表结构)的具体数据如下图。

 

总结:

可以资源权限(数据集权限)的思想,解决公司的温湿度监控系统中的,用户对相应仓库的管理权限,就像是跟项目管理一样的。

1:类似定义一个视图(对哪些资源上设置权限)

SELECT Id, Realname, Description FROM Base_Project WHERE DeleteMark = 0 AND Enabled = 1 ORDER BY SortCode

2:哪个用户,哪个角色对什么资源,有什么权限是通用的一个解决资源权限(数据集权限)的一种方法,接近于万能的。

例如 哪个用户可以管理哪个项目?哪个用户可以管理哪个仓库??????可能会有很多种想不到的资源。

3:可以继承先有的权限管理窗体,里面的大部分功能是共性的,只有很少的地方,甚至就一个按钮是个性的。

就把用户权限管理的,设置权限的按钮的方法覆盖一下,用个性化的代码覆盖,当然需要允许覆盖,可覆盖为前提。

4:当然要提供C/S的页面支持,还需要提供相应的B/S调用接口,调用函数。

5:其实,权限过滤函数,能计算到某个用户,到底对什么资源的(主键Ids)有什么权限就可以了,其他是应用软件的自己的事情了。

 

自己拼命狂写,搞得自己死去活来,还不如引用一下dll,简单做一下个性化的改进,配置文件配置配置就可以了,何必跟自己过不去呢。

 

资源权限的接口参考如下:

28171301_Rmvr.gif 代码
        
//
        
///
 资源权限范围设定关系相关
        
//
        
///
 
<summary>
        
///
 56.获取资源权限范围主键数组
        
///
 
</summary>
        
///
 
<param name="userInfo">
用户
</param>
        
///
 
<param name="resourceCategory">
资源分类
</param>
        
///
 
<param name="resourceId">
资源主键
</param>
        
///
 
<param name="targetCategory">
目标类别
</param>
        
///
 
<param name="permissionItemCode">
权限编号
</param>
        
///
 
<returns>
主键数组
</returns>
        [OperationContract]
        
string
[] GetResourcePermissionScopeTargetIds(BaseUserInfo userInfo, 
string
 resourceCategory, 
string
 resourceId, 
string
 targetCategory, 
string
 permissionItemCode);
        
///
 
<summary>
        
///
 57.授予资源的权限范围
        
///
 
</summary>
        
///
 
<param name="userInfo">
用户
</param>
        
///
 
<param name="resourceCategory">
资源分类
</param>
        
///
 
<param name="resourceId">
资源主键
</param>
        
///
 
<param name="targetCategory">
目标类别
</param>
        
///
 
<param name="grantTargetIds">
目标主键数组
</param>
        
///
 
<param name="permissionItemId">
权限主键
</param>
        
///
 
<returns>
影响的行数
</returns>
        [OperationContract]
        
int
 GrantResourcePermissionScopeTarget(BaseUserInfo userInfo, 
string
 resourceCategory, 
string
 resourceId, 
string
 targetCategory, 
string
[] grantTargetIds, 
string
 permissionItemId);
        
///
 
<summary>
        
///
 58.撤消资源的权限范围
        
///
 
</summary>
        
///
 
<param name="userInfo">
用户
</param>
        
///
 
<param name="resourceCategory">
资源分类
</param>
        
///
 
<param name="resourceId">
资源主键
</param>
        
///
 
<param name="targetCategory">
目标类别
</param>
        
///
 
<param name="revokeTargetIds">
目标主键数组
</param>
        
///
 
<param name="permissionItemId">
权限主键
</param>
        
///
 
<returns>
影响的行数
</returns>
        [OperationContract]
        
int
 RevokeResourcePermissionScopeTarget(BaseUserInfo userInfo, 
string
 resourceCategory, 
string
 resourceId, 
string
 targetCategory, 
string
[] revokeTargetIds, 
string
 permissionItemId);
        
///
 
<summary>
        
///
 59.获取用户的某个资源的权限范围
        
///
 
</summary>
        
///
 
<param name="userInfo">
用户
</param>
        
///
 
<param name="userId">
用户主键
</param>
        
///
 
<param name="targetCategory">
目标类别
</param>
        
///
 
<param name="permissionItemCode">
权限编号
</param>
        
///
 
<returns>
主键数组
</returns>
        [OperationContract]
        
string
[] GetResourceScopeIds(BaseUserInfo userInfo, 
string
 userId, 
string
 targetCategory, 
string
 permissionItemCode);

  

资源权限的判断函数参考如下:

28171301_Rmvr.gif 代码
        
///
 
<summary>
        
///
 获得用户的某个权限范围资源主键数组
        
///
 
</summary>
        
///
 
<param name="userId">
用户
</param>
        
///
 
<param name="targetCategory">
资源分类
</param>
        
///
 
<param name="permissionItemCode">
权限编号
</param>
        
///
 
<returns>
主键数组
</returns>
        
public
 
string
[] GetResourceScopeIds(
string
 userId, 
string
 targetCategory, 
string
 permissionItemCode)
        {
            BasePermissionItemManager permissionItemManager 
=
 
new
 BasePermissionItemManager(DbHelper, UserInfo);
            
string
 permissionItemId 
=
 permissionItemManager.GetID(BasePermissionItemTable.FieldCode, permissionItemCode);
            BaseUserManager userManager 
=
 
new
 BaseUserManager(DbHelper, UserInfo);
            
string
 defaultRoleId 
=
 userManager.GetProperty(userId, BaseUserTable.FieldRoleId);
            
string
 sqlQuery 
=
 
string
.Empty;
            sqlQuery 
=
  
                        
//
 用户的权限
                          
"
 SELECT Base_ResourcePermissionScope.TargetId 
"
                        
+
 
"
   FROM Base_ResourcePermissionScope 
"
                        
+
 
"
  WHERE (Base_ResourcePermissionScope.ResourceCategory = 'User') 
"
                        
+
 
"
        AND (Base_ResourcePermissionScope.ResourceId = '
"
 
+
 userId 
+
 
"
') 
"
                        
+
 
"
        AND (Base_ResourcePermissionScope.TargetCategory = '
"
 
+
 targetCategory 
+
 
"
') 
"
                        
+
 
"
        AND (Base_ResourcePermissionScope.PermissionId = '
"
 
+
 permissionItemId 
+
 
"
') 
"
                        
+
 
"
        AND (Base_ResourcePermissionScope.Enabled = 1) 
"
                        
+
 
"
        AND (Base_ResourcePermissionScope.DeleteMark = 0)
"
                      
                        
+
 
"
 UNION 
"
               
                        
//
 用户归属的角色的权限                            
                        
+
 
"
 SELECT Base_ResourcePermissionScope.TargetId 
"
                        
+
 
"
   FROM Base_ResourcePermissionScope 
"
                        
+
 
"
  WHERE (Base_ResourcePermissionScope.ResourceCategory  = 'Role') 
"
                        
+
 
"
        AND (Base_ResourcePermissionScope.TargetCategory  = '
"
 
+
 targetCategory 
+
 
"
') 
"
                        
+
 
"
        AND (Base_ResourcePermissionScope.PermissionId = '
"
 
+
 permissionItemId 
+
 
"
') 
"
                        
+
 
"
        AND (Base_ResourcePermissionScope.DeleteMark = 0)
"
                        
+
 
"
        AND (Base_ResourcePermissionScope.Enabled = 1) 
"
                        
+
 
"
        AND ((Base_ResourcePermissionScope.ResourceId IN ( 
"
                        
+
 
"
             SELECT Base_UserRole.RoleId 
"
                        
+
 
"
               FROM Base_UserRole 
"
                        
+
 
"
              WHERE (Base_UserRole.UserId  = '
"
 
+
 userId 
+
 
"
') 
"
                        
+
 
"
                  AND (Base_UserRole.Enabled = 1) 
"
                        
+
 
"
                  AND (Base_UserRole.DeleteMark = 0) )
"
                        
//
 用户的默认角色
                        
+
 
"
              OR (Base_ResourcePermissionScope.ResourceId = '
"
 
+
 defaultRoleId 
+
 
"
'))
"
 
                        
+
 
"
"
;
            DataTable dataTable 
=
 DbHelper.Fill(sqlQuery);
            
string
[] resourceIds 
=
 BaseBusinessLogic.FieldToArray(dataTable, BaseResourcePermissionScopeTable.FieldTargetId);
            
return
 resourceIds;
        }

 

没有真正的通用,但是允许个性化需求定制、有丰富的底层API可调用,有比较考虑完善的底层数据设计,有完善的例子程序,配套文档,就相当于是通用了,给你了一把刀,能把这把到刀耍成什么样,还是有天大的差别的,武林高手用这把刀?我的农民爷爷用这把刀?能把这个刀耍成什么样?我们自己想像就可以了。

 

 等空时,再讲讲,在公司假劣药查询网站系统中使用C# .NET 走火入魔权限组件的经验。

 

 

 

 

 

转载于:https://my.oschina.net/iwenr/blog/227863

你可能感兴趣的文章
hadoop1.x作业提交过程分析(源码分析第二篇)
查看>>
默认安装vsftpd后
查看>>
《Redis设计与实现》读书笔记
查看>>
waiting for changelog lock.
查看>>
小白学爬虫-批量部署Splash负载集群
查看>>
你离BAT之间,只差这一套Java面试题
查看>>
laravel package 推荐,数据备份
查看>>
Synchronized锁在Spring事务管理下,为啥还线程不安全?
查看>>
环境变量PATH cp命令 mv命令 文档查看cat/more/less/head/tail
查看>>
阿里云亮相2019联通合作伙伴大会,边缘计算等3款云产品助力5G时代产业数字化转型...
查看>>
dubbo源码分析-服务端发布流程-笔记
查看>>
阿里云发布Apsara SA系列混合云存储阵列
查看>>
GoJS教程:链接模版
查看>>
QListWidget方式显示缩略图
查看>>
金三银四:蚂蚁金服JAVA后端面试题及答案之二面
查看>>
Ubuntu 外网不通解决方案
查看>>
OSChina 周六乱弹 —— 历史总是惊人的相似
查看>>
MySQL 大小写
查看>>
Lync 2013部署图片赏析-证书服务安装配置
查看>>
HTML5 本地缓存 (web存储)
查看>>