基于umi配置头部路由,侧边路由及权限

726 阅读2分钟

1.配置router.js

    export default [
      { path: '/', component: '@/pages/Login/index' }, // 登录
      {
        component: '@/layouts/CommonLayout.js',
        routes: [
          { path: '/homePage', component: '@/pages/HomePage/index' }, // 首页
          { path: '/emptyPage', component: '@/pages/EmptyPage/index' }, // 无权限空白页
          {
            // 数据模型
            path: '/management',
            routes: [
              {
                path: '/management/dataConnect',
                component: '@/pages/Management/DataConnect/index',
                showSlider: true, //展示侧边栏
              }, //数据连接
              {
                path: '/management/dataModal',
                component: '@/pages/Management/DataModal/index',
                showSlider: true, //展示侧边栏
              }, // 数据模型
            ],
          },
          {
            path: '/designCenter',
            routes: [
              // 设计中心
              {
                path: '/designCenter/formManage',
                component: '@/pages/DesignCenter/FormManage/index',
                showSlider: true, //展示侧边栏
              }, // 表单管理
              {
                path: '/designCenter/formDesign',
                component: '@/pages/DesignCenter/FormDesign/index',
                showSlider: true, //展示侧边栏
              }, // 表单设计
              {
                path: '/designCenter/processManage',
                component: '@/pages/DesignCenter/ProcessManage/index',
                showSlider: true, //展示侧边栏
              }, // 流程管理
              {
                path: '/designCenter/processDesign',
                component: '@/pages/DesignCenter/ProcessDesign/index',
                showSlider: true, //展示侧边栏
              }, // 流程设计
            ],
          },
          {
            path: '/taskCenter',
            routes: [
              // 用户体系
              {
                path: '/taskCenter',
                showSlider: true, //展示侧边栏
                routes: [
                  {
                    path: '/taskCenter/creatTask',
                    component: '@/pages/TaskCenter/CreatTask/index',
                    showSlider: true, //展示侧边栏
                  }, // 接口申请
                  {
                    path: '/taskCenter/waitTask',
                    component: '@/pages/TaskCenter/WaitTask/index',
                    showSlider: true, //展示侧边栏
                  }, // 待填报任务
                ],
              },
            ],
          },
          {
            // 系统设置
            path: '/systemSetting',
            routes: [
              {
                path: '/systemSetting/userSystem',
                component: '@/pages/SystemSetting/UserSystem/index',
                showSlider: true, //展示侧边栏
              }, // 用户管理
              {
                path: '/systemSetting/roleSystem',
                component: '@/pages/SystemSetting/RoleSystem/index',
                showSlider: true, //展示侧边栏
              }, // 角色管理
            ],
          },
          { component: '@/pages/404' },
        ],
      },
      { component: '@/pages/404' },
    ];

showSlider是判断侧边slider是否展示

2.配置commonHeader.js

    import { useEffect, useState } from 'react';
    import { history, useSelector, useDispatch } from 'umi';
    import { Layout, Menu, Dropdown } from 'antd';
    import userArrow from '../../../public/userArrow.png';
    import styles from './index.less';
    import { UserOutlined } from '@ant-design/icons';

    const CommonHeader = () => {
      const { Header } = Layout;
      const { location } = history;
      const { pathname, query } = location;
      const dispatch = useDispatch();
      const [activeKey, setActiveKey] = useState('');
      const [activeSubKey, setActiveSubKey] = useState('');
      const [loginoutVisible, setLoginoutVisible] = useState(false);
      const userInfo = JSON.parse(localStorage.getItem('userInfo'));

      useEffect(() => {
        setActiveKey(pathname.split('/')[1]);
        setActiveSubKey(pathname.split('/')[1]);
      }, [pathname]);

      const logOut = () => {
        localStorage.clear();
        history.push('/');
      };

      const auth = JSON.parse(localStorage.getItem('auth'));
      const menuList = [
        // { name: '首页', key: 'homePage', url: 'homePage' },
        {
          name: '数据模型',
          key: 'management',
          url: auth.includes('sjmx_sjlj')
            ? 'management/dataConnect'
            : 'management/dataModal',
          auth: 'sjmx',
        },
        {
          name: '设计中心',
          key: 'designCenter',
          url: auth.includes('sjzx_bdgl')
            ? 'designCenter/formManage'
            : 'designCenter/formDesign',
          auth: 'sjzx',
        },
        {
          name: '任务中心',
          key: 'taskCenter',
          url: auth.includes('rwzx_tbrw_wcj')
            ? 'taskCenter/creatTask'
            : 'taskCenter/waitTask',
          auth: 'rwzx',
        },
        {
          name: '系统设置',
          key: 'systemSetting',
          url: 'systemSetting/userSystem',
          auth: 'xtsz',
        },
      ];

      const dropMenu = (
        <Menu
          items={[
            {
              label: (
                <div className={styles.logOut} onClick={logOut}>
                  退出登录
                </div>
              ),
            },
          ]}
        />
      );

      const changeMenuItem = (item) => {
        let url = menuList.find((items) => items.key === item.key)?.url;
        history.push(`/${url}`);
      };

      return (
        <Header className={styles.header}>
          <div className={styles.headerLeft}>
            <div className={styles.logoText}>指标填报平台</div>
            <Menu
              mode="horizontal"
              openKeys={[activeSubKey]}
              selectedKeys={[activeKey]}
              style={{
                height: '100%',
                width: '100%',
                borderRight: 0,
                marginLeft: 175,
                flexShrink: 0,
              }}
              onClick={changeMenuItem}
            >
              {menuList.map((item) => {
                if (auth.includes(item.auth)) {
                  return <Menu.Item key={item.key}>{item.name}</Menu.Item>;
                }
              })}
            </Menu>
          </div>
          <div className={styles.headerRight}>
            <div className={styles.userName}>
              <div className={styles.user}>
                <Dropdown
                  trigger="click"
                  placement="bottom"
                  overlayClassName={styles.dropdownStyles}
                  overlay={dropMenu}
                  onOpenChange={(visible) => setLoginoutVisible(visible)}
                  arrow
                >
                  <div
                    onClick={(e) => {
                      e.preventDefault();
                    }}
                    style={{ display: 'flex', alignItems: 'center' }}
                  >
                    <UserOutlined />
                    <div className={styles.userInfo}>
                      {userInfo?.username || '管理员'}
                    </div>
                    <img
                      className={
                        loginoutVisible
                          ? styles.loginShowOpenArrow
                          : styles.loginCloseArrow
                      }
                      style={{ marginLeft: 6 }}
                      src={userArrow}
                      alt=""
                    />
                  </div>
                </Dropdown>
              </div>
            </div>
          </div>
        </Header>
      );
    };

    export default CommonHeader;

