CustomQuery.js 6.14 KB
import { parseExp, parseUrl } from '@/utils/parse.js'
import { getValueByPath } from '@/utils/value.js'
import { Message } from 'element-ui'
import request from '@/utils/request.js'

const CustomQuery = {
  /**
   * 通过别名获取关联查询定义
   */
  get: (alias) => {
    return new Promise((resolve, reject) => {
      if (!alias) {
        reject('alias can not be null.')
      }
      request({
        url: `${window.context.form}/form/customQuery/v1/getByAlias`,
        method: 'post',
        data: alias,
      })
        .then((response) => resolve(response))
        .catch((error) => reject(error))
    })
  },
  /**
   * 传入关联查询别名和查询参数,返回查询到的数据
   */
  load: (alias, params) => {
    return new Promise((resolve, reject) => {
      CustomQuery.get(alias).then(
        (query) => {
          if (!query) {
            reject(`未获取到别名为:${alias}的关联查询`)
          } else {
            // 执行关联查询
            CustomQuery._doQuery(query, params, '1', (data) => {
              resolve(data)
            })
          }
        },
        () => {
          reject()
        }
      )
    })
  },
  _throwException: (msg) => {
    Message.error(msg)
    throw msg
  },
  // 处理POST请求时的参数
  _handlePostData: (query, queryParams) => {
    if (!query.dataParam || query.dataParam.constructor != String) {
      return queryParams
    }
    // 构建上下文数据对象
    let ctx = {}
    queryParams &&
      queryParams.forEach((element) => {
        ctx[element.key] = element.value
      })
    const exp = parseExp(query.dataParam, ctx)
    try {
      return JSON.parse(exp)
    } catch (e) {
      CustomQuery._throwException(
        `POST参数不是有效的JSON格式${query.dataParam}`
      )
    }
  },
  // 处理GET请求的URL(GET请求的查询参数追加到URL后面)
  _handleGetUrl: (url, queryParams) => {
    if (!url) {
      CustomQuery._throwException('Restful类型的url地址为空')
    }
    let urlParamsAry = []
    queryParams &&
      queryParams.forEach((q) => {
        urlParamsAry.push(`${q.key}=${q.value}`)
      })
    const linkWord = url.indexOf('?') == -1 ? '?' : '&'
    return `${url}${linkWord}${urlParamsAry.join('&')}`
  },
  _doQuery: (query, params, type, cb) => {
    params = params || {}
    // 复制一份关联查询对象
    query = { ...query }
    // 关联数据始终查询第一页
    const page = 1
    // 关联数据查询参数
    let queryParams = []

    if (query.conditionfield) {
      try {
        const conditionFields = JSON.parse(query.conditionfield)
        // 构建查询参数
        if (
          conditionFields &&
          conditionFields.constructor == Array &&
          conditionFields.length > 0
        ) {
          conditionFields.forEach((c) => {
            // 默认按照固定值构建查询参数
            let obj = {
              key: c.field,
              value: c.defaultValue,
            }
            // 参数传入时获取传入的params中的同名参数值
            if (c.defaultType == '1' || c.defaultType == '4') {
              if (params.hasOwnProperty(c.field)) {
                obj.value = params[c.field]
              }
            }
            queryParams.push(obj)
          })
        }
      } catch (e) {
        CustomQuery._throwException(`条件字段的JSON格式错误:${e}`)
      }
    }
    let queryUrl = query.url
    let requestMethod = 'POST'
    if (query.dsType == 'selectedApi') {
      queryParams = encodeURIComponent(
        Base64.encode(`${JSON.stringify(queryParams)}`)
      )
      queryUrl = `${context.portal}/portal/portalInterfaceManager/v1/doQuery?alias=${query.apiAlias}&paramData=${queryParams}}`
      requestMethod = 'GET'
    } else if (query.dsType == 'dataSource') {
      queryUrl = `${context.form}/form/customQuery/v1/doQuery?alias=${query.alias}&page=${page}`
    } else {
      // POST请求,则处理queryParams参数
      if (query.requestType == 'POST') {
        queryParams = CustomQuery._handlePostData(query, queryParams)
      }
      // GET请求,则处理url地址
      else if (query.requestType == 'GET') {
        query.url = CustomQuery._handleGetUrl(query.url, queryParams)
      }
      queryUrl = query.url
      //如果关联数据列表查询数据不是数据源则请求方法为restful配置的请求方式
      requestMethod = query.requestType
    }
    // 处理url地址中的${服务名}
    queryUrl = parseUrl(queryUrl)
    //查询数据
    request(
      {
        url: queryUrl,
        method: requestMethod,
        data: queryParams,
        headers: query.header,
      },
      query.dsType
    ).then(
      (response) => {
        //自定义对话框因为要显示分页信息,并且显示字段的key是小写,故此处直接返回,由自定义对话框组件本身处理数据
        if (type == '1') {
          //如果数据来源是数据源
          if (query.dsType == 'dataSource') {
            cb(response.rows)
          } else {
            // 如果数据来源是REST接口
            const data = CustomQuery._handleResponse(response, query.listKey)
            cb(data)
          }
        }
      },
      (reason) => {
        cb([])
        CustomQuery._throwException(reason)
      }
    )
  },
  _handleResponse: (data, rowsKey) => {
    if (!data) {
      Message.error('返回的数据为空')
      return []
    }
    if (data.constructor == String) {
      try {
        data = JSON.parse(data)
      } catch (e) {
        CustomQuery._throwException(`将返回值解析为JSON对象时出错了:${e}`)
      }
    }

    if (data.constructor == Object) {
      // 如果没有指定提取key,则将返回值包装为列表
      if (!rowsKey) {
        return [data]
      }
      try {
        return getValueByPath(data, rowsKey)
      } catch (e) {
        CustomQuery._throwException(`从返回的数据中提取数组时出错了:${e}`)
      }
    } else if (data.constructor == Array) {
      // 已经是数组类型时,不再通过rowsKey提取
      return data
    } else {
      CustomQuery._throwException(`返回的数据无法解析:${data}`)
    }
  },
}

export default CustomQuery