BasicLayout.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import { Layout, message } from 'antd';
  4. import DocumentTitle from 'react-document-title';
  5. import { connect } from 'dva';
  6. import { Route, Redirect, Switch } from 'dva/router';
  7. import { ContainerQuery } from 'react-container-query';
  8. import classNames from 'classnames';
  9. import { enquireScreen } from 'enquire-js';
  10. import GlobalHeader from '../components/GlobalHeader';
  11. import SiderMenu from '../components/SiderMenu';
  12. import NotFound from '../routes/Exception/404';
  13. import { projectName } from '../utils/config';
  14. import { getRoutes } from '../utils/utils';
  15. import Authorized from '../utils/Authorized';
  16. import { getMenuData } from '../common/menu';
  17. import logo from '../assets/logo.jpg';
  18. const { Content, Header } = Layout;
  19. const { AuthorizedRoute } = Authorized;
  20. /**
  21. * 根据菜单取得重定向地址.
  22. */
  23. const redirectData = [];
  24. const getRedirect = (item) => {
  25. if (item && item.children) {
  26. if (item.children[0] && item.children[0].path) {
  27. redirectData.push({
  28. from: `${item.path}`,
  29. to: `${item.children[0].path}`,
  30. });
  31. item.children.forEach((children) => {
  32. getRedirect(children);
  33. });
  34. }
  35. }
  36. };
  37. getMenuData().forEach(getRedirect);
  38. const query = {
  39. 'screen-xs': {
  40. maxWidth: 575,
  41. },
  42. 'screen-sm': {
  43. minWidth: 576,
  44. maxWidth: 767,
  45. },
  46. 'screen-md': {
  47. minWidth: 768,
  48. maxWidth: 991,
  49. },
  50. 'screen-lg': {
  51. minWidth: 992,
  52. maxWidth: 1199,
  53. },
  54. 'screen-xl': {
  55. minWidth: 1200,
  56. },
  57. };
  58. let isMobile;
  59. enquireScreen((b) => {
  60. isMobile = b;
  61. });
  62. class BasicLayout extends React.PureComponent {
  63. static childContextTypes = {
  64. location: PropTypes.object,
  65. breadcrumbNameMap: PropTypes.object,
  66. }
  67. state = {
  68. isMobile,
  69. };
  70. getChildContext() {
  71. const { location, routerData } = this.props;
  72. return {
  73. location,
  74. breadcrumbNameMap: routerData,
  75. };
  76. }
  77. componentDidMount() {
  78. enquireScreen((mobile) => {
  79. this.setState({
  80. isMobile: mobile,
  81. });
  82. });
  83. this.props.dispatch({
  84. type: 'user/fetchCurrent',
  85. });
  86. }
  87. getPageTitle() {
  88. const { routerData, location } = this.props;
  89. const { pathname } = location;
  90. let title = projectName;
  91. if (routerData[pathname] && routerData[pathname].name) {
  92. title = `${routerData[pathname].name} - ${projectName}`;
  93. }
  94. return title;
  95. }
  96. getBashRedirect = () => {
  97. // According to the url parameter to redirect
  98. // 这里是重定向的,重定向到 url 的 redirect 参数所示地址
  99. const urlParams = new URL(window.location.href);
  100. const redirect = urlParams.searchParams.get('redirect');
  101. // Remove the parameters in the url
  102. if (redirect) {
  103. urlParams.searchParams.delete('redirect');
  104. window.history.replaceState(null, 'redirect', urlParams.href);
  105. } else {
  106. return '/dashboard/analysis';
  107. }
  108. return redirect;
  109. }
  110. handleMenuCollapse = (collapsed) => {
  111. this.props.dispatch({
  112. type: 'global/changeLayoutCollapsed',
  113. payload: collapsed,
  114. });
  115. }
  116. handleNoticeClear = (type) => {
  117. message.success(`清空了${type}`);
  118. this.props.dispatch({
  119. type: 'global/clearNotices',
  120. payload: type,
  121. });
  122. }
  123. handleMenuClick = ({ key }) => {
  124. if (key === 'logout') {
  125. this.props.dispatch({
  126. type: 'login/logout',
  127. });
  128. }
  129. }
  130. handleNoticeVisibleChange = (visible) => {
  131. if (visible) {
  132. this.props.dispatch({
  133. type: 'global/fetchNotices',
  134. });
  135. }
  136. }
  137. render() {
  138. const {
  139. currentUser, collapsed, fetchingNotices, notices, routerData, match, location,
  140. } = this.props;
  141. const bashRedirect = this.getBashRedirect();
  142. const layout = (
  143. <Layout>
  144. <Header style={{ padding: 0, height: 50, position: 'fixed', top: 0, left: 0, width: '100%' }}>
  145. <GlobalHeader
  146. logo={logo}
  147. currentUser={currentUser}
  148. fetchingNotices={fetchingNotices}
  149. notices={notices}
  150. collapsed={collapsed}
  151. isMobile={this.state.isMobile}
  152. onNoticeClear={this.handleNoticeClear}
  153. onCollapse={this.handleMenuCollapse}
  154. onMenuClick={this.handleMenuClick}
  155. onNoticeVisibleChange={this.handleNoticeVisibleChange}
  156. />
  157. </Header>
  158. <Layout style={{ position: 'fixed', marginTop: 50, overflow: 'hidden', top: 0, bottom: 0, width: '100%' }}>
  159. <SiderMenu
  160. // 不带Authorized参数的情况下如果没有权限,会强制跳到403界面
  161. // If you do not have the Authorized parameter
  162. // you will be forced to jump to the 403 interface without permission
  163. Authorized={Authorized}
  164. menuData={getMenuData()}
  165. collapsed={collapsed}
  166. location={location}
  167. isMobile={this.state.isMobile}
  168. onCollapse={this.handleMenuCollapse}
  169. />
  170. <Content style={{ marginBottom: '50px' }}>
  171. <Switch>
  172. {
  173. redirectData.map(item =>
  174. <Redirect key={item.from} exact from={item.from} to={item.to} />
  175. )
  176. }
  177. {
  178. getRoutes(match.path, routerData).map(item =>
  179. (
  180. <AuthorizedRoute
  181. key={item.key}
  182. path={item.path}
  183. component={item.component}
  184. exact={item.exact}
  185. authority={item.authority}
  186. redirectPath="/exception/403"
  187. />
  188. )
  189. )
  190. }
  191. <Redirect exact from="/" to={bashRedirect} />
  192. <Route render={NotFound} />
  193. </Switch>
  194. </Content>
  195. </Layout>
  196. </Layout>
  197. );
  198. return (
  199. <DocumentTitle title={this.getPageTitle()}>
  200. <ContainerQuery query={query}>
  201. {params => <div className={classNames(params)}>{layout}</div>}
  202. </ContainerQuery>
  203. </DocumentTitle>
  204. );
  205. }
  206. }
  207. export default connect(({ user, global, loading }) => ({
  208. currentUser: user.currentUser,
  209. collapsed: global.collapsed,
  210. fetchingNotices: loading.effects['global/fetchNotices'],
  211. notices: global.notices,
  212. }))(BasicLayout);