auth是判断当前是否有header菜单权限

配置commonSlider.js

    import { useEffect, useState } from 'react';
    import { history, useSelector } from 'umi';
    import { SolutionOutlined, UserOutlined } from '@ant-design/icons';
    import { Layout, Menu } from 'antd';
    import silderBtn from '../../../public/silderBtn.png';
    import dataConnect from '../../assets/silder/dataConnect.png';
    import dataModal from '../../assets/silder/dataModal.png';
    import formManage from '../../assets/silder/formManage.png';
    import processDesign from '../../assets/silder/processDesign.png';
    import personalCenter from '../../assets/silder/personalCenter.png';
    import styles from './index.less';
    const CommonSlider = () => {
      const { Sider } = Layout;
      const { SubMenu } = Menu;
      const { location } = history;
      const { pathname } = location;
      const configure = useSelector((state) => state.common.configure);
      const [activeKey, setActiveKey] = useState('');
      const [activeSubKey, setActiveSubKey] = useState('');
      const [collapsed, setCollapsed] = useState(false);
      useEffect(() => {
        setActiveKey(pathname.slice(1));
        setActiveSubKey(pathname.split('/').slice(1, 3).join('/'));
      }, [pathname]);

      // const auth = ['sjzx_bdgl', 'sjzx_bdsj', 'sjmx_sjmx'];
      const auth = JSON.parse(localStorage.getItem('auth'));
      // 设计中心
      const designCenterMenuList = [
        {
          name: '表单管理',
          icon: (
            <img src={formManage} style={{ width: '16px', height: '16px' }}></img>
          ),
          url: 'designCenter/formManage',
          auth: 'sjzx_bdgl',
        },
        {
          name: '表单设计',
          icon: (
            <img
              src={processDesign}
              style={{ width: '16px', height: '16px' }}
            ></img>
          ),
          url: 'designCenter/formDesign',
          auth: 'sjzx_bdsj',
        },
        // {
        //   name: '流程管理',
        //   icon: (
        //     <img
        //       src={processDesign}
        //       style={{ width: '16px', height: '16px' }}
        //     ></img>
        //   ),
        //   url: 'designCenter/processManage',
        // },
        // {
        //   name: '流程设计',
        //   icon: (
        //     <img
        //       src={processDesign}
        //       style={{ width: '16px', height: '16px' }}
        //     ></img>
        //   ),
        //   url: 'designCenter/processDesign',
        // },
      ];

      // 任务中心
      const taskCenterMenuList = [
        {
          name: '填报任务',
          icon: (
            <img
              src={personalCenter}
              style={{ width: '16px', height: '16px' }}
            ></img>
          ),
          url: 'taskCenter',
          auth: 'rwzx_tbrw',
          children: [
            {
              name: '我创建任务',
              icon: '',
              url: 'taskCenter/creatTask',
              auth: 'rwzx_tbrw_wcj',
            },
            {
              name: '待填报任务',
              icon: '',
              url: 'taskCenter/waitTask',
              auth: 'rwzx_tbrw_dtb',
            },
          ],
        },
      ];

      // 数据模型
      const ManagementList = [
        {
          name: '数据连接',
          icon: (
            <img src={dataConnect} style={{ width: '16px', height: '16px' }}></img>
          ),
          url: 'management/dataConnect',
          auth: 'sjmx_sjlj',
        },
        {
          name: '数据模型',
          icon: (
            <img src={dataModal} style={{ width: '16px', height: '16px' }}></img>
          ),
          url: 'management/dataModal',
          auth: 'sjmx_sjmx',
        },
      ];

      const settingList = [
        {
          name: '用户管理',
          icon: (
            <img src={dataConnect} style={{ width: '16px', height: '16px' }}></img>
          ),
          url: 'systemSetting/userSystem',
          auth: 'xtsz_yhgl',
        },
        // {
        //   name: '角色管理',
        //   icon: (
        //     <img src={dataModal} style={{ width: '16px', height: '16px' }}></img>
        //   ),
        //   url: 'systemSetting/roleSystem',
        // },
      ];

      const changeMenuItem = (item) => {
        history.push(`/${item.key}`);
      };
      const menuList = (Url) => {
        switch (Url) {
          case 'designCenter':
            return designCenterMenuList;
          case 'taskCenter':
            return taskCenterMenuList;
          case 'management':
            return ManagementList;
          case 'systemSetting':
            return settingList;
          default:
            break;
        }
      };

      const clickSubMenu = ({ key }) => {
        if (activeSubKey === key) {
          setActiveSubKey('');
        } else {
          setActiveSubKey(key);
        }
      };

      return (
        <Sider className={styles.siderBackground} collapsed={collapsed}>
          <div className={styles.toggle}>
            {collapsed ? (
              <div
                onClick={() => {
                  setCollapsed(false);
                }}
                className={styles.openMenu}
              >
                <img src={silderBtn} alt="" />
              </div>
            ) : (
              <div
                onClick={() => {
                  setCollapsed(true);
                }}
                className={styles.closeMenu}
              >
                <img src={silderBtn} alt="" />
              </div>
            )}
          </div>
          <Menu
            mode="inline"
            openKeys={activeSubKey}
            selectedKeys={[activeKey]}
            className={styles.menuStyles}
            onClick={changeMenuItem}
            key={configure.path}
            defaultSelectedKeys={
              configure.showSlider
                ? menuList(configure.path.split('/')[1])[0].url
                : null
            }
          >
            {menuList(configure.path?.split('/')[1]).map((item) => {
              if (!item.children && auth.includes(item.auth)) {
                return (
                  <Menu.Item key={item.url} icon={item.icon}>
                    {item.name}
                  </Menu.Item>
                );
              } else {
                if (auth.includes(item.auth)) {
                  return (
                    <SubMenu
                      title={item.name}
                      icon={item.icon}
                      key={item.url}
                      onTitleClick={clickSubMenu}
                    >
                      {item.children.map((res, index) => {
                        if (auth.includes(res.auth)) {
                          return <Menu.Item key={res.url}>{res.name}</Menu.Item>;
                        }
                      })}
                    </SubMenu>
                  );
                }
              }
            })}
          </Menu>
        </Sider>
      );
    };

    export default CommonSlider;

