菜单树形结构
package com.yun.entity.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@Data
public class MenuVO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键")
private Integer id;
@ApiModelProperty(value = "菜单名称")
private String name;
@ApiModelProperty(value = "菜单图标")
private String icon;
@ApiModelProperty(value = "菜单路由")
private String link;
@ApiModelProperty(value = "菜单索引")
private String indexTag;
@ApiModelProperty(value = "菜单类型,目录:12801001,菜单:12801002,按钮:12801003")
private Integer type;
@ApiModelProperty(value = "排序")
private Integer sort;
@ApiModelProperty(value = "状态,启用:12781001,停用:12781002")
private Integer status;
@ApiModelProperty(value = "权限标识")
private String permission;
@ApiModelProperty(value = "父节点主键,-1为根节点")
private Integer parentId;
@ApiModelProperty(value = "用于前端显示开关,status=12781001为true")
private boolean enable;
@ApiModelProperty(value = "菜单子表")
private List<MenuVO> children = new ArrayList<>();
}
package com.yun.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yun.constant.DictConstant;
import com.yun.entity.dto.UserDTO;
import com.yun.entity.po.MenuPO;
import com.yun.entity.vo.MenuVO;
import com.yun.mapper.MenuMapper;
import com.yun.service.MenuService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 菜单表 服务实现类
* </p>
*
* @author CNSTT
* @since 2023-01-21
*/
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, MenuPO> implements MenuService {
/**
* 菜单树形查询
*
* @param dto 传参
* @return List<MenuVO>
*/
@Override
public List<MenuVO> searchDefault(MenuDTO dto) {
LambdaQueryWrapper<MenuPO> wrapper = new QueryWrapper<MenuPO>().lambda();
// 查询菜单或目录
wrapper.in(MenuPO::getType, DictConstant.DICT_MENU_TYPE_CATALOG, DictConstant.DICT_MENU_TYPE_MENU);
wrapper.eq(MenuPO::getDeleteFlag, DictConstant.DICT_NO);
List<MenuPO> menuList = baseMapper.selectList(wrapper);
if (!CollectionUtils.isEmpty(menuList)) {
// 树形返回
return packageListFunc(menuList);
}
return new ArrayList<>();
}
/**
* 组装菜单树形结构主方法
*
* @param menuList 全量数据
* @return List<MenuVO>
*/
private List<MenuVO> packageListFunc(List<MenuPO> menuList) {
List<MenuVO> result = new ArrayList<>();
List<MenuVO> list = convertResult(menuList);
for (MenuVO node : list) {
// parentId = -1为顶层目录或菜单
if (node.getParentId() == -1) {
result.add(findChildren(node, list));
}
}
return result;
}
/**
* 递归查询 - 根据父节点获取子节点
*
* @param node 父节点
* @param result 全量数据
* @return MenuVO 填充完父节点
*/
private MenuVO findChildren(MenuVO node, List<MenuVO> result) {
for (MenuVO dto : result) {
// 父节点的ID等于子节点的父节点ID
if (node.getId().equals(dto.getParentId())) {
if (node.getChildren() == null) {
node.setChildren(new ArrayList<>());
}
node.getChildren().add(findChildren(dto, result));
}
}
return node;
}
/**
* 公共方法 - 实体转化VO出参集合
*
* @param menuList PO结果集
* @return List<MenuVO>
*/
private List<MenuVO> convertResult(List<MenuPO> menuList) {
List<MenuVO> result = new ArrayList<>();
if (!CollectionUtils.isEmpty(menuList)) {
menuList.forEach(menuPO -> {
MenuVO vo = new MenuVO();
BeanUtils.copyProperties(menuPO, vo);
vo.setEnable(vo.getStatus() != null && vo.getStatus() == DictConstant.DICT_YES);
result.add(vo);
});
}
return result;
}
}