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