- 首先在src/pages下创建403,404,ErrorBoundary
403
import { Button, Result } from 'antd';
import { history } from '@umijs/max';
const UnAccessible = () => (
<Result
status="403"
title="403"
subTitle="抱歉,您无权限访问当前页面"
extra={<Button type="primary" onClick={()=>{
history.push('/')
}}>返回主页</Button>}
/>
);
export default UnAccessible;
404
import { Button, Result } from 'antd';
import { history } from '@umijs/max';
const NotFound = () => (
<Result
status="404"
title="404"
subTitle="抱歉,无法找到你需要的页面"
extra={<Button type="primary" onClick={()=>{
history.push('/')
}}>返回主页</Button>}
/>
);
export default NotFound;
ErrorBoundary(错误边界)
import { Result, Button, Tooltip, Typography } from 'antd';
import React from 'react';
// eslint-disable-next-line @typescript-eslint/ban-types
export default class ErrorBoundary extends React.Component {
state = { hasError: false, errorInfo: '' };
static getDerivedStateFromError(error) {
return { hasError: true, errorInfo: error.message };
}
componentDidCatch(error, errorInfo) {
// You can also log the error to an error reporting service
// eslint-disable-next-line no-console
console.log(error, errorInfo);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return (
<Result
status="500"
title={<b style={{fontSize:14}}>抱歉,服务发生错误!请刷新页面</b>}
subTitle={<Tooltip title={this.state.errorInfo}>
<Typography.Paragraph copyable={{
text:this.state.errorInfo
}}>错误信息</Typography.Paragraph>
</Tooltip>}
extra={
<Button
type="primary"
onClick={() => {
window.location.reload();
}}
>
刷新页面
</Button>
}
/>
);
}
return this.props.children;
}
}
- 在app.js配置
- 对于没有权限的页面,在浏览器输入地址,前端拦截,需要access.js方法拦截,src/access.js
4中routes.js中配置的access就是作为key(accessObj获取的key要和routes.js中配置的access一致)
/* eslint-disable array-callback-return */
import allData from '../config/routes';
//获取权限 key 根据 path 生成
function convertToAccessArray(data) {
let accessArray = [];
data.map(obj => {
if (obj.path && obj.path !== '/' && obj.path !== '/home') {
// 去掉路径中的斜杠,并且将首字母大写
const access = obj.path.replace(/\//g, '').charAt(0).toUpperCase() + obj.path.replace(/\//g, '').slice(1);
accessArray.push(access);
}
if (obj.routes) {
const childAccessArray = convertToAccessArray(obj.routes);
accessArray = accessArray.concat(childAccessArray);
}
});
return accessArray;
}
export default (initialState) => {
const {menuData} = initialState;
//后端返回的页面(路由)
const AccessList = convertToAccessArray(menuData?.routes??[]);
//全部页面
const AllList = convertToAccessArray(allData?.routes);
//结果对象 accessKey 对应配置的 routes 里面的 access
// {
// accessKey: true or false
// }
const accessObj = {};
//添加权限
AllList?.map(it=>{
accessObj[it] = AccessList.includes(it);
})
return accessObj;
};
//后端返回的页面(路由)格式类似:
[
{
"name": "首页",
"key": "2024042410100000000",
"path": "/home",
"icon": null,
"routes": []
},
{
"name": "IoT管理",
"key": "2024042410200000000",
"path": "/iot",
"icon": null,
"routes": [
{
"name": "设备管理",
"key": "2024042410200200000",
"path": "/iot/device",
"icon": "icon-shebeiguanli",
"routes": [
{
"name": "设备台账",
"key": "2024042410200201000",
"path": "/iot/device/account",
"icon": null,
"routes": []
}
]
}
]
}
]
- 如果要对没有权限的页面进行拦截,还需要在routes.js配置access
{
path: '/',
routes: [
{
path: '/',
redirect: '/home',
},
{
name: '首页',
path: '/home',
component: './Home',
},
{
name: 'IoT管理',
path: '/iot',
access: 'Iot',
routes: [
{
name: '设备清单',
path: '/iot/devicelist',
icon: 'icon-zhiduguifan',
component: './Iot/DeviceList',
access: 'Iotdevicelist',
}
],
},
{
path:'/*',
name: '404',
component: './404',
hideInMenu: true,
},
],
}