auth是判断当前人是否有侧边栏某一菜单的权限

4.commonLayout.js

    import { Layout } from 'antd';
    import { useEffect } from 'react';
    import { useSelector } from 'umi';
    import { ConfigProvider } from 'antd';
    import CommonHeader from '@/compontents/CommonHeader';
    import CommonSlider from '@/compontents/CommonSlider';
    import zh_CN from 'antd/lib/locale-provider/zh_CN';
    import moment from 'moment';
    import styles from './CommonLayout.less';
    import 'moment/locale/zh-cn';
    moment.locale('zh-cn');

    const CommonLayout = ({ children }) => {
      const { Content } = Layout;
      // 获取当前路由
      const configure = useSelector((state) => state.common.configure);
      return (
        <ConfigProvider locale={zh_CN}>
          <Layout className={styles.layout}>
            <CommonHeader />
            <Layout>
              {configure.showSlider ? <CommonSlider /> : ''}
              <Layout style={{ overflow: 'auto' }}>
                <Content className="site-layout-background" style={{ margin: 0 }}>
                  {children}
                </Content>
              </Layout>
            </Layout>
          </Layout>
        </ConfigProvider>
      );
    };

    export default CommonLayout;

5.捕捉路由信息 app.sj

    import { history } from 'umi';
    import { getDvaApp } from 'umi';

    //路由变化参数捕捉
    export function onRouteChange({ matchedRoutes }) {
      const g_app = getDvaApp();
      const route = matchedRoutes[matchedRoutes.length - 1].route;
      const url = history.location.pathname;
      // 将路由信息存到全局中
      g_app._store.dispatch({
        type: 'common/saveRouterUrl',
        payload: url,
      });
      g_app._store.dispatch({
        type: 'common/updateModel',
        payload: { configure: route },
      });
    }

6.commonModal.js

    const commonModal = {
      namespace: 'common',
      state: {
        routerUrl: '',
        configure: {},
      },
      effects: {},
      reducers: {
        saveRouterUrl: (state, data) => {
          return (state = {
            ...state,
            routerUrl: data.payload.split('/')[1],
          });
        },
        updateModel: (state, { payload }) => {
          return (state = {
            ...state,
            ...payload,
          });
        },
      },
    };
    export default commonModal;