Commit 7783af89b6f6a09088f958ef86d0ae6a6cdc5035

Authored by ww
1 parent 500be415

perf(custom request): 自定义请求使用其他配置的axios

  1 +import type { ErrorMessageMode } from '/#/external/axios';
  2 +
  3 +export function checkStatus(
  4 + status: number,
  5 + msg: string,
  6 + errorMessageMode: ErrorMessageMode = 'message'
  7 +) {
  8 + let errMessage = msg;
  9 + switch (status) {
  10 + case 400:
  11 + errMessage = `${msg}`;
  12 + break;
  13 + // 401: Not logged in
  14 + // Jump to the login page if not logged in, and carry the path of the current page
  15 + // Return to the current page after successful login. This step needs to be operated on the login page.
  16 + case 401:
  17 + errMessage = '没有权限';
  18 + break;
  19 + case 403:
  20 + errMessage = '未授权';
  21 + break;
  22 + // 404请求不存在
  23 + case 404:
  24 + errMessage = '未找到该资源!';
  25 + break;
  26 + case 405:
  27 + errMessage = '网络请求错误,请求方法未允许!';
  28 + break;
  29 + case 408:
  30 + errMessage = '网络请求超时!';
  31 + break;
  32 + case 500:
  33 + errMessage = '服务器错误,请联系管理员!';
  34 + break;
  35 + case 501:
  36 + errMessage = '网络未实现!';
  37 + break;
  38 + case 502:
  39 + errMessage = '网络错误!';
  40 + break;
  41 + case 503:
  42 + errMessage = '服务不可用,服务器暂时过载或维护!';
  43 + break;
  44 + case 504:
  45 + errMessage = '网络超时!';
  46 + break;
  47 + case 505:
  48 + errMessage = 'http版本不支持该请求!';
  49 + break;
  50 + default:
  51 + }
  52 +
  53 + if (errMessage) {
  54 + if (errorMessageMode === 'message') {
  55 + const { error } = window['$message']
  56 + error(errMessage);
  57 + }
  58 + }
  59 + return !!errMessage
  60 +}
  1 +import type { AxiosResponse } from 'axios';
  2 +import type { RequestOptions, Result } from '/#/external/axios';
  3 +import type { AxiosTransform, CreateAxiosOptions } from '@/utils/external/http/axios/axiosTransform';
  4 +import { useGlobSetting } from '@/hooks/external/setting';
  5 +import { RequestEnum, ContentTypeEnum } from '@/enums/external/httpEnum';
  6 +import { isString } from '@/utils/external/is';
  7 +import { getJwtToken } from '@/utils/external/auth';
  8 +import { setObjToUrlParams, deepMerge } from '@/utils/external';
  9 +import { formatRequestDate, joinTimestamp } from '@/utils/external/http/axios/helper';
  10 +import { VAxios } from '@/utils/external/http/axios/Axios';
  11 +import { checkStatus } from './checkStatus';
  12 +
  13 +const globSetting = useGlobSetting();
  14 +const urlPrefix = globSetting.urlPrefix;
  15 +
  16 +/**
  17 + * @description: 数据处理,方便区分多种处理方式
  18 + */
  19 +const transform: AxiosTransform = {
  20 + /**
  21 + * @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误
  22 + */
  23 + transformRequestHook: (res: AxiosResponse<Result>, options: RequestOptions) => {
  24 + const { isReturnNativeResponse } = options;
  25 + // 是否返回原生响应头 比如:需要获取响应头时使用该属性
  26 + if (isReturnNativeResponse) {
  27 + return res;
  28 + }
  29 + return res.data;
  30 + },
  31 +
  32 + // 请求之前处理config
  33 + beforeRequestHook: (config, options) => {
  34 + const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true } = options;
  35 +
  36 + if (joinPrefix) {
  37 + config.url = `${urlPrefix}${config.url}`;
  38 + }
  39 +
  40 + if (apiUrl && isString(apiUrl)) {
  41 + config.url = `${apiUrl}${config.url}`;
  42 + }
  43 +
  44 + const params = config.params || {};
  45 + const data = config.data || false;
  46 + formatDate && data && !isString(data) && formatRequestDate(data);
  47 + if (config.method?.toUpperCase() === RequestEnum.GET) {
  48 + if (!isString(params)) {
  49 + // 给 get 请求加上时间戳参数,避免从缓存中拿数据。
  50 + config.params = Object.assign(params || {}, joinTimestamp(joinTime, false));
  51 + } else {
  52 + // 兼容restful风格
  53 + config.url = config.url + params + `${joinTimestamp(joinTime, true)}`;
  54 + config.params = undefined;
  55 + }
  56 + } else {
  57 + if (!isString(params)) {
  58 + formatDate && formatRequestDate(params);
  59 + if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) {
  60 + config.data = data;
  61 + config.params = params;
  62 + } else {
  63 + // 非GET请求如果没有提供data,则将params视为data
  64 + config.data = params;
  65 + config.params = undefined;
  66 + }
  67 + if (joinParamsToUrl) {
  68 + config.url = setObjToUrlParams(
  69 + config.url as string,
  70 + Object.assign({}, config.params, config.data)
  71 + );
  72 + }
  73 + } else {
  74 + // 兼容restful风格
  75 + config.url = config.url + params;
  76 + config.params = undefined;
  77 + }
  78 + }
  79 + return config;
  80 + },
  81 +
  82 + /**
  83 + * @description: 请求拦截器处理
  84 + */
  85 + requestInterceptors: (config, options) => {
  86 + // 请求之前处理config
  87 + const token = getJwtToken();
  88 + if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
  89 + // jwt token
  90 + config.headers!['X-Authorization'] = options.authenticationScheme
  91 + ? `${options.authenticationScheme} ${token}`
  92 + : token as string;
  93 + }
  94 +
  95 + return config;
  96 + },
  97 +
  98 + /**
  99 + * @description: 响应拦截器处理
  100 + */
  101 + responseInterceptors: (res: AxiosResponse<any>) => {
  102 + return res;
  103 + },
  104 +
  105 + /**
  106 + * @description: 响应错误处理
  107 + */
  108 + responseInterceptorsCatch: (error: any) => {
  109 +
  110 + const { response, config } = error || {};
  111 + const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none';
  112 + const errorMsgIsObj = typeof response?.data === 'object';
  113 + const msg: string = errorMsgIsObj
  114 + ? response?.data?.message || response?.data?.msg
  115 + : response?.data;
  116 +
  117 + const flag = checkStatus(error?.response?.status, msg, errorMessageMode);
  118 + return Promise.reject(response?.data);
  119 + },
  120 +};
  121 +
  122 +function createAxios(opt?: Partial<CreateAxiosOptions>) {
  123 + return new VAxios(
  124 + deepMerge(
  125 + {
  126 + // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
  127 + // authentication schemes,e.g: Bearer
  128 + // authenticationScheme: 'Bearer',
  129 + authenticationScheme: 'Bearer',
  130 + timeout: 10 * 1000,
  131 + // 基础接口地址
  132 + // baseURL: globSetting.apiUrl,
  133 + // 接口可能会有通用的地址部分,可以统一抽取出来
  134 + urlPrefix: urlPrefix,
  135 + headers: { 'Content-Type': ContentTypeEnum.JSON },
  136 + // 如果是form-data格式
  137 + // headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
  138 + // 数据处理方式
  139 + transform,
  140 + // 配置项,下面的选项都可以在独立的接口请求中覆盖
  141 + requestOptions: {
  142 + // 默认将prefix 添加到url
  143 + joinPrefix: true,
  144 + // 是否返回原生响应头 比如:需要获取响应头时使用该属性
  145 + isReturnNativeResponse: false,
  146 + // 需要对返回数据进行处理
  147 + isTransformResponse: true,
  148 + // post请求的时候添加参数到url
  149 + joinParamsToUrl: false,
  150 + // 格式化提交参数时间
  151 + formatDate: true,
  152 + // 消息提示类型
  153 + errorMessageMode: 'message',
  154 + // 接口地址
  155 + apiUrl: globSetting.apiUrl,
  156 + // 是否加入时间戳
  157 + joinTime: true,
  158 + // 忽略重复请求
  159 + ignoreCancelToken: true,
  160 + // 是否携带token
  161 + withToken: false
  162 + },
  163 + },
  164 + opt || {}
  165 + )
  166 + );
  167 +}
  168 +export const customHttp = createAxios();
  169 +
