feat: 动态路由
This commit is contained in:
@@ -12,13 +12,14 @@ const Settings: ProLayoutProps & {
|
||||
colorPrimary: "#1890ff",
|
||||
layout: "mix",
|
||||
contentWidth: "Fluid",
|
||||
fixedHeader: false,
|
||||
fixedHeader: true,
|
||||
fixSiderbar: true,
|
||||
colorWeak: false,
|
||||
title: "tashow - 管理后台",
|
||||
title: "百业到家云控台",
|
||||
pwa: true,
|
||||
logo: "https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg",
|
||||
logo: "/logo.svg",
|
||||
iconfontUrl: "",
|
||||
splitMenus: true,
|
||||
token: {
|
||||
// 参见ts声明,demo 见文档,通过token 修改样式
|
||||
//https://procomponents.ant.design/components/layout#%E9%80%9A%E8%BF%87-token-%E4%BF%AE%E6%94%B9%E6%A0%B7%E5%BC%8F
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
* @param icon 配置路由的图标,取值参考 https://ant.design/components/icon-cn, 注意去除风格后缀和大小写,如想要配置图标为 <StepBackwardOutlined /> 则取值应为 stepBackward 或 StepBackward,如想要配置图标为 <UserOutlined /> 则取值应为 user 或者 User
|
||||
* @doc https://umijs.org/docs/guides/routes
|
||||
*/
|
||||
|
||||
export default [
|
||||
{
|
||||
path: "/user",
|
||||
@@ -28,6 +29,24 @@ export default [
|
||||
icon: "smile",
|
||||
component: "./Welcome",
|
||||
},
|
||||
// {
|
||||
// path: "/system1",
|
||||
// name: "system1",
|
||||
// icon: "smile",
|
||||
// routes: [
|
||||
// {
|
||||
// name: "tenant",
|
||||
// path: "/system1/tenant",
|
||||
// routes: [
|
||||
// {
|
||||
// name: "package",
|
||||
// path: "/system1/tenant/package",
|
||||
// component: "system/tenant/package",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
path: "/admin",
|
||||
name: "admin",
|
||||
@@ -58,6 +77,6 @@ export default [
|
||||
{
|
||||
component: "404",
|
||||
layout: false,
|
||||
path: "./*",
|
||||
path: "*",
|
||||
},
|
||||
];
|
||||
|
||||
101
src/app.tsx
101
src/app.tsx
@@ -1,9 +1,9 @@
|
||||
import { LinkOutlined } from "@ant-design/icons";
|
||||
import React, { Children, Component, JSX, Suspense } from "react";
|
||||
import { Spin } from "antd";
|
||||
import type { Settings as LayoutSettings } from "@ant-design/pro-components";
|
||||
import { SettingDrawer } from "@ant-design/pro-components";
|
||||
import type { RequestConfig, RunTimeLayoutConfig } from "@umijs/max";
|
||||
import { history, Link } from "@umijs/max";
|
||||
import React from "react";
|
||||
import { history, Link, Navigate } from "@umijs/max";
|
||||
import {
|
||||
AvatarDropdown,
|
||||
AvatarName,
|
||||
@@ -16,13 +16,20 @@ import type { UserVO, TokenType, UserInfoVO } from "@/services/login/types";
|
||||
import defaultSettings from "../config/defaultSettings";
|
||||
import { errorConfig } from "./requestErrorConfig";
|
||||
import "@ant-design/v5-patch-for-react-19";
|
||||
import { getAccessToken, getRefreshToken, getTenantId } from "./utils/auth";
|
||||
import { getAccessToken, getRefreshToken, getTenantId } from "@/utils/auth";
|
||||
import { CACHE_KEY, useCache } from "./hooks/web/useCache";
|
||||
import { MenuVO } from "./services/system/menu";
|
||||
|
||||
import {
|
||||
transformBackendMenuToFlatRoutes,
|
||||
transformMenuToRoutes,
|
||||
} from "@/utils/menuUtils";
|
||||
const isDev = process.env.NODE_ENV === "development";
|
||||
const isDevOrTest = isDev || process.env.CI;
|
||||
const loginPath = "/user/login";
|
||||
|
||||
// 全局存储菜单数据和路由映射
|
||||
|
||||
/**
|
||||
* @see https://umijs.org/docs/api/runtime-config#getinitialstate
|
||||
* */
|
||||
@@ -43,6 +50,9 @@ export async function getInitialState(): Promise<{
|
||||
const { data } = await getInfo();
|
||||
wsCache.set(CACHE_KEY.USER, data);
|
||||
wsCache.set(CACHE_KEY.ROLE_ROUTERS, data.menus);
|
||||
|
||||
// 转换菜单格式
|
||||
|
||||
return data;
|
||||
} catch (_error) {
|
||||
history.push(loginPath);
|
||||
@@ -51,12 +61,17 @@ export async function getInitialState(): Promise<{
|
||||
};
|
||||
// 如果不是登录页面,执行
|
||||
const { location } = history;
|
||||
|
||||
if (
|
||||
![loginPath, "/user/register", "/user/register-result"].includes(
|
||||
location.pathname
|
||||
)
|
||||
) {
|
||||
const currentUser = await fetchUserInfo();
|
||||
const currentUser = wsCache.get(CACHE_KEY.USER);
|
||||
if (getAccessToken() && !currentUser) {
|
||||
fetchUserInfo();
|
||||
}
|
||||
|
||||
return {
|
||||
fetchUserInfo,
|
||||
currentUser,
|
||||
@@ -79,6 +94,10 @@ export const layout: RunTimeLayoutConfig = ({
|
||||
<Question key="doc" />,
|
||||
<SelectLang key="SelectLang" />,
|
||||
],
|
||||
menu: {
|
||||
locale: false,
|
||||
// 关闭国际化-
|
||||
},
|
||||
avatarProps: {
|
||||
src: initialState?.currentUser?.user.avatar,
|
||||
title: <AvatarName />,
|
||||
@@ -117,17 +136,9 @@ export const layout: RunTimeLayoutConfig = ({
|
||||
width: "331px",
|
||||
},
|
||||
],
|
||||
links: isDevOrTest
|
||||
? [
|
||||
<Link key="openapi" to="/umi/plugin/openapi" target="_blank">
|
||||
<LinkOutlined />
|
||||
<span>OpenAPI 文档</span>
|
||||
</Link>,
|
||||
]
|
||||
: [],
|
||||
menuHeaderRender: undefined,
|
||||
// 自定义 403 页面
|
||||
// unAccessible: <div>unAccessible</div>,
|
||||
unAccessible: <div>unAccessible</div>,
|
||||
// 增加一个 loading 的状态
|
||||
childrenRender: (children) => {
|
||||
// if (initialState?.loading) return <PageLoading />;
|
||||
@@ -187,3 +198,65 @@ export const request: RequestConfig = {
|
||||
},
|
||||
],
|
||||
};
|
||||
// umi 4 使用 modifyRoutes
|
||||
export function patchClientRoutes({ routes }: { routes: any }) {
|
||||
const { wsCache } = useCache();
|
||||
const globalMenus = wsCache.get(CACHE_KEY.ROLE_ROUTERS);
|
||||
const routerIndex = routes.findIndex((item: any) => item.path === "/");
|
||||
const parentId = routes[routerIndex].id;
|
||||
|
||||
if (globalMenus) {
|
||||
routes[routerIndex]["routes"].push(...loopMenuItem(globalMenus, parentId));
|
||||
}
|
||||
}
|
||||
|
||||
const loopMenuItem = (menus: any[], pId: number | string): any[] => {
|
||||
return menus.flatMap((item) => {
|
||||
let Component: React.ComponentType<any> | null = null;
|
||||
if (item.component && item.component.length > 0) {
|
||||
// 防止配置了路由,但本地暂未添加对应的页面,产生的错误
|
||||
console.log(item.component);
|
||||
Component = React.lazy(() => {
|
||||
const importComponent = () => import(`@/pages/${item.component}`);
|
||||
const import404 = () => import("@/pages/404");
|
||||
return importComponent().catch(import404);
|
||||
});
|
||||
}
|
||||
if (item.children && item.children.length > 0) {
|
||||
return [
|
||||
{
|
||||
path: item.path,
|
||||
name: item.name,
|
||||
icon: item.icon,
|
||||
id: item.id,
|
||||
parentId: pId,
|
||||
children: [
|
||||
{
|
||||
path: item.url,
|
||||
element: <Navigate to={item.children[0].url} replace />,
|
||||
},
|
||||
...loopMenuItem(item.children, item.menuID),
|
||||
],
|
||||
},
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
{
|
||||
path: item.path,
|
||||
name: item.name,
|
||||
icon: item.icon,
|
||||
id: item.menuID,
|
||||
parentId: pId,
|
||||
element: (
|
||||
<React.Suspense
|
||||
fallback={<Spin style={{ width: "100%", height: "100%" }} />}
|
||||
>
|
||||
{Component && <Component />}
|
||||
</React.Suspense>
|
||||
),
|
||||
children: [], // 添加缺失的 children 属性
|
||||
},
|
||||
];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -45,9 +45,9 @@ body,
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family:
|
||||
AlibabaSans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans',
|
||||
sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
font-family: AlibabaSans, -apple-system, BlinkMacSystemFont, "Segoe UI",
|
||||
Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
}
|
||||
|
||||
.colorWeak {
|
||||
@@ -55,7 +55,7 @@ body,
|
||||
}
|
||||
|
||||
.ant-layout {
|
||||
min-height: 100vh;
|
||||
min-height: 100vh !important;
|
||||
}
|
||||
.ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed {
|
||||
left: unset;
|
||||
|
||||
@@ -1,52 +1,53 @@
|
||||
export default {
|
||||
'menu.welcome': '欢迎',
|
||||
'menu.more-blocks': '更多区块',
|
||||
'menu.home': '首页',
|
||||
'menu.admin': '管理页',
|
||||
'menu.admin.sub-page': '二级管理页',
|
||||
'menu.login': '登录',
|
||||
'menu.register': '注册',
|
||||
'menu.register-result': '注册结果',
|
||||
'menu.dashboard': 'Dashboard',
|
||||
'menu.dashboard.analysis': '分析页',
|
||||
'menu.dashboard.monitor': '监控页',
|
||||
'menu.dashboard.workplace': '工作台',
|
||||
'menu.exception.403': '403',
|
||||
'menu.exception.404': '404',
|
||||
'menu.exception.500': '500',
|
||||
'menu.form': '表单页',
|
||||
'menu.form.basic-form': '基础表单',
|
||||
'menu.form.step-form': '分步表单',
|
||||
'menu.form.step-form.info': '分步表单(填写转账信息)',
|
||||
'menu.form.step-form.confirm': '分步表单(确认转账信息)',
|
||||
'menu.form.step-form.result': '分步表单(完成)',
|
||||
'menu.form.advanced-form': '高级表单',
|
||||
'menu.list': '列表页',
|
||||
'menu.list.table-list': '查询表格',
|
||||
'menu.list.basic-list': '标准列表',
|
||||
'menu.list.card-list': '卡片列表',
|
||||
'menu.list.search-list': '搜索列表',
|
||||
'menu.list.search-list.articles': '搜索列表(文章)',
|
||||
'menu.list.search-list.projects': '搜索列表(项目)',
|
||||
'menu.list.search-list.applications': '搜索列表(应用)',
|
||||
'menu.profile': '详情页',
|
||||
'menu.profile.basic': '基础详情页',
|
||||
'menu.profile.advanced': '高级详情页',
|
||||
'menu.result': '结果页',
|
||||
'menu.result.success': '成功页',
|
||||
'menu.result.fail': '失败页',
|
||||
'menu.exception': '异常页',
|
||||
'menu.exception.not-permission': '403',
|
||||
'menu.exception.not-find': '404',
|
||||
'menu.exception.server-error': '500',
|
||||
'menu.exception.trigger': '触发错误',
|
||||
'menu.account': '个人页',
|
||||
'menu.account.center': '个人中心',
|
||||
'menu.account.settings': '个人设置',
|
||||
'menu.account.trigger': '触发报错',
|
||||
'menu.account.logout': '退出登录',
|
||||
'menu.editor': '图形编辑器',
|
||||
'menu.editor.flow': '流程编辑器',
|
||||
'menu.editor.mind': '脑图编辑器',
|
||||
'menu.editor.koni': '拓扑编辑器',
|
||||
"menu.welcome": "欢迎",
|
||||
"menu.more-blocks": "更多区块",
|
||||
"menu.home": "首页",
|
||||
"menu.admin": "管理页",
|
||||
"menu.admin.sub-page": "二级管理页",
|
||||
"menu.login": "登录",
|
||||
"menu.register": "注册",
|
||||
"menu.register-result": "注册结果",
|
||||
"menu.dashboard": "Dashboard",
|
||||
"menu.dashboard.analysis": "分析页",
|
||||
"menu.dashboard.monitor": "监控页",
|
||||
"menu.dashboard.workplace": "工作台",
|
||||
"menu.exception.403": "403",
|
||||
"menu.exception.404": "404",
|
||||
"menu.exception.500": "500",
|
||||
"menu.form": "表单页",
|
||||
"menu.form.basic-form": "基础表单",
|
||||
"menu.form.step-form": "分步表单",
|
||||
"menu.form.step-form.info": "分步表单(填写转账信息)",
|
||||
"menu.form.step-form.confirm": "分步表单(确认转账信息)",
|
||||
"menu.form.step-form.result": "分步表单(完成)",
|
||||
"menu.form.advanced-form": "高级表单",
|
||||
"menu.list": "列表页",
|
||||
"menu.list.table-list": "查询表格",
|
||||
"menu.list.basic-list": "标准列表",
|
||||
"menu.list.card-list": "卡片列表",
|
||||
"menu.list.search-list": "搜索列表",
|
||||
"menu.list.search-list.articles": "搜索列表(文章)",
|
||||
"menu.list.search-list.projects": "搜索列表(项目)",
|
||||
"menu.list.search-list.applications": "搜索列表(应用)",
|
||||
"menu.profile": "详情页",
|
||||
"menu.profile.basic": "基础详情页",
|
||||
"menu.profile.advanced": "高级详情页",
|
||||
"menu.result": "结果页",
|
||||
"menu.result.success": "成功页",
|
||||
"menu.result.fail": "失败页",
|
||||
"menu.exception": "异常页",
|
||||
"menu.exception.not-permission": "403",
|
||||
"menu.exception.not-find": "404",
|
||||
"menu.exception.server-error": "500",
|
||||
"menu.exception.trigger": "触发错误",
|
||||
"menu.account": "个人页",
|
||||
"menu.account.center": "个人中心",
|
||||
"menu.account.settings": "个人设置",
|
||||
"menu.account.trigger": "触发报错",
|
||||
"menu.account.logout": "退出登录",
|
||||
"menu.editor": "图形编辑器",
|
||||
"menu.editor.flow": "流程编辑器",
|
||||
"menu.editor.mind": "脑图编辑器",
|
||||
"menu.editor.koni": "拓扑编辑器",
|
||||
// 基础设施相关菜单
|
||||
};
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import { history, useIntl } from '@umijs/max';
|
||||
import { Button, Card, Result } from 'antd';
|
||||
import React from 'react';
|
||||
import { PageContainer } from "@ant-design/pro-components";
|
||||
import { history, useIntl } from "@umijs/max";
|
||||
import { Button, Card, Result } from "antd";
|
||||
import React from "react";
|
||||
|
||||
const NoFoundPage: React.FC = () => (
|
||||
<Card variant="borderless">
|
||||
<Result
|
||||
status="404"
|
||||
title="404"
|
||||
subTitle={useIntl().formatMessage({ id: 'pages.404.subTitle' })}
|
||||
subTitle={useIntl().formatMessage({ id: "pages.404.subTitle" })}
|
||||
extra={
|
||||
<Button type="primary" onClick={() => history.push('/')}>
|
||||
{useIntl().formatMessage({ id: 'pages.404.buttonText' })}
|
||||
<Button type="primary" onClick={() => history.push("/")}>
|
||||
{useIntl().formatMessage({ id: "pages.404.buttonText" })}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
5
src/pages/system/tenant/list/index.tsx
Normal file
5
src/pages/system/tenant/list/index.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
const TenantList = () => {
|
||||
return <div>TenantList</div>;
|
||||
};
|
||||
|
||||
export default TenantList;
|
||||
5
src/pages/system/tenant/package/index.tsx
Normal file
5
src/pages/system/tenant/package/index.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
const TenantPackage = () => {
|
||||
return <div>TenantPackage</div>;
|
||||
};
|
||||
|
||||
export default TenantPackage;
|
||||
@@ -104,7 +104,7 @@ const Page = () => {
|
||||
backdropFilter: "blur(4px)",
|
||||
}}
|
||||
onFinish={handleSubmit}
|
||||
subTitle="百业到家-管理平台"
|
||||
subTitle="百业到家云控台"
|
||||
// activityConfig={{
|
||||
// style: {
|
||||
// boxShadow: "0px 0px 8px rgba(0, 0, 0, 0.2)",
|
||||
|
||||
@@ -40,7 +40,6 @@ export async function login(
|
||||
// };
|
||||
|
||||
export async function getTenantIdByName(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: { name: string },
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
import request from '@/config/axios'
|
||||
import { request } from "@umijs/max";
|
||||
|
||||
// 获得授权信息
|
||||
export const getAuthorize = (clientId: string) => {
|
||||
return request.get({ url: '/system/oauth2/authorize?clientId=' + clientId })
|
||||
}
|
||||
// export const getAuthorize = (clientId: string) => {
|
||||
// return request.get({ url: '/system/oauth2/authorize?clientId=' + clientId })
|
||||
// }
|
||||
|
||||
// 发起授权
|
||||
export const authorize = (
|
||||
responseType: string,
|
||||
clientId: string,
|
||||
redirectUri: string,
|
||||
state: string,
|
||||
autoApprove: boolean,
|
||||
checkedScopes: string[],
|
||||
uncheckedScopes: string[]
|
||||
) => {
|
||||
// 构建 scopes
|
||||
const scopes = {}
|
||||
for (const scope of checkedScopes) {
|
||||
scopes[scope] = true
|
||||
}
|
||||
for (const scope of uncheckedScopes) {
|
||||
scopes[scope] = false
|
||||
}
|
||||
// 发起请求
|
||||
return request.post({
|
||||
url: '/system/oauth2/authorize',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
params: {
|
||||
response_type: responseType,
|
||||
client_id: clientId,
|
||||
redirect_uri: redirectUri,
|
||||
state: state,
|
||||
auto_approve: autoApprove,
|
||||
scope: JSON.stringify(scopes)
|
||||
}
|
||||
})
|
||||
}
|
||||
// // 发起授权
|
||||
// export const authorize = (
|
||||
// responseType: string,
|
||||
// clientId: string,
|
||||
// redirectUri: string,
|
||||
// state: string,
|
||||
// autoApprove: boolean,
|
||||
// checkedScopes: string[],
|
||||
// uncheckedScopes: string[]
|
||||
// ) => {
|
||||
// // 构建 scopes
|
||||
// const scopes = {}
|
||||
// for (const scope of checkedScopes) {
|
||||
// scopes[scope] = true
|
||||
// }
|
||||
// for (const scope of uncheckedScopes) {
|
||||
// scopes[scope] = false
|
||||
// }
|
||||
// // 发起请求
|
||||
// return request.post({
|
||||
// url: '/system/oauth2/authorize',
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/x-www-form-urlencoded'
|
||||
// },
|
||||
// params: {
|
||||
// response_type: responseType,
|
||||
// client_id: clientId,
|
||||
// redirect_uri: redirectUri,
|
||||
// state: state,
|
||||
// auto_approve: autoApprove,
|
||||
// scope: JSON.stringify(scopes)
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
@@ -16,6 +16,7 @@ export interface MenuVO {
|
||||
keepAlive: boolean;
|
||||
alwaysShow?: boolean;
|
||||
createTime: Date;
|
||||
children?: MenuVO[];
|
||||
}
|
||||
|
||||
// 查询菜单(精简)列表
|
||||
|
||||
97
src/utils/menuUtils.ts
Normal file
97
src/utils/menuUtils.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
// src/utils/menuUtils.ts
|
||||
import { MenuVO } from "@/services/system/menu";
|
||||
import type { MenuDataItem } from "@ant-design/pro-components";
|
||||
// src/utils/menuUtils.ts
|
||||
|
||||
// src/utils/menuUtils.ts
|
||||
// src/utils/route.ts
|
||||
export function transformMenuToRoutes(menuData: MenuVO[]): any[] {
|
||||
return menuData.map((item) => ({
|
||||
path: item.path,
|
||||
name: item.name,
|
||||
icon: item.icon,
|
||||
component: item.component,
|
||||
routes: item.children ? transformMenuToRoutes(item.children) : undefined,
|
||||
}));
|
||||
}
|
||||
|
||||
// src/utils/route.ts
|
||||
export function transformBackendMenuToFlatRoutes(menuData: any[]) {
|
||||
const flatRoutes: any[] = [];
|
||||
|
||||
function processMenu(items: any[], parentRouteId = "ant-design-pro-layout") {
|
||||
items.forEach((item) => {
|
||||
const currentRouteId = `route-${item.id}`;
|
||||
|
||||
// 处理路径 - 如果是子路由,需要组合完整路径
|
||||
let fullPath = item.path;
|
||||
if (item.parentId !== 0 && !item.path.startsWith("/")) {
|
||||
// 子路由需要相对路径
|
||||
fullPath = item.path;
|
||||
}
|
||||
|
||||
const route: any = {
|
||||
id: currentRouteId,
|
||||
path: fullPath,
|
||||
name: item.name,
|
||||
parentId: parentRouteId,
|
||||
};
|
||||
|
||||
// 添加图标(如果不是 # 的话)
|
||||
if (item.icon && item.icon !== "#") {
|
||||
route.icon = item.icon;
|
||||
}
|
||||
|
||||
// 添加组件路径
|
||||
if (item.component) {
|
||||
// 转换组件路径为动态导入格式
|
||||
route.component = item.component;
|
||||
}
|
||||
|
||||
// 其他属性
|
||||
if (!item.visible) {
|
||||
route.hideInMenu = true;
|
||||
}
|
||||
|
||||
flatRoutes.push(route);
|
||||
|
||||
// 递归处理子菜单
|
||||
if (item.children && item.children.length > 0) {
|
||||
processMenu(item.children, currentRouteId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
processMenu(menuData);
|
||||
return flatRoutes;
|
||||
}
|
||||
|
||||
export function transformMenuData(menuData: any[]) {
|
||||
const transformItem = (item: any, parentPath = "") => {
|
||||
const fullPath = item.path.startsWith("/")
|
||||
? item.path
|
||||
: `${parentPath}/${item.path}`;
|
||||
const result: any = {
|
||||
path: fullPath,
|
||||
name: item.name,
|
||||
key: `${item.id}`,
|
||||
};
|
||||
if (item.icon && item.icon !== "#") {
|
||||
result.icon = item.icon;
|
||||
}
|
||||
|
||||
if (!item.visible) {
|
||||
result.hideInMenu = true;
|
||||
}
|
||||
|
||||
if (item.children && item.children.length > 0) {
|
||||
result.children = item.children.map((child: any) =>
|
||||
transformItem(child, fullPath)
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
result;
|
||||
};
|
||||
return menuData.map((item) => transformItem(item));
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"jsx": "react-jsx",
|
||||
"esModuleInterop": true,
|
||||
|
||||
Reference in New Issue
Block a user