zhengyiming
3 天以前 add9b3bb61fcc337b02c15e7973967d670e7d3be
apps/h5/src/utils/request/index.ts
@@ -1,30 +1,36 @@
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();
  }
}
// 错误处理方案: 错误类型
@@ -76,8 +82,8 @@
}
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',
@@ -116,19 +122,21 @@
              // 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) {
@@ -140,10 +148,10 @@
        // 请求已经成功发起,但没有收到响应
        // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例,
        // 而在node.js中是 http.ClientRequest 的实例
        Message.error('服务器无响应,请重试');
        Message.errorMessage('服务器无响应,请重试');
      } else {
        // 发送请求时出了点问题
        Message.error('发送请求时出了点问题');
        Message.errorMessage('发送请求时出了点问题');
      }
    },
@@ -163,56 +171,54 @@
    [
      (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);
@@ -235,11 +241,14 @@
        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();
@@ -273,16 +282,22 @@
    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);