|
@@ -1,162 +1,148 @@
|
|
|
-import { updateMatch } from '@/store/modules/navigation'
|
|
|
-import { checkPermission } from '@/store/modules/user'
|
|
|
-import { RootState } from '@/store/reducers'
|
|
|
-import { NavigationGuardsProps, RouteModol } from '@/types/router'
|
|
|
-import React, { Dispatch, useEffect } from 'react'
|
|
|
-import { connect } from 'react-redux'
|
|
|
+import DefaultErrorPage from '@/pages/ErrorPage'
|
|
|
+import { frameState, userState } from '@/store/mobx'
|
|
|
+import { NavigationGuardsProps, RouteModel } from '@/types/router'
|
|
|
+import { combinationPath } from '@/utils/util'
|
|
|
+import React, { Component } from 'react'
|
|
|
+import KeepAlive from 'react-activation'
|
|
|
import { Redirect, Route } from "react-router-dom"
|
|
|
-import { AnyAction } from 'redux'
|
|
|
-
|
|
|
-const NavigationGuards:React.FC<NavigationGuardsProps> = props => {
|
|
|
- const { location, routeConfig, match, check, permission, isLogin, saveMatch } = props
|
|
|
- useEffect(() => {
|
|
|
- check()
|
|
|
- }, [])
|
|
|
-
|
|
|
- const parentPath: string | null = match?.path || null // 父路由的路径
|
|
|
- const targetPath: string | null = location?.pathname || null// 目标路由的位置
|
|
|
- const targetRoute: RouteModol | null = targetPath && findTargetRoute(parentPath, targetPath, routeConfig) || null
|
|
|
-
|
|
|
- // 利用重定向使 / 访问/dashboard路由
|
|
|
- if (targetRoute && targetRoute.redirect) {
|
|
|
- const redirectPath = combinationRedirect(parentPath, targetRoute.redirect)
|
|
|
- return <Redirect to={redirectPath}/>
|
|
|
- }
|
|
|
-
|
|
|
- // 未找到目标路由组件,返回404
|
|
|
- if (!targetRoute) {
|
|
|
- return <Redirect to='/404'/>
|
|
|
- }
|
|
|
-
|
|
|
- // 处理是否已登录
|
|
|
- if (isLogin) {
|
|
|
- return <LoginHandler targetRoute={targetRoute}></LoginHandler>
|
|
|
- } else {
|
|
|
- saveMatch(targetPath || '/')
|
|
|
- return <NotLoginHandler targetRoute={targetRoute}></NotLoginHandler>
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
+class NavigationGuards extends Component<NavigationGuardsProps, any> {
|
|
|
+ // constructor(props: NavigationGuardsProps) {
|
|
|
+ // super(props)
|
|
|
+ // userState.check()
|
|
|
+ // }
|
|
|
+ /**
|
|
|
+ * 判断pathTarget是否包涵pathConfig/
|
|
|
+ * 即,pathConfig是否为pathTarget的子路径
|
|
|
+ * @param pathConfig 配置文件中的路径的全路径
|
|
|
+ * @param pathTarget 用户请求的路径
|
|
|
+ */
|
|
|
+ static switchRoute(pathConfig: string, pathTarget: string) {
|
|
|
+ if (pathConfig === pathTarget) return true
|
|
|
+
|
|
|
+ const reg = new RegExp(`(^${pathConfig})(?=/)`)
|
|
|
+ return reg.test(pathTarget)
|
|
|
+ }
|
|
|
|
|
|
-/**
|
|
|
- * 判断一个路径是否是另一个路径的子路径
|
|
|
- * @param pathConfig - 配置文件中的路径
|
|
|
- * @param pathTarget - 用户请求的路径
|
|
|
- */
|
|
|
-function switchRoute (pathConfig: string, pathTarget: string):boolean {
|
|
|
- if (pathConfig === pathTarget) return true
|
|
|
- const reg = new RegExp(`(^${pathConfig})(?=/)`)
|
|
|
- return reg.test(pathTarget)
|
|
|
-}
|
|
|
|
|
|
+ static permissionAuthentication(authArray: string[], myPermis: string) {
|
|
|
+ return !!authArray.find((item) => item === myPermis)
|
|
|
+ }
|
|
|
|
|
|
-/**
|
|
|
- * 将子组件路径还原成带前缀的路径
|
|
|
- * @param parentPath - 父组件路径
|
|
|
- * @param pathOfTargetConfig - 用户希望访问的组件的在路由配置信息中填写的路径
|
|
|
- * @returns {string} 拼接后的path
|
|
|
- */
|
|
|
-const combinationPath = (parentPath: string|undefined, pathOfTargetConfig: string): string => {
|
|
|
- // if (parentPath && pathOfTargetConfig === '/') return parentPath
|
|
|
- // if (parentPath && parentPath === pathOfTargetConfig) return parentPath
|
|
|
- let combinedPath = !pathOfTargetConfig.startsWith('/') ? `/${pathOfTargetConfig}` : pathOfTargetConfig
|
|
|
- combinedPath = parentPath ? `${parentPath}${combinedPath}` : combinedPath
|
|
|
- return combinedPath
|
|
|
-}
|
|
|
+ shouldComponentUpdate(nextProps: any) {
|
|
|
+ //与上次请求的路径相同时不重新渲染
|
|
|
+ if (this.props.location.pathname === nextProps.location.pathname) return false
|
|
|
+ userState.check()
|
|
|
+ return true
|
|
|
+ }
|
|
|
|
|
|
-/**
|
|
|
- * 将重定向路径还原成带前缀的路径
|
|
|
- * @param parentPath - 父路由路径
|
|
|
- * @param redirectPath - 用户希望访问的组件的在路由配置信息中填写的重定向路径
|
|
|
- * @returns {string} 拼接后的重定向路径
|
|
|
- */
|
|
|
-const combinationRedirect = (parentPath: string|null, redirectPath: string): string => {
|
|
|
- if (parentPath === '/' || !parentPath) {
|
|
|
- return redirectPath.startsWith('/') ? redirectPath : `/${redirectPath}`
|
|
|
- } else {
|
|
|
- return redirectPath.startsWith('/') ? `${parentPath}${redirectPath}` : `${parentPath}/${redirectPath}`
|
|
|
- }
|
|
|
-}
|
|
|
-/**
|
|
|
- * 在路由配置信息中查找用户希望访问的组件
|
|
|
- * @param parentPath 父组件路径
|
|
|
- * @param targetPath 用户当前访问的路径
|
|
|
- * @param routeConfig 路由配置信息
|
|
|
- * @returns {RouteModol|null} 路由配置信息
|
|
|
- */
|
|
|
-function findTargetRoute (parentPath: any, targetPath: string, routeConfig: RouteModol[]): RouteModol | null {
|
|
|
- // 处理目标路径是父路由的子路由根路径, 比如 /console/management => /console/management/
|
|
|
- // 使其直接找到路由配置中的重定向配置项
|
|
|
- if (parentPath && parentPath === targetPath) {
|
|
|
- return routeConfig.find(item => item.path === '/') || null
|
|
|
- }
|
|
|
- for (let i = 0; i < routeConfig.length; i++) {
|
|
|
- const item = routeConfig[i]
|
|
|
- const path = combinationPath(parentPath, item.path)
|
|
|
-
|
|
|
- if (targetPath && switchRoute(path, targetPath)) {
|
|
|
- return { ...item, path }
|
|
|
+ /**
|
|
|
+ * 在路由配置信息中查找用户希望访问的组件
|
|
|
+ * @param parentPath 父路由的路径
|
|
|
+ * @param targetPath 用户当前希望访问的路径
|
|
|
+ * @param routeConfig 路由配置信息
|
|
|
+ * @param ErrorPage 错误页面
|
|
|
+ */
|
|
|
+ static findTargetRoute(parentPath: string, targetPath: string, routeConfig: RouteModel[]): { targetRoute: RouteModel | null | Error, realPath: string } {
|
|
|
+ for (let i = 0; i < routeConfig.length; i++) {
|
|
|
+ const item = routeConfig[i]
|
|
|
+ const path = combinationPath(parentPath, item.path)
|
|
|
+
|
|
|
+ if (targetPath && NavigationGuards.switchRoute(path, targetPath)) {
|
|
|
+ return { targetRoute: { ...item, path }, realPath: path }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return { targetRoute: null, realPath: "" }
|
|
|
}
|
|
|
- }
|
|
|
- return null
|
|
|
-}
|
|
|
|
|
|
-/**
|
|
|
- * 已经登录->路由处理
|
|
|
- */
|
|
|
-function LoginHandler(props: any) {
|
|
|
- const { targetRoute } = props
|
|
|
- const { path } = targetRoute
|
|
|
- if (path === '/login') {
|
|
|
- return <Redirect to="/"></Redirect>
|
|
|
- } else {
|
|
|
- return <Route path={path} render={
|
|
|
- props => (
|
|
|
- <targetRoute.component {...props} routeConfig={targetRoute.childRoutes}/>
|
|
|
- )
|
|
|
- }></Route>
|
|
|
- }
|
|
|
-}
|
|
|
+ render() {
|
|
|
+ console.log("我渲染了")
|
|
|
+ const { location, routeConfig, match } = this.props
|
|
|
+ //如果没有提供routeConfig则不做任何事情
|
|
|
+ if (!routeConfig || routeConfig.length <= 0) { return null }
|
|
|
+ const ErrorPage = DefaultErrorPage
|
|
|
+ //父路由的路径
|
|
|
+ const parentPath = match && match.path
|
|
|
+ //用户当前希望访问的路径
|
|
|
+ const targetPath: string | undefined = location?.pathname
|
|
|
|
|
|
-/**
|
|
|
- * 未登录->路由处理
|
|
|
- */
|
|
|
-function NotLoginHandler(props: any) {
|
|
|
- const { targetRoute } = props
|
|
|
- const { auth, path } = targetRoute
|
|
|
- if (auth) {
|
|
|
- return <Redirect to="/login"></Redirect>
|
|
|
- } else {
|
|
|
- return <Route path={path} render={
|
|
|
- props => (
|
|
|
- <targetRoute.component {...props} routeConfig={targetRoute.childRoutes}/>
|
|
|
- )
|
|
|
- }></Route>
|
|
|
- }
|
|
|
-}
|
|
|
|
|
|
-const mapStateToProps = (state: RootState) => {
|
|
|
- const { user: { permission, isLogin } } = state
|
|
|
- return {
|
|
|
- permission,
|
|
|
- isLogin
|
|
|
- }
|
|
|
+ //如果访问子菜单,则跳转到子菜单的默认路由
|
|
|
+ if (targetPath && frameState.defaultRouteMapping.has(targetPath)) {
|
|
|
+ const targetDefaultRoute: string = frameState.defaultRouteMapping.get(targetPath) as string
|
|
|
+ return <Redirect to={targetDefaultRoute}></Redirect>
|
|
|
+ }
|
|
|
+
|
|
|
+ const findRes = targetPath && NavigationGuards.findTargetRoute(parentPath, targetPath, routeConfig)
|
|
|
+ const targetRoute: RouteModel | null | "" | undefined | Error = findRes && findRes.targetRoute
|
|
|
+
|
|
|
+ const isLogin = userState.isLogin
|
|
|
+
|
|
|
+ if (targetRoute instanceof Error) return <ErrorPage/>
|
|
|
+
|
|
|
+ if (findRes) {
|
|
|
+ const path: string = findRes.realPath ? findRes.realPath : ""
|
|
|
+ targetRoute && frameState.setCurrentRoutePath(path)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!targetRoute) {
|
|
|
+ return <ErrorPage/>
|
|
|
+ }
|
|
|
+
|
|
|
+ if (targetRoute.redirect && !targetRoute.component) {
|
|
|
+ return <Redirect to={targetRoute.redirect}></Redirect>
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //以下部分可提出去作为用户自定义部分
|
|
|
+ if (isLogin) {
|
|
|
+ return <LoginHandler ErrorPage={ErrorPage} targetRoute={targetRoute}></LoginHandler>
|
|
|
+ } else {
|
|
|
+ return <NotLoginHandler targetRoute={targetRoute}></NotLoginHandler>
|
|
|
+ }
|
|
|
+}
|
|
|
}
|
|
|
|
|
|
-const mapDispatchToProps = (dispatch: Dispatch<AnyAction>) => {
|
|
|
- return {
|
|
|
- check() {
|
|
|
- dispatch(checkPermission())
|
|
|
- },
|
|
|
- saveMatch(path: string) {
|
|
|
- dispatch(updateMatch(path))
|
|
|
- }
|
|
|
- }
|
|
|
+//已经登陆的状态下,处理路由
|
|
|
+function LoginHandler(props: { targetRoute: RouteModel, ErrorPage: any }): any {
|
|
|
+ const { targetRoute, ErrorPage } = props
|
|
|
+ const { path, auth } = targetRoute
|
|
|
+ const noCache = targetRoute.meta?.noCache ? targetRoute.meta.noCache : false
|
|
|
+ if (path === '/login') {
|
|
|
+ return <Redirect to="/console/dashboard"></Redirect>
|
|
|
+ } else if (!auth || NavigationGuards.permissionAuthentication(auth, userState.userInfo.Role)) {
|
|
|
+ return (
|
|
|
+ <Route path={path} render={
|
|
|
+ props => (
|
|
|
+ noCache ?
|
|
|
+ <targetRoute.component {...props} routeConfig={targetRoute.childRoutes}></targetRoute.component> :
|
|
|
+ (
|
|
|
+ <KeepAlive id={`${path}`}>
|
|
|
+ <targetRoute.component {...props} routeConfig={targetRoute.childRoutes}></targetRoute.component>
|
|
|
+ </KeepAlive>
|
|
|
+ )
|
|
|
+ )
|
|
|
+ }></Route>
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ return <ErrorPage message="您无权访问此页"></ErrorPage>
|
|
|
+ }
|
|
|
}
|
|
|
-const connector = connect(mapStateToProps, mapDispatchToProps)
|
|
|
-export default connector(NavigationGuards)
|
|
|
|
|
|
-export {
|
|
|
- combinationPath
|
|
|
+//未登录状态下,处理路由
|
|
|
+function NotLoginHandler(props: { targetRoute: RouteModel}): any {
|
|
|
+ const { targetRoute } = props
|
|
|
+ const { path, auth } = targetRoute
|
|
|
+
|
|
|
+ if (auth && auth.length > 0) {
|
|
|
+ return <Redirect to="/login"></Redirect>
|
|
|
+ } else {
|
|
|
+ return <Route path={path} render={
|
|
|
+ props => (
|
|
|
+ <targetRoute.component {...props} routeConfig={targetRoute.childRoutes}></targetRoute.component>
|
|
|
+ )
|
|
|
+ }></Route>
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+export default NavigationGuards
|
|
|
+
|