BasicLayout.tsx 4.81 KB
Newer Older
zombieJ's avatar
zombieJ committed
1 2 3 4 5
/**
 * Ant Design Pro v4 use `@ant-design/pro-layout` to handle Layout.
 * You can view component api by:
 * https://github.com/ant-design/ant-design-pro-layout
 */
duanledexianxianxian's avatar
sync  
duanledexianxianxian committed
6
import { ConnectProps, ConnectState, Dispatch } from '@/models/connect';
7
import ProLayout, {
陈帅's avatar
陈帅 committed
8
  MenuDataItem,
9
  BasicLayoutProps as ProLayoutProps,
陈帅's avatar
陈帅 committed
10
  Settings,
duanledexianxianxian's avatar
duanledexianxianxian committed
11
  SettingDrawer,
陈帅's avatar
陈帅 committed
12
} from '@ant-design/pro-layout';
陈帅's avatar
陈帅 committed
13 14
import React, { useState } from 'react';
import Authorized from '@/utils/Authorized';
陈帅's avatar
陈帅 committed
15
import Link from 'umi/link';
duanledexianxianxian's avatar
sync  
duanledexianxianxian committed
16 17
import router from 'umi/router';

陈帅's avatar
陈帅 committed
18 19 20 21
import RightContent from '@/components/GlobalHeader/RightContent';
import { connect } from 'dva';
import { formatMessage } from 'umi-plugin-react/locale';
import { isAntDesignPro } from '@/utils/utils';
duanledexianxianxian's avatar
sync  
duanledexianxianxian committed
22 23 24
import { message } from 'antd';
import store from '@/utils/store';
import user from 'mock/user';
25
export interface BasicLayoutProps extends ProLayoutProps, Omit<ConnectProps, 'location'> {
陈帅's avatar
陈帅 committed
26 27 28
  breadcrumbNameMap: {
    [path: string]: MenuDataItem;
  };
陈帅's avatar
陈帅 committed
29
  settings: Settings;
陈小聪's avatar
陈小聪 committed
30
}
何乐's avatar
何乐 committed
31
export type BasicLayoutContext = { [K in 'location']: BasicLayoutProps[K] } & {
陈帅's avatar
陈帅 committed
32 33 34
  breadcrumbNameMap: {
    [path: string]: MenuDataItem;
  };
何乐's avatar
何乐 committed
35
};
陈帅's avatar
陈帅 committed
36
/**
陈帅's avatar
陈帅 committed
37
 * use Authorized check all menu item
陈帅's avatar
陈帅 committed
38
 */
duanledexianxianxian's avatar
duanledexianxianxian committed
39

陈帅's avatar
陈帅 committed
40 41
const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] =>
  menuList.map(item => {
duanledexianxianxian's avatar
duanledexianxianxian committed
42
    // 遍历给所有的children加上了[]
duanledexianxianxian's avatar
duanledexianxianxian committed
43
    const localItem = { ...item, children: item.children ? menuDataRender(item.children) : [] };
duanledexianxianxian's avatar
duanledexianxianxian committed
44
    // 检查菜单项是否有权限
陈帅's avatar
陈帅 committed
45 46 47
    return Authorized.check(item.authority, localItem, null) as MenuDataItem;
  });

duanledexianxianxian's avatar
duanledexianxianxian committed
48
// footer渲染
陈帅's avatar
陈帅 committed
49
const footerRender: BasicLayoutProps['footerRender'] = (_, defaultDom) => {
陈帅's avatar
陈帅 committed
50
  if (!isAntDesignPro()) {
陈帅's avatar
陈帅 committed
51 52
    return defaultDom;
  }
duanledexianxianxian's avatar
duanledexianxianxian committed
53

陈帅's avatar
陈帅 committed
54 55 56 57 58
  return (
    <>
      {defaultDom}
      <div
        style={{
陈帅's avatar
陈帅 committed
59
          padding: '0px 24px 24px',
陈帅's avatar
陈帅 committed
60
          textAlign: 'center',
陈帅's avatar
陈帅 committed
61 62
        }}
      >
陈帅's avatar
陈帅 committed
63
        <a href="https://www.netlify.com" target="_blank" rel="noopener noreferrer">
陈帅's avatar
陈帅 committed
64
          <img
陈帅's avatar
陈帅 committed
65
            src="https://www.netlify.com/img/global/badges/netlify-color-bg.svg"
陈帅's avatar
陈帅 committed
66
            width="82px"
陈帅's avatar
陈帅 committed
67 68 69 70 71 72 73 74
            alt="netlify logo"
          />
        </a>
      </div>
    </>
  );
};

