1.在app.js中全局监听路由变化
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 },
});
}
2.在router.js中设置动态路由middleRouter
import middleRouter from './src/utils/middleRouter';
export default [
{ path: '/', component: '@/pages/Login/index' },
{
component: '@/layouts/CommonLayout.js',
routes: [
{ path: '/homePage', component: '@/pages/HomePage/index' },
{ path: '/emptyPage', component: '@/pages/EmptyPage/index' },
...middleRouter,
{ component: '@/pages/404' },
],
},
{ component: '@/pages/404' },
];
3.middleRouter的层级不固定,功能包含路由权限和侧边栏是否展示
export default [
{
path: '/management',
auth: 'sjmx',
name: '数据模型',
routes: [
{
path: '/management/dataConnect',
component: '@/pages/Management/DataConnect/index',
showSlider: true,
auth: 'sjmx_sjlj',
},
{
path: '/management/dataModal',
component: '@/pages/Management/DataModal/index',
showSlider: true,
auth: 'sjmx_sjmx',
},
],
},
{
path: '/taskCenter',
auth: 'rwzx',
name: '任务中心',
routes: [
{
path: '/taskCenter',
showSlider: true,
auth: 'rwzx_tbrw',
routes: [
{
path: '/taskCenter/creatTask',
component: '@/pages/TaskCenter/CreatTask/index',
showSlider: true,
auth: 'rwzx_tbrw_wcj',
},
{
path: '/taskCenter/waitTask',
component: '@/pages/TaskCenter/WaitTask/index',
showSlider: true,
auth: 'rwzx_tbrw_dtb',
},
],
},
],
},
];
4.封装根据后端返回的权限列表,过滤出有权限的路由
/* routes : 动态路由部分, transRouter: 权限列表 */
const filterRouter = (routes, transRouter) => {
const authRoutes = []
routes.forEach((route) => {
if (transRouter.includes(route.auth)) {
authRoutes.push(route)
if (route.routes?.length) {
route.routes = filterRouter(route.routes, transRouter)
}
}
})
return authRoutes
}
export default filterRouter
5.登录页面,跳转到过滤之后的路由的第一个
dispatch({
type: 'homePage/getUserAuth',
payload: {
ids: res.data.id,
},
}).then(async (res) => {
if (res && res.status === 20000) {
localStorage.setItem('auth', JSON.stringify(res.data))
if (res.data.length != 0) {
let targetRouter = authRouter(middleRouter, res.data)
let originRouter = targetRouter.map((item) => {
if (item.routes.length != 0) {
return item.routes[0].path
}
})
history.push(originRouter[0])
}
} else {
message.error('获取权限失败')
}
})
6.根据动态路由处理顶部Menu
const findUrl = (data) => {
if (data.routes?.length) {
return findUrl(data.routes[0])
} else {
return data.path
}
}
const auth = JSON.parse(localStorage.getItem('auth'))
useEffect(() => {
// 根据权限获取到的路由
let targetRouter = authRouter(middleRouter, auth)
// 根据路由设置menu
const transMenuList = targetRouter.map((item) => {
return {
name: item.name,
key: item.path.substring(1),
url: findUrl(item).substring(1),
}
})
setMenuList(transMenuList)
}, [])
7.根据权限处理侧边栏Menu
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);
const hideInfo = history.location.query?.hideInfo;
useEffect(() => {
if (!hideInfo) {
setActiveKey(pathname.slice(1));
setActiveSubKey([pathname.split('/').slice(1, 2).join('/')]);
}
}, [pathname]);
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',
},
];
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/originSystem',
auth: 'xtsz_zzgl',
},
{
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',
auth: 'xtsz_jsgl',
},
{
name: '平台名称设置',
icon: (
<img src={dataModal} style={{ width: '16px', height: '16px' }}></img>
),
url: 'systemSetting/platformName',
auth: 'xtsz_ptmcsz',
},
];
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[0] === 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;