index.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import DefaultErrorPage from '@/pages/ErrorPage'
  2. import { frameState, userState } from '@/store/mobx'
  3. import { NavigationGuardsProps, RouteModel } from '@/types/router'
  4. import { combinationPath } from '@/utils/util'
  5. import React, { Component } from 'react'
  6. import KeepAlive from 'react-activation'
  7. import { Redirect, Route } from "react-router-dom"
  8. class NavigationGuards extends Component<NavigationGuardsProps, any> {
  9. // constructor(props: NavigationGuardsProps) {
  10. // super(props)
  11. // userState.check()
  12. // }
  13. /**
  14. * 判断pathTarget是否包涵pathConfig/
  15. * 即,pathConfig是否为pathTarget的子路径
  16. * @param pathConfig 配置文件中的路径的全路径
  17. * @param pathTarget 用户请求的路径
  18. */
  19. static switchRoute(pathConfig: string, pathTarget: string) {
  20. if (pathConfig === pathTarget) return true
  21. const reg = new RegExp(`(^${pathConfig})(?=/)`)
  22. return reg.test(pathTarget)
  23. }
  24. static permissionAuthentication(authArray: string[], myPermis: string) {
  25. return !!authArray.find((item) => item === myPermis)
  26. }
  27. shouldComponentUpdate(nextProps: any) {
  28. //与上次请求的路径相同时不重新渲染
  29. if (this.props.location.pathname === nextProps.location.pathname) return false
  30. userState.check()
  31. return true
  32. }
  33. /**
  34. * 在路由配置信息中查找用户希望访问的组件
  35. * @param parentPath 父路由的路径
  36. * @param targetPath 用户当前希望访问的路径
  37. * @param routeConfig 路由配置信息
  38. * @param ErrorPage 错误页面
  39. */
  40. static findTargetRoute(parentPath: string, targetPath: string, routeConfig: RouteModel[]): { targetRoute: RouteModel | null | Error, realPath: string } {
  41. for (let i = 0; i < routeConfig.length; i++) {
  42. const item = routeConfig[i]
  43. const path = combinationPath(parentPath, item.path)
  44. if (targetPath && NavigationGuards.switchRoute(path, targetPath)) {
  45. return { targetRoute: { ...item, path }, realPath: path }
  46. }
  47. }
  48. return { targetRoute: null, realPath: "" }
  49. }
  50. render() {
  51. console.log("路由守卫渲染")
  52. const { location, routeConfig, match } = this.props
  53. //如果没有提供routeConfig则不做任何事情
  54. if (!routeConfig || routeConfig.length <= 0) { return null }
  55. const ErrorPage = DefaultErrorPage
  56. //父路由的路径
  57. const parentPath = match && match.path
  58. //用户当前希望访问的路径
  59. const targetPath: string | undefined = location?.pathname
  60. //如果访问子菜单,则跳转到子菜单的默认路由
  61. if (targetPath && frameState.defaultRouteMapping.has(targetPath)) {
  62. const targetDefaultRoute: string = frameState.defaultRouteMapping.get(targetPath) as string
  63. return <Redirect to={targetDefaultRoute}></Redirect>
  64. }
  65. const findRes = targetPath && NavigationGuards.findTargetRoute(parentPath, targetPath, routeConfig)
  66. const targetRoute: RouteModel | null | "" | undefined | Error = findRes && findRes.targetRoute
  67. const isLogin = userState.isLogin
  68. if (targetRoute instanceof Error) return <ErrorPage/>
  69. if (findRes) {
  70. const path: string = findRes.realPath ? findRes.realPath : ""
  71. targetRoute && frameState.setCurrentRoutePath(path)
  72. }
  73. if (!targetRoute) {
  74. return <ErrorPage/>
  75. }
  76. if (targetRoute.redirect && !targetRoute.component) {
  77. return <Redirect to={targetRoute.redirect}></Redirect>
  78. }
  79. //以下部分可提出去作为用户自定义部分
  80. if (isLogin) {
  81. return <LoginHandler ErrorPage={ErrorPage} targetRoute={targetRoute}></LoginHandler>
  82. } else {
  83. return <NotLoginHandler targetRoute={targetRoute}></NotLoginHandler>
  84. }
  85. }
  86. }
  87. //已经登陆的状态下,处理路由
  88. function LoginHandler(props: { targetRoute: RouteModel, ErrorPage: any }): any {
  89. const { targetRoute, ErrorPage } = props
  90. const { path, auth } = targetRoute
  91. const noCache = targetRoute.meta?.noCache ? targetRoute.meta.noCache : false
  92. if (path === '/login') {
  93. return <Redirect to="/console/dashboard"></Redirect>
  94. } else if (!auth || NavigationGuards.permissionAuthentication(auth, userState.role)) {
  95. return (
  96. <Route path={path} render={
  97. props => (
  98. noCache ?
  99. <targetRoute.component {...props} routeConfig={targetRoute.childRoutes}></targetRoute.component> :
  100. (
  101. <KeepAlive id={`${path}`}>
  102. <targetRoute.component {...props} routeConfig={targetRoute.childRoutes}></targetRoute.component>
  103. </KeepAlive>
  104. )
  105. )
  106. }></Route>
  107. )
  108. } else {
  109. return <ErrorPage message="您无权访问此页"></ErrorPage>
  110. }
  111. }
  112. //未登录状态下,处理路由
  113. function NotLoginHandler(props: { targetRoute: RouteModel}): any {
  114. const { targetRoute } = props
  115. const { path, auth } = targetRoute
  116. if (auth && auth.length > 0) {
  117. return <Redirect to="/login"></Redirect>
  118. } else {
  119. return <Route path={path} render={
  120. props => (
  121. <targetRoute.component {...props} routeConfig={targetRoute.childRoutes}></targetRoute.component>
  122. )
  123. }></Route>
  124. }
  125. }
  126. export default NavigationGuards