text: import React from 'react';
  import { Layout } from 'antd';
  import DocumentTitle from 'react-document-title';
  import isEqual from 'lodash/isEqual';
  import memoizeOne from 'memoize-one';
  import { connect } from 'dva';
  import { ContainerQuery } from 'react-container-query';
  import classNames from 'classnames';
  import pathToRegexp from 'path-to-regexp';
  import { enquireScreen, unenquireScreen } from 'enquire-js';
  import { formatMessage } from 'umi/locale';
  import SiderMenu from '@/components/SiderMenu';
  import Authorized from '@/utils/Authorized';
  import SettingDrawer from '@/components/SettingDrawer';
  import logo from '../assets/logo.svg';
  import Footer from './Footer';
  import Header from './Header';
  import Context from './MenuContext';
  import Exception403 from '../pages/Exception/403';
  
  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
  	},
  	'screen-sm': {
  		minWidth: 576,
  		maxWidth: 767
  	},
  	'screen-md': {
  		minWidth: 768,
  		maxWidth: 991
  	},
  	'screen-lg': {
  		minWidth: 992,
  		maxWidth: 1199
  	},
  	'screen-xl': {
  		minWidth: 1200,
  		maxWidth: 1599
  	},
  	'screen-xxl': {
  		minWidth: 1600
  	}
  };
  
  class BasicLayout extends React.PureComponent {
  	constructor(props) {
  		super(props);
  		this.getPageTitle = memoizeOne(this.getPageTitle);
  		this.getBreadcrumbNameMap = memoizeOne(this.getBreadcrumbNameMap, isEqual);
  		this.breadcrumbNameMap = this.getBreadcrumbNameMap();
  		this.matchParamsPath = memoizeOne(this.matchParamsPath, isEqual);
  	}
  
  	state = {
  		rendering: true,
  		isMobile: false,
  		menuData: this.getMenuData()
  	};
  
  	componentDidMount() {
  		const { dispatch } = this.props;
  		dispatch({
  			type: 'user/fetchCurrent'
  		});
  		dispatch({
  			type: 'setting/getSetting'
  		});
  		this.renderRef = requestAnimationFrame(() => {
  			this.setState({
  				rendering: false
  			});
  		});
  		this.enquireHandler = enquireScreen(mobile => {
  			const { isMobile } = this.state;
  			if (isMobile !== mobile) {
  				this.setState({
  					isMobile: mobile
  				});
  			}
  		});
  	}
  
  	componentDidUpdate(preProps) {
  		// After changing to phone mode,
  		// if collapsed is true, you need to click twice to display
  		this.breadcrumbNameMap = this.getBreadcrumbNameMap();
  		const { isMobile } = this.state;
  		const { collapsed } = this.props;
  		if (isMobile && !preProps.isMobile && !collapsed) {
  			this.handleMenuCollapse(false);
  		}
  	}
  
  	componentWillUnmount() {
  		cancelAnimationFrame(this.renderRef);
  		unenquireScreen(this.enquireHandler);
  	}
  
  	getContext() {
  		const { location } = this.props;
  		return {
  			location,
  			breadcrumbNameMap: this.breadcrumbNameMap
  		};
  	}
  
  	getMenuData() {
  		const {
  			route: { routes, authority }
  		} = this.props;
  		return memoizedMapRoutesToMenu(routes, authority);
  	}
  
  	/**
  	 * 获取面包屑映射
  	 * @param {Object} menuData 菜单配置
  	 */
  	getBreadcrumbNameMap() {
  		const routerMap = {};
  		const flattenMenuData = data => {
  			data.forEach(menuItem => {
  				if (menuItem.children) {
  					flattenMenuData(menuItem.children);
  				}
  				// Reduce memory usage
  				routerMap[menuItem.path] = menuItem;
  			});
  		};
  		flattenMenuData(this.getMenuData());
  		return routerMap;
  	}
  
  	matchParamsPath = pathname => {
  		const pathKey = Object.keys(this.breadcrumbNameMap).find(key => pathToRegexp(key).test(pathname));
  		return this.breadcrumbNameMap[pathKey];
  	};
  
  	getPageTitle = pathname => {
  		const currRouterData = this.matchParamsPath(pathname);
  
  		if (!currRouterData) {
  			return 'Ant Design Pro';
  		}
  		const pageName = formatMessage({
  			id: currRouterData.locale || currRouterData.name,
  			defaultMessage: currRouterData.name
  		});
  		return `${pageName} - Ant Design Pro`;
  	};
  
  	getLayoutStyle = () => {
  		const { isMobile } = this.state;
  		const { fixSiderbar, collapsed, layout } = this.props;
  		if (fixSiderbar && layout !== 'topmenu' && !isMobile) {
  			return {
  				paddingLeft: collapsed ? '80px' : '256px'
  			};
  		}
  		return null;
  	};
  
  	getContentStyle = () => {
  		const { fixedHeader } = this.props;
  		return {
  			margin: '24px 24px 0',
  			paddingTop: fixedHeader ? 64 : 0
  		};
  	};
  
  	handleMenuCollapse = collapsed => {
  		const { dispatch } = this.props;
  		dispatch({
  			type: 'global/changeLayoutCollapsed',
  			payload: collapsed
  		});
  	};
  
  	renderSettingDrawer() {
  		// Do not render SettingDrawer in production
  		// unless it is deployed in preview.pro.ant.design as demo
  		const { rendering } = this.state;
  		if ((rendering || process.env.NODE_ENV === 'production') && APP_TYPE !== 'site') {
  			return null;
  		}
  		return <SettingDrawer />;
  	}
  
  	render() {
  		const {
  			navTheme,
  			layout: PropsLayout,
  			children,
  			location: { pathname }
  		} = this.props;
  		const { isMobile, menuData } = this.state;
  		const isTop = PropsLayout === 'topmenu';
  		const routerConfig = this.matchParamsPath(pathname);
  		const layout = (
  			<Layout>
  				{/* 菜单栏 */}
  				{isTop && !isMobile ? null : (
  					<SiderMenu
  						logo={logo}
  						Authorized={Authorized}
  						theme={navTheme}
  						onCollapse={this.handleMenuCollapse}
  						menuData={menuData}
  						isMobile={isMobile}
  						{...this.props}
  					/>
  				)}
  				{/* 导航栏 */}
  				<Layout
  					style={{
  						...this.getLayoutStyle(),
  						minHeight: '100vh'
  					}}
  				>
  					<Header
  						menuData={menuData}
  						handleMenuCollapse={this.handleMenuCollapse}
  						logo={logo}
  						isMobile={isMobile}
  						{...this.props}
  					/>
  					<Content style={this.getContentStyle()}>
  						<Authorized authority={routerConfig && routerConfig.authority} noMatch={<Exception403 />}>
  							{children}
  						</Authorized>
  					</Content>
  					{/* <Footer /> */}
  				</Layout>
  			</Layout>
  		);
  		return (
  			<React.Fragment>
  				<DocumentTitle title={this.getPageTitle(pathname)}>
  					<ContainerQuery query={query}>
  						{params => (
  							<Context.Provider value={this.getContext()}>
  								<div className={classNames(params)}>{layout}</div>
  							</Context.Provider>
  						)}
  					</ContainerQuery>
  				</DocumentTitle>
  				{this.renderSettingDrawer()}
  			</React.Fragment>
  		);
  	}
  }
  
  export default connect(({ global, setting }) => ({
  	collapsed: global.collapsed,
  	layout: setting.layout,
  	...setting
  }))(BasicLayout);
  