| | |
| | | import { type IRequestOptions, Request, type RequestConfig } from 'senior-request'; |
| | | import { type IRequestOptions, BoleRequest, type RequestConfig } from '@bole-core/core'; |
| | | import { type AxiosRequestConfig, type AxiosError } from 'axios'; |
| | | import qs from 'qs'; |
| | | import Taro from '@tarojs/taro'; |
| | | import { getToken, Message } from '@/utils'; |
| | | import { tokenIsExpired, SensitiveManage } from '@life-payment/utils'; |
| | | import { useUserStoreWithOut } from '@/stores/modules/user'; |
| | | import NProgress from '../progress'; |
| | | import { loadEnv } from '@build/index'; |
| | | import { getToken, getUserInfo } from '../storage'; |
| | | import { useUserStoreHook } from '@/store/modules/user'; |
| | | import { ElLoading as Loading, ElNotification } from 'element-plus'; |
| | | import { router } from '@/router'; |
| | | import { Message, tokenIsExpired } from '@/utils'; |
| | | |
| | | const RefreshTokenUrl = '/gettokenbyrefreshtoken'; |
| | | // 加载环境变量 VITE_PROXY_DOMAIN(开发环境) VITE_PROXY_DOMAIN_REAL(打包后的线上环境) |
| | | const { VITE_PROXY_DOMAIN, VITE_PROXY_DOMAIN_REAL, DEV } = loadEnv(); |
| | | |
| | | const RefreshTokenUrl = '/GetTokenByRefreshToken'; |
| | | |
| | | /** 请求白名单,放置一些不需要token的接口(通过设置请求白名单,防止token过期后再请求造成的死循环问题) */ |
| | | const whiteList = [RefreshTokenUrl]; |
| | | const whiteList = [RefreshTokenUrl, '/GetToken']; |
| | | |
| | | export function startLoading(showNavigationBarLoading: boolean) { |
| | | if (showNavigationBarLoading) { |
| | | Taro.showNavigationBarLoading(); |
| | | } else { |
| | | Taro.showLoading({ |
| | | title: '', |
| | | mask: true, |
| | | }); |
| | | } |
| | | let loadingInstance: ReturnType<typeof Loading.service>; |
| | | |
| | | function startLoading() { |
| | | loadingInstance = Loading.service({ |
| | | fullscreen: true, |
| | | lock: true, |
| | | background: 'transparent', |
| | | }); |
| | | } |
| | | |
| | | export function endLoading() { |
| | | Taro.hideNavigationBarLoading(); |
| | | Taro.hideLoading(); |
| | | function endLoading() { |
| | | if (loadingInstance) { |
| | | loadingInstance.close(); |
| | | } |
| | | } |
| | | |
| | | // 错误处理方案: 错误类型 |
| | |
| | | } |
| | | |
| | | const AxiosOptions: AxiosRequestConfig = { |
| | | baseURL: process.env.BASE_URL, |
| | | timeout: 10 * 1000, |
| | | baseURL: DEV ? VITE_PROXY_DOMAIN : VITE_PROXY_DOMAIN_REAL, |
| | | timeout: 30000, |
| | | headers: { |
| | | Accept: 'application/json, text/plain, */*', |
| | | 'Content-Type': 'application/json', |
| | |
| | | // do nothing |
| | | break; |
| | | case ErrorShowType.WARN_MESSAGE: |
| | | Message.warning(errorMessage); |
| | | Message.warnMessage(errorMessage); |
| | | break; |
| | | case ErrorShowType.ERROR_MESSAGE: |
| | | Message.error(errorMessage); |
| | | Message.errorMessage(errorMessage); |
| | | break; |
| | | case ErrorShowType.NOTIFICATION: |
| | | Message.error(errorMessage); |
| | | ElNotification.error({ |
| | | message: `${errorCode}: ${errorMessage}`, |
| | | }); |
| | | break; |
| | | case ErrorShowType.REDIRECT: |
| | | // TODO: redirect |
| | | break; |
| | | default: |
| | | Message.error(errorMessage); |
| | | Message.errorMessage(errorMessage); |
| | | } |
| | | } |
| | | } else if ((error as AxiosError<ResponseStructure, IRequestOptions>).response) { |
| | |
| | | // 请求已经成功发起,但没有收到响应 |
| | | // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例, |
| | | // 而在node.js中是 http.ClientRequest 的实例 |
| | | Message.error('服务器无响应,请重试'); |
| | | Message.errorMessage('服务器无响应,请重试'); |
| | | } else { |
| | | // 发送请求时出了点问题 |
| | | Message.error('发送请求时出了点问题'); |
| | | Message.errorMessage('发送请求时出了点问题'); |
| | | } |
| | | }, |
| | | |
| | |
| | | [ |
| | | (config) => { |
| | | const $config = config; |
| | | // 开启进度条动画 |
| | | if (config.needNProcess) { |
| | | NProgress.start(); |
| | | } |
| | | |
| | | const token = getToken(); |
| | | |
| | | const userStore = useUserStoreWithOut(); |
| | | const userInfo = getUserInfo(); |
| | | |
| | | const userInfo = userStore.userInfo; |
| | | const { showLoading = true, mock } = $config; |
| | | |
| | | const { showLoading = true, showNavigationBarLoading, mock } = $config; |
| | | |
| | | if (mock && process.env.NODE_ENV === 'development') { |
| | | $config.baseURL = 'http://localhost:9527'; |
| | | if (mock) { |
| | | $config.url = $config.url.replace(/^\/api/, ''); |
| | | } |
| | | |
| | | /** |
| | | * 如果是refreshToken这个方法 就直接返回 防止内存泄漏 |
| | | */ |
| | | if (whiteList.some((url) => $config.url!.toLowerCase().includes(url.toLowerCase()))) { |
| | | if (whiteList.some((url) => $config.url.toLowerCase().includes(url.toLowerCase()))) { |
| | | return $config; |
| | | } |
| | | |
| | | if (showLoading) { |
| | | startLoading(showNavigationBarLoading); |
| | | startLoading(); |
| | | } |
| | | |
| | | return new Promise((resolve, reject) => { |
| | | if (userInfo && token && $config.withCredentials) { |
| | | return new Promise((resolve) => { |
| | | if (token && $config.withCredentials) { |
| | | if (tokenIsExpired(userInfo)) { |
| | | if (!Request.refreshTokenPending) { |
| | | Request.refreshTokenPending = true; |
| | | if (!BoleRequest.refreshTokenPending) { |
| | | const userStore = useUserStoreHook(); |
| | | BoleRequest.refreshTokenPending = true; |
| | | // token过期刷新 |
| | | useUserStoreWithOut() |
| | | .getTokenByRefreshToken({ |
| | | userStore |
| | | .refreshToken({ |
| | | refreshToken: userInfo.refreshToken, |
| | | clientId: userStore.accountInfo?.client_id, |
| | | 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); |
| | | BoleRequest.requests.forEach((cb) => cb(res.accessToken)); |
| | | BoleRequest.requests = []; |
| | | }) |
| | | .finally(() => { |
| | | Request.refreshTokenPending = false; |
| | | BoleRequest.refreshTokenPending = false; |
| | | }); |
| | | } |
| | | resolve(Request.retryOriginalRequest($config)); |
| | | resolve(BoleRequest.retryOriginalRequest($config)); |
| | | } else { |
| | | $config.headers['Authorization'] = 'Bearer ' + token; |
| | | resolve($config); |
| | |
| | | |
| | | const { needNProcess, getResponse = false } = $config; |
| | | |
| | | // 关闭进度条动画 |
| | | if (needNProcess) { |
| | | NProgress.done(); |
| | | } |
| | | |
| | | endLoading(); |
| | | |
| | | return getResponse |
| | | ? response |
| | | : SensitiveManage.filterSensitiveWord((response.data as any).result); |
| | | return getResponse ? response : (response.data as any).result; |
| | | }, |
| | | (error) => { |
| | | endLoading(); |
| | |
| | | if (error.response.data?.error?.message) { |
| | | message = error.response.data?.error?.message; |
| | | } |
| | | |
| | | if (error.response?.status === 401) { |
| | | handleLogout(); |
| | | } |
| | | |
| | | Message.error(message); |
| | | Message.errorMessage(message); |
| | | } |
| | | } |
| | | |
| | | function handleLogout() { |
| | | useUserStoreWithOut().logout(); |
| | | const userStore = useUserStoreHook(); |
| | | let path = '/'; |
| | | if (userStore.token) { |
| | | path = router.currentRoute.value.fullPath; |
| | | } |
| | | userStore.logout(); |
| | | router.replace(`/login?redirect=${path}`); |
| | | } |
| | | |
| | | export const request = Request.create(config); |
| | | export const request = BoleRequest.create(config); |