fix(接口管理): 用例执行响应内容默认为空且折叠&补充api权限&样式细节调整
This commit is contained in:
parent
1e598e6da9
commit
66844564d6
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M10.1118 1.33333C10.5538 1.33333 10.9777 1.50892 11.2903 1.82148L12.5764 3.10753L14.1782 4.70939C14.4907 5.02195 14.6663 5.44586 14.6663 5.8879V13C14.6663 13.9205 13.9202 14.6667 12.9997 14.6667H2.99967C2.0792 14.6667 1.33301 13.9205 1.33301 13V2.99999C1.33301 2.07952 2.0792 1.33333 2.99967 1.33333H10.1118ZM10.1118 2.66666H2.99967C2.81558 2.66666 2.66634 2.8159 2.66634 2.99999V13C2.66634 13.1841 2.81557 13.3333 2.99967 13.3333H12.9997C13.1838 13.3333 13.333 13.1841 13.333 13V5.8879C13.333 5.79949 13.2979 5.71472 13.2354 5.65219L10.3475 2.76429C10.285 2.70177 10.2002 2.66666 10.1118 2.66666ZM6.24054 6.66666V7.37835H4.42034V7.90814H6.10882V8.58799H4.42034V9.24511H6.29323V10H3.33301V6.66666H6.24054ZM8.64034 7.53069C8.91018 7.53069 9.12134 7.60686 9.27382 7.7592C9.4263 7.91155 9.50254 8.14688 9.50254 8.46521V10H8.52298V8.67212C8.52298 8.52053 8.49344 8.41329 8.43437 8.35038C8.37529 8.28747 8.29226 8.25602 8.18529 8.25602C8.06713 8.25602 7.97133 8.29846 7.89789 8.38335C7.82444 8.46824 7.78772 8.62058 7.78772 8.84038V10H6.81295V7.58526H7.72066V7.97862C7.85637 7.81794 7.99369 7.70312 8.1326 7.63415C8.27151 7.56518 8.44075 7.53069 8.64034 7.53069ZM10.6785 7.58526L11.1719 9.1155L11.682 7.58526H12.6663L11.5862 10H10.7216L9.66301 7.58526H10.6785Z" fill="#959598"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -104,6 +104,14 @@
|
||||||
emit('batchAction', item as BatchActionParams);
|
emit('batchAction', item as BatchActionParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleMoreActionLength = () => {
|
||||||
|
moreAction.value?.forEach((key) => {
|
||||||
|
if (key.permission && hasAllPermission(key.permission as string[])) {
|
||||||
|
moreActionLength.value += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const computedLastVisibleIndex = () => {
|
const computedLastVisibleIndex = () => {
|
||||||
if (!refWrapper.value) {
|
if (!refWrapper.value) {
|
||||||
return;
|
return;
|
||||||
|
@ -146,17 +154,14 @@
|
||||||
const value = menuItemIndex - 1;
|
const value = menuItemIndex - 1;
|
||||||
baseAction.value = allAction.value.slice(0, value);
|
baseAction.value = allAction.value.slice(0, value);
|
||||||
moreAction.value = allAction.value.slice(value);
|
moreAction.value = allAction.value.slice(value);
|
||||||
|
handleMoreActionLength();
|
||||||
computedStatus.value = false;
|
computedStatus.value = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
moreAction.value = props.actionConfig?.moreAction || [];
|
moreAction.value = props.actionConfig?.moreAction || [];
|
||||||
baseAction.value = props.actionConfig?.baseAction || [];
|
baseAction.value = props.actionConfig?.baseAction || [];
|
||||||
moreAction.value.forEach((key) => {
|
handleMoreActionLength();
|
||||||
if (key.permission && hasAllPermission(key.permission as string[])) {
|
|
||||||
moreActionLength.value += 1;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<div class="flex cursor-pointer p-[8px]" @click.stop="goEnv">
|
<div class="flex cursor-pointer p-[8px]" @click.stop="goEnv">
|
||||||
<icon-location class="text-[var(--color-text-4)]" />
|
<svg-icon width="14px" height="14px" :name="'icon_env'" class="text-[var(--color-text-4)]" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-select>
|
</a-select>
|
||||||
|
@ -21,13 +21,14 @@
|
||||||
import { SelectOptionData } from '@arco-design/web-vue';
|
import { SelectOptionData } from '@arco-design/web-vue';
|
||||||
|
|
||||||
import { getEnvironment, getEnvList } from '@/api/modules/api-test/common';
|
import { getEnvironment, getEnvList } from '@/api/modules/api-test/common';
|
||||||
import router from '@/router';
|
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||||
import useAppStore from '@/store/modules/app';
|
import useAppStore from '@/store/modules/app';
|
||||||
|
|
||||||
import { EnvConfig } from '@/models/projectManagement/environmental';
|
import { EnvConfig } from '@/models/projectManagement/environmental';
|
||||||
import { ProjectManagementRouteEnum } from '@/enums/routeEnum';
|
import { ProjectManagementRouteEnum } from '@/enums/routeEnum';
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
|
const { openNewPage } = useOpenNewPage();
|
||||||
|
|
||||||
const currentEnv = ref('');
|
const currentEnv = ref('');
|
||||||
|
|
||||||
|
@ -64,9 +65,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function goEnv() {
|
function goEnv() {
|
||||||
router.push({
|
openNewPage(ProjectManagementRouteEnum.PROJECT_MANAGEMENT_ENVIRONMENT_MANAGEMENT);
|
||||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_ENVIRONMENT_MANAGEMENT,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
|
@ -180,7 +180,7 @@
|
||||||
>
|
>
|
||||||
<div class="tab-pane-container">
|
<div class="tab-pane-container">
|
||||||
<a-spin
|
<a-spin
|
||||||
v-if="requestVModel.activeTab === RequestComposition.PLUGIN"
|
v-show="requestVModel.activeTab === RequestComposition.PLUGIN"
|
||||||
:loading="pluginLoading"
|
:loading="pluginLoading"
|
||||||
class="min-h-[100px] w-full"
|
class="min-h-[100px] w-full"
|
||||||
>
|
>
|
||||||
|
@ -276,14 +276,14 @@
|
||||||
:is-expanded="isVerticalExpanded"
|
:is-expanded="isVerticalExpanded"
|
||||||
:hide-layout-switch="props.hideResponseLayoutSwitch"
|
:hide-layout-switch="props.hideResponseLayoutSwitch"
|
||||||
:request-task-result="requestVModel.response"
|
:request-task-result="requestVModel.response"
|
||||||
:is-edit="props.isDefinition && isHttpProtocol"
|
:is-edit="props.isDefinition && isHttpProtocol && !props.isCase"
|
||||||
:upload-temp-file-api="props.uploadTempFileApi"
|
:upload-temp-file-api="props.uploadTempFileApi"
|
||||||
:loading="requestVModel.executeLoading || loading"
|
:loading="requestVModel.executeLoading || loading"
|
||||||
:is-definition="props.isDefinition"
|
:is-definition="props.isDefinition"
|
||||||
@change-expand="changeVerticalExpand"
|
@change-expand="changeVerticalExpand"
|
||||||
@change-layout="handleActiveLayoutChange"
|
@change-layout="handleActiveLayoutChange"
|
||||||
@change="handleActiveDebugChange"
|
@change="handleActiveDebugChange"
|
||||||
@execute="execute"
|
@execute="(executeType) => (props.isCase ? emit('execute', executeType) : execute(executeType))"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</MsSplitBox>
|
</MsSplitBox>
|
||||||
|
@ -587,7 +587,7 @@
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
request: RequestParam; // 请求参数集合
|
request: RequestParam; // 请求参数集合
|
||||||
moduleTree?: ModuleTreeNode[]; // 模块树
|
moduleTree?: ModuleTreeNode[]; // 模块树
|
||||||
isCase?: boolean; // 是否是用例引用的组件
|
isCase?: boolean; // 是否是用例引用的组件,只显示请求参数和响应内容,响应内容默认为空且折叠
|
||||||
apiDetail?: RequestParam; // 用例引用的时候需要接口定义的数据
|
apiDetail?: RequestParam; // 用例引用的时候需要接口定义的数据
|
||||||
detailLoading?: boolean; // 详情加载状态
|
detailLoading?: boolean; // 详情加载状态
|
||||||
isDefinition?: boolean; // 是否是接口定义模式
|
isDefinition?: boolean; // 是否是接口定义模式
|
||||||
|
@ -608,7 +608,7 @@
|
||||||
update: string;
|
update: string;
|
||||||
};
|
};
|
||||||
}>();
|
}>();
|
||||||
const emit = defineEmits(['addDone']);
|
const emit = defineEmits(['addDone', 'execute']);
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -931,7 +931,8 @@
|
||||||
() =>
|
() =>
|
||||||
isHttpProtocol.value ||
|
isHttpProtocol.value ||
|
||||||
!props.isDefinition ||
|
!props.isDefinition ||
|
||||||
requestVModel.value.response?.requestResults[0]?.responseResult.responseCode
|
requestVModel.value.response?.requestResults[0]?.responseResult.responseCode ||
|
||||||
|
props.isCase
|
||||||
);
|
);
|
||||||
const splitBoxSize = ref<string | number>(!showResponse.value ? 1 : 0.6);
|
const splitBoxSize = ref<string | number>(!showResponse.value ? 1 : 0.6);
|
||||||
const activeLayout = ref<'horizontal' | 'vertical'>('vertical');
|
const activeLayout = ref<'horizontal' | 'vertical'>('vertical');
|
||||||
|
@ -1543,6 +1544,7 @@
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
makeRequestParams,
|
makeRequestParams,
|
||||||
|
changeVerticalExpand,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@
|
||||||
</template>
|
</template>
|
||||||
<template #method="{ record }">
|
<template #method="{ record }">
|
||||||
<a-select
|
<a-select
|
||||||
v-if="props.protocol === 'HTTP'"
|
v-if="props.protocol === 'HTTP' && hasAnyPermission(['PROJECT_API_DEFINITION:READ+UPDATE'])"
|
||||||
v-model:model-value="record.method"
|
v-model:model-value="record.method"
|
||||||
class="param-input w-full"
|
class="param-input w-full"
|
||||||
size="mini"
|
size="mini"
|
||||||
|
@ -96,6 +96,7 @@
|
||||||
</template>
|
</template>
|
||||||
<template #status="{ record }">
|
<template #status="{ record }">
|
||||||
<a-select
|
<a-select
|
||||||
|
v-if="hasAnyPermission(['PROJECT_API_DEFINITION:READ+UPDATE'])"
|
||||||
v-model:model-value="record.status"
|
v-model:model-value="record.status"
|
||||||
class="param-input w-full"
|
class="param-input w-full"
|
||||||
size="mini"
|
size="mini"
|
||||||
|
@ -108,16 +109,27 @@
|
||||||
<apiStatus :status="item" size="small" />
|
<apiStatus :status="item" size="small" />
|
||||||
</a-option>
|
</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
|
<apiStatus v-else :status="record.status" size="small" />
|
||||||
</template>
|
</template>
|
||||||
<template #action="{ record }">
|
<template #action="{ record }">
|
||||||
<MsButton type="text" class="!mr-0" @click="executeDefinition(record)">
|
<MsButton
|
||||||
|
v-permission="['PROJECT_API_DEFINITION:READ+EXECUTE']"
|
||||||
|
type="text"
|
||||||
|
class="!mr-0"
|
||||||
|
@click="executeDefinition(record)"
|
||||||
|
>
|
||||||
{{ t('apiTestManagement.execute') }}
|
{{ t('apiTestManagement.execute') }}
|
||||||
</MsButton>
|
</MsButton>
|
||||||
<a-divider direction="vertical" :margin="8"></a-divider>
|
<a-divider v-permission="['PROJECT_API_DEFINITION:READ+EXECUTE']" direction="vertical" :margin="8"></a-divider>
|
||||||
<MsButton type="text" class="!mr-0" @click="copyDefinition(record)">
|
<MsButton
|
||||||
|
v-permission="['PROJECT_API_DEFINITION:READ+ADD']"
|
||||||
|
type="text"
|
||||||
|
class="!mr-0"
|
||||||
|
@click="copyDefinition(record)"
|
||||||
|
>
|
||||||
{{ t('common.copy') }}
|
{{ t('common.copy') }}
|
||||||
</MsButton>
|
</MsButton>
|
||||||
<a-divider direction="vertical" :margin="8"></a-divider>
|
<a-divider v-permission="['PROJECT_API_DEFINITION:READ+ADD']" direction="vertical" :margin="8"></a-divider>
|
||||||
<MsTableMoreAction :list="tableMoreActionList" @select="handleTableMoreActionSelect($event, record)" />
|
<MsTableMoreAction :list="tableMoreActionList" @select="handleTableMoreActionSelect($event, record)" />
|
||||||
</template>
|
</template>
|
||||||
</ms-base-table>
|
</ms-base-table>
|
||||||
|
@ -263,6 +275,7 @@
|
||||||
import useModal from '@/hooks/useModal';
|
import useModal from '@/hooks/useModal';
|
||||||
import useTableStore from '@/hooks/useTableStore';
|
import useTableStore from '@/hooks/useTableStore';
|
||||||
import useAppStore from '@/store/modules/app';
|
import useAppStore from '@/store/modules/app';
|
||||||
|
import { hasAnyPermission } from '@/utils/permission';
|
||||||
|
|
||||||
import { ApiDefinitionDetail } from '@/models/apiTest/management';
|
import { ApiDefinitionDetail } from '@/models/apiTest/management';
|
||||||
import { DragSortParams } from '@/models/common';
|
import { DragSortParams } from '@/models/common';
|
||||||
|
@ -289,6 +302,13 @@
|
||||||
const refreshModuleTree: (() => Promise<any>) | undefined = inject('refreshModuleTree');
|
const refreshModuleTree: (() => Promise<any>) | undefined = inject('refreshModuleTree');
|
||||||
const keyword = ref('');
|
const keyword = ref('');
|
||||||
|
|
||||||
|
const hasOperationPermission = computed(() =>
|
||||||
|
hasAnyPermission([
|
||||||
|
'PROJECT_API_DEFINITION:READ+DELETE',
|
||||||
|
'PROJECT_API_DEFINITION:READ+ADD',
|
||||||
|
'PROJECT_API_DEFINITION:READ+EXECUTE',
|
||||||
|
])
|
||||||
|
);
|
||||||
let columns: MsTableColumn = [
|
let columns: MsTableColumn = [
|
||||||
{
|
{
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
|
@ -363,11 +383,11 @@
|
||||||
width: 180,
|
width: 180,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'common.operation',
|
title: hasOperationPermission.value ? 'common.operation' : '',
|
||||||
slotName: 'action',
|
slotName: 'action',
|
||||||
dataIndex: 'operation',
|
dataIndex: 'operation',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
width: 150,
|
width: hasOperationPermission.value ? 150 : 50,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(
|
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(
|
||||||
|
@ -398,10 +418,12 @@
|
||||||
{
|
{
|
||||||
label: 'common.edit',
|
label: 'common.edit',
|
||||||
eventTag: 'edit',
|
eventTag: 'edit',
|
||||||
|
permission: ['PROJECT_API_DEFINITION:READ+UPDATE'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'common.move',
|
label: 'common.move',
|
||||||
eventTag: 'move',
|
eventTag: 'move',
|
||||||
|
permission: ['PROJECT_API_DEFINITION:READ+UPDATE'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
moreAction: [
|
moreAction: [
|
||||||
|
@ -418,6 +440,7 @@
|
||||||
eventTag: 'delete',
|
eventTag: 'delete',
|
||||||
label: t('common.delete'),
|
label: t('common.delete'),
|
||||||
danger: true,
|
danger: true,
|
||||||
|
permission: ['PROJECT_API_DEFINITION:READ+DELETE'],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -236,9 +236,10 @@
|
||||||
</a-collapse-item>
|
</a-collapse-item>
|
||||||
<a-collapse-item
|
<a-collapse-item
|
||||||
v-if="
|
v-if="
|
||||||
previewDetail.responseDefinition &&
|
(previewDetail.responseDefinition &&
|
||||||
previewDetail.responseDefinition.length > 0 &&
|
previewDetail.responseDefinition.length > 0 &&
|
||||||
props.detail.protocol === 'HTTP'
|
props.detail.protocol === 'HTTP') ||
|
||||||
|
props.isCase
|
||||||
"
|
"
|
||||||
key="response"
|
key="response"
|
||||||
>
|
>
|
||||||
|
|
|
@ -83,11 +83,11 @@
|
||||||
import MsDetailCard from '@/components/pure/ms-detail-card/index.vue';
|
import MsDetailCard from '@/components/pure/ms-detail-card/index.vue';
|
||||||
import caseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
|
import caseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
|
||||||
import type { CaseLevel } from '@/components/business/ms-case-associate/types';
|
import type { CaseLevel } from '@/components/business/ms-case-associate/types';
|
||||||
import environmentSelect from '../../environmentSelect.vue';
|
|
||||||
import detailTab from '../api/preview/detail.vue';
|
import detailTab from '../api/preview/detail.vue';
|
||||||
import createAndEditCaseDrawer from './createAndEditCaseDrawer.vue';
|
import createAndEditCaseDrawer from './createAndEditCaseDrawer.vue';
|
||||||
import execute from './execute.vue';
|
|
||||||
import apiMethodName from '@/views/api-test/components/apiMethodName.vue';
|
import apiMethodName from '@/views/api-test/components/apiMethodName.vue';
|
||||||
|
import environmentSelect from '@/views/api-test/components/environmentSelect.vue';
|
||||||
|
import execute from '@/views/api-test/components/executeButton.vue';
|
||||||
import { RequestParam } from '@/views/api-test/components/requestComposition/index.vue';
|
import { RequestParam } from '@/views/api-test/components/requestComposition/index.vue';
|
||||||
import TabCaseChangeHistory from '@/views/api-test/management/components/management/case/tabContent/tabCaseChangeHistory.vue';
|
import TabCaseChangeHistory from '@/views/api-test/management/components/management/case/tabContent/tabCaseChangeHistory.vue';
|
||||||
import TabCaseDependency from '@/views/api-test/management/components/management/case/tabContent/tabCaseDependency.vue';
|
import TabCaseDependency from '@/views/api-test/management/components/management/case/tabContent/tabCaseDependency.vue';
|
||||||
|
@ -236,16 +236,28 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
:deep(.arco-tabs-nav) {
|
.arco-tabs {
|
||||||
border-bottom: 1px solid var(--color-text-n8);
|
@apply flex flex-col;
|
||||||
}
|
:deep(.arco-tabs-nav) {
|
||||||
:deep(.arco-tabs-nav-extra) {
|
border-bottom: 1px solid var(--color-text-n8);
|
||||||
line-height: 32px;
|
&-extra {
|
||||||
}
|
line-height: 32px;
|
||||||
:deep(.arco-tabs-content) {
|
}
|
||||||
@apply pt-0;
|
}
|
||||||
.arco-tabs-content-item {
|
:deep(.arco-tabs-content) {
|
||||||
@apply px-0;
|
@apply flex-1 pt-0;
|
||||||
|
.arco-tabs-content-item {
|
||||||
|
@apply px-0;
|
||||||
|
}
|
||||||
|
.arco-tabs-content-list {
|
||||||
|
@apply h-full;
|
||||||
|
}
|
||||||
|
.arco-tabs-content-list .arco-tabs-content-item:nth-of-type(1) .arco-tabs-pane {
|
||||||
|
@apply h-full overflow-hidden;
|
||||||
|
}
|
||||||
|
.arco-collapse {
|
||||||
|
height: calc(100% - 85px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:deep(.ms-detail-card-desc) {
|
:deep(.ms-detail-card-desc) {
|
||||||
|
|
|
@ -569,7 +569,7 @@
|
||||||
selectable: true,
|
selectable: true,
|
||||||
showSelectAll: true,
|
showSelectAll: true,
|
||||||
draggable: { type: 'handle', width: 32 },
|
draggable: { type: 'handle', width: 32 },
|
||||||
heightUsed: 308,
|
heightUsed: props.isApi ? 356 : 308,
|
||||||
});
|
});
|
||||||
const batchActions = {
|
const batchActions = {
|
||||||
baseAction: [
|
baseAction: [
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
/>
|
/>
|
||||||
<environmentSelect ref="environmentSelectRef" />
|
<environmentSelect ref="environmentSelectRef" />
|
||||||
<execute
|
<execute
|
||||||
|
ref="executeRef"
|
||||||
v-model:detail="detailForm"
|
v-model:detail="detailForm"
|
||||||
:environment-id="currentEnvConfig?.id as string"
|
:environment-id="currentEnvConfig?.id as string"
|
||||||
:request="requestCompositionRef?.makeRequestParams"
|
:request="requestCompositionRef?.makeRequestParams"
|
||||||
|
@ -56,10 +57,10 @@
|
||||||
<a-form-item field="status" :label="t('apiTestManagement.apiStatus')">
|
<a-form-item field="status" :label="t('apiTestManagement.apiStatus')">
|
||||||
<a-select v-model:model-value="detailForm.status" :placeholder="t('common.pleaseSelect')">
|
<a-select v-model:model-value="detailForm.status" :placeholder="t('common.pleaseSelect')">
|
||||||
<template #label>
|
<template #label>
|
||||||
<apiStatus :status="detailForm.status" />
|
<apiStatus :status="detailForm.status" size="small" />
|
||||||
</template>
|
</template>
|
||||||
<a-option v-for="item of Object.values(RequestDefinitionStatus)" :key="item" :value="item">
|
<a-option v-for="item of Object.values(RequestDefinitionStatus)" :key="item" :value="item">
|
||||||
<apiStatus :status="item" />
|
<apiStatus :status="item" size="small" />
|
||||||
</a-option>
|
</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
@ -82,7 +83,8 @@
|
||||||
:file-module-options-api="getTransferOptionsCase"
|
:file-module-options-api="getTransferOptionsCase"
|
||||||
:file-save-as-api="transferFileCase"
|
:file-save-as-api="transferFileCase"
|
||||||
:current-env-config="currentEnvConfig"
|
:current-env-config="currentEnvConfig"
|
||||||
:is-definition="true"
|
is-definition
|
||||||
|
@execute="(val: 'localExec' | 'serverExec')=>executeRef?.execute(val)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -98,10 +100,10 @@
|
||||||
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
|
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
|
||||||
import caseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
|
import caseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
|
||||||
import type { CaseLevel } from '@/components/business/ms-case-associate/types';
|
import type { CaseLevel } from '@/components/business/ms-case-associate/types';
|
||||||
import environmentSelect from '../../environmentSelect.vue';
|
|
||||||
import execute from './execute.vue';
|
|
||||||
import apiMethodName from '@/views/api-test/components/apiMethodName.vue';
|
import apiMethodName from '@/views/api-test/components/apiMethodName.vue';
|
||||||
import apiStatus from '@/views/api-test/components/apiStatus.vue';
|
import apiStatus from '@/views/api-test/components/apiStatus.vue';
|
||||||
|
import environmentSelect from '@/views/api-test/components/environmentSelect.vue';
|
||||||
|
import execute from '@/views/api-test/components/executeButton.vue';
|
||||||
import requestComposition, { RequestParam } from '@/views/api-test/components/requestComposition/index.vue';
|
import requestComposition, { RequestParam } from '@/views/api-test/components/requestComposition/index.vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -173,6 +175,7 @@
|
||||||
});
|
});
|
||||||
const detailForm = ref(cloneDeep(defaultDetail.value));
|
const detailForm = ref(cloneDeep(defaultDetail.value));
|
||||||
const isEdit = ref(false);
|
const isEdit = ref(false);
|
||||||
|
const executeRef = ref<InstanceType<typeof execute>>();
|
||||||
|
|
||||||
async function open(apiId: string, record?: ApiCaseDetail | RequestParam, isCopy?: boolean) {
|
async function open(apiId: string, record?: ApiCaseDetail | RequestParam, isCopy?: boolean) {
|
||||||
apiDefinitionId.value = apiId;
|
apiDefinitionId.value = apiId;
|
||||||
|
@ -185,10 +188,15 @@
|
||||||
// 创建或者复制的时候,请求参数为接口定义的请求参数
|
// 创建或者复制的时候,请求参数为接口定义的请求参数
|
||||||
detailForm.value = {
|
detailForm.value = {
|
||||||
...cloneDeep(defaultDetail.value),
|
...cloneDeep(defaultDetail.value),
|
||||||
headers: apiDetailInfo.value.headers ?? apiDetailInfo.value.request.headers,
|
...(apiDetailInfo.value.protocol === 'HTTP'
|
||||||
body: apiDetailInfo.value.body ?? apiDetailInfo.value.request.body,
|
? {
|
||||||
rest: apiDetailInfo.value.rest ?? apiDetailInfo.value.request.rest,
|
headers: apiDetailInfo.value.headers ?? apiDetailInfo.value.request.headers,
|
||||||
query: apiDetailInfo.value.query ?? apiDetailInfo.value.request.query,
|
body: apiDetailInfo.value?.body ?? apiDetailInfo.value.request.body,
|
||||||
|
rest: apiDetailInfo.value.rest ?? apiDetailInfo.value.request.rest,
|
||||||
|
query: apiDetailInfo.value.query ?? apiDetailInfo.value.request.query,
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
url: apiDetailInfo.value.url ?? apiDetailInfo.value.request.url,
|
||||||
};
|
};
|
||||||
// 复制
|
// 复制
|
||||||
if (isCopy) {
|
if (isCopy) {
|
||||||
|
@ -201,6 +209,8 @@
|
||||||
detailForm.value.isNew = false;
|
detailForm.value.isNew = false;
|
||||||
}
|
}
|
||||||
innerVisible.value = true;
|
innerVisible.value = true;
|
||||||
|
await nextTick();
|
||||||
|
requestCompositionRef.value?.changeVerticalExpand(false); // 响应内容默认折叠
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSaveCaseCancel() {
|
function handleSaveCaseCancel() {
|
||||||
|
@ -250,7 +260,16 @@
|
||||||
if (!isContinue) {
|
if (!isContinue) {
|
||||||
handleSaveCaseCancel();
|
handleSaveCaseCancel();
|
||||||
}
|
}
|
||||||
detailForm.value = cloneDeep(defaultDetail.value);
|
// 继续创建
|
||||||
|
detailForm.value = {
|
||||||
|
...cloneDeep(defaultDetail.value),
|
||||||
|
id: `case-${Date.now()}`,
|
||||||
|
headers: apiDetailInfo.value.headers ?? apiDetailInfo.value.request.headers,
|
||||||
|
body: apiDetailInfo.value.body ?? apiDetailInfo.value.request.body,
|
||||||
|
rest: apiDetailInfo.value.rest ?? apiDetailInfo.value.request.rest,
|
||||||
|
query: apiDetailInfo.value.query ?? apiDetailInfo.value.request.query,
|
||||||
|
url: apiDetailInfo.value.url ?? apiDetailInfo.value.request.url,
|
||||||
|
};
|
||||||
drawerLoading.value = false;
|
drawerLoading.value = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,20 +21,7 @@
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</template>
|
</template>
|
||||||
</MsEditableTab>
|
</MsEditableTab>
|
||||||
<a-select
|
<environmentSelect ref="environmentSelectRef" />
|
||||||
v-model:model-value="currentEnv"
|
|
||||||
:options="envOptions"
|
|
||||||
class="!w-[200px] pl-0 pr-[8px]"
|
|
||||||
:loading="envLoading"
|
|
||||||
allow-search
|
|
||||||
@change="initEnvironment"
|
|
||||||
>
|
|
||||||
<template #prefix>
|
|
||||||
<div class="flex cursor-pointer p-[8px]" @click.stop="goEnv">
|
|
||||||
<icon-location class="text-[var(--color-text-4)]" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</a-select>
|
|
||||||
</div>
|
</div>
|
||||||
<api
|
<api
|
||||||
v-show="(activeApiTab.id === 'all' && currentTab === 'api') || activeApiTab.type === 'api'"
|
v-show="(activeApiTab.id === 'all' && currentTab === 'api') || activeApiTab.type === 'api'"
|
||||||
|
@ -59,20 +46,19 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { SelectOptionData } from '@arco-design/web-vue';
|
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
|
||||||
import MsEditableTab from '@/components/pure/ms-editable-tab/index.vue';
|
import MsEditableTab from '@/components/pure/ms-editable-tab/index.vue';
|
||||||
import api from './api/index.vue';
|
import api from './api/index.vue';
|
||||||
import apiCase from './case/index.vue';
|
import apiCase from './case/index.vue';
|
||||||
import apiMethodName from '@/views/api-test/components/apiMethodName.vue';
|
import apiMethodName from '@/views/api-test/components/apiMethodName.vue';
|
||||||
|
import environmentSelect from '@/views/api-test/components/environmentSelect.vue';
|
||||||
import { RequestParam } from '@/views/api-test/components/requestComposition/index.vue';
|
import { RequestParam } from '@/views/api-test/components/requestComposition/index.vue';
|
||||||
|
|
||||||
// import MockTable from '@/views/api-test/management/components/management/mock/mockTable.vue';
|
// import MockTable from '@/views/api-test/management/components/management/mock/mockTable.vue';
|
||||||
import { getEnvironment, getEnvList, getProtocolList } from '@/api/modules/api-test/common';
|
import { getProtocolList } from '@/api/modules/api-test/common';
|
||||||
import { getLocalConfig } from '@/api/modules/user/index';
|
import { getLocalConfig } from '@/api/modules/user/index';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import router from '@/router';
|
|
||||||
import useAppStore from '@/store/modules/app';
|
import useAppStore from '@/store/modules/app';
|
||||||
|
|
||||||
import { ProtocolItem } from '@/models/apiTest/common';
|
import { ProtocolItem } from '@/models/apiTest/common';
|
||||||
|
@ -86,7 +72,6 @@
|
||||||
RequestMethods,
|
RequestMethods,
|
||||||
ResponseComposition,
|
ResponseComposition,
|
||||||
} from '@/enums/apiEnum';
|
} from '@/enums/apiEnum';
|
||||||
import { ProjectManagementRouteEnum } from '@/enums/routeEnum';
|
|
||||||
|
|
||||||
import { defaultBodyParams, defaultResponse, defaultResponseItem } from '@/views/api-test/components/config';
|
import { defaultBodyParams, defaultResponse, defaultResponseItem } from '@/views/api-test/components/config';
|
||||||
|
|
||||||
|
@ -230,49 +215,10 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const currentEnv = ref('');
|
|
||||||
const currentEnvConfig = ref<EnvConfig>();
|
|
||||||
const envLoading = ref(false);
|
|
||||||
const envOptions = ref<SelectOptionData[]>([]);
|
|
||||||
|
|
||||||
async function initEnvironment() {
|
|
||||||
try {
|
|
||||||
currentEnvConfig.value = await getEnvironment(currentEnv.value);
|
|
||||||
currentEnvConfig.value.id = currentEnv.value;
|
|
||||||
} catch (error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function initEnvList() {
|
|
||||||
try {
|
|
||||||
envLoading.value = true;
|
|
||||||
const res = await getEnvList(appStore.currentProjectId);
|
|
||||||
envOptions.value = res.map((item) => ({
|
|
||||||
label: item.name,
|
|
||||||
value: item.id,
|
|
||||||
}));
|
|
||||||
currentEnv.value = res[0]?.id || '';
|
|
||||||
initEnvironment();
|
|
||||||
} catch (error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(error);
|
|
||||||
} finally {
|
|
||||||
envLoading.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshApiTable() {
|
function refreshApiTable() {
|
||||||
apiRef.value?.refreshTable();
|
apiRef.value?.refreshTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
function goEnv() {
|
|
||||||
router.push({
|
|
||||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_ENVIRONMENT_MANAGEMENT,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同步模块树的接口信息更新操作
|
* 同步模块树的接口信息更新操作
|
||||||
*/
|
*/
|
||||||
|
@ -333,7 +279,7 @@
|
||||||
const apiLocalExec = ref<Record<string, any> | LocalConfig | undefined>({});
|
const apiLocalExec = ref<Record<string, any> | LocalConfig | undefined>({});
|
||||||
async function initLocalConfig() {
|
async function initLocalConfig() {
|
||||||
try {
|
try {
|
||||||
const res = await getLocalConfig(); // TODO: 会报错
|
const res = await getLocalConfig();
|
||||||
apiLocalExec.value = res.find((e) => e.type === 'API');
|
apiLocalExec.value = res.find((e) => e.type === 'API');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
|
@ -341,8 +287,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const environmentSelectRef = ref<InstanceType<typeof environmentSelect>>();
|
||||||
|
const currentEnvConfig = computed<EnvConfig | undefined>(() => environmentSelectRef.value?.currentEnvConfig);
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
initEnvList();
|
|
||||||
initProtocolList();
|
initProtocolList();
|
||||||
initLocalConfig();
|
initLocalConfig();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue