index.ts 3.28 KB
import { RequestBodyEnum, RequestParams } from "@/enums/httpEnum"
import { ExtraRequestConfigType } from "@/store/external/modules/extraComponentInfo.d"
import { RequestConfigType } from "@/store/modules/chartEditStore/chartEditStore.d"
import { customHttp } from "./http"

export enum ParamsType {
  REQUIRED,
  OPTIONAL
}

export const getOriginUrl = (originUrl: string) => {
  const locationUrl = 'localhost'
  return originUrl === locationUrl ? location.origin : originUrl
}

const regOptionalParams = /(?={\?)/g
const regDynamicParams = /(?={).+?(?<=})/g

/**
 * @description 判断是否是动态参数
 * @param url 
 */
export const isDynamicUrl = (url: string) => {
  regDynamicParams.lastIndex = 0
  return regDynamicParams.test(url)
}

/**
 * @description 解析动态参数
 * @param url 
 */
export const decomposeDynamicParams = (url: string) => {
  regDynamicParams.lastIndex = 0
  regOptionalParams.lastIndex = 0

  return Array.from((url || '').matchAll(regDynamicParams), ([item]) => {
    return {
      type: regOptionalParams.test(item) ? ParamsType.OPTIONAL : ParamsType.REQUIRED,
      originValue: item,
      value: item.replaceAll(/[{}?]/g, '').split(',')
    }
  })
}

/**
 * @description 正则替换url中的动态参数
 * @param requestUrl 
 * @param Params 
 */
const getDynamicRequestUrl = (requestUrl = '', Params: Recordable) => {
  requestUrl = decodeURI(requestUrl || '')

  const paramsList = decomposeDynamicParams(requestUrl)
  requestUrl = paramsList.reduce((prev, next) => {
    const { type, value, originValue } = next
    if (type === ParamsType.REQUIRED) {
      value.forEach(key => {
        prev = prev.replace(key, Reflect.get(Params, key))
        Reflect.deleteProperty(Params, key)
      })
    }

    if (type === ParamsType.OPTIONAL) {
      prev = prev.replace(originValue, '')
    }

    return prev
  }, requestUrl)

  return requestUrl.replaceAll(/[{}?]/g, '')
}

const transformBodyValue = (body: RequestParams['Body'], requestParamsBodyType: RequestBodyEnum) => {
  let value = Reflect.get(body, requestParamsBodyType)

  if (requestParamsBodyType === RequestBodyEnum.FORM_DATA) {
    const formData = new FormData()
    Object.keys(value as RequestParams['Body']['form-data']).forEach(key => {
      formData.append(key, value[key])
    })
    value = formData
  }

  return value
}

const extraValue = (object: Recordable) => {
  return Object.keys(object).reduce((prev, next) => {
    return { ...prev, ...(object[next] ? { [next]: object[next] } : {}) }
  }, {})
}

export const customRequest = async (request: RequestConfigType) => {
  const { requestHttpType, requestParams, requestParamsBodyType, requestOriginUrl } = request as ExtraRequestConfigType
  let { requestUrl } = request as ExtraRequestConfigType
  const { Header, Body } = requestParams
  let { Params } = requestParams
  Params = JSON.parse(JSON.stringify(Params))
  const isDynamicUrlFlag = isDynamicUrl(requestUrl || '')

  if (isDynamicUrlFlag) {
    requestUrl = getDynamicRequestUrl(requestUrl, Params)
  }

  const body = transformBodyValue(Body, requestParamsBodyType)

  return customHttp.request<any>({
    url: requestUrl,
    baseURL: getOriginUrl(requestOriginUrl!),
    method: requestHttpType,
    params: Params,
    data: body,
    headers: extraValue(Header)
  }, {
    joinPrefix: false,
    apiUrl: ''
  })
}