Browse Source

feat: 在路由守卫中增加最前线的登录态判断

lanjianrong 3 years atrás
parent
commit
46300fae2d

+ 7 - 1
src/components/Menu/index.tsx

@@ -5,7 +5,7 @@ import { validJLProject } from '@/utils/common/api'
 import consts from '@/utils/consts'
 import { Button, Dropdown, Menu, Tooltip } from "antd"
 import { observer } from 'mobx-react'
-import React from 'react'
+import React, { useEffect } from 'react'
 import { Link } from "react-router-dom"
 import SvgIcon from '../SvgIcon'
 import styles from './index.module.scss'
@@ -22,6 +22,12 @@ const NavSider: React.FC<iMenuProps> = (props) => {
     userStore.logout()
   }
 
+  useEffect(() => {
+    if (!userStore.isLogin) {
+      userStore.getUserInfo()
+    }
+  }, [])
+
   const redirectToJL = async (e: React.MouseEvent) => {
     e.preventDefault()  
     const { code = -1, data = {} } = await validJLProject()

+ 10 - 6
src/components/Navigation/index.tsx

@@ -8,10 +8,11 @@ import { Redirect, Route } from "react-router-dom"
 import * as H from 'history'
 import zhCN from 'antd/es/locale/zh_CN'
 import { ConfigProvider } from 'antd'
+import { observer } from 'mobx-react'
+@observer
 class NavigationGuards extends Component<NavigationGuardsProps, any> {
   constructor(props: NavigationGuardsProps) {
     super(props)
-    userStore.check()
   }
   /**
    * 判断pathTarget是否包涵pathConfig/
@@ -55,15 +56,17 @@ class NavigationGuards extends Component<NavigationGuardsProps, any> {
     this.changDocumentTitle(this.props.location.pathname)
 
   }
+
   componentDidMount() {
     this.changDocumentTitle(this.props.location.pathname)
+    userStore.check()
   }
-  shouldComponentUpdate(nextProps: any) {
+  // shouldComponentUpdate(nextProps: any) {
 
-    //与上次请求的路径相同时不重新渲染
-    if (this.props.location.pathname === nextProps.location.pathname) return false
-    return true
-  }
+  //   //与上次请求的路径相同时不重新渲染
+  //   if (this.props.location.pathname === nextProps.location.pathname) return false
+  //   return true
+  // }
 
   /**
    * 在路由配置信息中查找用户希望访问的组件
@@ -85,6 +88,7 @@ class NavigationGuards extends Component<NavigationGuardsProps, any> {
   }
 
   render() {
+    if (userStore.loading) return null
     const { location, routeConfig, match } = this.props
     //如果没有提供routeConfig则不做任何事情
     if (!routeConfig || routeConfig.length <= 0) { return null }

+ 3 - 1
src/pages/PreAuth/index.tsx

@@ -2,6 +2,7 @@ import { userStore } from '@/store/mobx'
 import { apiExternalAuthLogin } from '@/utils/common/api'
 import consts from '@/utils/consts'
 import history from '@/utils/history'
+import { message } from 'antd'
 import React, { useState, useEffect } from 'react'
 import cycling from '../../assets/img/svg_cycling.png'
 import wrong from '../../assets/img/svg_wrong.png'
@@ -32,7 +33,8 @@ const PreAuth = () => {
         }, 250)
       } else if( code === authStatus.fail) {
         setState({ ...state, status: code, redirect: data.redirect })
-      } else {
+      } else if(code === authStatus.disable){
+        message.error('该账号已被停用')
         setState({ ...state, status: code })
       }
     }

+ 22 - 8
src/store/mobx/user/index.ts

@@ -3,7 +3,7 @@ import { apiLogin } from '@/pages/Login/api'
 import { iFromValues } from '@/types/login'
 import { ProjectInfo } from '@/types/project'
 import { iGroup, iUserInfo } from '@/types/setting'
-import { apiGetGroupList, apiProjectInfo } from '@/utils/common/api'
+import { apiGetGroupList, apiProjectInfo, apiUserInfo } from '@/utils/common/api'
 import { delUserInfo, getUserInfo, saveUserInfo } from '@/utils/common/user'
 import consts from '@/utils/consts'
 import history from '@/utils/history'
@@ -26,6 +26,8 @@ class UserState {
     role: '',
     telephone: ''
   }
+  @observable loading: boolean = false
+
   @observable userInfo: iUserInfo = this.initUserState
 
   @observable permission: [] = []
@@ -57,7 +59,6 @@ class UserState {
     const { code = -1, data } = await apiLogin(values)
     if (code === consts.RET_CODE.SUCCESS) {
       await this.getProjectInfo()
-      saveUserInfo(data)
       this.userInfo = data
       history.push('/')
     }
@@ -74,18 +75,31 @@ class UserState {
 
   @action async logout() {
     await apiLogout()
-    delUserInfo()
     this.userInfo = this.initUserState
-    history.push('/login')
+    history.replace('/login')
+  }
+
+  @action async check() {
+    if (!this.userInfo?.id) {
+      this.toggleLoading()
+      await this.getUserInfo()
+      this.toggleLoading()
+    }
   }
 
-  @action check() {
-    const user: iUserInfo | null = getUserInfo()
-    if (user) {
-      this.userInfo = user
+  @action async getUserInfo() {
+    const { code = -1, data } = await apiUserInfo()
+    if (code === consts.RET_CODE.SUCCESS) {
+      this.userInfo = data
+    } else {
+      history.replace('/login')
     }
   }
 
+  @action toggleLoading() {
+    this.loading = !this.loading
+  }
+
   @action getGroupList() {
     apiGetGroupList().then(({ code = -1, data = [] }) => {
       if (code === consts.RET_CODE.SUCCESS) {

+ 6 - 0
src/utils/common/api.ts

@@ -117,4 +117,10 @@ export async function apiExternalAuthLogin(token: string) {
 export async function validJLProject() {
   const { data } = await request.post('/api/dashboard/project/exist')
   return data
+}
+
+/** 获取用户信息 */
+export async function apiUserInfo() {
+  const { data } = await request.get('/api/projectAccount/account')
+  return data
 }

+ 9 - 8
src/utils/common/request.ts

@@ -5,7 +5,7 @@ import { tenderStore, userStore } from '@/store/mobx'
 import { PendingType, ResponseData } from '@/types/request'
 import consts from '@/utils/consts'
 import { storage } from '@/utils/util'
-import { message } from 'antd'
+import { message, notification } from 'antd'
 import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
 import history from '../history'
 const pending: Array<PendingType> = []
@@ -31,6 +31,7 @@ const service = axios.create({
   baseURL: process.env.NODE_ENV === 'development' ? consts.BASE_URL.DEV : consts.BASE_URL.PROD,
   timeout: 5000,
   withCredentials: true
+  
 })
 
 /**
@@ -42,14 +43,14 @@ service.interceptors.request.use(
     request.cancelToken = new axios.CancelToken(func => {
       pending.push({ url: request.url, method: request.method, params: request.params, data: request.data, cancel: func })
     })
-    let csrf_token
-    try {
-      csrf_token  = storage.get('csrf_token')
-    } catch (error) {
-      throw new Error('csrf_token不存在')
-      
+    const csrf_token = storage.get('csrf_token')
+    if (!csrf_token && request?.method?.toLocaleUpperCase() === 'POST') {
+      history.replace('/login')
+      notification.error({
+        message: '用户信息过期,请重新登录!'
+      })
+      return Promise.reject()
     }
-    
     if (request?.method !== 'get' && csrf_token) {
       request.headers['X-CSRF-Token'] = csrf_token
     }

+ 5 - 4
src/utils/util.ts

@@ -26,11 +26,12 @@ function getCookie(name: string) {
 // 本地存储封装
 const storage = {
   get(key: string) {
-    const val: string | null = localStorage.getItem(key)
-    if (val) {
-      return JSON.parse(val)
+    try {
+      const val: string | undefined | null = localStorage.getItem(key)
+      return val && JSON.parse(val)
+    } catch (error) {
+      return null
     }
-    return null
   },
   set(key: string, value: any) {
     if (value) {