import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { Layout, Icon, message } from 'antd';
import DocumentTitle from 'react-document-title';
import { connect } from 'dva';
import { Route, Redirect, Switch, routerRedux } from 'dva/router';
import { ContainerQuery } from 'react-container-query';
import classNames from 'classnames';
import pathToRegexp from 'path-to-regexp';
import { enquireScreen, unenquireScreen } from 'enquire-js';
import GlobalHeader from '../components/GlobalHeader';
import GlobalFooter from '../components/GlobalFooter';
import SiderMenu from '../components/SiderMenu';
import NotFound from '../routes/Exception/404';
import { getRoutes } from '../utils/utils';
import Authorized from '../utils/Authorized';
import { getMenuData } from '../common/menu';
import logo from '../assets/logo.svg';
const { Content, Header, Footer } = Layout;
const { AuthorizedRoute, check } = Authorized;
/**
* 根据菜单取得重定向地址.
*/
const redirectData = [];
const getRedirect = item => {
if (item && item.children) {
if (item.children[0] && item.children[0].path) {
redirectData.push({
from: `${item.path}`,
to: `${item.children[0].path}`,
});
item.children.forEach(children => {
getRedirect(children);
});
}
}
};
getMenuData().forEach(getRedirect);
/**
* 获取面包屑映射
* @param {Object} menuData 菜单配置
* @param {Object} routerData 路由配置
*/
const getBreadcrumbNameMap = (menuData, routerData) => {
const result = {};
const childResult = {};
for (const i of menuData) {
if (!routerData[i.path]) {
result[i.path] = i;
}
if (i.children) {
Object.assign(childResult, getBreadcrumbNameMap(i.children, routerData));
}
}
return Object.assign({}, routerData, result, childResult);
};
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,
},
};
let isMobile;
enquireScreen(b => {
isMobile = b;
});
@connect(({ user, global = {}, loading }) => ({
currentUser: user.currentUser,
collapsed: global.collapsed,
fetchingNotices: loading.effects['global/fetchNotices'],
notices: global.notices,
}))
export default class BasicLayout extends React.PureComponent {
static childContextTypes = {
location: PropTypes.object,
breadcrumbNameMap: PropTypes.object,
};
state = {
isMobile,
};
getChildContext() {
const { location, routerData } = this.props;
return {
location,
breadcrumbNameMap: getBreadcrumbNameMap(getMenuData(), routerData),
};
}
componentDidMount() {
this.enquireHandler = enquireScreen(mobile => {
this.setState({
isMobile: mobile,
});
});
const { dispatch } = this.props;
dispatch({
type: 'user/fetchCurrent',
});
}
componentWillUnmount() {
unenquireScreen(this.enquireHandler);
}
getPageTitle() {
const { routerData, location } = this.props;
const { pathname } = location;
let title = 'Ant Design Pro';
// match params path
const currRouterData = (Object.entries(routerData).find(([key]) =>
pathToRegexp(key).test(pathname)
) || [])[1];
if (currRouterData && currRouterData.name) {
title = `${currRouterData.name} - Ant Design Pro`;
}
return title;
}
getBaseRedirect = () => {
// According to the url parameter to redirect
// 这里是重定向的,重定向到 url 的 redirect 参数所示地址
const urlParams = new URL(window.location.href);
const redirect = urlParams.searchParams.get('redirect');
// Remove the parameters in the url
if (redirect) {
urlParams.searchParams.delete('redirect');
window.history.replaceState(null, 'redirect', urlParams.href);
} else {
const { routerData } = this.props;
// get the first authorized route path in routerData
const authorizedPath = Object.keys(routerData).find(
item => check(routerData[item].authority, item) && item !== '/'
);
return authorizedPath;
}
return redirect;
};
handleMenuCollapse = collapsed => {
const { dispatch } = this.props;
dispatch({
type: 'global/changeLayoutCollapsed',
payload: collapsed,
});
};
handleNoticeClear = type => {
message.success(`清空了${type}`);
const { dispatch } = this.props;
dispatch({
type: 'global/clearNotices',
payload: type,
});
};
handleMenuClick = ({ key }) => {
const { dispatch } = this.props;
if (key === 'triggerError') {
dispatch(routerRedux.push('/exception/trigger'));
return;
}
if (key === 'logout') {
dispatch({
type: 'login/logout',
});
}
};
handleNoticeVisibleChange = visible => {
const { dispatch } = this.props;
if (visible) {
dispatch({
type: 'global/fetchNotices',
});
}
};
render() {
const {
currentUser,
collapsed,
fetchingNotices,
notices,
routerData,
match,
location,
} = this.props;
const { isMobile: mb } = this.state;
const baseRedirect = this.getBaseRedirect();
const layout = (
{redirectData.map(item => (
))}
{getRoutes(match.path, routerData).map(item => (
))}
);
return (
{params => {layout}
}
);
}
}