跳至主要內容

04 权限模块系统设计

Java突击队大约 9 分钟

04 权限模块系统设计

前言

通过前面的文章的内容介绍,我们已经将苏三商城项目的骨架搭好,并且写了一个模板CRUD接口。

今天开始模块开发了,在做模块开发之前,为了让大家更好理解这个项目的各个模板的表结构,先做系统设计。

1 功能设计

权限系统是一个公共功能,是一个系统级别的模块,非业务级别的。

苏三商城的权限模块主要包含以下菜单:

  1. 部门管理
  2. 职位管理
  3. 菜单管理
  4. 角色管理
  5. 用户管理

一个职位属于某一个部门。

一个菜单包含多个功能权限。

一个角色可以包含多个菜单,和多个部门。或者多个角色包含同一个菜单,和同一个部门。是一种多对多的关系。

一个用户可以包含多个角色,多个用户也可以属于同一个角色。也是一种多对多的关系。

通过角色上的菜单,控制功能权限

通过角色上的部门,通过数据权限

权限点的功能包含在菜单管理中。

这里稍微简化了一下,没有设计通过岗位控制数据权限,不然太绕了。

2 表设计

在做表设计之前,先做一下规划,指定一些规范,让表风格统一。

2.1 表的规范

由于权限相关的表是属于系统级别的表,而非业务级别,因此表名中统一增加前缀sys_,方便后面好统一管理。

对于主表,比如:用户表、菜单表等,需要增加8个公共字段。

对于关联关系表,考虑很多事多对多的关系,保存的数据可能会非常多,就不加那8个公共字段了。

但id作为主键还是不能少。

主表的删除功能在表中做业务删除,二关联关系表做物理删除。

删除关联关系表时,需要更新主表的修改人和修改时间相关的字段。

id用bigint类型,由于非分布式系统,可以直接使用数据库自动增长的值。

时间用datetime(3)类型。

状态字段用tinyint类型。

名称字段用varchar类型,长度根据实际情况而定。

存储引擎使用InnoDB,主键使用AUTO_INCREMENT数据库自动增长,CHARSET用utf8mb4,避免一些特殊表情字符的问题。

所有的表和字段,都要加上注释。

数据库和表的变更,都需要将相关脚本写到代码中的sql目录下。

2.2 表的初步设计

有了上面的规范之后,可以开始设计表了。

根据上面的需求:

一个职位属于某一个部门。

一个菜单包含多个功能权限。

一个角色可以包含多个菜单,和多个部门。或者多个角色包含同一个菜单,和同一个部门。是一种多对多的关系。

一个用户可以包含多个角色,多个用户也可以属于同一个角色。也是一种多对多的关系。

表之间的关系,我们可以这样设计:

2.3 表的详细设计

首先设计部门表,它是一张基础表:

CREATE TABLE `sys_dept` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(30) NOT NULL COMMENT '名称',
  `pid` bigint NOT NULL COMMENT '上级部门ID',
  `valid_status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '有效状态 1:有效 0:无效',
  `create_user_id` bigint NOT NULL COMMENT '创建人ID',
  `create_user_name` varchar(30) NOT NULL COMMENT '创建人名称',
  `create_time` datetime(3) DEFAULT NULL COMMENT '创建日期',
  `update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
  `update_user_name` varchar(30)  DEFAULT NULL COMMENT '修改人名称',
  `update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
  `is_del` tinyint(1) DEFAULT '0' COMMENT '是否删除 1:已删除 0:未删除',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `index_pid` (`pid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='部门';

这张表包含了id、create_user_id、create_user_name、create_time、update_user_id、update_user_name、update_time、is_del这些公共字段之外。

还包含了name表示部门名称,pid表示上级部门ID,valid_status表示数据是否有效。

这张表比较简单。

下面看看岗位表