1 import { RequestBodyEnum, RequestParams } from "@/enums/httpEnum" 1 import { RequestBodyEnum, RequestParams } from "@/enums/httpEnum"
2 -import { ExternalRequestType, ExtraRequestConfigType } from "@/store/external/modules/extraComponentInfo.d"  
3 -import { RequestConfigType, RequestGlobalConfigType } from "@/store/modules/chartEditStore/chartEditStore.d"  
4 -import { defHttp } from "@/utils/external/http/axios" 2 +import { ExtraRequestConfigType } from "@/store/external/modules/extraComponentInfo.d"
  3 +import { RequestConfigType } from "@/store/modules/chartEditStore/chartEditStore.d"
  4 +import { customHttp } from "./http"
5 5
6 export enum ParamsType { 6 export enum ParamsType {
7 REQUIRED, 7 REQUIRED,
@@ -86,7 +86,7 @@ const transformBodyValue = (body: RequestParams['Body'], requestParamsBodyType: @@ -86,7 +86,7 @@ const transformBodyValue = (body: RequestParams['Body'], requestParamsBodyType:
86 86
87 const extraValue = (object: Recordable) => { 87 const extraValue = (object: Recordable) => {
88 return Object.keys(object).reduce((prev, next) => { 88 return Object.keys(object).reduce((prev, next) => {
89 - return {...prev, ...(object[next] ? {[next]: object[next]} : {} )} 89 + return { ...prev, ...(object[next] ? { [next]: object[next] } : {}) }
90 }, {}) 90 }, {})
91 } 91 }
92 92
@@ -104,7 +104,7 @@ export const customRequest = async (request: RequestConfigType) => { @@ -104,7 +104,7 @@ export const customRequest = async (request: RequestConfigType) => {
104 104
105 const body = transformBodyValue(Body, requestParamsBodyType) 105 const body = transformBodyValue(Body, requestParamsBodyType)
106 106
107 - return defHttp.request<any>({ 107 + return customHttp.request<any>({
108 url: requestUrl, 108 url: requestUrl,
109 baseURL: getOriginUrl(requestOriginUrl!), 109 baseURL: getOriginUrl(requestOriginUrl!),
110 method: requestHttpType, 110 method: requestHttpType,