前言:寫了兩篇關於DataGridView的文章:Winform系列——好用的DataGridview過濾控件(表格的高級搜索功能) 和 Winform系列——好看的DataGridView折疊控件。這章來記錄下權限系統。關於權限系統,網上版本非常多,大都實用性不太高,大多數的系統就是因為分得太細了反而使系統錯綜復雜,甚至有看到有按照角色、部門、地區、用戶四個方便分別去做權限分配的,我的個神,這樣一來,要取一個用戶的權限那個麻煩,當然並非說那些大神們封的東西不好,而是適用性的問題,對於某些大型公司的系統,對權限要求確實有那么高也說不定,但其實根據本人工作幾年的經驗來看,大部分的.Net系統其實對權限的要求並沒有想象中的那么高。在這里記錄下自己從頭到尾設計和開發的一個權限系統,個人覺得對於基本的權限分配夠用了。
1、系統介紹:說是系統,其實權限只是系統的一個模塊,此系統主要就是根據角色來分配權限的,通過角色分別控制用戶的菜單權限和菜單對應頁面的按鈕權限。
2、數據表設計:
(1)上圖
(2)表的DDL語句:

/*==============================================================*/ /* DBMS name: ORACLE Version 11g */ /* Created on: 2015/6/15 11:55:21 */ /*==============================================================*/ alter table TB_MenuRole drop constraint FK_TB_MENUR_REFERENCE_TB_ROLE; alter table TB_MenuRole drop constraint FK_TB_MENUR_REFERENCE_TB_MENU; alter table TB_UserRole drop constraint FK_TB_USERR_REFERENCE_TB_USERS; alter table TB_UserRole drop constraint FK_TB_USERR_REFERENCE_TB_ROLE; alter table TB_Users drop constraint FK_TB_USERS_REFERENCE_TB_DEPAR; drop table TB_Department cascade constraints; drop table TB_Menu cascade constraints; drop table TB_MenuRole cascade constraints; drop table TB_Role cascade constraints; drop table TB_UserRole cascade constraints; drop table TB_Users cascade constraints; /*==============================================================*/ /* Table: "TB_Department" */ /*==============================================================*/ create table TB_Department ( department_id VARCHAR(50) not null, department_name VARCHAR(50), parent_id VARCHAR(50), department_level VARCHAR(10), status VARCHAR(10), constraint PK_TB_DEPARTMENT primary key (department_id) ); /*==============================================================*/ /* Table: "TB_Menu" */ /*==============================================================*/ create table TB_Menu ( menu_id VARCHAR(50) not null, menu_name VARCHAR(50), menu_url VARCHAR(50), parent_id VARCHAR(50), menu_level VARCHAR(10), sort_order VARCHAR(50), status VARCHAR(10), remark VARCHAR(1000), constraint PK_TB_MENU primary key (menu_id) ); /*==============================================================*/ /* Table: "TB_MenuRole" */ /*==============================================================*/ create table TB_MenuRole ( id VARCHAR(50) not null, role_id VARCHAR(50), menu_id VARCHAR(50), role_type VARCHAR(10), button_id VARCHAR(50), constraint PK_TB_MENUROLE primary key (id) ); /*==============================================================*/ /* Table: "TB_Role" */ /*==============================================================*/ create table TB_Role ( role_id VARCHAR(50) not null, role_name VARCHAR(50), description VARCHAR(500), createtime DATE, modifytime DATE, constraint PK_TB_ROLE primary key (role_id) ); /*==============================================================*/ /* Table: "TB_UserRole" */ /*==============================================================*/ create table TB_UserRole ( id VARCHAR(50) not null, role_id VARCHAR(50), user_id VARCHAR(50), constraint PK_TB_USERROLE primary key (id) ); /*==============================================================*/ /* Table: "TB_Users" */ /*==============================================================*/ create table TB_Users ( user_id VARCHAR(50) not null, user_name VARCHAR(50), user_password VARCHAR(50), fullname VARCHAR(50), department_id VARCHAR(50), status VARCHAR(10), createtime DATE, modifytime DATE, remark VARCHAR(1000), constraint PK_TB_USERS primary key (user_id) ); comment on table TB_Users is '用戶信息表'; alter table TB_MenuRole add constraint FK_TB_MENUR_REFERENCE_TB_ROLE foreign key (role_id) references TB_Role (role_id); alter table TB_MenuRole add constraint FK_TB_MENUR_REFERENCE_TB_MENU foreign key (menu_id) references TB_Menu (menu_id); alter table TB_UserRole add constraint FK_TB_USERR_REFERENCE_TB_USERS foreign key (user_id) references TB_Users (user_id); alter table TB_UserRole add constraint FK_TB_USERR_REFERENCE_TB_ROLE foreign key (role_id) references TB_Role (role_id); alter table TB_Users add constraint FK_TB_USERS_REFERENCE_TB_DEPAR foreign key (department_id) references TB_Department (department_id);
(3) 表說明:權限模塊總共就6張表,即部門表、用戶表、角色表、用戶角色表、菜單表、菜單角色表(包含按鈕權限)。用戶表和角色表之間的關系是通用的多對多的關系,沒什么好說的。看看TB_MenuRole表,這個表用來存儲角色的菜單權限和按鈕權限,其中role_type取值為menu和button,如果是menu,則此行記錄用於存儲菜單權限,button_id為空;如果是button,則此行記錄用於存儲菜單下的某一個按鈕的權限,menu_id為按鈕所在的菜單id,button_id為對應的按鈕id。還有一個問題就是按鈕的id從哪里來?是否還應該有一個儲存按鈕ID的表呢?答案是不需要,后面會介紹。
3、效果圖:先做的是一個CS的系統,后續還會做BS的。
3.1 權限模塊主要分為4大頁面:用戶管理、角色管理、部門管理和菜單管理
3.2 用戶管理頁面:
“設置角色”操作:
3.3 角色管理頁面:
“編輯權限”操作:
在“編輯權限”彈出框中點擊“設置按鈕操作”
角色管理頁面的“管理成員”操作:
可以新增當前角色的用戶,點擊“新增”
3.4 部門管理頁面:
3.5 菜單管理頁面:
4、后台業務邏輯都是簡單的增刪改查,沒什么好說的。前面說的關於按鈕ID是否需要一張按鈕表的問題,我們系統在處理方式是
在點擊設置按操作的時候傳遞一個菜單url,然后在代碼里面通過反射得到所有的按鈕,然后勾選按鈕后保存到數據庫。注意一個頁面的按鈕的ID不會重復,所以通過這樣可以取到唯一的按鈕,而在數據表TB_MenuRole中保存的如果是按鈕權限,是有保存Menu_Id的,所以不必擔心不同頁面的問題。這樣設計的好處是當程序員在頁面上面新增刪除按鈕后不用修改配置,通過反射即可加載頁面的即時按鈕個數。純屬個人設計,如果有問題,歡迎大俠們指正。