背景:
最近看到不少關于權限設計的文章,發現很多都隻是談了個大概的設計方案,實作部分代碼非常少。正好前段時間也弄了套自己的方案,俺跟着也湊湊熱鬧。
系統分析:
權限:
在系統中,權限通過子產品+動作來産生,子產品就是整個系統中的一個子子產品,可能對應一個菜單,動作也就是整個子產品中(在B/S 系統中也就是一個頁面的所有操作,比如“浏覽、添加、修改、删除”等)。将子產品與之組合可以産生此子產品下的所有權限。
角色:
權限的集合,角色與角色之間屬于平級關系,将基本權限添加到一個角色中,友善權限的配置設定。
表設計:
我這裡偷了個懶,将角色表、角色_權限表二表合一。
角色表:Role: iSyscode,cName,cMenuList,dDate,iStatusCode
權限表:Menu:iSysCode,cName,iParentID,dDate,iStatusCode
過程:
1、登入:
使用者登入提取其角色ID,根據角色ID取出其享有的權限cMenuList。背景操作樹根據這個權限集合動态生成。需要說明的是這棵樹無重新整理動态提取子項。
效果:
1
2
1 public 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
11
13
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
18
20
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
25
27
26 try
28
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 catch
37
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實作。稍加改動,呵呵,正好用到這裡。
代碼:
1
2
1 protected 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+"')");
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
18
20
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}\" οnclick=\"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
26
28
27 result += "</div>";
29
28 }
30
29 return result;
31
30 }
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 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
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
{
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。
水準有限,寫的有點亂。有什麼不同意見歡迎一起交流!
轉載于:https://www.cnblogs.com/xpengfee/archive/2007/09/12/890800.html