feat(接口测试): Mock调整
This commit is contained in:
parent
b5bb1805df
commit
0f14d934bb
|
@ -394,17 +394,18 @@
|
||||||
class={['flex w-full items-center justify-between', collapsed.value ? 'h-[56px] w-[56px]' : '']}
|
class={['flex w-full items-center justify-between', collapsed.value ? 'h-[56px] w-[56px]' : '']}
|
||||||
key="personalInfo"
|
key="personalInfo"
|
||||||
>
|
>
|
||||||
{collapsed.value ? (
|
{
|
||||||
<div class="relative flex h-full items-center justify-center hover:!bg-transparent">
|
<div
|
||||||
<MsAvatar avatar={userStore.avatar} size={30} class="hover:!bg-transparent" />
|
class={[
|
||||||
|
collapsed.value
|
||||||
|
? 'relative flex h-full items-center justify-center hover:!bg-transparent'
|
||||||
|
: 'relative flex items-center gap-[8px] hover:!bg-transparent',
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<MsAvatar is-user size={20} class="!mr-0 hover:!bg-transparent" />
|
||||||
|
{collapsed.value ? null : userStore.name}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
}
|
||||||
<div class="relative flex items-center gap-[8px] hover:!bg-transparent">
|
|
||||||
<MsAvatar avatar={userStore.avatar} size={20} />
|
|
||||||
{userStore.name}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{collapsed.value ? null : <icon-caret-down class="!m-0" />}
|
{collapsed.value ? null : <icon-caret-down class="!m-0" />}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
</a-trigger>
|
</a-trigger>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<MsIcon
|
<MsIcon
|
||||||
v-if="props.avatar === 'default' || props.avatar === null"
|
v-if="innerAvatar === 'default' || innerAvatar === null"
|
||||||
type="icon-icon_that_person"
|
type="icon-icon_that_person"
|
||||||
:size="props.size"
|
:size="props.size"
|
||||||
class="text-[var(--color-text-4)]"
|
class="text-[var(--color-text-4)]"
|
||||||
|
@ -9,13 +9,13 @@
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<a-avatar
|
<a-avatar
|
||||||
v-else-if="props.avatar === 'word'"
|
v-else-if="innerAvatar === 'word'"
|
||||||
:size="props.size"
|
:size="props.size"
|
||||||
class="bg-[rgb(var(--primary-1))] text-[rgb(var(--primary-6))]"
|
class="bg-[rgb(var(--primary-1))] text-[rgb(var(--primary-6))]"
|
||||||
>
|
>
|
||||||
<slot>{{ props.word?.substring(0, 4) || userStore.name?.substring(0, 4) }}</slot>
|
<slot>{{ props.word?.substring(0, 4) || userStore.name?.substring(0, 4) }}</slot>
|
||||||
</a-avatar>
|
</a-avatar>
|
||||||
<a-avatar v-else :image-url="avatar" :size="props.size"></a-avatar>
|
<a-avatar v-else :image-url="innerAvatar" :size="props.size"></a-avatar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
@ -30,12 +30,23 @@
|
||||||
avatar?: 'default' | 'word' | string;
|
avatar?: 'default' | 'word' | string;
|
||||||
size?: number;
|
size?: number;
|
||||||
word?: string; // 用于显示文字头像
|
word?: string; // 用于显示文字头像
|
||||||
|
isUser?: boolean; // 是否是登录用户头像
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
avatar: 'default',
|
avatar: 'default',
|
||||||
size: 40,
|
size: 40,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const innerAvatar = ref(props.avatar);
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
if (props.isUser) {
|
||||||
|
innerAvatar.value = userStore.avatar || 'default';
|
||||||
|
} else {
|
||||||
|
innerAvatar.value = props.avatar;
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
<style lang="less" scoped></style>
|
||||||
|
|
|
@ -35,6 +35,7 @@ export interface MockResponse {
|
||||||
useApiResponse: boolean;
|
useApiResponse: boolean;
|
||||||
apiResponseId?: string; // useApiResponse 为 true 时必填
|
apiResponseId?: string; // useApiResponse 为 true 时必填
|
||||||
body: ResponseDefinitionBody;
|
body: ResponseDefinitionBody;
|
||||||
|
delay: number;
|
||||||
}
|
}
|
||||||
// mock 信息-请求通用匹配规则
|
// mock 信息-请求通用匹配规则
|
||||||
export interface MockMatchRuleCommon {
|
export interface MockMatchRuleCommon {
|
||||||
|
|
|
@ -342,6 +342,7 @@ export const mockDefaultParams: MockParams = {
|
||||||
sendAsBody: false,
|
sendAsBody: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
delay: 0,
|
||||||
},
|
},
|
||||||
apiDefinitionId: '',
|
apiDefinitionId: '',
|
||||||
uploadFileIds: [],
|
uploadFileIds: [],
|
||||||
|
|
|
@ -112,6 +112,9 @@
|
||||||
</a-select>
|
</a-select>
|
||||||
<apiMethodName v-else :method="record.method" is-tag />
|
<apiMethodName v-else :method="record.method" is-tag />
|
||||||
</template>
|
</template>
|
||||||
|
<template #caseTotal="{ record }">
|
||||||
|
{{ record.caseTotal }}
|
||||||
|
</template>
|
||||||
<template #status="{ record }">
|
<template #status="{ record }">
|
||||||
<a-select
|
<a-select
|
||||||
v-if="hasAnyPermission(['PROJECT_API_DEFINITION:READ+UPDATE'])"
|
v-if="hasAnyPermission(['PROJECT_API_DEFINITION:READ+UPDATE'])"
|
||||||
|
@ -449,6 +452,21 @@
|
||||||
width: 200,
|
width: 200,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'apiTestManagement.belongModule',
|
||||||
|
dataIndex: 'moduleName',
|
||||||
|
showTooltip: true,
|
||||||
|
width: 200,
|
||||||
|
showDrag: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'apiTestManagement.caseTotal',
|
||||||
|
dataIndex: 'caseTotal',
|
||||||
|
showTooltip: true,
|
||||||
|
width: 100,
|
||||||
|
showDrag: true,
|
||||||
|
slotName: 'caseTotal',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'common.tag',
|
title: 'common.tag',
|
||||||
dataIndex: 'tags',
|
dataIndex: 'tags',
|
||||||
|
|
|
@ -339,6 +339,12 @@
|
||||||
const preActiveApiTabId = activeApiTab.value.id;
|
const preActiveApiTabId = activeApiTab.value.id;
|
||||||
let loadedApiTab = apiTabs.value[isLoadedTabIndex] as RequestParam;
|
let loadedApiTab = apiTabs.value[isLoadedTabIndex] as RequestParam;
|
||||||
if (isDebugMock) {
|
if (isDebugMock) {
|
||||||
|
const mockEnvId = appStore.envList.find((e) => e.mock)?.id;
|
||||||
|
if (mockEnvId) {
|
||||||
|
appStore.showLoading();
|
||||||
|
await appStore.setEnvConfig(mockEnvId);
|
||||||
|
appStore.hideLoading();
|
||||||
|
}
|
||||||
loadedApiTab = {
|
loadedApiTab = {
|
||||||
...loadedApiTab,
|
...loadedApiTab,
|
||||||
...(apiInfo as ApiDefinitionDetail).request,
|
...(apiInfo as ApiDefinitionDetail).request,
|
||||||
|
@ -372,6 +378,10 @@
|
||||||
}
|
}
|
||||||
let { request } = res;
|
let { request } = res;
|
||||||
if (isDebugMock) {
|
if (isDebugMock) {
|
||||||
|
const mockEnvId = appStore.envList.find((e) => e.mock)?.id;
|
||||||
|
if (mockEnvId) {
|
||||||
|
await appStore.setEnvConfig(mockEnvId);
|
||||||
|
}
|
||||||
request = {
|
request = {
|
||||||
...res.request,
|
...res.request,
|
||||||
...(apiInfo as ApiDefinitionDetail).request,
|
...(apiInfo as ApiDefinitionDetail).request,
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
:ok-loading="loading"
|
:ok-loading="loading"
|
||||||
no-content-padding
|
no-content-padding
|
||||||
unmount-on-close
|
unmount-on-close
|
||||||
|
@continue="() => handleSave(true)"
|
||||||
@confirm="handleSave"
|
@confirm="handleSave"
|
||||||
@cancel="handleCancel"
|
@cancel="handleCancel"
|
||||||
@close="handleCancel"
|
@close="handleCancel"
|
||||||
|
@ -227,7 +228,7 @@
|
||||||
|
|
||||||
import { ResponseDefinition } from '@/models/apiTest/common';
|
import { ResponseDefinition } from '@/models/apiTest/common';
|
||||||
import { MockParams } from '@/models/apiTest/mock';
|
import { MockParams } from '@/models/apiTest/mock';
|
||||||
import { RequestBodyFormat, RequestComposition } from '@/enums/apiEnum';
|
import { RequestBodyFormat, RequestComposition, RequestParamsType } from '@/enums/apiEnum';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
defaultHeaderParamsItem,
|
defaultHeaderParamsItem,
|
||||||
|
@ -499,7 +500,9 @@
|
||||||
// form-data 的匹配规则含有文件类型,特殊处理
|
// form-data 的匹配规则含有文件类型,特殊处理
|
||||||
const formDataMatch = res.mockMatchRule.body.formDataBody.matchRules.map((item) => {
|
const formDataMatch = res.mockMatchRule.body.formDataBody.matchRules.map((item) => {
|
||||||
const newParamType =
|
const newParamType =
|
||||||
currentBodyKeyOptions.value.find((e) => e.value === item.key)?.paramType || defaultMatchRuleItem.paramType;
|
currentBodyKeyOptions.value.find((e) => e.value === item.key)?.paramType || item.files
|
||||||
|
? RequestParamsType.FILE
|
||||||
|
: defaultMatchRuleItem.paramType;
|
||||||
item.paramType = newParamType;
|
item.paramType = newParamType;
|
||||||
item.files = item.files || [];
|
item.files = item.files || [];
|
||||||
return item;
|
return item;
|
||||||
|
@ -535,6 +538,15 @@
|
||||||
appendDefaultMatchRuleItem();
|
appendDefaultMatchRuleItem();
|
||||||
}
|
}
|
||||||
isEdit.value = !!props.isEditMode;
|
isEdit.value = !!props.isEditMode;
|
||||||
|
if (mockDetail.value.mockMatchRule.body.bodyType !== RequestBodyFormat.NONE) {
|
||||||
|
activeTab.value = RequestComposition.BODY;
|
||||||
|
} else if (mockDetail.value.mockMatchRule.header.matchRules.length > 0) {
|
||||||
|
activeTab.value = RequestComposition.HEADER;
|
||||||
|
} else if (mockDetail.value.mockMatchRule.query) {
|
||||||
|
activeTab.value = RequestComposition.QUERY;
|
||||||
|
} else if (mockDetail.value.mockMatchRule.rest) {
|
||||||
|
activeTab.value = RequestComposition.REST;
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
@ -612,7 +624,7 @@
|
||||||
handleCancel();
|
handleCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleSave() {
|
async function handleSave(isContinue = false) {
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const { body } = mockDetail.value.mockMatchRule;
|
const { body } = mockDetail.value.mockMatchRule;
|
||||||
|
@ -696,7 +708,11 @@
|
||||||
Message.success(t('common.createSuccess'));
|
Message.success(t('common.createSuccess'));
|
||||||
}
|
}
|
||||||
emit('addDone');
|
emit('addDone');
|
||||||
handleCancel();
|
if (isContinue) {
|
||||||
|
mockDetail.value = makeDefaultParams();
|
||||||
|
} else {
|
||||||
|
handleCancel();
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<a-form ref="formRef" :model="formModel" layout="vertical">
|
<a-form ref="formRef" :model="formModel" layout="vertical">
|
||||||
<a-spin :loading="loading" class="block">
|
<a-spin :loading="loading" class="block">
|
||||||
<div
|
<div
|
||||||
v-if="matchRules.length > 0"
|
v-if="matchRules.length > 0 || !disabled"
|
||||||
:class="`flex ${
|
:class="`flex ${
|
||||||
matchRules.length > 1 ? 'items-stretch' : 'items-center'
|
matchRules.length > 1 ? 'items-stretch' : 'items-center'
|
||||||
} gap-[16px] bg-[var(--color-text-n9)] p-[12px]`"
|
} gap-[16px] bg-[var(--color-text-n9)] p-[12px]`"
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
:placeholder="t('apiTestDebug.paramName')"
|
:placeholder="t('apiTestDebug.paramName')"
|
||||||
:options="props.keyOptions"
|
:options="props.keyOptions"
|
||||||
allow-search
|
allow-search
|
||||||
|
allow-create
|
||||||
@change="(val) => selectedKey(item, idx)"
|
@change="(val) => selectedKey(item, idx)"
|
||||||
>
|
>
|
||||||
</a-select>
|
</a-select>
|
||||||
|
|
|
@ -1,9 +1,23 @@
|
||||||
<template>
|
<template>
|
||||||
<a-spin :loading="loading" class="block">
|
<a-spin :loading="loading" class="block">
|
||||||
<div class="mt-[16px] font-medium">{{ t('apiTestManagement.responseContent') }}</div>
|
<div class="mt-[16px] font-medium">{{ t('apiTestManagement.responseContent') }}</div>
|
||||||
<div class="mt-[8px] flex items-center gap-[4px]">
|
<div class="mt-[8px] flex items-center gap-[16px]">
|
||||||
<a-switch v-model:model-value="mockResponse.useApiResponse" size="small" :disabled="props.disabled"></a-switch>
|
<div class="flex items-center gap-[4px]">
|
||||||
{{ t('mockManagement.followDefinition') }}
|
<a-switch
|
||||||
|
v-model:model-value="mockResponse.useApiResponse"
|
||||||
|
size="small"
|
||||||
|
:disabled="props.disabled"
|
||||||
|
@change="handleUseApiResponseChange"
|
||||||
|
></a-switch>
|
||||||
|
{{ t('mockManagement.followDefinition') }}
|
||||||
|
</div>
|
||||||
|
<a-select
|
||||||
|
v-if="mockResponse.useApiResponse"
|
||||||
|
v-model:model-value="mockResponse.apiResponseId"
|
||||||
|
:options="mockResponseOptions"
|
||||||
|
class="w-[150px]"
|
||||||
|
:disabled="props.disabled"
|
||||||
|
></a-select>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="!mockResponse.useApiResponse">
|
<template v-if="!mockResponse.useApiResponse">
|
||||||
<MsTab
|
<MsTab
|
||||||
|
@ -59,7 +73,6 @@
|
||||||
:columns="jsonSchemaColumns"
|
:columns="jsonSchemaColumns"
|
||||||
/> -->
|
/> -->
|
||||||
<MsCodeEditor
|
<MsCodeEditor
|
||||||
ref="responseEditorRef"
|
|
||||||
v-model:model-value="currentBodyCode"
|
v-model:model-value="currentBodyCode"
|
||||||
:language="currentCodeLanguage"
|
:language="currentCodeLanguage"
|
||||||
theme="vs"
|
theme="vs"
|
||||||
|
@ -125,23 +138,156 @@
|
||||||
@change="handleResponseTableChange"
|
@change="handleResponseTableChange"
|
||||||
/>
|
/>
|
||||||
<a-select
|
<a-select
|
||||||
v-else
|
v-else-if="activeTab === ResponseComposition.CODE"
|
||||||
v-model:model-value="mockResponse.statusCode"
|
v-model:model-value="mockResponse.statusCode"
|
||||||
:options="statusCodeOptions"
|
:options="statusCodeOptions"
|
||||||
class="w-[200px]"
|
class="w-[200px]"
|
||||||
:disabled="props.disabled"
|
:disabled="props.disabled"
|
||||||
@change="() => emit('change')"
|
@change="() => emit('change')"
|
||||||
/>
|
/>
|
||||||
|
<a-input-number
|
||||||
|
v-else
|
||||||
|
v-model:model-value="mockResponse.delay"
|
||||||
|
:disabled="props.disabled"
|
||||||
|
mode="button"
|
||||||
|
:step="100"
|
||||||
|
:precision="0"
|
||||||
|
:max="600000"
|
||||||
|
:min="0"
|
||||||
|
class="w-[200px]"
|
||||||
|
>
|
||||||
|
<template #suffix> ms </template>
|
||||||
|
</a-input-number>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="currentSelectedDefinitionResponse">
|
||||||
|
<MsTab
|
||||||
|
v-model:active-key="definitionActiveTab"
|
||||||
|
:content-tab-list="responseCompositionTabList.filter((e) => e.value !== 'DELAY')"
|
||||||
|
class="no-content relative my-[8px] border-b"
|
||||||
|
:show-badge="false"
|
||||||
|
/>
|
||||||
|
<div class="mt-[8px]">
|
||||||
|
<template v-if="definitionActiveTab === ResponseComposition.BODY">
|
||||||
|
<div class="mb-[8px] flex items-center justify-between">
|
||||||
|
<a-radio-group
|
||||||
|
v-model:model-value="currentSelectedDefinitionResponse.body.bodyType"
|
||||||
|
type="button"
|
||||||
|
size="small"
|
||||||
|
disabled
|
||||||
|
@change="(val) => emit('change')"
|
||||||
|
>
|
||||||
|
<a-radio
|
||||||
|
v-for="item of ResponseBodyFormat"
|
||||||
|
v-show="item !== ResponseBodyFormat.NONE"
|
||||||
|
:key="item"
|
||||||
|
:value="item"
|
||||||
|
>
|
||||||
|
{{ ResponseBodyFormat[item].toLowerCase() }}
|
||||||
|
</a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
<!-- <div v-if="currentSelectedDefinitionResponse.body.bodyType === ResponseBodyFormat.JSON" class="ml-auto flex items-center">
|
||||||
|
<a-radio-group
|
||||||
|
v-model:model-value="currentSelectedDefinitionResponse.body.jsonBody.enableJsonSchema"
|
||||||
|
size="mini"
|
||||||
|
@change="emit('change')"
|
||||||
|
>
|
||||||
|
<a-radio :value="false">Json</a-radio>
|
||||||
|
<a-radio class="mr-0" :value="true"> Json Schema </a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
<div class="flex items-center gap-[8px]">
|
||||||
|
<a-switch v-model:model-value="currentSelectedDefinitionResponse.body.jsonBody.enableTransition" size="small" type="line" />
|
||||||
|
{{ t('apiTestManagement.dynamicConversion') }}
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="
|
||||||
|
[ResponseBodyFormat.JSON, ResponseBodyFormat.XML, ResponseBodyFormat.RAW].includes(
|
||||||
|
currentSelectedDefinitionResponse.body.bodyType
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<!-- <MsJsonSchema
|
||||||
|
v-if="currentSelectedDefinitionResponse.body.jsonBody.enableJsonSchema"
|
||||||
|
:data="currentSelectedDefinitionResponse.body.jsonBody.jsonSchema"
|
||||||
|
:columns="jsonSchemaColumns"
|
||||||
|
/> -->
|
||||||
|
<MsCodeEditor
|
||||||
|
v-model:model-value="currentSelectedDefinitionBodyCode"
|
||||||
|
:language="currentSelectedDefinitionCodeLanguage"
|
||||||
|
theme="vs"
|
||||||
|
:show-full-screen="false"
|
||||||
|
:show-theme-change="false"
|
||||||
|
:show-language-change="false"
|
||||||
|
:show-charset-change="false"
|
||||||
|
show-code-format
|
||||||
|
read-only
|
||||||
|
>
|
||||||
|
</MsCodeEditor>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div class="mb-[16px] flex justify-between gap-[8px] bg-[var(--color-text-n9)] p-[12px]">
|
||||||
|
<a-input
|
||||||
|
v-model:model-value="currentSelectedDefinitionResponse.body.binaryBody.description"
|
||||||
|
:placeholder="t('common.desc')"
|
||||||
|
:max-length="255"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
<MsAddAttachment
|
||||||
|
v-model:file-list="fileList"
|
||||||
|
mode="input"
|
||||||
|
:multiple="false"
|
||||||
|
:fields="{
|
||||||
|
id: 'fileId',
|
||||||
|
name: 'fileName',
|
||||||
|
}"
|
||||||
|
disabled
|
||||||
|
@change="handleFileChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<a-switch
|
||||||
|
v-model:model-value="currentSelectedDefinitionResponse.body.binaryBody.sendAsBody"
|
||||||
|
class="mr-[8px]"
|
||||||
|
size="small"
|
||||||
|
type="line"
|
||||||
|
disabled
|
||||||
|
></a-switch>
|
||||||
|
<span>{{ t('apiTestDebug.sendAsMainText') }}</span>
|
||||||
|
<a-tooltip position="right">
|
||||||
|
<template #content>
|
||||||
|
<div>{{ t('apiTestDebug.sendAsMainTextTip1') }}</div>
|
||||||
|
<div>{{ t('apiTestDebug.sendAsMainTextTip2') }}</div>
|
||||||
|
</template>
|
||||||
|
<icon-question-circle
|
||||||
|
class="ml-[4px] text-[var(--color-text-4)] hover:text-[rgb(var(--primary-5))]"
|
||||||
|
size="16"
|
||||||
|
/>
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<paramTable
|
||||||
|
v-else-if="definitionActiveTab === ResponseComposition.HEADER"
|
||||||
|
:params="filterKeyValParams(currentSelectedDefinitionResponse.headers, defaultKeyValueParamItem).validParams"
|
||||||
|
:columns="columns"
|
||||||
|
:default-param-item="defaultKeyValueParamItem"
|
||||||
|
:selectable="false"
|
||||||
|
disabled-param-value
|
||||||
|
disabled-except-param
|
||||||
|
@change="handleResponseTableChange"
|
||||||
|
/>
|
||||||
|
<a-select
|
||||||
|
v-else-if="definitionActiveTab === ResponseComposition.CODE"
|
||||||
|
v-model:model-value="currentSelectedDefinitionResponse.statusCode"
|
||||||
|
:options="statusCodeOptions"
|
||||||
|
class="w-[200px]"
|
||||||
|
disabled
|
||||||
|
@change="() => emit('change')"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-else class="mt-[8px]">
|
|
||||||
<a-select
|
|
||||||
v-model:model-value="mockResponse.apiResponseId"
|
|
||||||
:options="mockResponseOptions"
|
|
||||||
class="w-[150px]"
|
|
||||||
:disabled="props.disabled"
|
|
||||||
></a-select>
|
|
||||||
</div>
|
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -162,6 +308,7 @@
|
||||||
import { ResponseBodyFormat, ResponseComposition } from '@/enums/apiEnum';
|
import { ResponseBodyFormat, ResponseComposition } from '@/enums/apiEnum';
|
||||||
|
|
||||||
import { defaultKeyValueParamItem, statusCodes } from '@/views/api-test/components/config';
|
import { defaultKeyValueParamItem, statusCodes } from '@/views/api-test/components/config';
|
||||||
|
import { filterKeyValParams } from '@/views/api-test/components/utils';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
definitionResponses: ResponseItem[];
|
definitionResponses: ResponseItem[];
|
||||||
|
@ -182,6 +329,7 @@
|
||||||
props.definitionResponses.map((item) => ({
|
props.definitionResponses.map((item) => ({
|
||||||
label: `${t(item.label || item.name)}(${item.statusCode})`,
|
label: `${t(item.label || item.name)}(${item.statusCode})`,
|
||||||
value: item.id,
|
value: item.id,
|
||||||
|
defaultFlag: item.defaultFlag,
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -198,6 +346,10 @@
|
||||||
label: t('apiTestManagement.responseCode'),
|
label: t('apiTestManagement.responseCode'),
|
||||||
value: ResponseComposition.CODE,
|
value: ResponseComposition.CODE,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: t('mockManagement.responseDelay'),
|
||||||
|
value: 'DELAY',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const statusCodeOptions = statusCodes.map((e) => ({
|
const statusCodeOptions = statusCodes.map((e) => ({
|
||||||
|
@ -300,6 +452,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleUseApiResponseChange(val: string | number | boolean) {
|
||||||
|
if (val) {
|
||||||
|
mockResponse.value.apiResponseId = (mockResponseOptions.value.find((e) => e.defaultFlag)?.value as string) || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => mockResponse.value.body.binaryBody.file?.fileId,
|
() => mockResponse.value.body.binaryBody.file?.fileId,
|
||||||
() => {
|
() => {
|
||||||
|
@ -312,6 +470,48 @@
|
||||||
immediate: true,
|
immediate: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const currentSelectedDefinitionResponse = computed(() =>
|
||||||
|
props.definitionResponses.find((e) => e.id === mockResponse.value.apiResponseId)
|
||||||
|
);
|
||||||
|
const definitionActiveTab = ref(ResponseComposition.BODY);
|
||||||
|
// 当前显示的代码
|
||||||
|
const currentSelectedDefinitionBodyCode = computed({
|
||||||
|
get() {
|
||||||
|
if (currentSelectedDefinitionResponse.value?.body.bodyType === ResponseBodyFormat.JSON) {
|
||||||
|
return currentSelectedDefinitionResponse.value.body.jsonBody.jsonValue;
|
||||||
|
}
|
||||||
|
if (currentSelectedDefinitionResponse.value?.body.bodyType === ResponseBodyFormat.XML) {
|
||||||
|
return currentSelectedDefinitionResponse.value.body.xmlBody.value;
|
||||||
|
}
|
||||||
|
return currentSelectedDefinitionResponse.value?.body.rawBody.value;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
if (
|
||||||
|
currentSelectedDefinitionResponse.value?.body.bodyType === ResponseBodyFormat.JSON &&
|
||||||
|
currentSelectedDefinitionResponse.value.body.jsonBody
|
||||||
|
) {
|
||||||
|
currentSelectedDefinitionResponse.value.body.jsonBody.jsonValue = val || '';
|
||||||
|
} else if (
|
||||||
|
currentSelectedDefinitionResponse.value?.body.bodyType === ResponseBodyFormat.XML &&
|
||||||
|
currentSelectedDefinitionResponse.value.body.xmlBody
|
||||||
|
) {
|
||||||
|
currentSelectedDefinitionResponse.value.body.xmlBody.value = val || '';
|
||||||
|
} else if (currentSelectedDefinitionResponse.value) {
|
||||||
|
currentSelectedDefinitionResponse.value.body.rawBody.value = val || '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// 当前代码编辑器的语言
|
||||||
|
const currentSelectedDefinitionCodeLanguage = computed(() => {
|
||||||
|
if (currentSelectedDefinitionResponse.value?.body.bodyType === ResponseBodyFormat.JSON) {
|
||||||
|
return LanguageEnum.JSON;
|
||||||
|
}
|
||||||
|
if (currentSelectedDefinitionResponse.value?.body.bodyType === ResponseBodyFormat.XML) {
|
||||||
|
return LanguageEnum.XML;
|
||||||
|
}
|
||||||
|
return LanguageEnum.PLAINTEXT;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -163,6 +163,7 @@ export default {
|
||||||
'apiTestManagement.script': 'Script',
|
'apiTestManagement.script': 'Script',
|
||||||
'apiTestManagement.variable': 'Variable',
|
'apiTestManagement.variable': 'Variable',
|
||||||
'apiTestManagement.regex': 'Regular Expression',
|
'apiTestManagement.regex': 'Regular Expression',
|
||||||
|
'apiTestManagement.caseTotal': 'Case total',
|
||||||
'case.execute.selectEnv': 'Select Environment',
|
'case.execute.selectEnv': 'Select Environment',
|
||||||
'case.execute.defaultEnv': 'Default Environment',
|
'case.execute.defaultEnv': 'Default Environment',
|
||||||
'case.execute.newEnv': 'New Environment',
|
'case.execute.newEnv': 'New Environment',
|
||||||
|
@ -248,4 +249,5 @@ export default {
|
||||||
'mockManagement.batchEdit': 'Batch Edit',
|
'mockManagement.batchEdit': 'Batch Edit',
|
||||||
'mockManagement.batchDelete': 'Batch Delete',
|
'mockManagement.batchDelete': 'Batch Delete',
|
||||||
'mockManagement.noMatchRules': 'No matching rules found',
|
'mockManagement.noMatchRules': 'No matching rules found',
|
||||||
|
'mockManagement.responseDelay': 'Response delay',
|
||||||
};
|
};
|
||||||
|
|
|
@ -156,6 +156,7 @@ export default {
|
||||||
'apiTestManagement.script': '脚本',
|
'apiTestManagement.script': '脚本',
|
||||||
'apiTestManagement.variable': '变量',
|
'apiTestManagement.variable': '变量',
|
||||||
'apiTestManagement.regex': '正则表达式',
|
'apiTestManagement.regex': '正则表达式',
|
||||||
|
'apiTestManagement.caseTotal': '用例数',
|
||||||
'case.execute.selectEnv': '环境选择',
|
'case.execute.selectEnv': '环境选择',
|
||||||
'case.execute.defaultEnv': '默认环境',
|
'case.execute.defaultEnv': '默认环境',
|
||||||
'case.execute.newEnv': '新环境',
|
'case.execute.newEnv': '新环境',
|
||||||
|
@ -238,4 +239,5 @@ export default {
|
||||||
'mockManagement.batchEdit': '批量编辑',
|
'mockManagement.batchEdit': '批量编辑',
|
||||||
'mockManagement.batchDelete': '批量删除',
|
'mockManagement.batchDelete': '批量删除',
|
||||||
'mockManagement.noMatchRules': '无该类匹配规则',
|
'mockManagement.noMatchRules': '无该类匹配规则',
|
||||||
|
'mockManagement.responseDelay': '响应延时',
|
||||||
};
|
};
|
||||||
|
|
|
@ -1161,7 +1161,7 @@
|
||||||
url: res.path,
|
url: res.path,
|
||||||
name: res.name, // request里面还有个name但是是null
|
name: res.name, // request里面还有个name但是是null
|
||||||
resourceId: res.id,
|
resourceId: res.id,
|
||||||
stepId: props.step?.uniqueId || '',
|
stepId: props.step?.id || '',
|
||||||
responseActiveTab: ResponseComposition.BODY,
|
responseActiveTab: ResponseComposition.BODY,
|
||||||
...parseRequestBodyResult,
|
...parseRequestBodyResult,
|
||||||
};
|
};
|
||||||
|
|
|
@ -985,7 +985,7 @@
|
||||||
stepName: activeStep.value?.name || res.name,
|
stepName: activeStep.value?.name || res.name,
|
||||||
name: res.name, // request里面还有个name但是是null
|
name: res.name, // request里面还有个name但是是null
|
||||||
resourceId: res.id,
|
resourceId: res.id,
|
||||||
stepId: props.request?.stepId || '',
|
stepId: activeStep.value?.id || '',
|
||||||
...parseRequestBodyResult,
|
...parseRequestBodyResult,
|
||||||
};
|
};
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
|
Loading…
Reference in New Issue