index.tsx 5.6 KB

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