apiTest.vue 9.98 KB
<route lang="yaml">
    name: apiTest
    </route>

<script lang="ts" setup name="apiTest">
import { ref } from 'vue';
import {
  getValidApi,
  testApiData,
  getApiDetail
} from "@/api/modules/dataService";
import { TableColumnWidth } from '@/utils/enum';
import { useValidator } from '@/hooks/useValidator';
import { useRouter } from "vue-router";

const { required } = useValidator();
const router = useRouter();
const { proxy } = getCurrentInstance() as any;
/** API下拉列表。已发布的启用的API名称,选择后自动带出路径和请求参数。 */
const validApiList = ref([]);

const apiFormRef = ref();
/** 选择要测试的API. */
const apiFormItems = ref([
  {
    type: 'select',
    label: 'API名称',
    field: 'apiGuid',
    default: '',
    placeholder: '请选择',
    options: validApiList.value,
    col: 'path-w30',
    props: {
      label: "apiName",
      children: "children",
      value: 'guid',
      isLeaf: 'isLeaf'
    },
    filterable: true,
    clearable: true,
    required: true
  },
  // {
  //   type: 'input',
  //   label: 'API路径',
  //   field: 'path',
  //   default: '',
  //   maxlength: 50,
  //   col: 'path-w30',
  //   disabled: true,
  //   required: false
  // },
  // {
  //   type: 'input',
  //   label: '场景名称',
  //   field: 'sceneName',
  //   default: '',
  //   maxlength: 50,
  //   col: 'path-w20',
  //   disabled: true,
  //   required: false,
  // },{
  //   type: 'input',
  //   label: '场景名称',
  //   field: 'sceneGuid',
  //   default: '',
  //   maxlength: 50,
  //   col: 'path-w20',
  //   disabled: true,
  //   required: false,
  //   visible: false,
  // },{
  //   type: 'input',
  //   label: '加工单号',
  //   field: 'processOrderNo',
  //   default: '',
  //   maxlength: 50,
  //   col: 'path-w20',
  //   disabled: true,
  //   required: false,
  // },
]);

const apiFormRules = ref({
  apiGuid: [required('请选择API')]
});

