基于角色的用户权限设计+TreeView【栏目权限 操作权限】

背景:
         最近看到不少关于权限设计的文章,发现很多都只是谈了个大概的设计方案,实现部分代码非常少。正好前段时间也弄了套自己的方案,俺跟着也凑凑热闹。

系统分析:

     权限:
             在系统中,权限通过模块+动作来产生,模块就是整个系统中的一个子模块,可能对应一个菜单,动作也就是整个模块中(在B/S 系统中也就是一个页面的所有操作,比如“浏览、添加、修改、删除”等)。将模块与之组合可以产生此模块下的所有权限。

     角色:
            权限的集合,角色与角色之间属于平级关系,将基本权限添加到一个角色中,方便权限的分配。
    表设计
            我这里偷了个懒,将角色表、角色_权限表二表合一。
            角色表:Role: iSyscode,cName,cMenuList,dDate,iStatusCode
            权限表:Menu:iSysCode,cName,iParentID,dDate,iStatusCode

过程:
     1、登录:
           用户登录提取其角色ID,根据角色ID取出其享有的权限cMenuList。后台操作树根据这个权限集合动态生成。需要说明的是这棵树无刷新动态提取子项。
 效果:

 1
 2 1public void Treeview1_TreeNodePopulate(object sender, TreeNodeEventArgs e)
 3 2    {
 4 3        if (IsCallback)
 5 4        {
 6 5            if (e.Node.ChildNodes.Count == 0)
 7 6            {
 8 7                LoadChildNode(e.Node);
 9 8            }

10 9        }

1110    }

1211
1312    private void LoadChildNode(TreeNode node)
1413    {
1514        int iParentID = Convert.ToInt32(node.Value);
1615        //1  系统管理员   //2  总经理    //3    用户  
1716        Basic_Menu bmMain = new Basic_Menu();
1817        IList<Basic_MenuInfo> bmInfoList = bmMain.GetMenu_List(1, iParentID);
1918
2019        foreach (Basic_MenuInfo bmInfo in bmInfoList)
2120        {
2221            TreeNode subNode = new TreeNode(bmInfo.cName);
2322            subNode.Value = bmInfo.iSysCode.ToString();
2423            subNode.NavigateUrl = "http://www.lxqq.cn";
2524            subNode.Target = "_blank";
2625
2726            try
2827            {
2928                if (bmInfo.iChildCount > 0)
3029                {
3130                    subNode.SelectAction = TreeNodeSelectAction.SelectExpand;
3231                    subNode.PopulateOnDemand = true;
3332                    subNode.NavigateUrl = "#";
3433                }

3534            }

3635            catch
3736            {
3837                subNode.ImageUrl = "WebResource.axd?a=s&r=TreeView_XP_Explorer_ParentNode.gif&t=632242003305625000";
3938            }

4039            node.ChildNodes.Add(subNode);
4140        }

4241        
4342    }

     2、权限设置:
           在这里我用Div布局,用Css设定缩进效果,后台用了个递归取出所有权限项,并根据所设置对象拥有的权限项设定checkbox的状态是否选中。设置完毕,(用hidden包存所有选中项),后台用Request.Form取出所有选定项的值加以操作。在这还有一个重点是checkbox的onclick操作。如选中父项,则相应子项也随之选中;子项选中,父项也跟着选中。在这里,要感谢我的老大。呵呵,因为我刚弄到这,就发现我老大有这个功能的JS实现。稍加改动,呵呵,正好用到这里。

 代码:

 1
 2 1protected void Page_Load(object sender, EventArgs e)
 3 2    {
 4 3        if (!this.IsPostBack)
 5 4        {
 6 5            string str = BasicMenuList(0);
 7 6            content.InnerHtml = str;
 8 7
 9 8            string strMenuItem="1,2,3,4,5,6,7,8,11";
10 9            WebUtility.ScriptStartupRegister(this.Page, "SetDefaultValue('"+strMenuItem+"')");
1110        }

1211    }

1312    private string BasicMenuList(int iParentID)
1413    {
1514        string result = "";
1615        //1  系统管理员   //2  总经理    //3    用户   
1716        Basic_Menu bmMain = new Basic_Menu();
1817        IList<Basic_MenuInfo> bmInfoList = bmMain.GetMenu_List(1, iParentID);
1918
2019        foreach(Basic_MenuInfo bmInfo in bmInfoList)
2120        {
2221            result += "<div class=\"divIndent2\">" + string.Format("<input type=\"checkbox\" id=\"cb{0}\" parentID=\"{3}\" childCount=\"{4}\" value=\"{1}\" onclick=\"DoSelect(this);\">{2}", bmInfo.iSysCode, bmInfo.iSysCode, bmInfo.cName, iParentID, bmInfo.iChildCount);
2322            if (bmInfo.iChildCount > 0)
2423            {
2524                result += BasicMenuList(bmInfo.iSysCode);
2625            }

2726
2827            result += "</div>";
2928        }

3029        return result;
3130    }

