每天早上七点三十,准时推送干货
一、介绍
在实际的项目开发过程中,菜单权限功能可以说是后端管理系统中必不可少的一个环节,根据业务的复杂度,设计的时候可深可浅,但无论怎么变化,设计的思路基本都是围绕着用户、角色、菜单进行相应的扩展。
今天小编就和大家一起来讨论一下,怎么设计一套可以精确到按钮级别的菜单权限功能,废话不多说,直接开撸!
二、数据库设计
先来看一下,用户、角色、菜单表对应的ER图,如下:

其中,用户和角色是多对多的关系,角色与菜单也是多对多的关系,用户通过角色来关联到菜单,当然也有的业务系统菜单权限模型,是可以直接通过用户关联到菜单,对菜单权限可以直接控制到用户级别,不过这个都不是问题,这个也可以进行扩展。
对于用户、角色表比较简单,下面,我们重点来看看菜单表的设计,如下:

可以看到,整个菜单表就是一个树型结构,关键字段说明:
menu_code:菜单编码,用于后端权限控制
parent_id:菜单父节点ID,方便递归遍历菜单
node_type:节点类型,可以是文件夹、页面或者按钮类型
link_url:页面对应的地址,如果是文件夹或者按钮类型,可以为空
level:菜单树的层次,以便于查询指定层级的菜单
path:树id的路径,主要用于存放从根节点到当前树的父节点的路径,逗号分隔,想要找父节点会特别快
为了后面方便开发,我们先创建一个名为menu_auth_db
的数据库,初始脚本如下:
CREATE DATABASE IF NOT EXISTS menu_auth_db default charset utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE TABLE menu_auth_db.tb_user (
id bigint(20) unsigned NOT NULL COMMENT '消息给过来的ID',
mobile varchar(20) NOT NULL DEFAULT '' COMMENT '手机号',
name varchar(100) NOT NULL DEFAULT '' COMMENT '姓名',
password varchar(128) NOT NULL DEFAULT '' COMMENT '密码',
is_delete tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除 1:已删除;0:未删除',
PRIMARY KEY (id),
KEY idx_name (name) USING BTREE,
KEY idx_mobile (mobile) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
CREATE TABLE menu_auth_db.tb_user_role (
id bigint(20) unsigned NOT NULL COMMENT '主键',
user_id bigint(20) NOT NULL COMMENT '用户ID',
role_id bigint(20) NOT NULL COMMENT '角色ID',
PRIMARY KEY (id),
KEY idx_user_id (user_id) USING BTREE,
KEY idx_role_id (role_id) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户角色表';
CREATE TABLE menu_auth_db.tb_role (
id bigint(20) unsigned NOT NULL COMMENT '主键',
code varchar(100) NOT NULL DEFAULT '' COMMENT '编码',
name varchar(100) NOT NULL DEFAULT '' COMMENT '名称',
is_delete tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除 1:已删除;0:未删除',
PRIMARY KEY (id),
KEY idx_code (code) USING BTREE,
KEY idx_name (name) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色表';
CREATE TABLE menu_auth_db.tb_role_menu (
id bigint(20) unsigned NOT NULL COMMENT '主键',
role_id bigint(20) NOT NULL COMMENT '角色ID',
menu_id bigint(20) NOT NULL COMMENT '菜单ID',
PRIMARY KEY (id),
KEY idx_role_id (role_id) USING BTREE,
KEY idx_menu_id (menu_id) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色菜单关系表';
CREATE TABLE menu_auth_db.tb_menu (
id bigint(20) NOT NULL COMMENT '主键',
name varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '名称',
menu_code varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '菜单编码',
parent_id bigint(20) DEFAULT NULL COMMENT '父节点',
node_type tinyint(4) NOT NULL DEFAULT '1' COMMENT '节点类型,1文件夹,2页面,3按钮',
icon_url varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '图标地址',
sort int(11) NOT NULL DEFAULT '1' COMMENT '排序号',
link_url varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '页面对应的地址',
level int(11) NOT NULL DEFAULT '0' COMMENT '层次',
path varchar(2500) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '树id的路径 整个层次上的路径id,逗号分隔,想要找父节点特别快',
is_delete tinyint(4) N