Sfoglia il codice sorgente

feat(menu): dynamic router

Next xyh
Lind 3 anni fa
parent
commit
56577226a6

+ 3 - 2
src/app.tsx

@@ -210,12 +210,13 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
 
 export function patchRoutes(routes: any) {
   if (extraRoutes && extraRoutes.length) {
-    routes.routes[1].routes = [...routes?.routes[1]?.routes, ...getRoutes(extraRoutes)];
+    console.log(getRoutes(extraRoutes));
+    routes.routes[1].routes = [...routes.routes[1].routes, ...getRoutes(extraRoutes)];
   }
 }
 
 export function render(oldRender: any) {
-  if (history.location.pathname !== loginPath && history.location.pathname !== '/') {
+  if (history.location.pathname !== loginPath) {
     MenuService.queryMenuThree({ paging: false }).then((res) => {
       if (res.status === 200) {
         extraRoutes = res.result;

+ 8 - 6
src/pages/system/Menu/components/permission.tsx

@@ -106,12 +106,14 @@ const ParentNode = (props: ParentNodeType) => {
           onChange={onChange}
           value={checkedList}
           disabled={props.disabled}
-          options={props.actions.map((item: any) => {
-            return {
-              label: item.name,
-              value: item.action,
-            };
-          })}
+          options={props.actions
+            .filter((a) => a.action)
+            .map((item) => {
+              return {
+                label: item.name,
+                value: item.action,
+              };
+            })}
         />
       </div>
     </div>

+ 4 - 7
src/pages/system/Menu/index.tsx

@@ -4,7 +4,7 @@ import ProTable from '@jetlinks/pro-table';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import { useRef, useState } from 'react';
 import { useIntl } from '@@/plugin-locale/localeExports';
-import { Button, message, Popconfirm, Tooltip, Card, Divider, Modal, Form, Input } from 'antd';
+import { Button, message, Popconfirm, Tooltip, Modal, Form, Input } from 'antd';
 import {
   SearchOutlined,
   PlusOutlined,
@@ -18,7 +18,7 @@ import SearchComponent from '@/components/SearchComponent';
 import Service from './service';
 import type { MenuItem } from './typing';
 import moment from 'moment';
-import { getMenuPathBuCode, MENUS_CODE } from '@/utils/menu';
+import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
 
 export const service = new Service('menu');
 
@@ -61,7 +61,7 @@ export default observer(() => {
    */
   const pageJump = (id: string) => {
     // 跳转详情
-    history.push(`${getMenuPathBuCode(MENUS_CODE['system/Menu/Detail'])}?id=${id}`);
+    history.push(`${getMenuPathByCode(MENUS_CODE['system/Menu/Detail'])}?id=${id}`);
   };
 
   const columns: ProColumns<MenuItem>[] = [
@@ -218,10 +218,7 @@ export default observer(() => {
 
   return (
     <PageContainer>
-      <Card>
-        <SearchComponent field={columns} onSearch={searchFn} />
-      </Card>
-      <Divider />
+      <SearchComponent field={columns} onSearch={searchFn} />
       <ProTable<MenuItem>
         columns={columns}
         actionRef={actionRef}

+ 3 - 1
src/pages/user/Login/index.tsx

@@ -48,7 +48,9 @@ const Login: React.FC = () => {
       const { redirect } = query as {
         redirect: string;
       };
-      history.push(redirect || '/');
+      // history.push(redirect || '/');
+      // 用于触发app中的render,生成路由
+      window.location.href = redirect || '/';
       setLoading(false);
     }, 10);
   };

+ 39 - 15
src/utils/menu.ts

@@ -100,6 +100,8 @@ export const MENUS_CODE = {
   'visualization/Screen': 'visualization/Screen',
 };
 
+const isRedirect = false;
+
 /**
  * 根据url获取映射的组件
  * @param files
@@ -137,24 +139,34 @@ const getRoutes = (extraRoutes: MenuItem[], level: number = 1) => {
   const Menus: IRouteProps[] = [];
   extraRoutes.forEach((route) => {
     const component = allComponents[route.code] || null;
-    if (level === 1) {
-      Menus.push({
-        key: route.url,
-        name: route.name,
-        path: route.url,
-        children: getRoutes(flatRoute(route.children || []), level + 1),
-      });
+    const _route: IRouteProps = {
+      key: route.url,
+      name: route.name,
+      path: route.url,
+    };
+    if (level === 1 && route.children) {
+      _route.children = [
+        ...getRoutes(flatRoute(route.children || []), level + 1),
+        {
+          path: _route.path,
+          redirect: route.children[0].url,
+        },
+      ];
+      Menus.push(_route);
     }
     if (component) {
-      Menus.push({
-        key: route.url,
-        name: route.name,
-        path: route.url,
-        exact: true,
-        component,
-      });
+      _route.component = component;
+      _route.exact = true;
+      Menus.push(_route);
     }
   });
+
+  if (level === 1 && !isRedirect && extraRoutes.length) {
+    Menus.push({
+      path: '/',
+      redirect: extraRoutes[0].url,
+    });
+  }
   return Menus;
 };
 
@@ -196,10 +208,22 @@ export const saveMenusCache = (routes: MenuItem[]) => {
  * 通过缓存的数据取出相应的路由url
  * @param code
  */
-export const getMenuPathBuCode = (code: string): string => {
+export const getMenuPathByCode = (code: string): string => {
   const menusStr = localStorage.getItem(MENUS_DATA_CACHE) || '{}';
   const menusData = JSON.parse(menusStr);
+  console.log(code, menusData);
   return menusData[code];
 };
 
+/**
+ * 通过缓存的数据取出相应的路由url
+ * @param code 路由Code
+ * @param id 路由携带参数
+ * @param regStr 路由参数code
+ */
+export const getMenuPathByParams = (code: string, id: string, regStr: string = ':id') => {
+  const menusData = getMenuPathByCode(code);
+  return menusData.replace(regStr, id);
+};
+
 export default getRoutes;