import React from 'react'; import PropTypes from 'prop-types'; import { Layout, Menu, Icon, Avatar, Dropdown, Tag, message, Spin } from 'antd'; import DocumentTitle from 'react-document-title'; import { connect } from 'dva'; import { Link, Route, Redirect, Switch } from 'dva/router'; import moment from 'moment'; import groupBy from 'lodash/groupBy'; import { ContainerQuery } from 'react-container-query'; import classNames from 'classnames'; import Debounce from 'lodash-decorators/debounce'; import HeaderSearch from '../components/HeaderSearch'; import NoticeIcon from '../components/NoticeIcon'; import GlobalFooter from '../components/GlobalFooter'; import NotFound from '../routes/Exception/404'; import styles from './BasicLayout.less'; import logo from '../assets/logo.svg'; const { Header, Sider, Content } = Layout; const { SubMenu } = Menu; 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, }, }; class BasicLayout extends React.PureComponent { static childContextTypes = { location: PropTypes.object, breadcrumbNameMap: PropTypes.object, } constructor(props) { super(props); // 把一级 Layout 的 children 作为菜单项 this.menus = props.navData.reduce((arr, current) => arr.concat(current.children), []); this.state = { openKeys: this.getDefaultCollapsedSubMenus(props), }; } getChildContext() { const { location, navData, getRouteData } = this.props; const routeData = getRouteData('BasicLayout'); const firstMenuData = navData.reduce((arr, current) => arr.concat(current.children), []); const menuData = this.getMenuData(firstMenuData, ''); const breadcrumbNameMap = {}; routeData.concat(menuData).forEach((item) => { breadcrumbNameMap[item.path] = item.name; }); return { location, breadcrumbNameMap }; } componentDidMount() { this.props.dispatch({ type: 'user/fetchCurrent', }); } componentWillUnmount() { this.triggerResizeEvent.cancel(); } onCollapse = (collapsed) => { this.props.dispatch({ type: 'global/changeLayoutCollapsed', payload: collapsed, }); } onMenuClick = ({ key }) => { if (key === 'logout') { this.props.dispatch({ type: 'login/logout', }); } } getMenuData = (data, parentPath) => { let arr = []; data.forEach((item) => { if (item.children) { arr.push({ path: `${parentPath}/${item.path}`, name: item.name }); arr = arr.concat(this.getMenuData(item.children, `${parentPath}/${item.path}`)); } }); return arr; } getDefaultCollapsedSubMenus(props) { const currentMenuSelectedKeys = [...this.getCurrentMenuSelectedKeys(props)]; currentMenuSelectedKeys.splice(-1, 1); if (currentMenuSelectedKeys.length === 0) { return ['dashboard']; } return currentMenuSelectedKeys; } getCurrentMenuSelectedKeys(props) { const { location: { pathname } } = props || this.props; const keys = pathname.split('/').slice(1); if (keys.length === 1 && keys[0] === '') { return [this.menus[0].key]; } return keys; } getNavMenuItems(menusData, parentPath = '') { if (!menusData) { return []; } return menusData.map((item) => { if (!item.name) { return null; } let itemPath; if (item.path.indexOf('http') === 0) { itemPath = item.path; } else { itemPath = `${parentPath}/${item.path || ''}`.replace(/\/+/g, '/'); } if (item.children && item.children.some(child => child.name)) { return ( {item.name} ) : item.name } key={item.key || item.path} > {this.getNavMenuItems(item.children, itemPath)} ); } const icon = item.icon && ; return ( { /^https?:\/\//.test(itemPath) ? ( {icon}{item.name} ) : ( {icon}{item.name} ) } ); }); } getPageTitle() { const { location, getRouteData } = this.props; const { pathname } = location; let title = 'Ant Design Pro'; getRouteData('BasicLayout').forEach((item) => { if (item.path === pathname) { title = `${item.name} - Ant Design Pro`; } }); return title; } getNoticeData() { const { notices = [] } = this.props; if (notices.length === 0) { return {}; } const newNotices = notices.map((notice) => { const newNotice = { ...notice }; if (newNotice.datetime) { newNotice.datetime = moment(notice.datetime).fromNow(); } // transform id to item key if (newNotice.id) { newNotice.key = newNotice.id; } if (newNotice.extra && newNotice.status) { const color = ({ todo: '', processing: 'blue', urgent: 'red', doing: 'gold', })[newNotice.status]; newNotice.extra = {newNotice.extra}; } return newNotice; }); return groupBy(newNotices, 'type'); } 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], }); } toggle = () => { const { collapsed } = this.props; this.props.dispatch({ type: 'global/changeLayoutCollapsed', payload: !collapsed, }); this.triggerResizeEvent(); } @Debounce(600) triggerResizeEvent() { // eslint-disable-line const event = document.createEvent('HTMLEvents'); event.initEvent('resize', true, false); window.dispatchEvent(event); } handleNoticeClear = (type) => { message.success(`清空了${type}`); this.props.dispatch({ type: 'global/clearNotices', payload: type, }); } handleNoticeVisibleChange = (visible) => { if (visible) { this.props.dispatch({ type: 'global/fetchNotices', }); } } render() { const { currentUser, collapsed, fetchingNotices, getRouteData } = this.props; const menu = ( 个人中心 设置 退出登录 ); const noticeData = this.getNoticeData(); // Don't show popup menu when it is been collapsed const menuProps = collapsed ? {} : { openKeys: this.state.openKeys, }; const layout = (
logo

Ant Design Pro

{this.getNavMenuItems(this.menus)}
{ console.log('input', value); // eslint-disable-line }} onPressEnter={(value) => { console.log('enter', value); // eslint-disable-line }} /> { console.log(item, tabProps); // eslint-disable-line }} onClear={this.handleNoticeClear} onPopupVisibleChange={this.handleNoticeVisibleChange} loading={fetchingNotices} popupAlign={{ offset: [20, -16] }} > {currentUser.name ? ( {currentUser.name} ) : }
{ getRouteData('BasicLayout').map(item => ( ) ) }
Copyright 2017 蚂蚁金服体验技术部出品 } />
); return ( {params =>
{layout}
}
); } } export default connect(state => ({ currentUser: state.user.currentUser, collapsed: state.global.collapsed, fetchingNotices: state.global.fetchingNotices, notices: state.global.notices, }))(BasicLayout);