Просмотр исходного кода

remove menu authorized (#2911)

* Close: https://github.com/ant-design/ant-design-pro/issues/2910
* remove menu authorized to menu-model
陈小聪 7 лет назад
Родитель
Сommit
91be534a97

+ 3 - 1
src/components/Login/index.js

@@ -113,7 +113,9 @@ class Login extends Component {
                 </Tabs>
                 {otherChildren}
               </React.Fragment>
-            ) : children}
+            ) : (
+              children
+            )}
           </Form>
         </div>
       </LoginContext.Provider>

+ 1 - 15
src/components/SiderMenu/BaseMenu.js

@@ -40,11 +40,7 @@ export default class BaseMenu extends PureComponent {
     }
     return menusData
       .filter(item => item.name && !item.hideInMenu)
-      .map(item => {
-        // make dom
-        const ItemDom = this.getSubMenuOrItem(item, parent);
-        return this.checkPermissionItem(item.authority, ItemDom);
-      })
+      .map(item => this.getSubMenuOrItem(item, parent))
       .filter(item => item);
   };
 
@@ -121,16 +117,6 @@ export default class BaseMenu extends PureComponent {
     );
   };
 
-  // permission to check
-  checkPermissionItem = (authority, ItemDom) => {
-    const { Authorized } = this.props;
-    if (Authorized && Authorized.check) {
-      const { check } = Authorized;
-      return check(authority, ItemDom);
-    }
-    return ItemDom;
-  };
-
   conversionPath = path => {
     if (path && path.indexOf('http') === 0) {
       return path;

+ 13 - 53
src/layouts/BasicLayout.js

@@ -23,39 +23,6 @@ const SettingDrawer = React.lazy(() => import('@/components/SettingDrawer'));
 
 const { Content } = Layout;
 
-function mapRoutesToMenu(routes, parentAuthority, parentName) {
-  return routes
-    .map(item => {
-      if (!item.name || !item.path) {
-        return null;
-      }
-
-      let locale = 'menu';
-      if (parentName) {
-        locale = `${parentName}.${item.name}`;
-      } else {
-        locale = `menu.${item.name}`;
-      }
-
-      const result = {
-        ...item,
-        name: formatMessage({ id: locale, defaultMessage: item.name }),
-        locale,
-        authority: item.authority || parentAuthority,
-      };
-      if (item.routes) {
-        const children = mapRoutesToMenu(item.routes, item.authority, locale);
-        // Reduce memory usage
-        result.children = children;
-      }
-      delete result.routes;
-      return result;
-    })
-    .filter(item => item);
-}
-
-const memoizedMapRoutesToMenu = memoizeOne(mapRoutesToMenu, isEqual);
-
 const query = {
   'screen-xs': {
     maxWidth: 575,
@@ -90,18 +57,21 @@ class BasicLayout extends React.PureComponent {
     this.matchParamsPath = memoizeOne(this.matchParamsPath, isEqual);
   }
 
-  state = {
-    menuData: this.getMenuData(),
-  };
-
   componentDidMount() {
-    const { dispatch } = this.props;
+    const {
+      dispatch,
+      route: { routes, authority },
+    } = this.props;
     dispatch({
       type: 'user/fetchCurrent',
     });
     dispatch({
       type: 'setting/getSetting',
     });
+    dispatch({
+      type: 'menu/getMenuData',
+      payload: { routes, authority },
+    });
   }
 
   componentDidUpdate(preProps) {
@@ -114,10 +84,6 @@ class BasicLayout extends React.PureComponent {
     }
   }
 
-  componentWillUnmount() {
-    cancelAnimationFrame(this.renderRef);
-  }
-
   getContext() {
     const { location } = this.props;
     return {
@@ -126,19 +92,13 @@ class BasicLayout extends React.PureComponent {
     };
   }
 
-  getMenuData() {
-    const {
-      route: { routes, authority },
-    } = this.props;
-    return memoizedMapRoutesToMenu(routes, authority);
-  }
-
   /**
    * 获取面包屑映射
    * @param {Object} menuData 菜单配置
    */
   getBreadcrumbNameMap() {
     const routerMap = {};
+    const { menuData } = this.props;
     const flattenMenuData = data => {
       data.forEach(menuItem => {
         if (menuItem.children) {
@@ -148,7 +108,7 @@ class BasicLayout extends React.PureComponent {
         routerMap[menuItem.path] = menuItem;
       });
     };
-    flattenMenuData(this.getMenuData());
+    flattenMenuData(menuData);
     return routerMap;
   }
 
@@ -214,8 +174,8 @@ class BasicLayout extends React.PureComponent {
       children,
       location: { pathname },
       isMobile,
+      menuData,
     } = this.props;
-    const { menuData } = this.state;
     const isTop = PropsLayout === 'topmenu';
     const routerConfig = this.matchParamsPath(pathname);
     const layout = (
@@ -223,7 +183,6 @@ class BasicLayout extends React.PureComponent {
         {isTop && !isMobile ? null : (
           <SiderMenu
             logo={logo}
-            Authorized={Authorized}
             theme={navTheme}
             onCollapse={this.handleMenuCollapse}
             menuData={menuData}
@@ -273,9 +232,10 @@ class BasicLayout extends React.PureComponent {
   }
 }
 
-export default connect(({ global, setting }) => ({
+export default connect(({ global, setting, menu }) => ({
   collapsed: global.collapsed,
   layout: setting.layout,
+  menuData: menu.menuData,
   ...setting,
 }))(props => (
   <Media query="(max-width: 599px)">

+ 0 - 2
src/layouts/Header.js

@@ -7,7 +7,6 @@ import router from 'umi/router';
 import GlobalHeader from '@/components/GlobalHeader';
 import TopNavHeader from '@/components/TopNavHeader';
 import styles from './Header.less';
-import Authorized from '@/utils/Authorized';
 
 const { Header } = Layout;
 
@@ -128,7 +127,6 @@ class HeaderView extends PureComponent {
           <TopNavHeader
             theme={navTheme}
             mode="horizontal"
-            Authorized={Authorized}
             onCollapse={handleMenuCollapse}
             onNoticeClear={this.handleNoticeClear}
             onMenuClick={this.handleMenuClick}

+ 99 - 0
src/models/menu.js

@@ -0,0 +1,99 @@
+import memoizeOne from 'memoize-one';
+import isEqual from 'lodash/isEqual';
+import { formatMessage } from 'umi/locale';
+import Authorized from '@/utils/Authorized';
+
+const { check } = Authorized;
+
+// Conversion router to menu.
+function formatter(data, parentAuthority, parentName) {
+  return data
+    .map(item => {
+      if (!item.name || !item.path) {
+        return null;
+      }
+
+      let locale = 'menu';
+      if (parentName) {
+        locale = `${parentName}.${item.name}`;
+      } else {
+        locale = `menu.${item.name}`;
+      }
+
+      const result = {
+        ...item,
+        name: formatMessage({ id: locale, defaultMessage: item.name }),
+        locale,
+        authority: item.authority || parentAuthority,
+      };
+      if (item.routes) {
+        const children = formatter(item.routes, item.authority, locale);
+        // Reduce memory usage
+        result.children = children;
+      }
+      delete result.routes;
+      return result;
+    })
+    .filter(item => item);
+}
+
+const memoizeOneFormatter = memoizeOne(formatter, isEqual);
+
+/**
+ * get SubMenu or Item
+ */
+const getSubMenu = item => {
+  // doc: add hideChildrenInMenu
+  if (item.children && !item.hideChildrenInMenu && item.children.some(child => child.name)) {
+    return {
+      ...item,
+      children: filterMenuData(item.children), // eslint-disable-line
+    };
+  }
+  return item;
+};
+
+/**
+ * filter menuData
+ */
+const filterMenuData = menuData => {
+  if (!menuData) {
+    return [];
+  }
+  return menuData
+    .filter(item => item.name && !item.hideInMenu)
+    .map(item => {
+      // make dom
+      const ItemDom = getSubMenu(item);
+      const data = check(item.authority, ItemDom);
+      return data;
+    })
+    .filter(item => item);
+};
+
+export default {
+  namespace: 'menu',
+
+  state: {
+    menuData: [],
+  },
+
+  effects: {
+    *getMenuData({ payload }, { put }) {
+      const { routes, authority } = payload;
+      yield put({
+        type: 'save',
+        payload: filterMenuData(memoizeOneFormatter(routes, authority)),
+      });
+    },
+  },
+
+  reducers: {
+    save(state, action) {
+      return {
+        ...state,
+        menuData: action.payload,
+      };
+    },
+  },
+};