Java实现多级菜单
菜单管理数据库设计
pgsql表
CREATE TABLE "ads"."sys_menu_permission" (
"menu_id" int4 DEFAULT nextval('"ads".sys_menu_permission_menu_id_seq'::regclass) NOT NULL,
"menu_pid" int4 DEFAULT 0,
"menu_name" varchar(100) COLLATE "default",
"menu_type" varchar(20) COLLATE "default",
"url" varchar(100) COLLATE "default",
"active" varchar(1) COLLATE "default" DEFAULT 1,
"visible" varchar(1) COLLATE "default" DEFAULT 1,
"sort" int4 DEFAULT 0,
"level" int4,
"icon" varchar(100) COLLATE "default",
"created_at" timestamp DEFAULT now(),
CONSTRAINT "sys_menu_permission_pkey" PRIMARY KEY ("menu_id")
)
WITH (OIDS=FALSE)
;
菜单管理实体类
@Data
public class SysMenuPermissionEntityParent extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* ID
*/
private Integer menuId;
/**
* 菜单父ID
*/
private Integer menuPid;
/**
* 菜单名称
*/
private String menuName;
/**
* 菜单类型(menu, permission)
*/
private String menuType;
List children;
/**
* 路由地址
*/
private String url;
/**
* 是否可用(1:可用;0:不可用)
*/
private String active;
/**
* 是否可见(1:可见;0:不可见)
*/
private String visible;
/**
* 组内排序
*/
private Integer sort;
/**
* 菜单层级
*/
private Integer level;
/**
* 矢量图标
*/
private String icon;
/**
* 创建时间
*/
private Date createdAt;
}
Controller 层
/**
* 查询菜单列表(递归查询)
* @return
*/
@ApiOperation("递归查询菜单列表")
@GetMapping("/findMenuList")
@IgnoreServiceAuth
public Map findMenuList() {
return sysMenuPermissionService.findMenuList();
}
Service 层
@Override
public Map findMenuList() {
Map data = new HashMap();
try { //查询所有菜单
List allMenu = sysMenuPermissionMapper.queryList();
//根节点集合
List rootMenu = new ArrayList();
for (SysMenuPermissionEntity entity : allMenu) {
if (entity.getMenuPid() == 0) { //父节点是0的,为根节点。
rootMenu.add(entity);
}
}
/* 根据Menu类的order排序 */
//Collections.sort(rootMenu, order());
//为根菜单设置子菜单,getClild是递归调用的
for (SysMenuPermissionEntity entity : rootMenu) {
/* 获取根节点下的所有子节点 使用getChild方法*/
List childList = getChild(entity.getMenuId().toString(), allMenu);
entity.setChildren(childList);//给根节点设置子节点
}
/**
* 输出构建好的菜单数据。
*/
data.put("code", "0");
data.put("msg", "ok");
data.put("result", rootMenu);
return data;
} catch (Exception e) {
data.put("code", "-1");
data.put("result", new ArrayList());
return data;
}
}
/**
* 获取子节点
*
* @param id 父节点id
* @param allMenu 所有菜单列表
* @return 每个根节点下,所有子菜单列表
*/
public List getChild(String id, List allMenu) {
//子菜单
List childList = new ArrayList();
for (SysMenuPermissionEntity entity : allMenu) {
// 遍历所有节点,将所有菜单的父id与传过来的根节点的id比较
//相等说明:为该根节点的子节点。
if (entity.getMenuPid().toString().equals(id)) {
childList.add(entity);
}
}
//递归
for (SysMenuPermissionEntity entity : childList) {
entity.setChildren(getChild(entity.getMenuId().toString(), allMenu));
}
//Collections.sort(childList,order()); //排序
//如果节点下没有子节点,返回一个空List(递归退出)
if (childList.size() == 0) {
return new ArrayList();
}
return childList;
}
Dao 层
select
from ads.sys_menu_permission
order by ${orderBy}
模拟表数据
{
"msg": "ok",
"result": [
{
"menuId": 1,
"menuPid": 0,
"menuName": "test menu",
"menuType": "menu",
"active": "1",
"visible": "1",
"sort": 0,
"level": 1,
"createdAt": "2020-11-03 00:00:00",
"children": [
{
"menuId": 6,
"menuPid": 1,
"menuName": "ggg",
"children": [
{
"menuId": 12,
"menuPid": 6,
"menuName": "sads2c",
"menuType": "22r32sac",
"url": "sfafa2s",
"active": "1",
"visible": "1",
"sort": 0,
"createdAt": "2020-11-18 18:05:14",
"children": []
}
]
},
{
"menuId": 3,
"menuPid": 1,
"menuName": "string",
"menuType": "string",
"url": "string",
"active": "1",
"visible": "s",
"sort": 0,
"level": 0,
"createdAt": "2020-11-16 17:00:00",
"children": [
{
"menuId": 9,
"menuPid": 3,
"menuName": "dsdsaf",
"menuType": "sadfas",
"url": "sfas",
"active": "1",
"visible": "1",
"sort": 0,
"createdAt": "2020-11-18 18:04:42",
"children": []
},
{
"menuId": 10,
"menuPid": 3,
"menuName": "dsaf2sdsc",
"menuType": "fasdf",
"url": "sdfasd",
"active": "1",
"visible": "1",
"sort": 0,
"createdAt": "2020-11-18 18:04:53",
"children": []
}
]
},
{
"menuId": 4,
"menuPid": 1,
"menuName": "hhh",
"menuType": "hhh",
"url": "hhh",
"active": "1",
"visible": "0",
"sort": 0,
"level": 0,
"icon": "hhh",
"createdAt": "2020-11-16 17:00:00",
"children": [
{
"menuId": 11,
"menuPid": 4,
"menuName": "2dsaf",
"menuType": "asf2dhg",
"url": "hgfgj",
"active": "1",
"visible": "1",
"sort": 0,
"createdAt": "2020-11-18 18:05:02",
"children": []
}
]
}
]
},
{
"menuId": 2,
"menuPid": 0,
"menuName": "test2",
"menuType": "menu",
"active": "1",
"visible": "1",
"sort": 0,
"createdAt": "2020-11-03 15:31:20",
"children": [
{
"menuId": 7,
"menuPid": 2,
"menuName": "dfa",
"menuType": "dfa",
"url": "fadfa",
"active": "1",
"visible": "1",
"sort": 0,
"createdAt": "2020-11-18 17:43:11",
"children": []
},
{
"menuId": 8,
"menuPid": 2,
"menuName": "2333",
"menuType": "safa23",
"url": "dfas3c",
"active": "1",
"visible": "1",
"sort": 0,
"icon": "",
"createdAt": "2020-11-18 17:43:31",
"children": []
},
{
"menuId": 5,
"menuPid": 2,
"menuName": "sfas",
"menuType": "23",
"url": "232fdsfa",
"active": "1",
"visible": "1",
"sort": 0,
"createdAt": "2020-11-18 17:46:11",
"children": []
}
]
}
],
"code": "0"
}