权限管理系统,一直是很多Mis系统和一些常见的管理系统所需要的,所以一般可以作为独立的模块进行开发,需要的时候进行整合即可,不需要每次从头开发,除非特殊的系统需求。我在Winform开发框架介绍中的随笔中,很早之前在《Winform开发框架之权限管理系统》就写过关于我的通用权限管理系统的一些介绍,当时这个版本的还是传统样式的,界面如下所示。

由于我的Winform开发框架需要,我把权限管理系统、字典管理模块、分页控件等都扩展了支持传统样式、DotNetBar控件样式,以及DevExpress控件样式。这些样式的界面之前也已经介绍不少了,本文主要介绍使用DevExpress控件样式的权限管理系统,对一些新的功能扩展以及完善,包括系统类型管理、菜单管理、功能管理、登陆日志管理等模块进行介绍。

本权限管理系统包括用户管理、组织机构管理、角色管理、系统类型定义、功能管理、菜单管理、用户登录日志管理,以及对相应对象的权限控制管理等功能。整个权限管理系统是基于RBAC(基于角色的访问控制)方式进行权限控制,是一个独立的权限管理系统,需要的时候业务系统与之进行整合即可,实现通用模块的高效利用和统一管理等方面。

1、系统类型管理

系统类型,是我们在权限系统中定义的一个系统分类,对于不同的系统,我们通过这个定义进行区分,可以实现多个业务系统的管理(虽然一般情况下,我们只是管理一个系统)。系统类型管理界面如下所示。

这个对象的管理,以前一直在权限系统中,通过修改数据库进行初始化,不过我觉得把它作为一个独立的数据进行维护,然后为功能定义、菜单、登陆日志等和系统类型关联的数据进行设置管理,应该是比较方便的。

因为,功能定义是基于某个系统而增加的一系列功能控制ID的定义,方便实现按钮级别和数据级别的权限控制的基础。

菜单的定义,是用来实现基于动态配置功能模块的菜单,引入该模块的初衷是用来方便动态配置Winform或者Web的功能菜单,这个也是不同的系统肯定有不同的菜单了。

登陆日志管理,是用来方便记录来自业务系统对权限系统接口的重要接口调用的记录,如登陆、修改密码等操作,一般情况下,我们用不同的业务系统来区分它们的数据。

2、菜单管理

刚才说到,这里的菜单管理,是指用来实现基于动态配置功能模块的菜单,用来实现基于Winform、Web菜单的集成统一,对于不同的系统,菜单定义是不同的,因此他们是基于某个系统类型下面的数据管理。

为了有效管理菜单数据,我把菜单的关系用树形控件进行展示,并通过SplitContainer控件实现布局的合理切分,可以实现自由拖动,界面效果如下所示。

菜单的数据显示,左边使用了树形控件,数据通过递归方式进行绑定。右边数据是通过我的分页控件进行数据绑定,并且绑定的数据是通过了层级的缩进格式化了的。

树菜单绑定的核心递归代码如下所示。

        /// <summary>
