public static List<PermissionMenuVO.MenuInfo> buildMenu(final List<ResourceVO> metaList) {
        
        List<PermissionMenuVO.MenuInfo> retList = new ArrayList<>();
        if (CollectionUtils.isEmpty(metaList)) {
            return retList;
        }
        Map<String, PermissionMenuVO.MenuInfo> menuInfoMap = metaList.stream()
                .map(PermissionMenuVO.MenuInfo::buildMenuInfo)
                .filter(menuInfo -> Objects.nonNull(menuInfo) && StringUtils.isNotEmpty(menuInfo.getId()))
                .collect(Collectors.toMap(PermissionMenuVO.MenuInfo::getId, Function.identity(), (value1, value2) -> value1));
        
        metaList.stream()
                .filter(meta -> Objects.nonNull(meta) && StringUtils.isNotEmpty(meta.getId()))
                .collect(Collectors.toMap(ResourceVO::getParentId, ResourceUtil::convertIds, ListUtil::mergeSet))
                .forEach((parent, children) -> {
                    PermissionMenuVO.MenuInfo menuInfo = menuInfoMap.get(parent);
                    if (CollectionUtils.isNotEmpty(children)) {
                        List<PermissionMenuVO.MenuInfo> targetList = Objects.isNull(menuInfo) ? retList : menuInfo.getChildren();
                        children.stream().map(menuInfoMap::get).filter(Objects::nonNull)
                                .sorted(comparing(PermissionMenuVO.MenuInfo::getSort, nullsLast(naturalOrder())))
                                .forEach(targetList::add);
                    }
                });
        
        return retList;
    }
get Menu Info.

@param metaList {@linkplain List} resource list
@return {@linkplain List} menu infos.
shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/ResourceUtil.java