系统设计——权限系统
前言:写了两篇关于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的,所以不必担心不同页面的问题。这样设计的好处是当程序员在页面上面新增删除按钮后不用修改配置,通过反射即可加载页面的即时按钮个数。纯属个人设计,如果有问题,欢迎大侠们指正。