JS实现代码:

  1
  2  1<div style="text-align: left;">
  3  2            <div>权限管理示例</div><br />
  4  3            <div id="content" class="divIndent1" runat="server">
  5  4            </div>
  6  5            <br />
  7  6            <asp:Button ID="btnShow" Text="SET-Permission" OnClientClick="return setValue();" runat="server" OnClick="btnShow_Click" />
  8  7            <input type="hidden" id="hiddenRes" runat="server" />
  9  8        </div>
 10  9
 11 10        <script language="javascript" type="text/javascript">
 12 11            var checkStatus;
 13 12
 14 13            //将值保存在Hidden里,以便后台读取
 15 14            function setValue()
 16 15            {
 17 16                var t = document.getElementsByTagName("input");
 18 17                var str="";
 19 18                            
 20 19                for(var i=0; i<t.length; i++)
 21 20                {
 22 21                    if (t[i].type == "checkbox" && t[i].checked==true)
 23 22                    {
 24 23                        str+=t[i].value+",";
 25 24                    }

 26 25                }

 27 26                document.getElementById("hiddenRes").value=str;
 28 27            }

 29 28
 30 29            //设置默认值
 31 30            function SetDefaultValue( xValue )
 32 31            {
 33 32                var x;
 34 33                if( xValue.length == 0)
 35 34                {
 36 35                    return false;
 37 36                }

 38 37                else
 39 38                {
 40 39                    x = xValue.split(",");
 41 40                }

 42 41                
 43 42                with( document.all)
 44 43                {
 45 44                    forvar i = 0; i<x.length; i++)
 46 45                    {
 47 46                        item("cb" + x[i]).checked = true;
 48 47                    }

 49 48                }

 50 49            }

 51 50
 52 51            //
 53 52            function DoSelect(objElement)
 54 53            {
 55 54                var iParentID=objElement.parentID;
 56 55                var iSysCode=objElement.value;
 57 56                checkStatus = objElement.checked;
 58 57                
 59 58                //处理自己
 60 59                //if()
 61 60                //处理父节点
 62 61                if(checkStatus==true)//选中则处理父节点
 63 62                {
 64 63                    DoSelectParent(iParentID);
 65 64                    DoSelectChild(iSysCode);
 66 65                }

 67 66                //处理子节点
 68 67                if(checkStatus==false)
 69 68                {
 70 69                    DoSelectChild(iSysCode);
 71 70                }

 72 71            }

 73 72
 74 73            //处理父节点
 75 74            function DoSelectParent(iParentID)
 76 75            {
 77 76                var t = document.getElementsByTagName("input");
 78 77                            
 79 78                for(var i=0; i<t.length; i++)
 80 79                {
 81 80                    if (t[i].type == "checkbox" && t[i].value==String(iParentID))
 82 81                    {
 83 82                        t[i].checked = checkStatus;
 84 83                        if( t[i].parentID != 0)
 85 84                        {
 86 85                            DoSelectParent(t[i].parentID);
 87 86                        }

 88 87                    }

 89 88                }

 90 89            }

 91 90
 92 91            //处理子节点
 93 92            function DoSelectChild(iSysCode)
 94 93            {
 95 94                var t = document.getElementsByTagName("input");
 96 95                            
 97 96                for(var i=0; i<t.length; i++)
 98 97                {
 99 98                    if (t[i].type == "checkbox" && t[i].parentID==String(iSysCode))
100 99                    {
101100                        t[i].checked = checkStatus;
102101                        if( t[i].childCount!=0)
103102                        {
104103                            DoSelectChild(t[i].value);
105104                        }

106105                    }

107106                }

108107            }

109108        </script>


以前还从没想过可以在HTML元素里自定义属性,这里我在checkbox里添加了好几个,parentID,childCount.别说,还真好用。 

说明:
        此权限设计实为测试版本,实际开发中,数据库设计将进一步分解。例如分为:用户表Users,权限表:Permission 角色表Role,用户角色表:User_Role,角色权限表:Role_Permission。另外如果有需要的话,还可以进一步分为栏目权限和操作权限,增加操作表:Operate 栏目操作表:Permission_Operate。
        水平有限,写的有点乱。有什么不同意见欢迎一起交流!

原文地址:https://www.cnblogs.com/xpengfee/p/890800.html