通用业务逻辑点,菜单的递归处理,Java

1,253 阅读2分钟

目标:功能菜单逻辑开发

最近在新开发一套功能,最基本的菜单权限这块也在其中,这里我记录下菜单递归逻辑,快速写出菜单的父子结构。

基础类定义

菜单基础表或者bean对象

/**
菜单对象  表结构
**/
@Data
public class SysMenuEntity implements Serializable {
   private static final long serialVersionUID = 1L;
   
   /**
    * 菜单ID
    */
   @TableId
   private Long menuId;

   /**
    * 父菜单ID,一级菜单为0
    */
   private Long parentId;
   
   /**
    * 父菜单名称
    */
   @TableField(exist=false)
   private String parentName;

   /**
    * 菜单名称
    */
   private String name;

   /**
    * 菜单URL
    */
   private String url;

   /**
    * 授权(多个用逗号分隔,如:user:list,user:create)
    */
   private String perms;

   /**
    * 类型     0:目录   1:菜单   2:按钮
    */
   private Integer type;

   /**
    * 菜单图标
    */
   private String icon;

   /**
    * 排序
    */
   private Integer orderNum;
   
   /**
    * ztree属性
    */
   @TableField(exist=false)
   private Boolean open;

   @TableField(exist=false)
   private List<SysMenuEntity> list;
}

菜单类型 枚举

/**
 * 菜单类型
 */
   public enum MenuType {
       /**
        * 目录
        */
       CATALOG(0),
       /**
        * 菜单
        */
       MENU(1),
       /**
        * 按钮
        */
       BUTTON(2);
       private int value;
       MenuType(int value) {
           this.value = value;
       }
       public int getValue() {
           return value;
       }
   }

业务逻辑

方法入口

如果没用到用户权限啥的,就忽略userID的逻辑就好

@Override
public List<SysMenuEntity> getUserMenuList(Long userId) {
   //系统管理员,拥有最高权限
   if(userId == Constant.SUPER_ADMIN){
      return getAllMenuList(null);
   }
   
   //用户菜单列表
   List<Long> menuIdList = sysUserService.queryAllMenuId(userId);
   return getAllMenuList(menuIdList);
}

/**queryAllMenuId 的实现简单copy出来下,就是查找用户有哪些menu权限的IDs**/
@Override
public List<Long> queryAllMenuId(Long userId) {
   return baseMapper.queryAllMenuId(userId);
}

获取所有菜单,去处理递归

/**
 * 获取所有菜单列表  ,这里的入参 menuIdList  如user没考虑就空了
 */
private List<SysMenuEntity> getAllMenuList(List<Long> menuIdList){
   //查询根菜单列表
   List<SysMenuEntity> menuList = queryListParentId(0L, menuIdList);
   //递归获取子菜单
   getMenuTreeList(menuList, menuIdList);
   
   return menuList;
}

菜单递归逻辑

返回的List对象就是当前菜单的父子结构数据

/**
 * 递归 返回的List对象就是当前菜单的父子结构数据
 */
private List<SysMenuEntity> getMenuTreeList(List<SysMenuEntity> menuList, List<Long> menuIdList){
   List<SysMenuEntity> subMenuList = new ArrayList<SysMenuEntity>();
   for(SysMenuEntity entity : menuList){
      //目录
      if(entity.getType() == Constant.MenuType.CATALOG.getValue()){
         entity.setList(getMenuTreeList(queryListParentId(entity.getMenuId(), menuIdList), menuIdList));
      }
      subMenuList.add(entity);
   }
   
   return subMenuList;
}

总结

其实也没啥哈,就是简单记录下每个业务逻辑点,这种通用的做法,当然也看具体需求,如果需求上不需要多级菜单,那可以简单嵌套2个for就可以了。 但这个是通用的, 管他几层是吧,OK,just mark it !