/// 绑定树形数据
/// </summary>
private void InitTree()
{
treeView1.Nodes.Clear();
treeView1.BeginUpdate();
Cursor.Current = Cursors.WaitCursor; //先获取系统类型,然后对不同的系统类型下的菜单进行绑定显示
List<SystemTypeInfo> typeList = BLLFactory<SystemType>.Instance.GetAll();
foreach (SystemTypeInfo typeInfo in typeList)
{
TreeNode pNode = new TreeNode();
pNode.Text = typeInfo.Name;//系统类型节点
pNode.Name = typeInfo.OID;
pNode.ImageIndex = ;
pNode.SelectedImageIndex = ;
this.treeView1.Nodes.Add(pNode); string systemType = typeInfo.OID;//系统标识ID //绑定树控件
//一般情况下,对Ribbon样式而言,一级菜单表示RibbonPage;二级菜单表示PageGroup;三级菜单才是BarButtonItem最终的菜单项。
List<MenuNodeInfo> menuList = BLLFactory<SysMenu>.Instance.GetTree(systemType);
foreach (MenuNodeInfo info in menuList)
{
TreeNode item = new TreeNode();
item.Name = info.ID;
item.Text = info.Name;//一级菜单节点
item.Tag = info;//对菜单而言,记录其MenuNodeInfo到Tag中,作为判断依据
item.ImageIndex = ;
item.SelectedImageIndex = ;
pNode.Nodes.Add(item); AddChildNode(info.Children, item);
}
} Cursor.Current = Cursors.Default;
treeView1.EndUpdate();
this.treeView1.ExpandAll();
} private void AddChildNode(List<MenuNodeInfo> list, TreeNode fnode)
{
foreach (MenuNodeInfo info in list)
{
TreeNode item = new TreeNode();
item.Name = info.ID;
item.Text = info.Name;//二、三级菜单节点
item.Tag = info;//对菜单而言,记录其MenuNodeInfo到Tag中,作为判断依据
int index = (fnode.ImageIndex + > ) ? : fnode.ImageIndex + ;
item.ImageIndex = index;
item.SelectedImageIndex = index;
fnode.Nodes.Add(item); AddChildNode(info.Children, item);
}
}

菜单的列表数据,通过分页控件绑定的代码如下所示。

        /// <summary>
/// 根据查询条件构造查询语句
/// </summary>
private string GetConditionSql()
{
SearchCondition condition = new SearchCondition();
condition.AddCondition("Name", this.txtName.Text, SqlOperator.Like);
condition.AddCondition("FunctionId", this.txtFunctionId.Text, SqlOperator.Like);
condition.AddCondition("Visible", this.txtVisible.Checked ? : , SqlOperator.Equal);
condition.AddCondition("WinformType", this.txtWinformType.Text, SqlOperator.Like);
condition.AddCondition("Url", this.txtUrl.Text, SqlOperator.Like); string where = condition.BuildConditionSql().Replace("Where", ""); return where;
} /// <summary>
/// 绑定列表数据
/// </summary>
private void BindData()
{
//entity
this.winGridViewPager1.DisplayColumns = "Name,Icon,Seq,FunctionId,Visible,WinformType,Url";
#region 添加别名解析 this.winGridViewPager1.AddColumnAlias("ID", "");
this.winGridViewPager1.AddColumnAlias("Name", "显示名称");
this.winGridViewPager1.AddColumnAlias("Icon", "图标");
this.winGridViewPager1.AddColumnAlias("Seq", "排序");
this.winGridViewPager1.AddColumnAlias("FunctionId", "功能ID");
this.winGridViewPager1.AddColumnAlias("Visible", "菜单可见");
this.winGridViewPager1.AddColumnAlias("WinformType", "Winform窗体类型");
this.winGridViewPager1.AddColumnAlias("Url", "Web界面Url地址"); #endregion string where = GetConditionSql();
List<MenuInfo> list = BLLFactory<SysMenu>.Instance.FindWithPager(where, this.winGridViewPager1.PagerInfo);
list = CollectionHelper<MenuInfo>.Fill("-1", , list, "PID", "ID", "Name");
this.winGridViewPager1.DataSource = new WHC.Pager.WinControl.SortableBindingList<MenuInfo>(list);
this.winGridViewPager1.PrintTitle = "功能菜单信息报表";
}

菜单的编辑界面如下所示。

本篇主要是介绍菜单的管理,对于菜单的动态加载管理,我会在另外一篇Winform开发框架中进行介绍。菜单定义数据里面的功能控件ID,是来自功能模块的功能控件ID,是用来控制不同用户所能访问的菜单资源的。

3、功能管理

功能定义,也是基于某个系统类型下面的,对于不同的业务系统,我们可以集中放在一个权限管理系统里面进行管理,但是功能的定义,根据不同的系统类型进行区分即可,这样的目标是用来实现多种企业应用的有效整合。