const requestParamsTableInfo = ref({
  id: "query-params-table",
  height: '214px',
  fields: [
    { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
    { label: "参数名", field: "paramName", width: 140 },
    { label: "参数位置", field: "paramPositionName", width: 100 },
    { label: "参数类型", field: "dataTypeName", width: 120 },
    {
      label: "是否必填", field: "isRequired", width: 100, getName: (scope) => {
        return scope.row.isRequired == 'Y' ? '是' : '否'
      }
    },
    {
      label: "是否多值", field: "isManyValue", width: 100, getName: (scope) => {
        return scope.row.isManyValue == 'Y' ? '是' : '否'
      }
    },
    {
      label: "值", field: "introductionValue", width: 240, columClass: 'edit-colum', type: 'edit', dataTypeName: 'paramType', getVisible: (scope) => {
        return !scope.row.isConst;
      }
    },
    { label: "描述", field: "description", width: 120 },
  ],
  editInfo: {
    introductionValue: {
      label: '',
      type: 'input',
      field: 'introductionValue',
      default: '',
      placeholder: '请输入',
      clearable: true,
    }
  },
  STATUS: 'edit',
  data: <Array<Object>>[],
  showPage: false,
  actionInfo: {
    show: false
  },
  loading: false
});

const defaultParamsData: any = ref([{
  paramName: 'pageSize',
  dataType: '整型',
  isRequired: '是',
  value: 50
}, {
  paramName: 'pageIndex',
  dataType: '整型',
  isRequired: '是',
  value: 1
}]);

/** default参数表格配置 */
const defaultParamsTableInfo = ref({
  id: "default-params-table",
  height: 'auto',
  minHeight: '50px',
  minPanelHeight: '50px',
  fields: [
    { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
    { label: "参数名", field: "paramName", width: 140 },
    { label: "参数类型", field: "dataType", width: 100 },
    { label: "是否必填", field: "isRequired", width: 100 },
    { label: "值", field: "value", width: 240, columClass: 'edit-colum', type: 'edit' },
  ],
  editInfo: {
    value: { //只能输入大于0的整数。
      label: '',
      type: 'input',
      field: 'value',
      default: '',
      maxlength: 50,
      min: 1,
      regexp: /\D/g,
      placeholder: '请输入',
      clearable: false,
    }
  },
  STATUS: 'edit',
  data: defaultParamsData.value,
  showPage: false,
  actionInfo: {
    show: false
  },
  loading: false
});

/** api测试结果详情表单 */
const resultFormItems = ref([{
  label: '请求详情',
  type: 'textarea',
  placeholder: '输出请求详情',
  field: 'requestUrlDetail',
  default: '',
  rows: 10,
  readonly: true,
  maxlength: "",
  clearable: true,
  required: false,
}, {
  label: '返回内容',
  type: 'textarea',
  placeholder: '输出返回内容',
  field: 'resultInfo',
  default: '',
  rows: 10,
  readonly: true,
  maxlength: "",
  clearable: true,
  required: false,
}]);

const getValidLabelPromise: any = ref(null);

onBeforeMount(() => {
  getValidApi().then((res: any) => {
    if (res.code == proxy.$passCode) {
      validApiList.value = res.data || [];
      apiFormItems.value[0].options = validApiList.value;
    } else {
      proxy.$ElMessage.error(res.msg);
    }
  })
})

const getApiDetailPromise: any = ref(null);
const selectApiDetailInfo: any = ref({});////选择数据产品后带出来的信息

const apiSelectChange = (val) => {
  if (!val) {//清空值
    apiFormItems.value[0].default = val;
    // apiFormItems.value[1].default = '';
    requestParamsTableInfo.value.data = [];
    resultFormItems.value[0].default = '';
    resultFormItems.value[1].default = '';
  } else {
    resultFormItems.value[0].default = '';
    resultFormItems.value[1].default = '';
    requestParamsTableInfo.value.loading = true;
    getApiDetail(val).then((res: any) => {
      requestParamsTableInfo.value.loading = false;
      requestParamsTableInfo.value.data = [];
      if (res.code == proxy.$passCode) {
        selectApiDetailInfo.value = res.data || {};
        apiFormItems.value[0].default = val;
        let apiConfigAccessRSVOS = selectApiDetailInfo.value.apiConfigAccessRSVOS || [];
        apiConfigAccessRSVOS.forEach(vo => {
          if (vo.paramType == 'REQ') {
            requestParamsTableInfo.value.data.push({ ...vo, introductionValue: vo.defaultValue });
          } else if (vo.paramType == 'CONSTANT') {
            requestParamsTableInfo.value.data.push({ ...vo, isConst: true, introductionValue: vo.defaultValue });
          }
        })
        defaultParamsTableInfo.value.data = defaultParamsData.value;
      }
      else {
        proxy.$ElMessage.error(res.msg);
      }
    })
  }
}

const startTestApiBtnLoading = ref(false);

const startTestApi = () => {
  apiFormRef.value?.ruleFormRef?.validate((valid, errorItem) => {
    if (valid) {
      let requestParamsData: any[] = requestParamsTableInfo.value.data;
      if (requestParamsData.length) {
        let dataIndex = 1;
        for (const d of requestParamsData) {
          if (d.isRequired == 'Y' && d.introductionValue !== 0 && !d.introductionValue) {
            proxy.$ElMessage.error(`第 ${dataIndex} 个请求参数为必填则值不能为空`);
            return;
          }
          dataIndex++;
        }
      }
      let defaultParamsDataInfo = defaultParamsTableInfo.value.data;
      if (defaultParamsDataInfo.length == 3 && !defaultParamsDataInfo[2].value) {
        proxy.$ElMessage.error(`请填写参数appKey`);
        return;
      }
      resultFormItems.value[0].default = '';
      resultFormItems.value[1].default = '';
      startTestApiBtnLoading.value = true;
      testApiData({
        pageSize: defaultParamsDataInfo[0].value,
        pageIndex: defaultParamsDataInfo[1].value,
        appKey: defaultParamsDataInfo.length == 3 ? defaultParamsDataInfo[2].value : '',
        guid: apiFormRef.value.formInline.apiGuid,
        apiConfigAccessDTOS: requestParamsData
      }).then((res: any) => {
        startTestApiBtnLoading.value = false;
        if (res.code == proxy.$passCode) {
          proxy.$ElMessage.success('测试API调用成功');
          let info = res.data;
          resultFormItems.value[0].default = JSON.stringify(info.apiInvokeReqVO, null, 4);
          resultFormItems.value[1].default = JSON.stringify(info.apiInvokeRespVO, null, 4);
        } else {
          proxy.$ElMessage.error(res.msg);
        }
      }).catch(() => {
        startTestApiBtnLoading.value = false;
      });
    } else {
      var obj = Object.keys(errorItem);
      apiFormRef.value.ruleFormRef.scrollToField(obj[0])
    }
  });
}

</script>

<template>
  <div class="container_wrap full">
    <ContentWrap id="id-requestParams" title="请求参数" description="">
      <div>
        <Form ref="apiFormRef" :itemList="apiFormItems" formId="table-base-form" :rules="apiFormRules" col="col3"
          @select-change="apiSelectChange" />
      </div>

      <Table :tableInfo="requestParamsTableInfo" class="mb10 mt8" />
    </ContentWrap>
    <ContentWrap id="id-defaultParams" title="DEFAULT" description="" class="mt16">
      <Table :tableInfo="defaultParamsTableInfo" class="mb10" />
    </ContentWrap>
    <ContentWrap id="id-test" title="测试API" description="" class="mt16">
      <el-button :disabled="requestParamsTableInfo.loading" :loading="startTestApiBtnLoading" @click="startTestApi"
        class="mb10">开始测试</el-button>
      <Form ref="resultInfoFormRef" :itemList="resultFormItems" formId="result-base-form" col="col2" />
    </ContentWrap>
  </div>
</template>

<style lang="scss" scoped>
.container_wrap.full {
  overflow-y: auto;
  padding: 16px;
}

:deep(.el-form) {
  .el-form-item.path-w50 {
    width: calc(60% - 6px) !important;
    max-width: 720px;
  }

  .el-form-item.path-w30 {
    width: calc(30% - 6px) !important;
    max-width: 540px;
  }

  .el-form-item.path-w20 {
    width: calc(18% - 6px) !important;
    max-width: 540px;
    margin-right: 8px !important;
  }

  .el-textarea .el-textarea__inner {
    overflow-wrap: break-word;
    white-space: pre-wrap;
    word-break: break-all;
  }
}

.mt8 {
  margin-top: 8px;
}

.mt16 {
  margin-top: 16px;
}

.mb10 {
  margin-bottom: 10px;
}

.value {
  color: #212121;
}
</style>