Winform开发框架之权限管理系统的改进

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

权限管理系统,一直是很多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 = 0;
                pNode.SelectedImageIndex = 0;
                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 = 1;
                    item.SelectedImageIndex = 1;
                    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 + 1 > 3) ? 3 : fnode.ImageIndex + 1;
                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 ? 1 : 0, 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", 0, 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开发框架之权限管理系统的改进,如需转载请自行联系原博主。



相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1月前
|
Linux Shell 数据安全/隐私保护
第十一篇:系统管理体系之服务管理
第十一篇:系统管理体系之服务管理
|
4月前
|
安全 Java 数据安全/隐私保护
构建高效网站后台:权限管理系统设计与实现
【7月更文挑战第5天】在现代Web应用开发中,权限管理是后台系统不可或缺的一部分,它确保了系统的安全性与用户数据的隐私。良好的权限管理系统能够精细控制不同用户角色对功能模块及数据资源的访问权限,从而提升系统的灵活性和安全性。本文将深入探讨权限管理的基本概念、设计思路,并通过一个简单的代码示例展示如何在Web后台中实现基本的权限控制逻辑。
298 2
|
5月前
|
监控 安全 Java
老程序员分享:JeeSite快速开发平台、功能介绍、用户权限、数据权限、系统管理
老程序员分享:JeeSite快速开发平台、功能介绍、用户权限、数据权限、系统管理
175 0
|
存储 运维 监控
三大架构图—结合若依权限管理系统
最近在进行架构师的培训,结合具体的项目也许能够帮助我们更好的理解架构对我们而言的意义,今天我着重从技术架构图来讨论架构图的具体应用
|
存储 设计模式 缓存
权限管理系统,可以这么设计
权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源,不多不少。对权限做管理的系统,就是权限管理系统。
|
数据安全/隐私保护
JSP+Servlet培训班作业管理系统[22]–番外篇之过滤器与权限管理
本文目录 1. 本章任务 2. 开发过滤器类 3. 过滤器拦截 4. 过滤器通过 5. 权限管理的实现
134 0
|
数据库 数据安全/隐私保护 开发框架
|
存储 关系型数据库 数据库
下一篇
无影云桌面