| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| import React, { createElement } from "react"; |
| import { Spin } from "antd"; |
| import pathToRegexp from "path-to-regexp"; |
| import Loadable from "react-loadable"; |
| import { getMenuData } from "./menu"; |
| |
| let routerDataCache; |
| |
| const modelNotExisted = (app, model) => |
| // eslint-disable-next-line |
| !app._models.some(({ namespace }) => { |
| return namespace === model.substring(model.lastIndexOf("/") + 1); |
| }); |
| |
| // wrapper of dynamic |
| const dynamicWrapper = (app, models, component) => { |
| // register models |
| models.forEach(model => { |
| if (modelNotExisted(app, model)) { |
| // eslint-disable-next-line |
| app.model(require(`../models/${model}`).default); |
| } |
| }); |
| |
| // () => require('module') |
| // transformed by babel-plugin-dynamic-import-node-sync |
| if (component.toString().indexOf(".then(") < 0) { |
| return props => { |
| if (!routerDataCache) { |
| routerDataCache = getRouterData(app); |
| } |
| return createElement(component().default, { |
| ...props, |
| routerData: routerDataCache |
| }); |
| }; |
| } |
| // () => import('module') |
| return Loadable({ |
| loader: () => { |
| if (!routerDataCache) { |
| routerDataCache = getRouterData(app); |
| } |
| return component().then(raw => { |
| const Component = raw.default || raw; |
| return props => |
| createElement(Component, { |
| ...props, |
| routerData: routerDataCache |
| }); |
| }); |
| }, |
| loading: () => { |
| return <Spin size="large" className="global-spin" />; |
| } |
| }); |
| }; |
| |
| function getFlatMenuData(menus) { |
| let keys = {}; |
| menus.forEach(item => { |
| if (item.children) { |
| keys[item.path] = { ...item }; |
| keys = { ...keys, ...getFlatMenuData(item.children) }; |
| } else { |
| keys[item.path] = { ...item }; |
| } |
| }); |
| return keys; |
| } |
| |
| export const getRouterData = app => { |
| const routerConfig = { |
| "/": { |
| component: dynamicWrapper(app, ["user", "login"], () => |
| import("../layouts/BasicLayout") |
| ) |
| }, |
| "/home": { |
| component: dynamicWrapper(app, [], () => import("../routes/Home")) |
| }, |
| "/plug/:index/:id": { |
| component: dynamicWrapper(app, ["common"], () => |
| import("../routes/Plugin/Common") |
| ) |
| }, |
| "/system/role": { |
| // 角色管理 |
| component: dynamicWrapper(app, ["role"], () => |
| import("../routes/System/Role") |
| ) |
| }, |
| "/system/manage": { |
| // 用户管理 |
| component: dynamicWrapper(app, ["manage", "dataPermission"], () => |
| import("../routes/System/User") |
| ) |
| }, |
| "/system/resource": { |
| // 资源管理 |
| component: dynamicWrapper(app, ["resource"], () => |
| import("../routes/System/Resource") |
| ) |
| }, |
| "/config/metadata": { |
| // 元数据管理 |
| component: dynamicWrapper(app, ["metadata"], () => |
| import("../routes/System/Metadata") |
| ) |
| }, |
| "/config/plugin": { |
| // 插件管理 |
| component: dynamicWrapper(app, ["plugin"], () => |
| import("../routes/System/Plugin") |
| ) |
| }, |
| "/config/pluginhandle": { |
| // 插件处理管理 |
| component: dynamicWrapper(app, ["pluginHandle"], () => |
| import("../routes/System/PluginHandle") |
| ) |
| }, |
| "/config/auth": { |
| // 认证管理 |
| component: dynamicWrapper(app, ["auth"], () => |
| import("../routes/System/AppAuth") |
| ) |
| }, |
| "/config/dict": { |
| // 字典管理 |
| component: dynamicWrapper(app, ["shenyuDict"], () => |
| import("../routes/System/Dict") |
| ) |
| }, |
| "/exception/403": { |
| component: dynamicWrapper(app, [], () => |
| import("../routes/Exception/403") |
| ) |
| }, |
| "/exception/404": { |
| component: dynamicWrapper(app, [], () => |
| import("../routes/Exception/404") |
| ) |
| }, |
| "/exception/500": { |
| component: dynamicWrapper(app, [], () => |
| import("../routes/Exception/500") |
| ) |
| }, |
| "/exception/trigger": { |
| component: dynamicWrapper(app, ["error"], () => |
| import("../routes/Exception/triggerException") |
| ) |
| }, |
| "/user": { |
| component: dynamicWrapper(app, [], () => import("../layouts/UserLayout")) |
| }, |
| "/user/login": { |
| component: dynamicWrapper(app, ["login"], () => |
| import("../routes/User/Login") |
| ) |
| } |
| }; |
| // Get name from ./menu.js or just set it in the router data. |
| const menuData = getFlatMenuData(getMenuData()); |
| // Route configuration data |
| // eg. {name,authority ...routerConfig } |
| const routerData = {}; |
| // The route matches the menu |
| Object.keys(routerConfig).forEach(path => { |
| // Regular match item name |
| // eg. router /user/:id === /user/chen |
| const pathRegexp = pathToRegexp(path); |
| const menuKey = Object.keys(menuData).find(key => |
| pathRegexp.test(`${key}`) |
| ); |
| let menuItem = {}; |
| // If menuKey is not empty |
| if (menuKey) { |
| menuItem = menuData[menuKey]; |
| } |
| let router = routerConfig[path]; |
| // If you need to configure complex parameter routing, |
| // https://github.com/ant-design/ant-design-pro-site/blob/master/docs/router-and-nav.md#%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E8%B7%AF%E7%94%B1%E8%8F%9C%E5%8D%95 |
| // eg . /list/:type/user/info/:id |
| router = { |
| ...router, |
| name: router.name || menuItem.name, |
| authority: router.authority || menuItem.authority, |
| hideInBreadcrumb: router.hideInBreadcrumb || menuItem.hideInBreadcrumb |
| }; |
| routerData[path] = router; |
| }); |
| return routerData; |
| }; |