功能的管理,是整个权限系统的核心,因为通过对他们的定义,以及权限分配,都会影响各个角色用户可访问的功能;功能定义的数据,其实也是一个树形结构,可以用树控件进行展示出来,如下所示。

4、日志管理

我们知道,一般权限系统,管理用户很常见的,因此用户的登陆日志,一般情况下是由权限管理系统记录即可, 如每次用户登陆的时候,我们记录用户的登陆日志;如果用户修改密码,我们也做一个重要记录,这样对于在业务系统端的管理,我们就不需要管理他们的登陆方面的事件了。

日志管理分为两个部分,一个是通过权限管理系统本身的登录入口进行登录的,一个是通过与之集成的业务系统,通过API调用方式进行登录验证的, 他们的登录接口基本一样,只是部分数据不同。

            try
{
//判断用户是否登录成功
string ip = NetworkUtil.GetLocalIP();
string macAddr = HardwareInfoHelper.GetMacAddress(); string identity = BLLFactory<User>.Instance.VerifyUser(this.txtLogin.Text, this.txtPassword.Text, "WareMis", ip, macAddr);
if (!string.IsNullOrEmpty(identity))
{
//进一步判断用户角色
if (BLLFactory<User>.Instance.UserInRole(this.txtLogin.Text, RoleInfo.AdminName))
{
MessageUtil.ShowTips(string.Format("用户【{0}】身份验证正确", this.txtLogin.Text));
}
else
{
MessageUtil.ShowWarning("该用户没有管理员权限");
return;
}
}
else
{
MessageUtil.ShowWarning("用户名或密码错误");
return;
}
}
catch (Exception err)
{
MessageUtil.ShowError(err.Message);
}

权限管理系统对日志进行统一管理和展示,具体界面如下所示。

整个权限管理系统,目的提高系统开发速度和效率,因此通过独立开发,模块重用,易于集成等方式实现我们生产效率的最大化。

Winform开发框架之权限管理系统的改进的更多相关文章

  1. Winform开发框架之权限管理系统改进的经验总结(1)-TreeListLookupEdit控件的使用

    最近一直在做一些技术性的研究和框架改进工作,博客也落下好几天没有更新了,也该是时候静下心来,总结这段时间的一些技术改进的经验了.和上一阶段的CRM系统开发和技术研究一样,我都喜欢在一个项目或者模块完成 ...

  2. Winform开发框架之权限管理系统改进的经验总结(2)-用户选择界面的设计

    在上篇总结随笔<Winform开发框架之权限管理系统改进的经验总结(1)-TreeListLookupEdit控件的使用>介绍了权限管理模块的用户管理部分,其中主要介绍了其中的用户所属公司 ...

  3. Winform开发框架之权限管理系统改进的经验总结(4)-一行代码实现表操作日志记录

    在前面介绍了几篇关于我的权限系统改进的一些经验总结,本篇继续这一系列主体,介绍如何一行代码实现重要表的操作日志记录.我们知道,在很多业务系统里面,数据是很敏感的,特别对于一些增加.修改.删除等关键的操 ...

  4. Winform开发框架之权限管理系统改进的经验总结(4)--用户分级管理

    在实际的系统应用环境中,用户的分级管理一般也是比较常见的功能,小的业务系统可以不需要,但是一般涉及到集团.分子公司.或者是事业单位里面的各个处室或者某某局的人员管理,这些分级管理就显得比较必要,否则单 ...

  5. Winform开发框架之权限管理系统改进的经验总结(3)-系统登录黑白名单的实现

    在一般的权限系统里面,可能经常会看到系统的黑名单或者白名单的拦截功能.在一般权限系统里面,常见的黑名单就是禁止用户在某些IP上登录系统,白名单就是允许用户只在某些IP上登录系统.本随笔主要介绍在我的权 ...

  6. Winform开发框架之权限管理系统

    本文章转载:http://www.cnblogs.com/wuhuacong/archive/2011/05/08/2040620.html 至此,权限管理模块介绍已经完毕,下面给出一个调用例子Dem ...

  7. Web开发框架之权限管理系统

    Web开发框架之权限管理系统 记得我在很早之前,开始介绍我的Winform开发框架和我的WCF开发框架之初,我曾经给出下面的视图,介绍我整理的一个框架体系,其中包含有WInform开发框架以及我的We ...

  8. Winform开发框架之权限管理系统功能介绍

    权限管理系统的重要特性总结: 1) 高度集成的权限系统.独立模块,能快速整合使用.2) 符合权限的国际通用标准,基于RBAC(基于角色的访问控制)的角色权限控制.3) 多数据库架构支持,内置支持Sql ...

  9. ASP.NET MVC4.0+ WebAPI+EasyUI+KnockOutJS快速开发框架 通用权限管理系统

    1.基于 ASP.NET MVC4.0 + WebAPI + EasyUI + Knockout 的架构设计开发 2.采用MVC的框架模式,具有耦合性低.重用性高.生命周期成本低.可维护性高.有利软件 ...

