递归处理树形结构

递归处理应用场景
…在一个后台管理系统中,必然少不了菜单和目录,而菜单和目录存在父子级关系,我们往往需要把它做成支持无限扩展,例如省里面有多个市,市里面有多个区,区里面多个镇…无限扩展,如何实现呢?很简单,递归就行,本文以菜单目录为例。

案例:
表设计
在这里插入图片描述
表就4个字段,分别含义是:模块(菜单)主键,模块(菜单)名称,父模块(菜单)主键,排序号。
在这里插入图片描述
这里是一张简单的菜单表,其中字段parent_module_id,是处理成树形结构的关键。

先建一个vo值对象实体类

@Data
@ApiModel(description = "模块值实体")
public class ModuleVo extends SerializeEntity {

    @ApiModelProperty(value = "模块主键")
    @JsonSerialize(using = ToStringSerializer.class)
    private Long moduleId;

    @ApiModelProperty(value = "模块名称")
    private String moduleName;

    @ApiModelProperty(value = "父级主键")
    @JsonSerialize(using = ToStringSerializer.class)
    private Long parentModuleId;

    @ApiModelProperty(value = "子模块列表")
    private List<ModuleVo> childList;

    @ApiModelProperty(value = "模块权限")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private List<PermissionVo> perVoList;
}

serviceImpl层代码

  /**
     * 获取模块列表
     * @param type 是否展示权限列表(0:否 1:是)
     * @return
     */
    @Override
    public List<ModuleVo> selectModules(Integer type) {
    	//这一步是调用mapper层把所有菜单查出来,这样下面就可以重复使用这个菜单列表,
    	//查询一次db即可(切记:递归查询数据库是大忌)
        List<ModuleVo> modules = knowBgSysModuleMapper.queryAllModules();
        //结果集
        List<ModuleVo> resultList = new ArrayList<>();
        //遍历,把顶级的菜单先抽取出来
        modules.forEach(item1->{
            if(0 == item1.getParentModuleId().longValue()){
            	//将顶级菜单的子菜单先设置为空list
                item1.setChildList(new ArrayList<ModuleVo>());
                item1.setPerVoList(null);
                resultList.add(item1);
            }
        });
        //处理成树形结构
        treeSort(resultList,modules,type);
        return resultList;
    }


/**
     * 处理成树形结构
     * @param list1 集合一
     * @param list2 集合二
     * @param type 是否展示权限列表(0:否 1:是)
     */
    private void treeSort(List<ModuleVo> list1,List<ModuleVo> list2,Integer type){
    	//参数校验,如果为空则退出方法,也是递归退出的临界条件
        if(ParamUtils.isNullForCollection(list1)){
            return;
        }
        //先拿顶级菜单和所有菜单遍历比较,把菜单中父级id等于顶级菜单id的添加到顶级菜单的子菜单列表即可
        list1.forEach(item1->{
            list2.forEach(item2->{
                if(item2.getParentModuleId().longValue() == item1.getModuleId()){
                    item2.setChildList(new ArrayList<ModuleVo>());
                    //if这一步是是否展现菜单下的权限,本文这里可以忽略
                    if(0 == type){
                        item2.setPerVoList(null);
                    }
                    //上一级菜单添加子菜单
                    item1.getChildList().add(item2);
                }
            });
            //递归重复调用添加子菜单
            treeSort(item1.getChildList(),list2,type);
        });
    }

controller方法代码


    @ApiOperation("获取模块列表")
    @Permission(blacklist = 1,permissionName = "获取模块列表",sort = 100)
    @RequestMapping(value = "selectModules",method = RequestMethod.POST)
    public JsonResult<List<ModuleVo>> selectModules(){
        return new JsonResult<List<ModuleVo>>(knowBgSysModuleService.selectModules(0));
    }

最终swagger调用的效果图
在这里插入图片描述
图片展示效果有限,这里用代码补全


{
  "state": 200,
  "message": "请求成功",
  "data": [
    {
      "moduleId": "100",
      "moduleName": "网站概况",
      "parentModuleId": "0",
      "childList": []
    },
    {
      "moduleId": "200",
      "moduleName": "知识产品",
      "parentModuleId": "0",
      "childList": [
        {
          "moduleId": "20040",
          "moduleName": "问题咨询",
          "parentModuleId": "200",
          "childList": []
        },
        {
          "moduleId": "20050",
          "moduleName": "职场故事",
          "parentModuleId": "200",
          "childList": []
        },
        {
          "moduleId": "20070",
          "moduleName": "通知公告",
          "parentModuleId": "200",
          "childList": []
        }
      ]
    },
    {
      "moduleId": "300",
      "moduleName": "企业招聘",
      "parentModuleId": "0",
      "childList": []
    },
    {
      "moduleId": "400",
      "moduleName": "品台互动",
      "parentModuleId": "0",
      "childList": []
    },
    {
      "moduleId": "500",
      "moduleName": "数据分析",
      "parentModuleId": "0",
      "childList": []
    },
    {
      "moduleId": "600",
      "moduleName": "营销管理",
      "parentModuleId": "0",
      "childList": []
    },
    {
      "moduleId": "700",
      "moduleName": "会员管理",
      "parentModuleId": "0",
      "childList": []
    },
    {
      "moduleId": "800",
      "moduleName": "财务数据",
      "parentModuleId": "0",
      "childList": []
    },
    {
      "moduleId": "900",
      "moduleName": "系统设置",
      "parentModuleId": "0",
      "childList": [
        {
          "moduleId": "90010",
          "moduleName": "员工设置",
          "parentModuleId": "900",
          "childList": []
        },
        {
          "moduleId": "90020",
          "moduleName": "部门设置",
          "parentModuleId": "900",
          "childList": []
        },
        {
          "moduleId": "90030",
          "moduleName": "角色设置",
          "parentModuleId": "900",
          "childList": []
        }
      ]
    }
  ]
}
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值