umi6.x + react + antd的项目增加403(无权限页面拦截),404,错误处理页面

  1. 首先在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;
  }
}

  1. 在app.js配置
    在这里插入图片描述
  2. 对于没有权限的页面,在浏览器输入地址,前端拦截,需要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": []
                    }
                ]
            }
        ]
    }
]
  1. 如果要对没有权限的页面进行拦截,还需要在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,
    },
  ],
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值