随机推荐

  1. AtomicInteger简介

    这个类真的非常实用,更重要的是 它确实非常简单: 附上自己的代码,可以自己试试: AtomicInteger,一个提供原子操作的Integer的类.在Java语言中,++i和i++操作并不是线程安全的 ...

  2. Python: 拷贝函数签名

    使用场景有很多,比如C API在Python下很多都变成了(*args, **kwargs)的参数,这时候可能需要为其添加一个更严格签名来约束参数. 查了许多资料,能有效的拷贝函数签名貌似只能通过动态 ...

  3. magic_quotes_gpc 、 magic_quotes_runtime 、 magic_quotes_sybase 介绍

    一.三个配置项的作用与区别 magic_quotes_gpc 作用:对php服务器端接收的 GET POST COOKIE 的值执行 addslashes() 操作.作用范围是:WEB客户服务端.作用 ...

  4. 用Hibernate Tools生成Hibernate Mapping映射文件

    Eclipse中要集成安装Hibernate Tools组件 如果没有,请查看:Eclipse juno 中安装 JBoss Tools,集成Hibernate 一.确定环境: 1.Maven3.0. ...

  5. BugTracker.NET的配置

    需求管理+任务管理+bug管理+看板管理 要求一定要简单,切忌不要太复杂 之前用的禅道的,功能虽然很强大,但是忒复杂了,用不下去. 几点需要注意的地方: 1.web.config里邮件的地方有好几个地 ...

  6. Etl之HiveSql调优(left join where的位置)

    一.前言 公司实用Hadoop构建数据仓库,期间不可避免的实用HiveSql,在Etl过程中,速度成了避无可避的问题.本人有过几个数据表关联跑1个小时的经历,你可能觉得无所谓,可是多次Etl就要多个小 ...

  7. node-sass 安装卡在 node scripts/install.js 解决办法

    转自:https://segmentfault.com/a/1190000005921721 ======== 7月12日更新 ======== 总的来说就是两种方法解决: SASS_BINARY_S ...

  8. 由于无法创建应用程序域,因此未能执行请求。错误: 0x80070002 系统找不到指定的文件

    前两天安装了一堆补丁后突然发现,原本正常使用了一年的应用系统打不开了,到事件日志中发现有.net framewok 2.0的补丁安装失败的日志,于从从重装补丁开始.到重新注册.net框架,再到所有.n ...

  9. python 字符串复制

    通过变量来进行赋值 fstr = 'strcpy'sstr = fstrfstr = 'strcpy2'print sstr

  10. [转]GeoHash核心原理解析

    原文出处: zhanlijun    引子 机机是个好动又好学的孩子,平日里就喜欢拿着手机地图点点按按来查询一些好玩的东西.某一天机机到北海公园游玩,肚肚饿了,于是乎打开手机地图,搜索北海公园附近的餐 ...