text: import React, { PureComponent } from 'react';
  import { Layout, Menu, Icon } from 'antd';
  import { Link } from 'dva/router';
  import styles from './index.less';
  
  const { Sider } = Layout;
  // Allow menu.js config icon as string or ReactNode
  //   icon: 'setting',
  //   icon: 'http://demo.com/icon.png',
  //   icon: <Icon type="setting" />,
  const getIcon = (icon) => {
    if (typeof icon === 'string' && icon.indexOf('http') === 0) {
      return <img src={icon} alt="icon" className={styles.icon} />;
    }
    if (typeof icon === 'string') {
      return <Icon type={icon} />;
    }
    return icon;
  };
  
  export default class SiderMenu extends PureComponent {
    constructor(props) {
      super(props);
      this.menus = props.menuData;
      this.state = {
        openKeys: this.getDefaultCollapsedSubMenus(props),
      };
    }
    componentWillReceiveProps(nextProps) {
      if (nextProps.location.pathname !== this.props.location.pathname) {
        this.setState({
          openKeys: this.getDefaultCollapsedSubMenus(nextProps),
        });
      }
    }
    getDefaultCollapsedSubMenus(props) {
      const { location: { pathname } } = props || this.props;
      const snippets = pathname.split('/').slice(1, -1);
      const currentPathSnippets = snippets.map((item, index) => {
        const arr = snippets.filter((_, i) => i <= index);
        return arr.join('/');
      });
      let currentMenuSelectedKeys = [];
      currentPathSnippets.forEach((item) => {
        currentMenuSelectedKeys = currentMenuSelectedKeys.concat(this.getSelectedMenuKeys(item));
      });
      if (currentMenuSelectedKeys.length === 0) {
        return ['dashboard'];
      }
      return currentMenuSelectedKeys;
    }
    getFlatMenuKeys(menus) {
      let keys = [];
      menus.forEach((item) => {
        if (item.children) {
          keys.push(item.path);
          keys = keys.concat(this.getFlatMenuKeys(item.children));
        } else {
          keys.push(item.path);
        }
      });
      return keys;
    }
    getSelectedMenuKeys = (path) => {
      const flatMenuKeys = this.getFlatMenuKeys(this.menus);
      if (flatMenuKeys.indexOf(path.replace(/^\//, '')) > -1) {
        return [path.replace(/^\//, '')];
      }
      if (flatMenuKeys.indexOf(path.replace(/^\//, '').replace(/\/$/, '')) > -1) {
        return [path.replace(/^\//, '').replace(/\/$/, '')];
      }
      return flatMenuKeys.filter((item) => {
        const itemRegExpStr = `^${item.replace(/:[\w-]+/g, '[\\w-]+')}$`;
        const itemRegExp = new RegExp(itemRegExpStr);
        return itemRegExp.test(path);
      });
    }
    /**
    * 判断是否是http链接.返回 Link 或 a
    * Judge whether it is http link.return a or Link
    * @memberof SiderMenu
    */
    getMenuItemPath = (item) => {
      const itemPath = this.conversionPath(item.path);
      const icon = getIcon(item.icon);
      const { target, name } = item;
      // Is it a http link
      if (/^https?:\/\//.test(itemPath)) {
        return (
          <a href={itemPath} target={target}>
            {icon}<span>{name}</span>
          </a>
        );
      }
      return (
        <Link
          to={itemPath}
          target={target}
          replace={itemPath === this.props.location.pathname}
        >
          {icon}<span>{name}</span>
        </Link>
      );
    }
    /**
     * get SubMenu or Item
     */
    getSubMenuOrItem = (item) => {
      return (
        <Menu.Item key={item.key || item.path}>
          {this.getMenuItemPath(item)}
        </Menu.Item>
      );
    }
    /**
    * 获得菜单子节点
    * @memberof SiderMenu
    */
    getNavMenuItems = (menusData) => {
      if (!menusData) {
        return [];
      }
      return menusData
        .filter(item => item.name && !item.hideInMenu)
        .map((item) => {
          const ItemDom = this.getSubMenuOrItem(item);
          return this.checkPermissionItem(item.authority, ItemDom);
        })
        .filter(item => !!item);
    }
    // conversion Path
    // 转化路径
    conversionPath = (path) => {
      if (path && path.indexOf('http') === 0) {
        return path;
      } else {
        return `/${path || ''}`.replace(/\/+/g, '/');
      }
    }
    // permission to check
    checkPermissionItem = (authority, ItemDom) => {
      if (this.props.Authorized && this.props.Authorized.check) {
        const { check } = this.props.Authorized;
        // console.log(authority);
        return check(
          authority,
          ItemDom
        );
      }
      return ItemDom;
    }
  
    handleOpenChange = (openKeys) => {
      const lastOpenKey = openKeys[openKeys.length - 1];
      const isMainMenu = this.menus.some(
        item => lastOpenKey && (item.key === lastOpenKey || item.path === lastOpenKey)
      );
      this.setState({
        openKeys: isMainMenu ? [lastOpenKey] : [...openKeys],
      });
    }
  
    render() {
      const { location: { pathname } } = this.props;
      const { openKeys } = this.state;
      const menuProps = { openKeys };
      // if pathname can't match, use the nearest parent's key
      const parentUrl = `${pathname.split('/')[1]}`;
      // const path = `${parentUrl}/${pathname.split('/').slice(-1)[0]}`;
      const menuData = this.menus.find((item) => {
        return item.path === parentUrl;
      });
      let selectedKeys = this.getSelectedMenuKeys(pathname);
      if (!selectedKeys.length) {
        selectedKeys = [openKeys[openKeys.length - 1]];
      }
      return (
        <Sider>
          <Menu
            key="Menu"
            mode="inline"
            className="leftMenu"
            {...menuProps}
            selectedKeys={selectedKeys}
            onOpenChange={this.handleOpenChange}
          >
            {menuData && this.getNavMenuItems(menuData.children)}
          </Menu>
        </Sider>
      );
    }
  }
  