index.ts 5.41 KB
import { RequestBodyEnum, RequestHttpEnum, RequestParams } from "@/enums/httpEnum"
import { ExtraRequestConfigType } from "@/store/external/modules/extraComponentInfo.d"
import { RequestConfigType } from "@/store/modules/chartEditStore/chartEditStore.d"
import { isShareMode } from "@/views/share/hook"
import { customHttp } from "./http"
import { SelectTimeAggregationFieldEnum } from "@/views/chart/ContentConfigurations/components/ChartData/external/components/SelectTImeAggregation"

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] } : {}) }
  }, {})
}

const handleParams = (Params: Recordable) => {
  Reflect.deleteProperty(Params, 'attrName')
  if (Params.keys && Params?.keys?.length) {
    // 过滤无效参数
    Reflect.deleteProperty(Params, 'attrName')
    /** ft 修改select联动下拉框选择了属性(单个)报错问题
     * 源代码 Params.keys = (Params.keys || [] as any).join(',')
     */
    if (!Array.isArray(Params.keys)) {
      Params.keys = ([Params.keys] || [] as any).join(',')
    } else {
      Params.keys = (Params.keys || [] as any).join(',')
    }
    //ft
  }

  const timePeriod = Params[SelectTimeAggregationFieldEnum.TIME_PERIOD]
  if (timePeriod) {
    Params.startTs = Date.now() - timePeriod
    Params.endTs = Date.now()
    Reflect.deleteProperty(Params, SelectTimeAggregationFieldEnum.TIME_PERIOD)
  }

  return Object.keys(Params).filter(Boolean).reduce((prev, next) => ({ ...prev, [next]: Params[next] }), {})
}

//post请求动态追加query参数
const objConvertQuery = (data: Recordable) => {
  const _result = [];
  for (const key in data) {
    const value = data[key];
    if (value.constructor == Array) {
      value.forEach(function (_value) {
        _result.push(key + "=" + _value);
      });
    } else {
      _result.push(key + '=' + value);
    }
  }
  return _result.join('&');
}

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)

  /**
   * ft 修改post请求针对这种接口(/api/yt/device,设备列表分页),是post请求,page和pageSize是query参数,body可以不传内容
   * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
   * 源代码 url: requestUrl
   * 修改后代码 requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl: `${requestUrl}?${objConvertQuery(Params)}
   */
  Params = handleParams(Params)
  
  return customHttp.request<any>({
    url: requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl : `${requestUrl}?${objConvertQuery(Params)}`,
    baseURL: getOriginUrl(requestOriginUrl!),
    method: requestHttpType,
    params: requestHttpType === RequestHttpEnum.GET.toUpperCase() ? Params : null,
    data: body,
    headers: extraValue(Header)
  }, {
    joinPrefix: false,
    apiUrl: '',
    withShareToken: isShareMode()
  })
  //ft
}