Java实现多级菜单(递归实现)

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<SysMenuPermissionEntity> 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<String, Object> findMenuList() {
	return sysMenuPermissionService.findMenuList();
}
Service 层
@Override
public Map<String, Object> findMenuList() {
    Map<String, Object> data = new HashMap<>();
    try { //查询所有菜单
        List<SysMenuPermissionEntity> allMenu = sysMenuPermissionMapper.queryList();
        //根节点集合
        List<SysMenuPermissionEntity> 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<SysMenuPermissionEntity> 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<SysMenuPermissionEntity> getChild(String id, List<SysMenuPermissionEntity> allMenu) {
    //子菜单
    List<SysMenuPermissionEntity> 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 id="queryList" resultMap="ResultMap">
	select
	<include refid="Column_List" />
	from ads.sys_menu_permission
	<include refid="Example_Where_Clause" />
	<if test="orderBy != null and orderBy != ''">
		order by ${orderBy}
	</if>
</select>
模拟表数据

在这里插入图片描述

返回给前端的JSON数据
{
  "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"
}
  • 26
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

white camel

感谢支持~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值