feat(接口定义): 请求/响应头输入联想&部分高优先级 bug 修复
This commit is contained in:
parent
a017474064
commit
263317e3c4
|
@ -17,6 +17,8 @@
|
|||
import { statusCodeOptions } from '@/components/pure/ms-advance-filter/index';
|
||||
import paramsTable, { type ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
|
||||
|
||||
import { responseHeaderOption } from '@/config/apiTest';
|
||||
|
||||
import type { ExecuteAssertionItem } from '@/models/apiTest/common';
|
||||
|
||||
interface Param {
|
||||
|
@ -41,21 +43,6 @@
|
|||
enable: true,
|
||||
};
|
||||
|
||||
const responseHeaderOption = [
|
||||
{ label: 'Accept', value: 'accept' },
|
||||
{ label: 'Accept-Encoding', value: 'acceptEncoding' },
|
||||
{ label: 'Accept-Language', value: 'acceptLanguage' },
|
||||
{ label: 'Cache-Control', value: 'cacheControl' },
|
||||
{ label: 'Content-Type', value: 'contentType' },
|
||||
{ label: 'Content-Length', value: 'contentLength' },
|
||||
{ label: 'User-Agent', value: 'userAgent' },
|
||||
{ label: 'Referer', value: 'referer' },
|
||||
{ label: 'Cookie', value: 'cookie' },
|
||||
{ label: 'Authorization', value: 'authorization' },
|
||||
{ label: 'If-None-Match', value: 'ifNoneMatch' },
|
||||
{ label: 'If-Modified-Since', value: 'ifModifiedSince' },
|
||||
];
|
||||
|
||||
const columns: ParamTableColumn[] = [
|
||||
{
|
||||
title: 'ms.assertion.responseHeader', // 响应头
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
import { statusCodeOptions } from '@/components/pure/ms-advance-filter/index';
|
||||
import paramsTable, { type ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
|
||||
|
||||
import { responseHeaderOption } from '@/config/apiTest';
|
||||
|
||||
interface Param {
|
||||
[key: string]: any;
|
||||
variableAssertionItems: any[];
|
||||
|
@ -37,21 +39,6 @@
|
|||
enable: true,
|
||||
};
|
||||
|
||||
const responseHeaderOption = [
|
||||
{ label: 'Accept', value: 'accept' },
|
||||
{ label: 'Accept-Encoding', value: 'acceptEncoding' },
|
||||
{ label: 'Accept-Language', value: 'acceptLanguage' },
|
||||
{ label: 'Cache-Control', value: 'cacheControl' },
|
||||
{ label: 'Content-Type', value: 'contentType' },
|
||||
{ label: 'Content-Length', value: 'contentLength' },
|
||||
{ label: 'User-Agent', value: 'userAgent' },
|
||||
{ label: 'Referer', value: 'referer' },
|
||||
{ label: 'Cookie', value: 'cookie' },
|
||||
{ label: 'Authorization', value: 'authorization' },
|
||||
{ label: 'If-None-Match', value: 'ifNoneMatch' },
|
||||
{ label: 'If-Modified-Since', value: 'ifModifiedSince' },
|
||||
];
|
||||
|
||||
const columns: ParamTableColumn[] = [
|
||||
{
|
||||
title: 'ms.assertion.variableName', // 变量名
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<a-breadcrumb v-if="appStore.breadcrumbList.length > 0" class="z-10 mb-[-8px] mt-[8px]">
|
||||
<a-breadcrumb v-if="appStore.breadcrumbList.length > 0" class="z-10 mb-[-8px]">
|
||||
<a-breadcrumb-item v-for="crumb of appStore.breadcrumbList" :key="crumb.name" @click="jumpTo(crumb)">
|
||||
{{ isEdit ? t(crumb.editLocale || crumb.locale) : t(crumb.locale) }}
|
||||
</a-breadcrumb-item>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
props.autoHeight ? '' : 'min-h-[500px]',
|
||||
props.noContentPadding ? 'ms-card--noContentPadding' : 'p-[24px]',
|
||||
props.noBottomRadius ? 'ms-card--noBottomRadius' : '',
|
||||
!props.hideFooter && !props.simple ? 'pb-[80px]' : '',
|
||||
]"
|
||||
>
|
||||
<a-scrollbar v-if="!props.simple" :style="{ overflow: 'auto' }">
|
||||
|
@ -149,9 +150,9 @@
|
|||
}
|
||||
if (props.simple) {
|
||||
// 简单模式没有标题、没有底部
|
||||
return props.noContentPadding ? 76 + _specialHeight : 124 + _specialHeight;
|
||||
return props.noContentPadding ? 66 + _specialHeight : 114 + _specialHeight;
|
||||
}
|
||||
return 190 + _specialHeight;
|
||||
return 250 + _specialHeight;
|
||||
});
|
||||
|
||||
const getComputedContentStyle = computed(() => {
|
||||
|
|
|
@ -88,6 +88,30 @@
|
|||
v-model:model-value="record[item.dataIndex as string]"
|
||||
@change="() => handleFormChange(record, rowIndex, item)"
|
||||
/>
|
||||
<template v-else-if="item.inputType === 'autoComplete'">
|
||||
<a-auto-complete
|
||||
v-model:model-value="record[item.dataIndex as string]"
|
||||
:data="item.autoCompleteParams?.filter((e) => e.isShow === true)"
|
||||
class="ms-form-table-input"
|
||||
:trigger-props="{ contentClass: 'ms-form-table-input-trigger' }"
|
||||
:filter-option="false"
|
||||
size="small"
|
||||
@search="(val) => handleSearchParams(val, item)"
|
||||
@change="() => handleFormChange(record, rowIndex, item)"
|
||||
@select="(val) => selectAutoComplete(val, record, item)"
|
||||
>
|
||||
<template #option="{ data: opt }">
|
||||
<div class="w-[350px]">
|
||||
{{ opt.raw.value }}
|
||||
<a-tooltip :content="t(opt.raw.desc)" position="bl" :mouse-enter-delay="300">
|
||||
<div class="one-line-text max-w-full text-[12px] leading-[16px] text-[var(--color-text-4)]">
|
||||
{{ t(opt.raw.desc) }}
|
||||
</div>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</a-auto-complete>
|
||||
</template>
|
||||
<template v-else-if="item.inputType === 'text'">
|
||||
{{
|
||||
typeof item.valueFormat === 'function' ? item.valueFormat(record) : record[item.dataIndex as string] || '-'
|
||||
|
@ -122,7 +146,6 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { TableColumnData, TableData } from '@arco-design/web-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
|
@ -140,12 +163,14 @@
|
|||
import { SelectAllEnum, TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
import { ActionsItem } from '../ms-table-more-action/types';
|
||||
import type { SelectOptionData, TableColumnData, TableData } from '@arco-design/web-vue';
|
||||
import { TableOperationColumn } from '@arco-design/web-vue/es/table/interface';
|
||||
|
||||
export interface FormTableColumn extends MsTableColumnData {
|
||||
enable?: boolean; // 是否启用
|
||||
required?: boolean; // 是否必填
|
||||
inputType?: 'input' | 'select' | 'tags' | 'switch' | 'text' | 'checkbox'; // 输入组件类型
|
||||
inputType?: 'input' | 'select' | 'tags' | 'switch' | 'text' | 'checkbox' | 'autoComplete'; // 输入组件类型
|
||||
autoCompleteParams?: SelectOptionData[]; // 自动补全参数
|
||||
valueFormat?: (record: Record<string, any>) => string; // 展示值格式化,仅在inputType为text时生效
|
||||
[key: string]: any; // 扩展属性
|
||||
}
|
||||
|
@ -330,6 +355,21 @@
|
|||
emitChange('deleteParam');
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索变量
|
||||
* @param val 变量名
|
||||
*/
|
||||
function handleSearchParams(val: string, item: FormTableColumn) {
|
||||
item.autoCompleteParams = item.autoCompleteParams?.map((e) => {
|
||||
e.isShow = e.label?.includes(val);
|
||||
return e;
|
||||
});
|
||||
}
|
||||
|
||||
function selectAutoComplete(val: string, record: Record<string, any>, item: FormTableColumn) {
|
||||
record[item.dataIndex as string] = val;
|
||||
}
|
||||
|
||||
await initColumns();
|
||||
</script>
|
||||
|
||||
|
@ -381,6 +421,16 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
:deep(.ms-form-table-input-trigger) {
|
||||
width: 350px;
|
||||
.arco-select-dropdown-list {
|
||||
.arco-select-option {
|
||||
@apply !h-auto;
|
||||
|
||||
padding: 2px 8px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.ms-form-table-input-number) {
|
||||
@apply bg-transparent pr-0;
|
||||
.arco-input {
|
||||
|
|
|
@ -23,3 +23,18 @@ export const requestBodyTypeMap = {
|
|||
[RequestBodyFormat.XML]: 'xml',
|
||||
[RequestBodyFormat.NONE]: 'none',
|
||||
};
|
||||
// 请求/响应头选项
|
||||
export const responseHeaderOption = [
|
||||
{ label: 'Accept', value: 'accept' },
|
||||
{ label: 'Accept-Encoding', value: 'acceptEncoding' },
|
||||
{ label: 'Accept-Language', value: 'acceptLanguage' },
|
||||
{ label: 'Cache-Control', value: 'cacheControl' },
|
||||
{ label: 'Content-Type', value: 'contentType' },
|
||||
{ label: 'Content-Length', value: 'contentLength' },
|
||||
{ label: 'User-Agent', value: 'userAgent' },
|
||||
{ label: 'Referer', value: 'referer' },
|
||||
{ label: 'Cookie', value: 'cookie' },
|
||||
{ label: 'Authorization', value: 'authorization' },
|
||||
{ label: 'If-None-Match', value: 'ifNoneMatch' },
|
||||
{ label: 'If-Modified-Since', value: 'ifModifiedSince' },
|
||||
];
|
||||
|
|
|
@ -41,12 +41,7 @@
|
|||
</a-drawer>
|
||||
<a-layout class="layout-content" :style="paddingStyle">
|
||||
<a-spin :loading="appStore.loading" :tip="appStore.loadingTip">
|
||||
<a-scrollbar
|
||||
:style="{
|
||||
overflow: 'auto',
|
||||
height: 'calc(100vh - 64px)',
|
||||
}"
|
||||
>
|
||||
<a-scrollbar class="flex h-[calc(100vh-56px)] flex-col gap-[8px] overflow-auto">
|
||||
<MsBreadCrumb />
|
||||
<a-layout-content>
|
||||
<slot name="page">
|
||||
|
@ -211,7 +206,6 @@
|
|||
transition: padding 0.2s cubic-bezier(0.34, 0.69, 0.1, 1);
|
||||
.arco-layout-content {
|
||||
padding: 8px 16px 0 0;
|
||||
min-height: 500px;
|
||||
}
|
||||
}
|
||||
.arco-layout-sider-light {
|
||||
|
|
|
@ -17,4 +17,10 @@
|
|||
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
<style lang="less" scoped>
|
||||
.page-content {
|
||||
@apply h-full overflow-y-auto;
|
||||
|
||||
min-height: 500px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -39,7 +39,7 @@ const ApiTest: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/api-test/management/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.apiTest.management',
|
||||
roles: ['*'],
|
||||
roles: ['PROJECT_API_DEFINITION:READ'],
|
||||
isTopMenu: true,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import {
|
||||
EnableKeyValueParam,
|
||||
ExecuteBody,
|
||||
ExecuteRequestCommonParam,
|
||||
ExecuteRequestFormBodyFormValue,
|
||||
KeyValueParam,
|
||||
RequestTaskResult,
|
||||
ResponseDefinition,
|
||||
} from '@/models/apiTest/common';
|
||||
import {
|
||||
RequestBodyFormat,
|
||||
RequestCaseStatus,
|
||||
RequestContentTypeEnum,
|
||||
RequestParamsType,
|
||||
|
@ -81,6 +84,54 @@ export const defaultResponseItem: ResponseDefinition = {
|
|||
},
|
||||
};
|
||||
|
||||
// 请求的默认 body 参数
|
||||
export const defaultBodyParams: ExecuteBody = {
|
||||
bodyType: RequestBodyFormat.NONE,
|
||||
formDataBody: {
|
||||
formValues: [],
|
||||
},
|
||||
wwwFormBody: {
|
||||
formValues: [],
|
||||
},
|
||||
jsonBody: {
|
||||
jsonValue: '',
|
||||
},
|
||||
xmlBody: { value: '' },
|
||||
binaryBody: {
|
||||
description: '',
|
||||
file: undefined,
|
||||
},
|
||||
rawBody: { value: '' },
|
||||
};
|
||||
|
||||
// 默认的响应内容结构
|
||||
export const defaultResponse: RequestTaskResult = {
|
||||
requestResults: [
|
||||
{
|
||||
body: '',
|
||||
headers: '',
|
||||
method: '',
|
||||
url: '',
|
||||
responseResult: {
|
||||
body: '',
|
||||
contentType: '',
|
||||
headers: '',
|
||||
dnsLookupTime: 0,
|
||||
downloadTime: 0,
|
||||
latency: 0,
|
||||
responseCode: 0,
|
||||
responseTime: 0,
|
||||
responseSize: 0,
|
||||
socketInitTime: 0,
|
||||
tcpHandshakeTime: 0,
|
||||
transferStartTime: 0,
|
||||
sslHandshakeTime: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
console: '',
|
||||
};
|
||||
|
||||
// 默认提取参数的 key-value 表格行的值
|
||||
export const defaultKeyValueParamItem: KeyValueParam = {
|
||||
key: '',
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<!-- 表格列 slot -->
|
||||
<!-- 参数名 or 请求/响应头联想输入 -->
|
||||
<template #key="{ record, columnConfig, rowIndex }">
|
||||
<a-popover
|
||||
position="tl"
|
||||
|
@ -69,7 +70,31 @@
|
|||
{{ record[columnConfig.dataIndex as string] }}
|
||||
</div>
|
||||
</template>
|
||||
<a-auto-complete
|
||||
v-if="columnConfig.inputType === 'autoComplete'"
|
||||
v-model:model-value="record[columnConfig.dataIndex as string]"
|
||||
:data="columnConfig.autoCompleteParams?.filter((e) => e.isShow === true)"
|
||||
class="ms-form-table-input"
|
||||
:trigger-props="{ contentClass: 'ms-form-table-input-trigger' }"
|
||||
:filter-option="false"
|
||||
size="mini"
|
||||
@search="(val) => handleSearchParams(val, columnConfig)"
|
||||
@change="() => addTableLine(rowIndex, columnConfig.addLineDisabled)"
|
||||
@select="(val) => selectAutoComplete(val, record, columnConfig)"
|
||||
>
|
||||
<template #option="{ data: opt }">
|
||||
<div class="w-[350px]">
|
||||
{{ t(opt.raw.label) }}
|
||||
<!-- <a-tooltip :content="t(opt.raw.label)" position="bl" :mouse-enter-delay="300">
|
||||
<div class="one-line-text max-w-full">
|
||||
{{ t(opt.raw.label) }}
|
||||
</div>
|
||||
</a-tooltip> -->
|
||||
</div>
|
||||
</template>
|
||||
</a-auto-complete>
|
||||
<a-input
|
||||
v-else
|
||||
v-model:model-value="record[columnConfig.dataIndex as string]"
|
||||
:placeholder="t('apiTestDebug.paramNamePlaceholder')"
|
||||
class="ms-form-table-input"
|
||||
|
@ -79,6 +104,7 @@
|
|||
/>
|
||||
</a-popover>
|
||||
</template>
|
||||
<!-- 参数类型 -->
|
||||
<template #paramType="{ record, columnConfig, rowIndex }">
|
||||
<a-tooltip
|
||||
v-if="columnConfig.hasRequired"
|
||||
|
@ -104,6 +130,7 @@
|
|||
@change="(val) => handleTypeChange(val, record, rowIndex, columnConfig.addLineDisabled)"
|
||||
/>
|
||||
</template>
|
||||
<!-- 提取类型 -->
|
||||
<template #extractType="{ record, columnConfig, rowIndex }">
|
||||
<a-select
|
||||
v-model:model-value="record.extractType"
|
||||
|
@ -113,6 +140,7 @@
|
|||
@change="() => addTableLine(rowIndex)"
|
||||
/>
|
||||
</template>
|
||||
<!-- 变量类型 -->
|
||||
<template #variableType="{ record, columnConfig, rowIndex }">
|
||||
<a-select
|
||||
v-model:model-value="record.variableType"
|
||||
|
@ -122,6 +150,7 @@
|
|||
@change="() => addTableLine(rowIndex)"
|
||||
/>
|
||||
</template>
|
||||
<!-- 提取范围 -->
|
||||
<template #extractScope="{ record, columnConfig, rowIndex }">
|
||||
<a-select
|
||||
v-model:model-value="record.extractScope"
|
||||
|
@ -131,9 +160,11 @@
|
|||
@change="() => addTableLine(rowIndex)"
|
||||
/>
|
||||
</template>
|
||||
<!-- 表达式 -->
|
||||
<template #expression="{ record, rowIndex, columnConfig }">
|
||||
<slot name="expression" :record="record" :row-index="rowIndex" :column-config="columnConfig"></slot>
|
||||
</template>
|
||||
<!-- 参数值 -->
|
||||
<template #value="{ record, columnConfig, rowIndex }">
|
||||
<a-popover
|
||||
v-if="columnConfig.isNormal"
|
||||
|
@ -185,6 +216,7 @@
|
|||
@apply="() => addTableLine(rowIndex)"
|
||||
/>
|
||||
</template>
|
||||
<!-- 长度范围 -->
|
||||
<template #lengthRange="{ record, rowIndex }">
|
||||
<div class="flex items-center justify-between">
|
||||
<a-input-number
|
||||
|
@ -208,6 +240,7 @@
|
|||
/>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 标签 -->
|
||||
<template #tag="{ record, columnConfig, rowIndex }">
|
||||
<a-popover
|
||||
position="tl"
|
||||
|
@ -232,6 +265,7 @@
|
|||
/>
|
||||
</a-popover>
|
||||
</template>
|
||||
<!-- 描述 -->
|
||||
<template #description="{ record, columnConfig, rowIndex }">
|
||||
<paramDescInput
|
||||
v-model:desc="record[columnConfig.dataIndex as string]"
|
||||
|
@ -241,6 +275,7 @@
|
|||
@change="handleDescChange"
|
||||
/>
|
||||
</template>
|
||||
<!-- 编码 -->
|
||||
<template #encode="{ record, rowIndex }">
|
||||
<a-switch
|
||||
v-model:model-value="record.encode"
|
||||
|
@ -250,12 +285,14 @@
|
|||
@change="() => addTableLine(rowIndex)"
|
||||
/>
|
||||
</template>
|
||||
<!-- 必须包含 -->
|
||||
<template #mustContain="{ record, columnConfig }">
|
||||
<a-checkbox
|
||||
v-model:model-value="record[columnConfig.dataIndex as string]"
|
||||
@change="handleMustContainColChange(false)"
|
||||
/>
|
||||
</template>
|
||||
<!-- 类型检查 -->
|
||||
<template #typeChecking="{ record, columnConfig }">
|
||||
<a-checkbox
|
||||
v-model:model-value="record[columnConfig.dataIndex as string]"
|
||||
|
@ -296,6 +333,7 @@
|
|||
</a-tooltip>
|
||||
<a-input v-model="record.expectedValue" size="mini" class="ms-form-table-input" />
|
||||
</template>
|
||||
<!-- 项目选择 -->
|
||||
<template #project="{ record, rowIndex }">
|
||||
<a-select
|
||||
v-model:model-value="record.projectId"
|
||||
|
@ -320,6 +358,7 @@
|
|||
</a-tooltip>
|
||||
</a-select>
|
||||
</template>
|
||||
<!-- 环境选择 -->
|
||||
<template #environment="{ record }">
|
||||
<MsSelect
|
||||
v-if="record.projectId"
|
||||
|
@ -340,6 +379,7 @@
|
|||
/>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
<!-- 域名 -->
|
||||
<template #host="{ record }">
|
||||
<MsTagsGroup
|
||||
v-if="Array.isArray(record.domain)"
|
||||
|
@ -349,6 +389,7 @@
|
|||
/>
|
||||
<div v-else class="text-[var(--color-text-1)]">{{ '-' }}</div>
|
||||
</template>
|
||||
<!-- 操作 -->
|
||||
<template #operation="{ record, rowIndex, columnConfig }">
|
||||
<div class="flex flex-row items-center" :class="{ 'justify-end': columnConfig.align === 'right' }">
|
||||
<a-switch
|
||||
|
@ -482,6 +523,7 @@
|
|||
const MsParamsInput = defineAsyncComponent(() => import('@/components/business/ms-params-input/index.vue'));
|
||||
|
||||
export interface ParamTableColumn extends FormTableColumn {
|
||||
isAutoComplete?: boolean; // 用于 key 列区分是否是请求/响应头联想输入
|
||||
isNormal?: boolean; // 用于 value 列区分是普通输入框还是 MsParamsInput
|
||||
hasRequired?: boolean; // 用于 type 列区分是否有 required 星号
|
||||
typeOptions?: { label: string; value: string }[]; // 用于 type 列选择器选项
|
||||
|
@ -923,6 +965,21 @@
|
|||
emitChange('handleFormTableChange');
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索变量
|
||||
* @param val 变量名
|
||||
*/
|
||||
function handleSearchParams(val: string, item: FormTableColumn) {
|
||||
item.autoCompleteParams = item.autoCompleteParams?.map((e) => {
|
||||
e.isShow = (e.label || '').includes(val);
|
||||
return e;
|
||||
});
|
||||
}
|
||||
|
||||
function selectAutoComplete(val: string, record: Record<string, any>, item: FormTableColumn) {
|
||||
record[item.dataIndex as string] = val;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
addTableLine,
|
||||
});
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
import batchAddKeyVal from '@/views/api-test/components/batchAddKeyVal.vue';
|
||||
import paramTable, { ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
|
||||
|
||||
import { responseHeaderOption } from '@/config/apiTest';
|
||||
|
||||
import { EnableKeyValueParam } from '@/models/apiTest/common';
|
||||
|
||||
import { filterKeyValParams } from '../utils';
|
||||
|
@ -47,6 +49,8 @@
|
|||
title: 'apiTestDebug.paramName',
|
||||
dataIndex: 'key',
|
||||
slotName: 'key',
|
||||
inputType: 'autoComplete',
|
||||
autoCompleteParams: responseHeaderOption,
|
||||
},
|
||||
{
|
||||
title: 'apiTestDebug.paramValue',
|
||||
|
|
|
@ -143,10 +143,10 @@
|
|||
v-model:active-key="requestVModel.activeTab"
|
||||
:content-tab-list="contentTabList"
|
||||
:get-text-func="getTabBadge"
|
||||
class="no-content relative mt-[8px]"
|
||||
class="no-content relative mt-[8px] border-b"
|
||||
/>
|
||||
</div>
|
||||
<div ref="splitContainerRef" class="h-[calc(100%-97px)]">
|
||||
<div ref="splitContainerRef" class="h-[calc(100%-87px)]">
|
||||
<MsSplitBox
|
||||
ref="horizontalSplitBoxRef"
|
||||
:size="props.isDefinition ? 0.7 : 1"
|
||||
|
@ -166,7 +166,7 @@
|
|||
min="10px"
|
||||
:direction="activeLayout"
|
||||
second-container-class="!overflow-y-hidden"
|
||||
:class="!showResponse ? 'hidden-second' : ''"
|
||||
:class="!showResponse ? 'hidden-second' : 'show-second'"
|
||||
@expand-change="handleVerticalExpandChange"
|
||||
>
|
||||
<template #first>
|
||||
|
@ -545,6 +545,7 @@
|
|||
defaultHeaderParamsItem,
|
||||
defaultKeyValueParamItem,
|
||||
defaultRequestParamsItem,
|
||||
defaultResponse,
|
||||
} from '@/views/api-test/components/config';
|
||||
import { filterKeyValParams, parseRequestBodyFiles } from '@/views/api-test/components/utils';
|
||||
import type { Api } from '@form-create/arco-design';
|
||||
|
@ -876,22 +877,16 @@
|
|||
function handleUrlChange(val: string) {
|
||||
const params = parseQueryParams(val.trim());
|
||||
if (params.length > 0) {
|
||||
requestVModel.value.query.splice(
|
||||
0,
|
||||
requestVModel.value.query.length - 2,
|
||||
requestVModel.value.query = [
|
||||
...params.map((e, i) => ({
|
||||
id: (new Date().getTime() + i).toString(),
|
||||
paramType: RequestParamsType.STRING,
|
||||
description: '',
|
||||
required: false,
|
||||
maxLength: undefined,
|
||||
minLength: undefined,
|
||||
encode: false,
|
||||
enable: true,
|
||||
...defaultRequestParamsItem,
|
||||
...e,
|
||||
}))
|
||||
);
|
||||
})),
|
||||
cloneDeep(defaultRequestParamsItem),
|
||||
];
|
||||
requestVModel.value.activeTab = RequestComposition.QUERY;
|
||||
[requestVModel.value.url] = val.split('?');
|
||||
}
|
||||
handleActiveDebugChange();
|
||||
}
|
||||
|
@ -1151,6 +1146,7 @@
|
|||
if (isHttpProtocol.value) {
|
||||
try {
|
||||
requestVModel.value.executeLoading = true;
|
||||
requestVModel.value.response = cloneDeep(defaultResponse);
|
||||
const res = await props.executeApi(makeRequestParams(executeType));
|
||||
if (executeType === 'localExec') {
|
||||
await props.localExecuteApi(localExecuteUrl.value, res);
|
||||
|
@ -1166,6 +1162,7 @@
|
|||
if (valid === true) {
|
||||
try {
|
||||
requestVModel.value.executeLoading = true;
|
||||
requestVModel.value.response = cloneDeep(defaultResponse);
|
||||
const res = await props.executeApi(makeRequestParams(executeType));
|
||||
if (executeType === 'localExec') {
|
||||
await props.localExecuteApi(localExecuteUrl.value, res);
|
||||
|
@ -1518,4 +1515,9 @@
|
|||
@apply hidden;
|
||||
}
|
||||
}
|
||||
.show-second {
|
||||
:deep(.arco-split-trigger) {
|
||||
@apply block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -178,6 +178,7 @@
|
|||
import paramTable, { ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
|
||||
import popConfirm from '@/views/api-test/components/popConfirm.vue';
|
||||
|
||||
import { responseHeaderOption } from '@/config/apiTest';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
||||
|
@ -397,7 +398,8 @@
|
|||
title: 'apiTestManagement.paramName',
|
||||
dataIndex: 'key',
|
||||
slotName: 'key',
|
||||
inputType: 'input',
|
||||
inputType: 'autoComplete',
|
||||
autoCompleteParams: responseHeaderOption,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.paramVal',
|
||||
|
|
|
@ -133,6 +133,7 @@
|
|||
ResponseComposition,
|
||||
} from '@/enums/apiEnum';
|
||||
|
||||
import { defaultBodyParams, defaultResponse } from '../components/config';
|
||||
import { parseRequestBodyFiles } from '../components/utils';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
@ -150,50 +151,6 @@
|
|||
}
|
||||
|
||||
const initDefaultId = `debug-${Date.now()}`;
|
||||
const defaultBodyParams: ExecuteBody = {
|
||||
bodyType: RequestBodyFormat.NONE,
|
||||
formDataBody: {
|
||||
formValues: [],
|
||||
},
|
||||
wwwFormBody: {
|
||||
formValues: [],
|
||||
},
|
||||
jsonBody: {
|
||||
jsonValue: '',
|
||||
},
|
||||
xmlBody: { value: '' },
|
||||
binaryBody: {
|
||||
description: '',
|
||||
file: undefined,
|
||||
},
|
||||
rawBody: { value: '' },
|
||||
};
|
||||
const defaultResponse: RequestTaskResult = {
|
||||
requestResults: [
|
||||
{
|
||||
body: '',
|
||||
headers: '',
|
||||
url: '',
|
||||
method: '',
|
||||
responseResult: {
|
||||
body: '',
|
||||
contentType: '',
|
||||
headers: '',
|
||||
dnsLookupTime: 0,
|
||||
downloadTime: 0,
|
||||
latency: 0,
|
||||
responseCode: 0,
|
||||
responseTime: 0,
|
||||
responseSize: 0,
|
||||
socketInitTime: 0,
|
||||
sslHandshakeTime: 0,
|
||||
tcpHandshakeTime: 0,
|
||||
transferStartTime: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
console: '',
|
||||
}; // 调试返回的响应内容
|
||||
const defaultDebugParams: RequestParam = {
|
||||
id: initDefaultId,
|
||||
moduleId: 'root',
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
ResponseComposition,
|
||||
} from '@/enums/apiEnum';
|
||||
|
||||
import { defaultResponseItem } from '@/views/api-test/components/config';
|
||||
import { defaultBodyParams, defaultResponse, defaultResponseItem } from '@/views/api-test/components/config';
|
||||
import type { RequestParam } from '@/views/api-test/components/requestComposition/index.vue';
|
||||
import { parseRequestBodyFiles } from '@/views/api-test/components/utils';
|
||||
// 懒加载requestComposition组件
|
||||
|
@ -138,51 +138,6 @@
|
|||
});
|
||||
|
||||
const initDefaultId = `definition-${Date.now()}`;
|
||||
const defaultBodyParams: ExecuteBody = {
|
||||
bodyType: RequestBodyFormat.NONE,
|
||||
formDataBody: {
|
||||
formValues: [],
|
||||
},
|
||||
wwwFormBody: {
|
||||
formValues: [],
|
||||
},
|
||||
jsonBody: {
|
||||
jsonValue: '',
|
||||
},
|
||||
xmlBody: { value: '' },
|
||||
binaryBody: {
|
||||
description: '',
|
||||
file: undefined,
|
||||
},
|
||||
rawBody: { value: '' },
|
||||
};
|
||||
// 调试返回的响应内容
|
||||
const defaultResponse: RequestTaskResult = {
|
||||
requestResults: [
|
||||
{
|
||||
body: '',
|
||||
headers: '',
|
||||
method: '',
|
||||
url: '',
|
||||
responseResult: {
|
||||
body: '',
|
||||
contentType: '',
|
||||
headers: '',
|
||||
dnsLookupTime: 0,
|
||||
downloadTime: 0,
|
||||
latency: 0,
|
||||
responseCode: 0,
|
||||
responseTime: 0,
|
||||
responseSize: 0,
|
||||
socketInitTime: 0,
|
||||
tcpHandshakeTime: 0,
|
||||
transferStartTime: 0,
|
||||
sslHandshakeTime: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
console: '',
|
||||
};
|
||||
const defaultDefinitionParams: RequestParam = {
|
||||
id: initDefaultId,
|
||||
moduleId: props.activeModule === 'all' ? 'root' : props.activeModule,
|
||||
|
|
|
@ -313,10 +313,10 @@
|
|||
label: 'apiTestManagement.share',
|
||||
eventTag: 'share',
|
||||
},
|
||||
{
|
||||
label: 'apiTestManagement.shareModule',
|
||||
eventTag: 'shareModule',
|
||||
},
|
||||
// {
|
||||
// label: 'apiTestManagement.shareModule',
|
||||
// eventTag: 'shareModule',
|
||||
// }, // TODO:第一版没有文档,不需要分享模块
|
||||
{
|
||||
isDivider: true,
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue