zoukankan      html  css  js  c++  java
  • 多用户角色权限访问模块问题”的解决思路( 位运算 + ActionFilterAttribute )

    如果你还是不太懂位运算,请看我的文章:那些年我们一起遗忘的位运算!

    下面是我在这次项目中学习到的,我眼中的位运算的应用!主要是实现 通知的3个操作:

     1.  置顶

     2.  设为首页

     3.  同时为 “置顶”+ “设为首页”

    效果如图:

    我们要想简便的进行位运算,我们可以直接进行如下枚举定义,以2的次方定义,应为他们的值很特殊:

    数      二进制值

    1   1 2     10 4       100 8     1000 16     10000 32     100000 64     1000000 128   10000000

    复制代码
     /// <summary>
        /// 通知类型
        /// </summary>
        public enum NoticeType
        {
            /// <summary>
            /// 普通
            /// </summary>
            [Description("普通")]
            Normal = 1,
            /// <summary>
            /// 置顶
            /// </summary>
            [Description("置顶")]
            Top = 2,
            /// <summary>
            /// 设置首页
            /// </summary>
            [Description("设置首页")]
            Home = 4,
        }
    复制代码

    我们就可以很方便的接受参数来进行位运算的操作,代码如下:

    复制代码
            /// <summary>
            /// 置顶及设置为首页
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            [Role]
            public ActionResult Workshop_NoticeSet(int id, int typeFlag)
            {
                bool res = false;
                Workshop_Notice entity = workshopManager.GetWorkshop_Notice(i => i.WorkshopNoticeID == id);
                if (entity != null)
                {
                    switch ((NoticeType)typeFlag)
                    {
                        case NoticeType.Home:
                            if ((entity.TypeFlag & (int)NoticeType.Home) > 0)
                                entity.TypeFlag = entity.TypeFlag ^ (int)NoticeType.Home; //取消置顶
                            else
                                entity.TypeFlag = entity.TypeFlag | (int)NoticeType.Home; //置顶
                            break;
                        case NoticeType.Top:
                            if ((entity.TypeFlag & (int)NoticeType.Top) > 0)
                                entity.TypeFlag = entity.TypeFlag ^ (int)NoticeType.Top;  //取消设为首页
                            else
                                entity.TypeFlag = entity.TypeFlag | (int)NoticeType.Top; //设为首页
                            break;
                    }
                    if (workshopManager.EditWorkshop_Notice(i => new Workshop_Notice
                    {
                        TypeFlag = entity.TypeFlag,
                        WorkshopNoticeID = entity.WorkshopNoticeID,
                    }).IsComplete)
                        res = true;
                }
                return Content(res.ToString());
            }
    复制代码

    此项目需求就是根据给用户分配的权限,进行相应的权限模块浏览功能,因为项目不是很大,所以权限没有去用一张表去存,我的解决思路如下,希望大家给点建议。

    数据库用户表结构如下

     

    数据库表梳理:

    BankUserMember:权限分配表(1-省行管理员, 2-分行管理员, 0-网点负责人(普通会员),4-超级管理员)。

          BankUserInfo: 用户详细表。

              BankAgent: 机构层级表。

     用户权限枚举表如下

    复制代码
      /// <summary>
        /// 用户角色
        /// </summary>
        public enum Role
        {
            /// <summary>
            /// 注册会员
            /// </summary>
            Member = 0,
            /// <summary>
            /// 省行管理员
            /// </summary>
            ProvinceManager = 1,
            /// <summary>
            /// 分行管理员
            /// </summary>
            BranchManager = 2,
            /// <summary>
            /// 总行管理员
            /// </summary>
            Manager = 3,
            /// <summary>
            /// 超级管理员
            /// </summary>
            SuperManager = 4
      }
    复制代码

      普通会员查看功能如下代码

    复制代码
        /// <summary>
        /// 会员产看功能
        /// </summary>
        [Role(Entity.Enum.Role.Member)]
        public class PerformanceController : BaseController
        {
            [NoCache]
            public ActionResult Index(int? page)
            {            //todo:
            } 
        }
    复制代码

        (省行,分行)管理员查看功能如下代码:

    复制代码
     /// <summary>
        /// (省行,分行)管理员查看功能
        /// </summary>
        [Role(Entity.Enum.Role.ProvinceManager | Entity.Enum.Role.BranchManager)]
        public class AdminPerformanceController : BaseController
        {
            [NoCache]
            public ActionResult Index(int? page)
            {            //todo:
            }
        }
    复制代码

       权限 RoleAttribute过滤器 如下代码:

    复制代码
     /// <summary>
        /// Action角色访问控制
        /// </summary>
        public class RoleAttribute : ActionFilterAttribute
        {
            /// <summary>
            /// 控制角色
            /// </summary>
            public Entity.Enum.Role _role { get; set; }
            /// <summary>
            /// 登录角色
            /// </summary>
            public int memberLoginRole = 0;
    
            public RoleAttribute() { }
            /// <summary>
            /// 验证方式和角色进行构造
            /// </summary>
            /// <param name="flag"></param>
            public RoleAttribute(Entity.Enum.Role role)
            {
                _role = role;
            }
    
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                if (!CheckRole())
                {
                    string urlreffer = filterContext.HttpContext.Request.UrlReferrer == null ? string.Empty                                             : filterContext.HttpContext.Request.UrlReferrer.AbsoluteUri;
                    if (string.IsNullOrEmpty(urlreffer))
                        urlreffer = filterContext.HttpContext.Request.Url == null ? string.Empty : filterContext.HttpContext.Request.Url.AbsoluteUri;
    
                    string locationUrl = string.Empty;
                    locationUrl = TsingDa.Common.WebConfig.GetWebConfig("website_url", "") + "/Home/Login?ReturnUrl=" +                                              filterContext.HttpContext.Server.UrlEncode(urlreffer);
                    RedirectResult loginUrl = new RedirectResult(locationUrl);
                    filterContext.Result = loginUrl;
                }
                else
                {
                    //---------【验证用户的控制器的访问权限利用位运算灵活的解决多角色问题)】---------
                    if (((int)_role & (int)memberLoginRole) <= 0 && ((int)_role != memberLoginRole))
                    {
                        filterContext.Result = new RedirectResult("/Home/RoleError");
                    }
                }
    
                base.OnActionExecuting(filterContext);
            }
    
            private bool CheckRole()
            {
                //验证有没有登陆Cookie操作,省略代码。。。。。。。。
             }
        }
    复制代码
  • 相关阅读:
    BZOJ3752 : Hack
    XIV Open Cup named after E.V. Pankratiev. GP of SPb
    XIII Open Cup named after E.V. Pankratiev. GP of Ukraine
    BZOJ2087 : [Poi2010]Sheep
    BZOJ2080 : [Poi2010]Railway
    BZOJ2082 : [Poi2010]Divine divisor
    Moscow Pre-Finals Workshop 2016. National Taiwan U Selection
    XIII Open Cup named after E.V. Pankratiev. GP of Asia and South Caucasus
    XIII Open Cup named after E.V. Pankratiev. GP of Azov Sea
    XIII Open Cup named after E.V. Pankratiev. GP of SPb
  • 原文地址:https://www.cnblogs.com/fx2008/p/4281023.html
Copyright © 2011-2022 走看看