duanledexianxianxian's avatar
sync  
duanledexianxianxian committed
75 76 77 78
const loadInitData = (dispatch: Dispatch) => {
  Promise.all([dispatch({ type: 'public/getUserInfo' }), dispatch({ type: 'public/getUserInfo' })]);
};

何乐's avatar
何乐 committed
79
const BasicLayout: React.FC<BasicLayoutProps> = props => {
陈帅's avatar
陈帅 committed
80
  const { dispatch, children, settings } = props;
何乐's avatar
何乐 committed
81 82 83
  /**
   * constructor
   */
陈帅's avatar
陈帅 committed
84

duanledexianxianxian's avatar
sync  
duanledexianxianxian committed
85
  const [loaded, setLoaded] = useState(false);
陈小聪's avatar
陈小聪 committed
86
  useState(() => {
陈帅's avatar
陈帅 committed
87
    if (dispatch) {
duanledexianxianxian's avatar
sync  
duanledexianxianxian committed
88
      // 查看当前用户是否在登录状态
陈帅's avatar
陈帅 committed
89
      dispatch({
duanledexianxianxian's avatar
sync  
duanledexianxianxian committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
        type: 'user/checkUserLoginStatus',
      }).then(({ code, data = false }: { code: string; data: boolean }) => {
        setLoaded(true);
        if (code === 'sys.success') {
          // 登录成功
          if (data) {
            loadInitData(dispatch);
          } else if (store.get('userId')) {
            store.set('token', '');
            store.set('userId', '');
            message.error('登录已过期,请重新登录!');
            router.push('/user/login');
          } else {
            // 此处应该跳转到404或者403页面为佳
            // message.error("用户未登录,请先登录系统!");
            router.push('/404');
          }
        }
陈帅's avatar
陈帅 committed
108
      });
duanledexianxianxian's avatar
sync  
duanledexianxianxian committed
109 110 111 112

      // dispatch({
      //   type: 'settings/getSetting',
      // });
陈帅's avatar
陈帅 committed
113
    }
陈小聪's avatar
陈小聪 committed
114
  });
何乐's avatar
何乐 committed
115 116 117
  /**
   * init variables
   */
duanledexianxianxian's avatar
duanledexianxianxian committed
118

陈帅's avatar
陈帅 committed
119
  const handleMenuCollapse = (payload: boolean): void =>
陈帅's avatar
陈帅 committed
120 121
    dispatch &&
    dispatch({
陈帅's avatar
陈帅 committed
122 123 124 125
      type: 'global/changeLayoutCollapsed',
      payload,
    });

陈小聪's avatar
陈小聪 committed
126
  return (
duanledexianxianxian's avatar
sync  
duanledexianxianxian committed
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
    loaded && (
      <div className="kim-layout">
        <ProLayout
          siderWidth={200}
          logo={false}
          navTheme="dark"
          onCollapse={handleMenuCollapse}
          menuItemRender={(menuItemProps, defaultDom) => (
            <Link to={menuItemProps.path}>{defaultDom}</Link>
          )}
          breadcrumbRender={(routers = []) => [
            {
              path: '/',
              breadcrumbName: formatMessage({
                id: 'menu.home',
                defaultMessage: 'Home',
              }),
            },
            ...routers,
          ]}
          footerRender={false} // 不显示footer
          menuDataRender={menuDataRender} // 渲染导航菜单列表
          formatMessage={formatMessage}
          rightContentRender={rightProps => <RightContent {...rightProps} />}
          {...props}
          {...settings}
        >
          {children}
        </ProLayout>
        {/* 主题设置抽屉 */}
        <SettingDrawer
          settings={settings}
          onSettingChange={config =>
            dispatch({
              type: 'settings/changeSetting',
              payload: config,
            })
          }
        />
      </div>
    )
陈小聪's avatar
陈小聪 committed
168 169 170
  );
};

陈帅's avatar
陈帅 committed
171
export default connect(({ global, settings }: ConnectState) => ({
陈小聪's avatar
陈小聪 committed
172
  collapsed: global.collapsed,
陈帅's avatar
陈帅 committed
173
  settings,
陈小聪's avatar
陈小聪 committed
174
}))(BasicLayout);