feat(接口管理): 接口定义响应内容调整
This commit is contained in:
parent
05638aab20
commit
5e17fe21cb
|
@ -1,6 +1,6 @@
|
||||||
export interface TabItem {
|
export interface TabItem {
|
||||||
id: string | number;
|
id: string | number;
|
||||||
label: string;
|
label?: string;
|
||||||
closable?: boolean;
|
closable?: boolean;
|
||||||
unSaved?: boolean; // 未保存
|
unSaved?: boolean; // 未保存
|
||||||
draggable?: boolean;
|
draggable?: boolean;
|
||||||
|
|
|
@ -414,18 +414,13 @@ export interface ResponseDefinitionBody {
|
||||||
rawBody: ExecuteValueBody;
|
rawBody: ExecuteValueBody;
|
||||||
binaryBody: ExecuteBinaryBody;
|
binaryBody: ExecuteBinaryBody;
|
||||||
}
|
}
|
||||||
export interface ResponseDefinitionHeader extends EnableKeyValueParam {
|
|
||||||
notBlankValue: boolean;
|
|
||||||
valid: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 响应定义
|
// 响应定义
|
||||||
export interface ResponseDefinition {
|
export interface ResponseDefinition {
|
||||||
id: string | number;
|
id: string | number;
|
||||||
statusCode: string | number;
|
statusCode: string | number;
|
||||||
defaultFlag: boolean; // 默认响应标志
|
defaultFlag: boolean; // 默认响应标志
|
||||||
name: string; // 响应名称
|
name: string; // 响应名称
|
||||||
headers: ResponseDefinitionHeader[];
|
headers: KeyValueParam[];
|
||||||
body: ResponseDefinitionBody;
|
body: ResponseDefinitionBody;
|
||||||
[key: string]: any; // 用于前端渲染时填充的自定义信息,后台无此字段
|
[key: string]: any; // 用于前端渲染时填充的自定义信息,后台无此字段
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import {
|
||||||
EnableKeyValueParam,
|
EnableKeyValueParam,
|
||||||
ExecuteRequestCommonParam,
|
ExecuteRequestCommonParam,
|
||||||
ExecuteRequestFormBodyFormValue,
|
ExecuteRequestFormBodyFormValue,
|
||||||
|
ResponseDefinition,
|
||||||
} from '@/models/apiTest/common';
|
} from '@/models/apiTest/common';
|
||||||
import { RequestContentTypeEnum, RequestParamsType, ResponseBodyFormat, ResponseComposition } from '@/enums/apiEnum';
|
import { RequestContentTypeEnum, RequestParamsType, ResponseBodyFormat, ResponseComposition } from '@/enums/apiEnum';
|
||||||
|
|
||||||
|
@ -42,10 +43,10 @@ export const defaultRequestParamsItem: ExecuteRequestCommonParam = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 请求的响应 response 默认的响应信息项
|
// 请求的响应 response 默认的响应信息项
|
||||||
export const defaultResponseItem = {
|
export const defaultResponseItem: ResponseDefinition = {
|
||||||
id: new Date().getTime(),
|
id: new Date().getTime(),
|
||||||
label: 'apiTestManagement.response',
|
|
||||||
name: 'apiTestManagement.response',
|
name: 'apiTestManagement.response',
|
||||||
|
label: 'apiTestManagement.response',
|
||||||
closable: false,
|
closable: false,
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
defaultFlag: true,
|
defaultFlag: true,
|
||||||
|
@ -72,3 +73,6 @@ export const defaultResponseItem = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 请求的响应 response 的响应状态码集合
|
||||||
|
export const statusCodes = [200, 201, 202, 203, 204, 205, 400, 401, 402, 403, 404, 405, 500, 501, 502, 503, 504, 505];
|
||||||
|
|
|
@ -102,15 +102,15 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 接口定义多出一个输入框占高度 40px -->
|
<div ref="splitContainerRef" :class="splitContainerClass">
|
||||||
<div ref="splitContainerRef" :class="`${props.isDefinition ? 'h-[calc(100%-80px)]' : 'h-[calc(100%-40px)]'}`">
|
|
||||||
<MsSplitBox
|
<MsSplitBox
|
||||||
ref="splitBoxRef"
|
ref="splitBoxRef"
|
||||||
v-model:size="splitBoxSize"
|
v-model:size="splitBoxSize"
|
||||||
:max="0.98"
|
:max="!showResponse ? 1 : 0.98"
|
||||||
min="10px"
|
min="10px"
|
||||||
:direction="activeLayout"
|
:direction="activeLayout"
|
||||||
second-container-class="!overflow-y-hidden"
|
second-container-class="!overflow-y-hidden"
|
||||||
|
:class="!showResponse ? 'hidden-second' : ''"
|
||||||
@expand-change="handleExpandChange"
|
@expand-change="handleExpandChange"
|
||||||
>
|
>
|
||||||
<template #first>
|
<template #first>
|
||||||
|
@ -204,13 +204,14 @@
|
||||||
</template>
|
</template>
|
||||||
<template #second>
|
<template #second>
|
||||||
<response
|
<response
|
||||||
|
v-show="showResponse"
|
||||||
v-model:active-layout="activeLayout"
|
v-model:active-layout="activeLayout"
|
||||||
v-model:active-tab="requestVModel.responseActiveTab"
|
v-model:active-tab="requestVModel.responseActiveTab"
|
||||||
:is-expanded="isExpanded"
|
:is-expanded="isExpanded"
|
||||||
:response-definition="requestVModel.responseDefinition"
|
:response-definition="requestVModel.responseDefinition"
|
||||||
:hide-layout-switch="props.hideResponseLayoutSwitch"
|
:hide-layout-switch="props.hideResponseLayoutSwitch"
|
||||||
:request-task-result="requestVModel.response"
|
:request-task-result="requestVModel.response"
|
||||||
:is-edit="props.isDefinition"
|
:is-edit="props.isDefinition && isHttpProtocol"
|
||||||
:upload-temp-file-api="props.uploadTempFileApi"
|
:upload-temp-file-api="props.uploadTempFileApi"
|
||||||
:loading="requestVModel.executeLoading || loading"
|
:loading="requestVModel.executeLoading || loading"
|
||||||
@change-expand="changeExpand"
|
@change-expand="changeExpand"
|
||||||
|
@ -547,9 +548,16 @@
|
||||||
const formData = tempForm || requestVModel.value;
|
const formData = tempForm || requestVModel.value;
|
||||||
if (fApi.value) {
|
if (fApi.value) {
|
||||||
const form = {};
|
const form = {};
|
||||||
pluginScriptMap.value[requestVModel.value.protocol].apiDebugFields?.forEach((key) => {
|
if (props.isDefinition) {
|
||||||
form[key] = formData[key];
|
// 接口定义使用接口定义的字段集
|
||||||
});
|
pluginScriptMap.value[requestVModel.value.protocol].apiDefinitionFields?.forEach((key) => {
|
||||||
|
form[key] = formData[key];
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
pluginScriptMap.value[requestVModel.value.protocol].apiDebugFields?.forEach((key) => {
|
||||||
|
form[key] = formData[key];
|
||||||
|
});
|
||||||
|
}
|
||||||
fApi.value?.setValue(form);
|
fApi.value?.setValue(form);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -654,10 +662,22 @@
|
||||||
handleActiveDebugChange();
|
handleActiveDebugChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
const splitBoxSize = ref<string | number>(0.6);
|
const showResponse = computed(
|
||||||
|
() =>
|
||||||
|
isHttpProtocol.value ||
|
||||||
|
!props.isDefinition ||
|
||||||
|
requestVModel.value.response?.requestResults[0]?.responseResult.responseCode
|
||||||
|
);
|
||||||
|
const splitBoxSize = ref<string | number>(!showResponse.value ? 1 : 0.6);
|
||||||
const activeLayout = ref<'horizontal' | 'vertical'>('vertical');
|
const activeLayout = ref<'horizontal' | 'vertical'>('vertical');
|
||||||
const splitContainerRef = ref<HTMLElement>();
|
const splitContainerRef = ref<HTMLElement>();
|
||||||
const secondBoxHeight = ref(0);
|
const secondBoxHeight = ref(0);
|
||||||
|
const splitContainerClass = computed(() => {
|
||||||
|
if (!showResponse.value) {
|
||||||
|
return 'h-full';
|
||||||
|
}
|
||||||
|
return 'h-[calc(100%-40px)]';
|
||||||
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => splitBoxSize.value,
|
() => splitBoxSize.value,
|
||||||
|
@ -1056,4 +1076,9 @@
|
||||||
:deep(.arco-tabs-tab) {
|
:deep(.arco-tabs-tab) {
|
||||||
@apply leading-none;
|
@apply leading-none;
|
||||||
}
|
}
|
||||||
|
.hidden-second {
|
||||||
|
:deep(.arco-split-trigger) {
|
||||||
|
@apply hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<template #label="{ tab }">
|
<template #label="{ tab }">
|
||||||
<div class="response-tab">
|
<div class="response-tab">
|
||||||
<div v-if="tab.defaultFlag" class="response-tab-default-icon"></div>
|
<div v-if="tab.defaultFlag" class="response-tab-default-icon"></div>
|
||||||
{{ t(tab.label) }}({{ tab.statusCode }})
|
{{ t(tab.label || '') }}({{ tab.statusCode }})
|
||||||
<MsMoreAction
|
<MsMoreAction
|
||||||
:list="
|
:list="
|
||||||
tab.defaultFlag
|
tab.defaultFlag
|
||||||
|
@ -23,8 +23,8 @@
|
||||||
<popConfirm
|
<popConfirm
|
||||||
v-model:visible="tab.showRenamePopConfirm"
|
v-model:visible="tab.showRenamePopConfirm"
|
||||||
mode="tabRename"
|
mode="tabRename"
|
||||||
:field-config="{ field: t(tab.label) }"
|
:field-config="{ field: t(tab.label || '') }"
|
||||||
:all-names="responseTabs.map((e) => t(tab.label))"
|
:all-names="responseTabs.map((e) => t(tab.label || ''))"
|
||||||
:popup-offset="20"
|
:popup-offset="20"
|
||||||
@rename-finish="
|
@rename-finish="
|
||||||
(val) => {
|
(val) => {
|
||||||
|
@ -64,33 +64,33 @@
|
||||||
<a-tab-pane v-for="item of responseCompositionTabList" :key="item.value" :title="item.label" />
|
<a-tab-pane v-for="item of responseCompositionTabList" :key="item.value" :title="item.label" />
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
<div class="response-container">
|
<div class="response-container">
|
||||||
<div class="mb-[8px] flex items-center justify-between">
|
<template v-if="activeResponse.responseActiveTab === ResponseComposition.BODY">
|
||||||
<a-radio-group
|
<div class="mb-[8px] flex items-center justify-between">
|
||||||
v-model:model-value="activeResponse.body.bodyType"
|
|
||||||
type="button"
|
|
||||||
size="small"
|
|
||||||
@change="(val) => changeBodyFormat(val as ResponseBodyFormat)"
|
|
||||||
>
|
|
||||||
<a-radio v-for="item of ResponseBodyFormat" :key="item" :value="item">
|
|
||||||
{{ ResponseBodyFormat[item].toLowerCase() }}
|
|
||||||
</a-radio>
|
|
||||||
</a-radio-group>
|
|
||||||
<div v-if="activeResponse.body.bodyType === ResponseBodyFormat.JSON" class="ml-auto flex items-center">
|
|
||||||
<a-radio-group
|
<a-radio-group
|
||||||
v-model:model-value="activeResponse.body.jsonBody.enableJsonSchema"
|
v-model:model-value="activeResponse.body.bodyType"
|
||||||
size="mini"
|
type="button"
|
||||||
@change="emit('change')"
|
size="small"
|
||||||
|
@change="(val) => changeBodyFormat(val as ResponseBodyFormat)"
|
||||||
>
|
>
|
||||||
<a-radio :value="false">Json</a-radio>
|
<a-radio v-for="item of ResponseBodyFormat" :key="item" :value="item">
|
||||||
<a-radio class="mr-0" :value="true"> Json Schema </a-radio>
|
{{ ResponseBodyFormat[item].toLowerCase() }}
|
||||||
|
</a-radio>
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
<div class="flex items-center gap-[8px]">
|
<div v-if="activeResponse.body.bodyType === ResponseBodyFormat.JSON" class="ml-auto flex items-center">
|
||||||
<a-switch v-model:model-value="activeResponse.body.jsonBody.enableTransition" size="small" type="line" />
|
<a-radio-group
|
||||||
{{ t('apiTestManagement.dynamicConversion') }}
|
v-model:model-value="activeResponse.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="activeResponse.body.jsonBody.enableTransition" size="small" type="line" />
|
||||||
|
{{ t('apiTestManagement.dynamicConversion') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<template v-if="activeResponse.responseActiveTab === ResponseComposition.BODY">
|
|
||||||
<div
|
<div
|
||||||
v-if="
|
v-if="
|
||||||
[ResponseBodyFormat.JSON, ResponseBodyFormat.XML, ResponseBodyFormat.RAW].includes(
|
[ResponseBodyFormat.JSON, ResponseBodyFormat.XML, ResponseBodyFormat.RAW].includes(
|
||||||
|
@ -133,6 +133,20 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<paramTable
|
||||||
|
v-else-if="activeResponse.responseActiveTab === ResponseComposition.HEADER"
|
||||||
|
v-model:params="activeResponse.headers"
|
||||||
|
:columns="columns"
|
||||||
|
:default-param-item="[
|
||||||
|
{
|
||||||
|
key: '',
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
:selectable="false"
|
||||||
|
@change="emit('change')"
|
||||||
|
/>
|
||||||
|
<a-select v-else v-model:model-value="activeResponse.statusCode" :options="statusCodeOptions" class="w-[200px]" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -143,12 +157,11 @@
|
||||||
import { LanguageEnum } from '@/components/pure/ms-code-editor/types';
|
import { LanguageEnum } from '@/components/pure/ms-code-editor/types';
|
||||||
import MsEditableTab from '@/components/pure/ms-editable-tab/index.vue';
|
import MsEditableTab from '@/components/pure/ms-editable-tab/index.vue';
|
||||||
import { TabItem } from '@/components/pure/ms-editable-tab/types';
|
import { TabItem } from '@/components/pure/ms-editable-tab/types';
|
||||||
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
|
||||||
import useTable from '@/components/pure/ms-table/useTable';
|
|
||||||
import MsMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
import MsMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||||
import { MsFileItem } from '@/components/pure/ms-upload/types';
|
import { MsFileItem } from '@/components/pure/ms-upload/types';
|
||||||
import MsAddAttachment from '@/components/business/ms-add-attachment/index.vue';
|
import MsAddAttachment from '@/components/business/ms-add-attachment/index.vue';
|
||||||
|
import paramTable, { ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
|
||||||
import popConfirm from '@/views/api-test/components/popConfirm.vue';
|
import popConfirm from '@/views/api-test/components/popConfirm.vue';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
@ -157,7 +170,7 @@
|
||||||
import { ResponseDefinition } from '@/models/apiTest/common';
|
import { ResponseDefinition } from '@/models/apiTest/common';
|
||||||
import { ResponseBodyFormat, ResponseComposition } from '@/enums/apiEnum';
|
import { ResponseBodyFormat, ResponseComposition } from '@/enums/apiEnum';
|
||||||
|
|
||||||
import { defaultResponseItem } from '../../config';
|
import { defaultResponseItem, statusCodes } from '../../config';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
responseDefinition: ResponseDefinition[];
|
responseDefinition: ResponseDefinition[];
|
||||||
|
@ -338,42 +351,24 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const columns: MsTableColumn = [
|
const columns: ParamTableColumn[] = [
|
||||||
{
|
{
|
||||||
title: 'apiTestDebug.content',
|
title: 'apiTestManagement.paramName',
|
||||||
dataIndex: 'content',
|
dataIndex: 'key',
|
||||||
showTooltip: true,
|
slotName: 'key',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'apiTestDebug.status',
|
title: 'apiTestManagement.paramVal',
|
||||||
dataIndex: 'status',
|
dataIndex: 'value',
|
||||||
slotName: 'status',
|
slotName: 'value',
|
||||||
width: 80,
|
isNormal: true,
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '',
|
|
||||||
dataIndex: 'desc',
|
|
||||||
showTooltip: true,
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const { propsRes, propsEvent } = useTable(() => Promise.resolve([]), {
|
|
||||||
scroll: { x: '100%' },
|
const statusCodeOptions = statusCodes.map((e) => ({
|
||||||
columns,
|
label: e.toString(),
|
||||||
});
|
value: e,
|
||||||
propsRes.value.data = [
|
}));
|
||||||
{
|
|
||||||
id: new Date().getTime(),
|
|
||||||
content: 'Response Code equals: 200',
|
|
||||||
status: 1,
|
|
||||||
desc: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: new Date().getTime(),
|
|
||||||
content: '$.users[1].age REGEX: 31',
|
|
||||||
status: 0,
|
|
||||||
desc: `Value expected to match regexp '31', but it did not match: '30' match: '30'`,
|
|
||||||
},
|
|
||||||
] as any;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -131,23 +131,6 @@
|
||||||
<a-tab-pane v-if="!activeApiTab.isNew" key="case" :title="t('apiTestManagement.case')" class="ms-api-tab-pane">
|
<a-tab-pane v-if="!activeApiTab.isNew" key="case" :title="t('apiTestManagement.case')" class="ms-api-tab-pane">
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane v-if="!activeApiTab.isNew" key="mock" title="MOCK" class="ms-api-tab-pane"> </a-tab-pane>
|
<a-tab-pane v-if="!activeApiTab.isNew" key="mock" title="MOCK" class="ms-api-tab-pane"> </a-tab-pane>
|
||||||
<template #extra>
|
|
||||||
<div class="flex items-center gap-[8px] pr-[24px]">
|
|
||||||
<a-button type="outline" class="arco-btn-outline--secondary !p-[8px]">
|
|
||||||
<template #icon>
|
|
||||||
<icon-location class="text-[var(--color-text-4)]" />
|
|
||||||
</template>
|
|
||||||
</a-button>
|
|
||||||
<MsSelect
|
|
||||||
v-model:model-value="checkedEnv"
|
|
||||||
mode="static"
|
|
||||||
:options="envOptions"
|
|
||||||
class="!w-[150px]"
|
|
||||||
:search-keys="['label']"
|
|
||||||
allow-search
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -163,7 +146,6 @@
|
||||||
// import MsFormCreate from '@/components/pure/ms-form-create/formCreate.vue';
|
// import MsFormCreate from '@/components/pure/ms-form-create/formCreate.vue';
|
||||||
import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
|
import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
|
||||||
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
|
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
|
||||||
import MsSelect from '@/components/business/ms-select';
|
|
||||||
import addDependencyDrawer from './addDependencyDrawer.vue';
|
import addDependencyDrawer from './addDependencyDrawer.vue';
|
||||||
import apiTable from './apiTable.vue';
|
import apiTable from './apiTable.vue';
|
||||||
import apiMethodName from '@/views/api-test/components/apiMethodName.vue';
|
import apiMethodName from '@/views/api-test/components/apiMethodName.vue';
|
||||||
|
@ -402,26 +384,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkedEnv = ref('DEV');
|
|
||||||
const envOptions = ref([
|
|
||||||
{
|
|
||||||
label: 'DEV',
|
|
||||||
value: 'DEV',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'TEST',
|
|
||||||
value: 'TEST',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'PRE',
|
|
||||||
value: 'PRE',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'PROD',
|
|
||||||
value: 'PROD',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// const fApi = ref();
|
// const fApi = ref();
|
||||||
// const options = {
|
// const options = {
|
||||||
// form: {
|
// form: {
|
||||||
|
|
|
@ -13,10 +13,28 @@
|
||||||
<a-tab-pane key="case" title="CASE" class="ms-api-tab-pane"> </a-tab-pane>
|
<a-tab-pane key="case" title="CASE" class="ms-api-tab-pane"> </a-tab-pane>
|
||||||
<a-tab-pane key="mock" title="MOCK" class="ms-api-tab-pane"> </a-tab-pane>
|
<a-tab-pane key="mock" title="MOCK" class="ms-api-tab-pane"> </a-tab-pane>
|
||||||
<a-tab-pane key="doc" :title="t('apiTestManagement.doc')" class="ms-api-tab-pane"> </a-tab-pane>
|
<a-tab-pane key="doc" :title="t('apiTestManagement.doc')" class="ms-api-tab-pane"> </a-tab-pane>
|
||||||
|
<template #extra>
|
||||||
|
<div class="flex items-center gap-[8px] pr-[24px]">
|
||||||
|
<a-button type="outline" class="arco-btn-outline--secondary !p-[8px]">
|
||||||
|
<template #icon>
|
||||||
|
<icon-location class="text-[var(--color-text-4)]" />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
<MsSelect
|
||||||
|
v-model:model-value="checkedEnv"
|
||||||
|
mode="static"
|
||||||
|
:options="envOptions"
|
||||||
|
class="!w-[150px]"
|
||||||
|
:search-keys="['label']"
|
||||||
|
allow-search
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import MsSelect from '@/components/business/ms-select';
|
||||||
import api from './api/index.vue';
|
import api from './api/index.vue';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
@ -44,6 +62,26 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const checkedEnv = ref('DEV');
|
||||||
|
const envOptions = ref([
|
||||||
|
{
|
||||||
|
label: 'DEV',
|
||||||
|
value: 'DEV',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'TEST',
|
||||||
|
value: 'TEST',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'PRE',
|
||||||
|
value: 'PRE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'PROD',
|
||||||
|
value: 'PROD',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
newTab,
|
newTab,
|
||||||
});
|
});
|
||||||
|
|
|
@ -88,6 +88,8 @@ export default {
|
||||||
'apiTestManagement.response': '响应{count}',
|
'apiTestManagement.response': '响应{count}',
|
||||||
'apiTestManagement.responseCode': '响应码',
|
'apiTestManagement.responseCode': '响应码',
|
||||||
'apiTestManagement.dynamicConversion': '动态转换',
|
'apiTestManagement.dynamicConversion': '动态转换',
|
||||||
'apiTestManagement.expandApi': '展开全部请求',
|
'apiTestManagement.expandApi': '显示全部请求',
|
||||||
'apiTestManagement.collapseApi': '收起全部请求',
|
'apiTestManagement.collapseApi': '隐藏全部请求',
|
||||||
|
'apiTestManagement.paramName': '参数名',
|
||||||
|
'apiTestManagement.paramVal': '参数值',
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue