java 如何实现菜单递归组成递归的Json字符串!

一般在进行数据库查询操作时,查询出来的都是二维数据,都是一条条数据,而对于树形结构展示时并不是很方便,那如何直接将树形结构以递归形式的方式组合成Json字符串呢?话不多说,直接上代码。

/**
 * Copyright (C), 2019, XXXXXX有限公司
 * FileName: MenuServiceImpl
 * Author:   Allen
 * Date:     2019/5/30
 * Description: 菜单服务处理类
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.xueying.seeker.core.service.impl.system;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xueying.seeker.client.dto.MenuDTO;
import com.xueying.seeker.client.dto.MenuTreeDTO;
import com.xueying.seeker.client.query.MenuFindQuery;
import com.xueying.seeker.client.query.MenuQuery;
import com.xueying.seeker.common.util.SimpleConverter;
import com.xueying.seeker.core.dao.MenuDAO;
import com.xueying.seeker.core.entity.MenuDO;
import com.xueying.seeker.core.entity.RoleMenuDO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 〈菜单服务处理类〉
 *
 * @author Allen
 * @date 2019/5/30
 * @since 1.0.0
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuDAO, MenuDO> {
    /**
     * 注入角色菜单
     */
    @Autowired
    private RoleMenuServiceImpl roleMenuService;

    /**
     * 根据用户编码查找权限范围内的菜单列表
     *
     * @param userId 用户编码
     * @return 用户权限内的菜单列表
     */
    public MenuTreeDTO selectPrivilegeMenuTreeByUserId(Long userId) {
        List<MenuDO> menuDOList = baseMapper.findPrivilegeMenuByUserId(userId);
        return getChildMenuTree(menuDOList);
    }

    /**
     * 根据菜单编码查找菜单树列表
     *
     * @param menuFindQuery 菜单查询入参
     * @return 菜单编码查找菜单树列表
     */
    public MenuTreeDTO selectMenuTreeById(MenuFindQuery menuFindQuery) {
        List<MenuDO> menuDOList = baseMapper.findMenuDO(menuFindQuery.getMenuId(), menuFindQuery.getDisplay(),
                menuFindQuery.getPublicAttribute());
        return getChildMenuTree(menuDOList);
    }

    /**
     * 得到树形结构菜单列表
     *
     * @param menuDOList 数据库菜单列表
     * @return 转换树形菜单列表
     */
    private MenuTreeDTO getChildMenuTree(List<MenuDO> menuDOList) {
        MenuTreeDTO menu = null;
        if (!CollectionUtils.isEmpty(menuDOList)) {
            List<MenuTreeDTO> menuTreeDTOList = SimpleConverter.convert(menuDOList, MenuTreeDTO.class);
            MenuTreeDTO rootTreeMenu = getRootTreeMenu(menuTreeDTOList);
            menu = setChildMenus(menuTreeDTOList, rootTreeMenu);
        }
        return menu;
    }

    /**
     * 转换树形结构
     *
     * @param menuTreeDTOList 菜单树列表
     * @return 树形结构的菜单树
     */
    private MenuTreeDTO getRootTreeMenu(List<MenuTreeDTO> menuTreeDTOList) {
        List<MenuTreeDTO> childList = new ArrayList<>();
        Map<Long, List<MenuTreeDTO>> collectMenuTree = menuTreeDTOList.stream().collect(Collectors
                .groupingBy(MenuTreeDTO::getParentMenuId));
        collectMenuTree.forEach((k, v) -> {
            if (v.size() == 1) {
                if (v.get(0).getMenuLevel() == 1 || v.get(0).getMenuLevel() == 0) {
                    childList.add(v.get(0));
                }
            }
        });
        return childList.get(0);
    }

    /**
     * 转换树形结构
     *
     * @param menuTreeDTOList 菜单树列表数据
     * @param menuTreeDTO     节点树形目录
     * @return 树形结构
     */
    private MenuTreeDTO setChildMenus(List<MenuTreeDTO> menuTreeDTOList,
                                      MenuTreeDTO menuTreeDTO) {
        List<MenuTreeDTO> menuTreeDTOS = menuTreeDTOList.stream().filter(a ->
                a.getParentMenuId().equals(menuTreeDTO.getId())).collect(Collectors.toList());
        menuTreeDTO.setChildMenus(menuTreeDTOS);
        menuTreeDTO.getChildMenus().forEach(t -> {
            setChildMenus(menuTreeDTOList, t);
        });
        return menuTreeDTO;
    }


}

其中getChildMenuTree方法就是将树形结构转换成子父关系的Json字符串的实现逻辑,其原理主要是通过java8新特性stream来实现groupingBy分组来达到分层组成对应的Json层级的思想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

apicescn

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值