|  |  | 
 |  |  | import qs from 'qs'; | 
 |  |  | import Taro from '@tarojs/taro'; | 
 |  |  | import { getToken } from '@/utils'; | 
 |  |  | import { tokenIsExpired, Message, SensitiveManage } from '@12333/utils'; | 
 |  |  | import * as accountServices from '@12333/services/api/Account'; | 
 |  |  | import { tokenIsExpired, Message, SensitiveManage, httpLoggerRecord } from '@12333/utils'; | 
 |  |  | import { useUserStoreWithOut } from '@/stores/modules/user'; | 
 |  |  |  | 
 |  |  | const RefreshTokenUrl = '/gettokenbyrefreshtoken'; | 
 |  |  |  | 
 |  |  | /** 请求白名单,放置一些不需要token的接口(通过设置请求白名单,防止token过期后再请求造成的死循环问题) */ | 
 |  |  | const whiteList = [RefreshTokenUrl]; | 
 |  |  | const RefreshTokenBlackList = ['wxmpLogin']; | 
 |  |  |  | 
 |  |  | export function startLoading(showNavigationBarLoading: boolean) { | 
 |  |  |   if (showNavigationBarLoading) { | 
 |  |  | 
 |  |  |   success: boolean; | 
 |  |  |   data: any; | 
 |  |  |   /** | 
 |  |  |    * http状态吗 | 
 |  |  |    */ | 
 |  |  |   code?: number; | 
 |  |  |   /** | 
 |  |  |    * 错误码 | 
 |  |  |    */ | 
 |  |  |   error?: number; | 
 |  |  |   errorCode?: string; | 
 |  |  |   /** | 
 |  |  |    * 错误信息 | 
 |  |  |    */ | 
 |  |  |   msg?: string; | 
 |  |  |   showType?: ErrorShowType; | 
 |  |  |   traceId?: string; | 
 |  |  | } | 
 |  |  |  | 
 |  |  | interface ErrorResponse { | 
 |  |  | 
 |  |  |     // 错误接收及处理 | 
 |  |  |     errorHandler: (error, opts) => { | 
 |  |  |       console.log('error: ', error); | 
 |  |  |  | 
 |  |  |       const url = opts.url ?? ''; | 
 |  |  |       httpLoggerRecord.error({ | 
 |  |  |         message: `[${url}] 请求错误`, | 
 |  |  |         httpParams: { | 
 |  |  |           url: url, | 
 |  |  |           //@ts-ignore | 
 |  |  |           traceId: error?.info?.traceId, | 
 |  |  |           stackTrace: error.stack, | 
 |  |  |         }, | 
 |  |  |         args: [{ data: opts.data, params: opts.params, headers: opts.headers }], | 
 |  |  |       }); | 
 |  |  |  | 
 |  |  |       if (opts?.skipErrorHandler) throw error; | 
 |  |  |  | 
 |  |  |       if (opts?.customErrorHandler) { | 
 |  |  | 
 |  |  |         const errorInfo: ErrorInfo | undefined = (error as any).info; | 
 |  |  |         if (errorInfo) { | 
 |  |  |           const { errorMessage, errorCode } = errorInfo; | 
 |  |  |           if (Number(errorCode) === 401) { | 
 |  |  |             handleLogout(); | 
 |  |  |           } | 
 |  |  |           switch (errorInfo.showType) { | 
 |  |  |             case ErrorShowType.SILENT: | 
 |  |  |               // do nothing | 
 |  |  | 
 |  |  |       } else if ((error as AxiosError<ResponseStructure, IRequestOptions>).response) { | 
 |  |  |         // Axios 的错误 | 
 |  |  |         // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围 | 
 |  |  |         handleAxiosResponseError(error as AxiosError<ErrorResponse, IRequestOptions>); | 
 |  |  |         handleAxiosResponseError(error as AxiosError<ResponseStructure, IRequestOptions>); | 
 |  |  |         // Message.errorMessage(`Response status:${(error as AxiosError).response.status}`); | 
 |  |  |       } else if ((error as AxiosError).request) { | 
 |  |  |         // 请求已经成功发起,但没有收到响应 | 
 |  |  | 
 |  |  |  | 
 |  |  |     // 错误抛出 | 
 |  |  |     errorThrower: (res) => { | 
 |  |  |       const { success, data, error: errorCode, msg, showType } = res; | 
 |  |  |       const { success, data, errorCode, msg, showType } = res; | 
 |  |  |       if (!success) { | 
 |  |  |         const error: any = new Error(msg); | 
 |  |  |         error.name = 'BizError'; | 
 |  |  | 
 |  |  |     [ | 
 |  |  |       (config) => { | 
 |  |  |         const $config = config; | 
 |  |  |  | 
 |  |  |         httpLoggerRecord.info({ | 
 |  |  |           message: `[${$config.url}] 请求开始`, | 
 |  |  |           httpParams: { | 
 |  |  |             url: $config.url, | 
 |  |  |           }, | 
 |  |  |           args: [{ data: $config.data, params: $config.params, headers: $config.headers }], | 
 |  |  |         }); | 
 |  |  |  | 
 |  |  |         const token = getToken(); | 
 |  |  |  | 
 |  |  | 
 |  |  |  | 
 |  |  |         return new Promise((resolve, reject) => { | 
 |  |  |           if (userInfo && token && $config.withCredentials) { | 
 |  |  |             if (tokenIsExpired(userInfo)) { | 
 |  |  |               if (!Request.refreshTokenPending) { | 
 |  |  |                 Request.refreshTokenPending = true; | 
 |  |  |                 // token过期刷新 | 
 |  |  |                 useUserStoreWithOut() | 
 |  |  |                   .getTokenByRefreshToken({ | 
 |  |  |                     refreshToken: userInfo.refreshToken, | 
 |  |  |                     clientId: userStore.accountInfo?.client_id, | 
 |  |  |                   }) | 
 |  |  |                   .then((res) => { | 
 |  |  |                     $config.headers['Authorization'] = 'Bearer ' + res.accessToken; | 
 |  |  |                     Request.requests.forEach((cb) => cb(res.accessToken)); | 
 |  |  |                     Request.requests = []; | 
 |  |  |                   }) | 
 |  |  |                   .catch((err) => { | 
 |  |  |                     Request.requests.forEach((cb) => cb()); | 
 |  |  |                     Request.requests = []; | 
 |  |  |                     reject(err); | 
 |  |  |                   }) | 
 |  |  |                   .finally(() => { | 
 |  |  |                     Request.refreshTokenPending = false; | 
 |  |  |                   }); | 
 |  |  |               } | 
 |  |  |               resolve(Request.retryOriginalRequest($config)); | 
 |  |  |             } else { | 
 |  |  |               $config.headers['Authorization'] = 'Bearer ' + token; | 
 |  |  |               resolve($config); | 
 |  |  |             } | 
 |  |  |             $config.headers['Authorization'] = 'Bearer ' + userInfo.accessToken; | 
 |  |  |             $config.headers['X-Authorization'] = 'Bearer ' + userInfo.refreshToken; | 
 |  |  |             resolve($config); | 
 |  |  |           } else { | 
 |  |  |             resolve($config); | 
 |  |  |           } | 
 |  |  | 
 |  |  |       (response) => { | 
 |  |  |         const $config = response.config as IRequestOptions; | 
 |  |  |  | 
 |  |  |         httpLoggerRecord.info({ | 
 |  |  |           message: `[${$config.url}] 请求结束`, | 
 |  |  |           httpParams: { | 
 |  |  |             url: $config.url, | 
 |  |  |             traceId: response.data?.traceId, | 
 |  |  |           }, | 
 |  |  |           args: [{ data: $config.data, params: $config.params, headers: $config.headers }], | 
 |  |  |         }); | 
 |  |  |  | 
 |  |  |         const { needNProcess, getResponse = false } = $config; | 
 |  |  |  | 
 |  |  |         const userStore = useUserStoreWithOut(); | 
 |  |  |  | 
 |  |  |         if ( | 
 |  |  |           response.headers['x-access-token'] && | 
 |  |  |           RefreshTokenBlackList.every((url) => !response.config.url?.includes(url)) | 
 |  |  |         ) { | 
 |  |  |           const tokenInfo: API.LoginCommandCallback = { | 
 |  |  |             accessToken: response.headers['access-token'], | 
 |  |  |             refreshToken: response.headers['x-access-token'], | 
 |  |  |           }; | 
 |  |  |           userStore.setTokenAction(tokenInfo); | 
 |  |  |           userStore.setUserInfoAction(tokenInfo); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         endLoading(); | 
 |  |  |  | 
 |  |  |         return getResponse | 
 |  |  |           ? response | 
 |  |  |           : SensitiveManage.filterSensitiveWord((response.data as any).result); | 
 |  |  |         return getResponse ? response : SensitiveManage.filterSensitiveWord(response.data.data); | 
 |  |  |       }, | 
 |  |  |       (error) => { | 
 |  |  |         endLoading(); | 
 |  |  | 
 |  |  |   [505]: 'HTTP版本不受支持', | 
 |  |  | }; | 
 |  |  |  | 
 |  |  | function handleAxiosResponseError(error: AxiosError<ErrorResponse, IRequestOptions>) { | 
 |  |  | function handleAxiosResponseError(error: AxiosError<ResponseStructure, IRequestOptions>) { | 
 |  |  |   if (error.response.config.url.toLowerCase().includes(RefreshTokenUrl.toLowerCase())) { | 
 |  |  |     handleLogout(); | 
 |  |  |     return; | 
 |  |  |   } | 
 |  |  |   if (error && error.response) { | 
 |  |  |     let message = ErrorMessageMap[error.response?.status] ?? '请求错误'; | 
 |  |  |     if (error.response.data?.error?.message) { | 
 |  |  |       message = error.response.data?.error?.message; | 
 |  |  |     if (error.response.data?.msg) { | 
 |  |  |       message = error.response.data?.msg; | 
 |  |  |     } | 
 |  |  |     if (error.response?.status === 401) { | 
 |  |  |     if (error.response?.status === 401 || error.response.data.code === 401) { | 
 |  |  |       handleLogout(); | 
 |  |  |     } | 
 |  |  |  |