字段的权限控制,一般就是控制对应角色人员对某个业务对象的一些敏感字段的可访问性:包括可见、可编辑性等处理。本篇随笔结合基于SqlSugar的开发框架进行的字段控制管理介绍。
在设计字段权限的时候,我们需要了解这些还是基于RBAC的概念,基于角色进行授权的,而且我们的字段列表是属于具体的业务对象列表的,这里的业务对象是指一些我们具体的业务模块,如客户基础信息、人员基础信息、报价单等等,我们就是基于这些业务进行字段的控制的。
1、字段权限表的设计和界面管理
基于SqlSugar的开发框架,对应处理的业务对象信息的,是相关的实体对象信息,我们在数据库中设计两个数据库,一个用于存储对应实体类名称的信息,如ID,实体类全名,类路径等主体信息;一个存储对应角色配置的字段列表信息,结合起来就可以实现对应角色的字段权限控制了,数据库表设计信息如下所示。
两个业务表的部分字段信息如下所示。
系统中对于字段权限的设置界面如下所示。
通过列表对每个实体对象信息进行配置,如果没有对应的实体,从程序集中选择列出来即可加入进来。
加入对应的实体信息,我们可以根据名称反射接口获得对应字段参考的中文信息,然后进行展示,用于加入控制列表。
这样配置后,系统就记录了相关的配置信息,我们接下来就可以利用这些配置信息,在Winform界面上进行控件的显示处理操作了
/// <summary> /// 设置控件字段的权限显示或者隐藏(默认不使用字段权限) /// </summary> private async void SetPermit() { #region 设置控件和字段的对应关系 this.txtName.Tag = "Name"; this.txtAge.Tag = "Age"; #endregion //获取列表权限的列表 var permitDict = await BLLFactory<IFieldPermitService>.Instance.GetColumnsPermit(typeof(CustomerInfo).FullName, LoginUserInfo.Id.ToInt32()); this.SetControlPermit(permitDict, this.layoutControl1); await Task.CompletedTask; }
2、在Winform界面上进行控件的显示处理操作
在界面上,我们为了绑定界面控件和字段的关系,需要设置一个Tag来标识,然后根据系统配置信息,自动进行字段权限的控制处理(隐藏、设置只读,不限制等)
/// <summary> /// 设置控件字段的权限显示或者隐藏(默认不使用字段权限) /// </summary> private async void SetPermit() { #region 设置控件和字段的对应关系 this.txtName.Tag = "Name"; this.txtAge.Tag = "Age"; #endregion //获取列表权限的列表 var permitDict = await BLLFactory<IFieldPermitService>.Instance.GetColumnsPermit(typeof(CustomerInfo).FullName, LoginUserInfo.Id.ToInt32()); this.SetControlPermit(permitDict, this.layoutControl1); await Task.CompletedTask; }
设置控件的字段显示方式 SetControlPermit ,代码如下所示。
/// <summary> /// 设置控件的可见、读写权限显示 /// </summary> /// <param name="panel">控件对象</param> /// <param name="permitDict">字段和权限字典,字典值为权限控制:0可读写,1只读,2隐藏值,3不显示</param> /// <param name="layoutControl">如果存在布局,则使用布局控件,否则为空</param> public static void SetControlPermit(this Control panel, Dictionary<string, int> permitDict, LayoutControl layoutControl = null) { foreach (Control ctrl in panel.Controls) { var baseCtrl = ctrl as BaseEdit; if (baseCtrl != null) { var tag = string.Concat(baseCtrl.Tag); if (!string.IsNullOrEmpty(tag) && permitDict.ContainsKey(tag)) { var permit = permitDict[tag]; var visible = (permit == 0 || permit == 1);//2、3不可见 if (layoutControl != null) { var layoutItem = layoutControl.GetItemByControl(baseCtrl); if (layoutItem != null) { layoutItem.ToVisibility(visible); } } baseCtrl.Visible = visible; baseCtrl.ReadOnly = permit == 1; } } ctrl.SetControlPermit(permitDict, layoutControl); } }
上面代码主要就是变量面板中的控件,并判断tag标签,然后进行只读、不可见、正常等的判断。
在列表界面中,我们可以通过设置隐藏字符让内容隐藏,如下界面效果所示。
如果不可见,就在界面上不显示这个列了,而非隐藏。
同样类似编辑控件界面,我们在列表界面也提供了对应的方法,用于隐藏列表字段的某些信息,如下代码所示。
//获取字段显示权限,并设置(默认不使用字段权限) this.winGridViewPager1.gridView1.SetColumnsPermit(permitDict);
它的实现规则也是类似,根据配置的字段权限控制点信息进行处理,决定是否显示,是否隐藏,是否正常处理。
它的permitDic也是根据配置信息读取出来进行判断即可。
//根据业务对象获取对应的显示字段,如果没有设置,那么根据FieldPermit表的配置获取字段权限列表 var permitDict = await BLLFactory<IFieldPermitService>.Instance.GetColumnsPermit(typeof(BlackIPInfo).FullName, Portal.gc.UserInfo.Id); var displayColumns = await BLLFactory<IBlackIPService>.Instance.GetDisplayColumns(); if (permitDict != null && permitDict.Keys.Count > 0) { //0可读写,1只读,2隐藏值,3不显示 displayColumns = string.Join(",", permitDict.Keys.Where(s => permitDict[s] < 2)); } this.winGridViewPager1.DisplayColumns = displayColumns;
下面是具体逻辑的通用控制方法,把它作为控件的扩展函数,我们就只需要一行代码调用就是写控制了
/// <summary> /// 根据参数权限字典的值:0可读写,1只读,2隐藏值,3不显示,设置列的权限。 /// </summary> /// <param name="gridView">GridView对象</param> /// <param name="fieNamePermitDict">字段和权限字典,字典值为权限控制:0可读写,1只读,2隐藏值,3不显示</param> public static void SetColumnsPermit(this GridView gridView, Dictionary<string,int> fieNamePermitDict) { char passwordChar = '*'; foreach (GridColumn col in gridView.Columns) { var include = fieNamePermitDict.ContainsKey(col.FieldName); if (include) { int permit = fieNamePermitDict[col.FieldName]; switch (permit) { case 0://正常可见、可读写 col.OptionsColumn.AllowEdit = true; col.OptionsColumn.ReadOnly = false; col.AppearanceHeader.ForeColor = Color.Black; col.Visible = true; break; case 1: //只读 col.OptionsColumn.AllowEdit = false; col.OptionsColumn.ReadOnly = true; col.AppearanceHeader.ForeColor = Color.Gray; col.Visible = true; break; case 2: //隐藏值 var edit = col.CreateTextEdit(); col.Tag = string.Concat(passwordChar);//用来在界面端进行判断,避免设置DisplayText edit.PasswordChar = passwordChar; col.Visible = true; break; case 3: //不可见 col.Visible = false; break; } } } }
通过上面的代码处理,我们就能实现对Winform界面中的列表,编辑窗体的控件,进行相关的字段权限控制显示了。如下是实现的界面效果。
这样在系统后台,就可以根据需要设置一些敏感字段的信息隐藏或者只读处理了。
系列文章:
《基于SqlSugar的开发框架的循序渐进介绍(1)--框架基础类的设计和使用》
《基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理》
《基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发》
《基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理 》
《基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转》
《基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口 》
《基于SqlSugar的开发框架循序渐进介绍(7)-- 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传》
《基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录》
《基于SqlSugar的开发框架循序渐进介绍(9)-- 结合Winform控件实现字段的权限控制》
《基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理》
《基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结》
《基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理》
《基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用》
《基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用》
《基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成》
《基于SqlSugar的开发框架循序渐进介绍(16)-- 工作流模块的功能介绍》
《基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理》
《基于SqlSugar的开发框架循序渐进介绍(18)-- 基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面》
专注于代码生成工具、.Net/.NetCore 框架架构及软件开发,以及各种Vue.js的前端技术应用。著有Winform开发框架/混合式开发框架、微信开发框架、Bootstrap开发框架、ABP开发框架、SqlSugar开发框架等框架产品。
转载请注明出处:撰写人:伍华聪 http://www.iqidi.com