背景:
最近看到不少关于权限设计的文章,发现很多都只是谈了个大概的设计方案,实现部分代码非常少。正好前段时间也弄了套自己的方案,俺跟着也凑凑热闹。
系统分析:
权限:
在系统中,权限通过模块+动作来产生,模块就是整个系统中的一个子模块,可能对应一个菜单,动作也就是整个模块中(在B/S 系统中也就是一个页面的所有操作,比如“浏览、添加、修改、删除”等)。将模块与之组合可以产生此模块下的所有权限。
角色:
权限的集合,角色与角色之间属于平级关系,将基本权限添加到一个角色中,方便权限的分配。
表设计:
我这里偷了个懒,将角色表、角色_权限表二表合一。
角色表:Role: iSyscode,cName,cMenuList,dDate,iStatusCode
权限表:Menu:iSysCode,cName,iParentID,dDate,iStatusCode
过程:
1、登录:
用户登录提取其角色ID,根据角色ID取出其享有的权限cMenuList。后台操作树根据这个权限集合动态生成。需要说明的是这棵树无刷新动态提取子项。
效果:

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 }11
10 }12
1113
12 private void LoadChildNode(TreeNode node)14
13 {15
14 int iParentID = Convert.ToInt32(node.Value);16
15 //1 系统管理员 //2 总经理 //3 用户 17
16 Basic_Menu bmMain = new Basic_Menu();18
17 IList<Basic_MenuInfo> bmInfoList = bmMain.GetMenu_List(1, iParentID);19
1820
19 foreach (Basic_MenuInfo bmInfo in bmInfoList)21
20 {22
21 TreeNode subNode = new TreeNode(bmInfo.cName);23
22 subNode.Value = bmInfo.iSysCode.ToString();24
23 subNode.NavigateUrl = "http://www.lxqq.cn";25
24 subNode.Target = "_blank";26
2527
26 try28
27 {29
28 if (bmInfo.iChildCount > 0)30
29 {31
30 subNode.SelectAction = TreeNodeSelectAction.SelectExpand;32
31 subNode.PopulateOnDemand = true;33
32 subNode.NavigateUrl = "#";34
33 }35
34 }36
35 catch37
36 {38
37 subNode.ImageUrl = "WebResource.axd?a=s&r=TreeView_XP_Explorer_ParentNode.gif&t=632242003305625000";39
38 }40
39 node.ChildNodes.Add(subNode);41
40 }42
41 43
42 }
2、权限设置:
在这里我用Div布局,用Css设定缩进效果,后台用了个递归取出所有权限项,并根据所设置对象拥有的权限项设定checkbox的状态是否选中。设置完毕,(用hidden包存所有选中项),后台用Request.Form取出所有选定项的值加以操作。在这还有一个重点是checkbox的onclick操作。如选中父项,则相应子项也随之选中;子项选中,父项也跟着选中。在这里,要感谢我的老大。呵呵,因为我刚弄到这,就发现我老大有这个功能的JS实现。稍加改动,呵呵,正好用到这里。

代码:

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
79
8 string strMenuItem="1,2,3,4,5,6,7,8,11";10
9 WebUtility.ScriptStartupRegister(this.Page, "SetDefaultValue('"+strMenuItem+"')");11
10 }12
11 }13
12 private string BasicMenuList(int iParentID)14
13 {15
14 string result = "";16
15 //1 系统管理员 //2 总经理 //3 用户 17
16 Basic_Menu bmMain = new Basic_Menu();18
17 IList<Basic_MenuInfo> bmInfoList = bmMain.GetMenu_List(1, iParentID);19
1820
19 foreach(Basic_MenuInfo bmInfo in bmInfoList)21
20 {22
21 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);23
22 if (bmInfo.iChildCount > 0)24
23 {25
24 result += BasicMenuList(bmInfo.iSysCode);26
25 }27
2628
27 result += "</div>";29
28 }30
29 return result;31
30 }JS实现代码:

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
911
10 <script language="javascript" type="text/javascript">12
11 var checkStatus;13
1214
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
2830
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 else39
38 {40
39 x = xValue.split(",");41
40 }42
41 43
42 with( document.all)44
43 {45
44 for( var i = 0; i<x.length; i++)46
45 {47
46 item("cb" + x[i]).checked = true;48
47 }49
48 }50
49 }51
5052
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
7274
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
9092
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 {101
100 t[i].checked = checkStatus;102
101 if( t[i].childCount!=0)103
102 {104
103 DoSelectChild(t[i].value);105
104 }106
105 }107
106 }108
107 }109
108 </script>
以前还从没想过可以在HTML元素里自定义属性,这里我在checkbox里添加了好几个,parentID,childCount.别说,还真好用。
说明:
此权限设计实为测试版本,实际开发中,数据库设计将进一步分解。例如分为:用户表Users,权限表:Permission 角色表Role,用户角色表:User_Role,角色权限表:Role_Permission。另外如果有需要的话,还可以进一步分为栏目权限和操作权限,增加操作表:Operate 栏目操作表:Permission_Operate。
水平有限,写的有点乱。有什么不同意见欢迎一起交流!

浙公网安备 33010602011771号