CREATE TABLE `sys_job` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(30) NOT NULL COMMENT '岗位名称',
  `sort` int(3) NOT NULL COMMENT '岗位排序',
  `dept_id` bigint NOT NULL COMMENT '部门ID',
  `valid_status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '有效状态 1:有效 0:无效',
  `create_user_id` bigint NOT NULL COMMENT '创建人ID',
  `create_user_name` varchar(30) NOT NULL COMMENT '创建人名称',
  `create_time` datetime(3) DEFAULT NULL COMMENT '创建日期',
  `update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
  `update_user_name` varchar(30)  DEFAULT NULL COMMENT '修改人名称',
  `update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
  `is_del` tinyint(1) DEFAULT '0' COMMENT '是否删除 1:已删除 0:未删除',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `index_dept_id` (`dept_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='岗位';

除了8个公共字段之外,还包含了name表示岗位名称,sort表示岗位排序,dept_id表示部门ID,valid_status表示数据是否有效。

接下来,看看菜单表

CREATE TABLE `sys_menu` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(255) DEFAULT NULL COMMENT '菜单名称',
  `pid` bigint NOT NULL COMMENT '上级菜单ID',
  `sort` int(3) NOT NULL COMMENT '排序',
  `icon` varchar(30) DEFAULT NULL COMMENT '图标',
  `path` varchar(255) DEFAULT NULL COMMENT '路由',
  `hidden` tinyint(1) DEFAULT '0' COMMENT '是否隐藏',
  `is_link` tinyint(1) DEFAULT '0' COMMENT '是否外链 1:是 0:否',
  `type` int(2) DEFAULT NULL COMMENT '类型 1:目录 2:菜单 3:按钮',
  `permission` varchar(255) DEFAULT NULL COMMENT '功能权限',
  `url` varchar(30) DEFAULT NULL COMMENT 'url地址',
  `create_user_id` bigint NOT NULL COMMENT '创建人ID',
  `create_user_name` varchar(30) NOT NULL COMMENT '创建人名称',
  `create_time` datetime(3) DEFAULT NULL COMMENT '创建日期',
  `update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
  `update_user_name` varchar(30)  DEFAULT NULL COMMENT '修改人名称',
  `update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
  `is_del` tinyint(1) DEFAULT '0' COMMENT '是否删除 1:已删除 0:未删除',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `index_pid` (`pid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4  COMMENT='菜单';

菜单表稍微有点复杂,除了包含了8个公共字段之外,还包含了name表示菜单名称,pid表示上级菜单ID,sort表示排序,icon表示菜单的图片,path表示菜单的路由,url表示页面地址,type表示菜单的类型目前有3种,hidden表示是否隐藏,is_link表示是否是外链,permission表示菜单的权限点。

然后就是角色表

CREATE TABLE `sys_role` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(30) NOT NULL COMMENT '名称',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `data_scope` varchar(255) DEFAULT NULL COMMENT '数据权限',
  `level` int DEFAULT NULL COMMENT '角色级别',
  `permission` varchar(255) DEFAULT NULL COMMENT '功能权限',
  `create_user_id` bigint NOT NULL COMMENT '创建人ID',
  `create_user_name` varchar(30) NOT NULL COMMENT '创建人名称',
  `create_time` datetime(3) DEFAULT NULL COMMENT '创建日期',
  `update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
  `update_user_name` varchar(30)  DEFAULT NULL COMMENT '修改人名称',
  `update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
  `is_del` tinyint(1) DEFAULT '0' COMMENT '是否删除 1:已删除 0:未删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4  COMMENT='角色表';

角色表除了包含了8个公共字段之外,还包含了name表示角色名称,remark表示备注,data_scope表示数据权限范围,level表示角色的等级,permission表示功能权限。

然后就是角色菜单关联关系表

CREATE TABLE `sys_role_menu` (
   `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
   `role_id` bigint NOT NULL COMMENT '角色ID',
   `menu_id` bigint NOT NULL COMMENT '菜单ID',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `index_role_id` ( `role_id`) USING BTREE,
  KEY `index_menu_id` ( `menu_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1  DEFAULT CHARSET=utf8mb4 COMMENT='角色菜单关联';

这张表是关联关系表,考虑到后面数据量可能会很大,没有加那8个共用的字段,可以节省一些磁盘空间。

角色菜单关联关系表中只包含了id表示主键,role_id表示角色ID,memu_id表示菜单ID。

有些人喜欢将role_id和memu_id创建一个联合主键,我个人认为这不是一个好的做法。

接下来是角色部门关联关系表

CREATE TABLE `sys_role_dept` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `role_id` bigint NOT NULL,
  `dept_id` bigint NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  KEY `index_role_id` ( `role_id`) USING BTREE,
  KEY `index_dept_id` ( `dept_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色部门关联';

这张表跟上面那张表类似,也只有3个字段,id表示主键,role_id表示角色ID,dept_id表示部门ID。

接下来,是用户表

CREATE TABLE `sys_user` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `avatar_id` bigint DEFAULT NULL COMMENT '头像',
  `email` varchar(50) DEFAULT NULL COMMENT '邮箱',
  `password` varchar(30) DEFAULT NULL COMMENT '密码',
  `user_name` varchar(30) DEFAULT NULL COMMENT '用户名',
  `dept_id` bigint DEFAULT NULL COMMENT '部门ID',
  `phone` varchar(20) DEFAULT NULL COMMENT '手机号码',
  `job_id` bigint DEFAULT NULL COMMENT '岗位ID',
  `last_change_password_time` datetime(3) DEFAULT NULL COMMENT '最后修改密码的时间',
  `nick_name` varchar(30) DEFAULT NULL COMMENT '别名',
  `sex` tinyint(2)  DEFAULT NULL COMMENT '性别 1:男 2:女',
  `valid_status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '有效状态 1:有效 0:无效',
  `create_user_id` bigint NOT NULL COMMENT '创建人ID',
  `create_user_name` varchar(30) NOT NULL COMMENT '创建人名称',
  `create_time` datetime(3) DEFAULT NULL COMMENT '创建日期',
  `update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
  `update_user_name` varchar(30)  DEFAULT NULL COMMENT '修改人名称',
  `update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
  `is_del` tinyint(1) DEFAULT '0' COMMENT '是否删除 1:已删除 0:未删除',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `uk_user_name` (`user_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户';

用户表包含了8个公共字段,还包含了avatar_id表示用户头像的ID,email表示邮箱,passord表示密码,user_name表示用户名称,dept_id表示部门ID,job_id表示岗位ID,phone表示用户手机号,last_change_password_time表示用户最后修改密码的时间,nick_name表示用户的别名,sex表示性别。

然后就是用户头像表

CREATE TABLE `sys_user_avatar` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `file_name` varchar(255)  DEFAULT NULL COMMENT '文件名',
  `path` varchar(255) DEFAULT NULL COMMENT '路径',
  `file_size` varchar(10)  DEFAULT NULL COMMENT '大小',
  `create_user_id` bigint NOT NULL COMMENT '创建人ID',
  `create_user_name` varchar(30) NOT NULL COMMENT '创建人名称',
  `create_time` datetime(3) DEFAULT NULL COMMENT '创建日期',
  `update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
  `update_user_name` varchar(30)  DEFAULT NULL COMMENT '修改人名称',
  `update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
  `is_del` tinyint(1) DEFAULT '0' COMMENT '是否删除 1:已删除 0:未删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户头像';

用户头像表也包含了8个公共字段,除此之外,还包含了file_name表示头像的名称,path表示文件的路径,file_size表示文件的大小。

最后是用户角色表


CREATE TABLE `sys_user_role` (
   `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `user_id` bigint NOT NULL COMMENT '用户ID',
  `role_id` bigint NOT NULL COMMENT '角色ID',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `index_user_id` (`user_id`) USING BTREE,
  KEY `index_role_id` (`role_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4  COMMENT='用户角色关联';

这张表也只包含了3个字段,id表示主键,user_id表示用户ID,role_id表示角色ID。