Просмотр исходного кода

refactor: 调整requestConfig配置

lanjianrong 4 лет назад
Родитель
Сommit
818574bd20
8 измененных файлов с 53 добавлено и 301 удалено
  1. 34 35
      src/app.tsx
  2. 1 1
      src/basic/consts.js
  3. 0 12
      src/basic/utils.js
  4. 0 100
      src/basic/utils/common.js
  5. 0 117
      src/basic/utils/request.js
  6. 1 0
      src/locales/zh-CN/pages.js
  7. 17 30
      src/pages/User/Login/index.jsx
  8. 0 6
      src/utils.js

+ 34 - 35
src/app.tsx

@@ -1,4 +1,6 @@
 import { queryCurrentUser, queryPermData } from './services/user'
+import type { RequestConfig } from 'umi'
+import { ErrorShowType } from 'umi'
 import { history } from 'umi'
 import RightContent from '@/components/RightContent'
 import { message, notification } from 'antd'
@@ -95,23 +97,33 @@ export const layout = ({ initialState, setInitialState }) => {
 }
 
 const errorHandler = error => {
-  const { response } = error
-
-  if (response && response.status) {
-    const errorText = codeMessage[response.status] || response.statusText
-    const { status, url } = response
-    notification.error({
-      message: `请求错误 ${status}: ${url}`,
-      description: errorText
-    })
-  } else if (!response) {
+  const { data, info } = error
+  if (info) {
+    const { errorMessage = '请求失败', showType, errorCode } = info
+    if (consts.TOKEN_INVALID_CODE.includes(errorCode)) {
+      history.replace(consts.LOGIN_PATH)
+    }
+    switch (showType) {
+      case ErrorShowType.ERROR_MESSAGE:
+        message.error(errorMessage)
+      case ErrorShowType.WARN_MESSAGE:
+        message.warn(errorMessage)
+      case ErrorShowType.NOTIFICATION:
+        const title = consts.TOKEN_INVALID_CODE.includes(errorCode) ? '用户信息过期' : '请求失败'
+        notification.error({
+          message: title,
+          description: errorMessage
+        })
+      default:
+        break
+    }
+  } else {
     notification.error({
       description: '您的网络发生异常,无法连接服务器',
       message: '网络异常'
     })
   }
-
-  return response
+  return data
 }
 
 const authHeaderInterceptor = (url, options) => {
@@ -128,28 +140,6 @@ const authHeaderInterceptor = (url, options) => {
   return { url, options }
 }
 
-const refreshTokenIfNeed = async (response, config) => {
-  const res = await response.clone().json()
-  if (
-    res &&
-    res.code !== consts.RET_CODE.SUCCESS &&
-    !consts.TOKEN_INVALID_CODE.includes(res.code) &&
-    config.url !== '/api/login'
-  ) {
-    message.error((res && res.msg) || '请求错误')
-    // return Promise.reject(response)
-    return response
-  }
-  if (res && res.code && consts.TOKEN_INVALID_CODE.includes(res.code)) {
-    history.replace(consts.LOGIN_PATH)
-  }
-  return response
-}
-
-/**
- * 配置request请求时的默认参数
- */
-
 export const request: RequestConfig = {
   errorHandler,
   prefix: '/api',
@@ -157,6 +147,15 @@ export const request: RequestConfig = {
   credentials: 'include', // 默认请求是否带上cookie
   prefix: consts.PREFIX_URL,
   cache: 'no-cache',
-  responseInterceptors: [(response, options) => refreshTokenIfNeed(response, options)],
+  errorConfig: {
+    adaptor: resData => {
+      return {
+        success: resData.code === consts.RET_CODE.SUCCESS,
+        errorMessage: resData.msg,
+        errorCode: resData.code,
+        showType: resData.showType
+      }
+    }
+  },
   requestInterceptors: [authHeaderInterceptor]
 }

+ 1 - 1
src/basic/consts.js

@@ -7,5 +7,5 @@ export default {
   LOGIN_PATH: '/user/login', //
   TOKEN_INVALID_CODE: [2, 3], // 接口返回码如果是2, 3 则表明token过期或无效 需要自动刷新token
   TOKEN_WHITE_LIST: ['/api/login'], // 不需要设置token的白名单
-  RET_CODE: { SUCCESS: 0, FAIL: 1, TOKEN_UNDEFINED: 19, TOKEN_EXPIRED: 2 } // 返回RET状态码解析
+  RET_CODE: { SUCCESS: 0, FAIL: -1, TOKEN_UNDEFINED: 19, TOKEN_EXPIRED: 2 } // 返回RET状态码解析
 }

+ 0 - 12
src/basic/utils.js

@@ -1,12 +0,0 @@
-export const importAll = context => {
-  const map = {}
-  // eslint-disable-next-line no-restricted-syntax
-  for (const key of context.keys()) {
-    const keyArr = key.split('/')
-    keyArr.shift() // 移除 ./
-    map[keyArr.join('.').replace(/\.js$/g, '')] = context(key)
-  }
-  return map
-}
-
-export default importAll(require.context('./utils', true, /\.js$/))

+ 0 - 100
src/basic/utils/common.js

@@ -1,100 +0,0 @@
-import { history } from 'umi'
-import consts from '../consts'
-
-const USER_INFO = 'USER_INFO' // 用户个人信息
-const USER_ACCOUNT = 'USER_ACCOUNT' // 用户账号
-const TOKEN_ID = 'TOKEN_ID' // TOKEN令牌ID
-
-// 本地存储封装
-const storage = {
-  get(key) {
-    const val = localStorage.getItem(key)
-    if (val) {
-      return JSON.parse(val)
-    }
-    return null
-  },
-  set(key, value) {
-    localStorage.setItem(key, JSON.stringify(value))
-  },
-  del(key) {
-    localStorage.removeItem(key)
-  },
-  clear() {
-    localStorage.clear()
-  }
-}
-
-/**
- * 保存用户信息到本地存储中
- * @param {*} user 用户信息
- */
-export const saveUserInfo = user => {
-  storage.set(USER_INFO, user)
-}
-
-/**
- * 获取用户信息
- */
-export const getUserInfo = () => {
-  const user = storage.get(USER_INFO)
-  return user
-}
-
-/**
- * 移除用户信息
- */
-export const removeUserInfo = () => {
-  return storage.del(USER_INFO)
-}
-
-/**
- * 保存用户账号信息
- * @param {*} account 账号
- */
-export const saveUserAccount = account => {
-  storage.set(USER_ACCOUNT, account)
-}
-
-/**
- * 获取用户账号信息
- */
-export const getUserAccount = () => {
-  return storage.get(USER_ACCOUNT)
-}
-
-/**
- * 移除用户账号信息
- */
-export const removeUserAccount = () => {
-  return storage.del(USER_ACCOUNT)
-}
-/**
- * 保存令牌ID到本地存储中
- * @param {*} id token令牌id
- */
-export const saveTokenId = id => {
-  return storage.set(TOKEN_ID, id)
-}
-
-/**
- * 移除令牌ID
- */
-export const removeTokenId = () => {
-  return storage.del(TOKEN_ID)
-}
-
-/**
- * 从本地存储中获取令牌ID
- */
-export const getTokenid = () => {
-  return storage.get(TOKEN_ID) || ''
-}
-
-/**
- * 重定向到登录页
- */
-export const redirectToLogin = url => {
-  // 重定向登录页面
-  history.replace(url || consts.LOGIN_PATH)
-}

+ 0 - 117
src/basic/utils/request.js

@@ -1,117 +0,0 @@
-/**
- * request 网络请求工具
- * 更详细的 api 文档: https://github.com/umijs/umi-request
- */
-import { extend } from 'umi'
-import { message, notification } from 'antd'
-import { redirectToLogin } from './common'
-import consts from '@/consts'
-import { getToken } from '@/utils/auth'
-
-const codeMessage = {
-  200: '服务器成功返回请求的数据。',
-  201: '新建或修改数据成功。',
-  202: '一个请求已经进入后台排队(异步任务)。',
-  204: '删除数据成功。',
-  400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
-  401: '用户没有权限(令牌、用户名、密码错误)。',
-  403: '用户得到授权,但是访问是被禁止的。',
-  404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
-  406: '请求的格式不可得。',
-  410: '请求的资源被永久删除,且不会再得到的。',
-  422: '当创建一个对象时,发生一个验证错误。',
-  500: '服务器发生错误,请检查服务器。',
-  502: '网关错误。',
-  503: '服务不可用,服务器暂时过载或维护。',
-  504: '网关超时。'
-}
-/**
- * 异常处理程序
- */
-
-const errorHandler = error => {
-  const { response } = error
-
-  if (response && response.status) {
-    const errorText = codeMessage[response.status] || response.statusText
-    const { status, url } = response
-    notification.error({
-      message: `请求错误 ${status}: ${url}`,
-      description: errorText
-    })
-  } else if (!response) {
-    notification.error({
-      description: '您的网络发生异常,无法连接服务器',
-      message: '网络异常'
-    })
-  }
-
-  return response
-}
-
-/**
- * 配置request请求时的默认参数
- */
-
-const request = extend({
-  errorHandler,
-  // 默认错误处理
-  credentials: 'include', // 默认请求是否带上cookie
-  prefix: consts.PREFIX_URL,
-  cache: 'no-cache'
-})
-
-// 请求拦截器
-request.interceptors.request.use((url, options) => {
-  const token = getToken()
-  if (token) {
-    // 在白名单里的请求放过
-    if (consts.TOKEN_WHITE_LIST.includes(url)) {
-      return { url, options }
-    }
-    // eslint-disable-next-line no-param-reassign
-    options.headers[consts.TOKEN_HEADER] = `bearer ${token}`
-    return { url, options }
-  }
-  return { url, options }
-})
-const refreshTokenIfNeed = async (response, config) => {
-  const res = await response.clone().json()
-  if (
-    res &&
-    res.code !== consts.RET_CODE.SUCCESS &&
-    !consts.TOKEN_INVALID_CODE.includes(res.code) &&
-    config.url !== '/api/login'
-  ) {
-    message.error((res && res.msg) || '请求错误')
-    // return Promise.reject(response)
-    return response
-  }
-  if (res && res.code && consts.TOKEN_INVALID_CODE.includes(res.code)) {
-    redirectToLogin()
-    // const account = getUserAccount()
-    // if (!account || !currentTokenRetry) {
-    //   return response
-    // }
-    // currentTokenRetry -= 1
-    // // token过期或者没有传token
-    // const data = await apiGetToken(account)
-    // if (data && data.data && data.data.code === consts.RET_CODE.SUCCESS) {
-    //   currentTokenRetry = RETRY_TOKEN_TIME // 重置token重试次数
-    //   // 刷新token成功,保存token
-    //   const token = data.data && data.data.token
-    //   setAuthCache(TOKEN_KEY, token)
-    //   // 重新发起请求
-    //   const newResponse = await request(response.url, config)
-    //   return newResponse
-    // }
-  }
-  return response
-}
-
-// 响应拦截器
-request.interceptors.response.use((response, options) => {
-  return refreshTokenIfNeed(response, options)
-})
-
-export default request

+ 1 - 0
src/locales/zh-CN/pages.js

@@ -1,5 +1,6 @@
 export default {
   'pages.layouts.userLayout.title': '纵横办公系统',
+  'pages.login.failure': '登录失败',
   'pages.login.accountLogin.tab': '账户密码登录',
   'pages.login.accountLogin.errorMessage': '错误的用户名或密码',
   'pages.login.username.placeholder': '用户名: admin or user',

+ 17 - 30
src/pages/User/Login/index.jsx

@@ -9,6 +9,7 @@ import { apiLogin } from '@/services/login'
 import { setAuthCache } from '@/utils/auth'
 import { TOKEN_KEY } from '@/utils/cache/cacheEnum'
 import { DEFAULT_CACHE_TIME } from '@/settings/encryptionSetting'
+import consts from '@/consts'
 
 const LoginMessage = ({ content }) => (
   <Alert
@@ -23,8 +24,11 @@ const LoginMessage = ({ content }) => (
 
 const Login = () => {
   const [submitting, setSubmitting] = useState(false)
-  const [userLoginState, setUserLoginState] = useState({})
-  const [type, setType] = useState('account')
+  const [userLoginState, setUserLoginState] = useState({
+    submitting: false,
+    status: '',
+    type: 'account'
+  })
   const { initialState, setInitialState } = useModel('@@initialState')
 
   const intl = useIntl()
@@ -58,33 +62,16 @@ const Login = () => {
   }
 
   const handleSubmit = async values => {
-    setSubmitting(true)
-    try {
-      // 登录
-      const res = await apiLogin({ ...values })
-      if (res.code === 0) {
-        setAuthCache(TOKEN_KEY, res.data.token, DEFAULT_CACHE_TIME)
-
-        // const defaultLoginSuccessMessage = intl.formatMessage({
-        //   id: 'pages.login.success',
-        //   defaultMessage: '登录成功!'
-        // })
-        // message.success(defaultLoginSuccessMessage)
-        const userinfo = await fetchUserInfo()
-        /** 此方法会跳转到 redirect 参数所在的位置 */
-        return goto(userinfo?.currentUser?.username)
-      }
-      // 如果失败去设置用户错误信息
-      setUserLoginState(res.msg)
-    } catch (error) {
-      const defaultLoginFailureMessage = intl.formatMessage({
-        id: 'pages.login.failure',
-        defaultMessage: '登录失败,请重试!'
-      })
-
-      return message.error(defaultLoginFailureMessage)
+    setUserLoginState({ ...userLoginState, submitting: true })
+    const { code = -1, data: { token = '' } = {} } = await apiLogin({ ...values })
+    if (code === consts.RET_CODE.SUCCESS) {
+      setAuthCache(TOKEN_KEY, token, DEFAULT_CACHE_TIME)
+      const userinfo = await fetchUserInfo()
+      /** 此方法会跳转到 redirect 参数所在的位置 */
+      return goto(userinfo?.currentUser?.username)
     }
-    return setSubmitting(false)
+    // 如果失败去设置用户错误信息
+    setUserLoginState({ ...userLoginState, status: 'error', submitting: false })
   }
   const { status, type: loginType } = userLoginState
 
@@ -128,7 +115,7 @@ const Login = () => {
               handleSubmit(values)
             }}
           >
-            <Tabs activeKey={type} onChange={setType}>
+            <Tabs activeKey={loginType}>
               <Tabs.TabPane
                 key="account"
                 tab={intl.formatMessage({
@@ -153,7 +140,7 @@ const Login = () => {
                 })}
               />
             )}
-            {type === 'account' && (
+            {loginType === 'account' && (
               <>
                 <ProFormText
                   name="username"

+ 0 - 6
src/utils.js

@@ -1,6 +0,0 @@
-import utils, { importAll } from '@/src/basic/utils'
-import merge from 'lodash-es/merge'
-
-const baseUtils = importAll(require.context('./utils', true, /\.js$/))
-
-export default merge(utils, baseUtils)