fix(接口测试): csv文件类型限制&场景步骤调整

This commit is contained in:
baiqi 2024-05-17 14:43:30 +08:00 committed by Craftsman
parent 586417e1bf
commit b84a874aa9
12 changed files with 234 additions and 214 deletions

View File

@ -8,7 +8,7 @@
<template #content> <template #content>
<MsUpload <MsUpload
v-model:file-list="innerFileList" v-model:file-list="innerFileList"
accept="none" :accept="props.accept || 'none'"
:auto-upload="false" :auto-upload="false"
:show-file-list="false" :show-file-list="false"
:limit="50" :limit="50"
@ -38,12 +38,13 @@
<script setup lang="ts"> <script setup lang="ts">
import MsIcon from '@/components/pure/ms-icon-font/index.vue'; import MsIcon from '@/components/pure/ms-icon-font/index.vue';
import MsUpload from '@/components/pure/ms-upload/index.vue'; import MsUpload from '@/components/pure/ms-upload/index.vue';
import { MsFileItem } from '@/components/pure/ms-upload/types'; import { MsFileItem, UploadType } from '@/components/pure/ms-upload/types';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
const props = defineProps<{ const props = defineProps<{
disabled?: boolean; disabled?: boolean;
accept?: UploadType;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{

View File

@ -51,6 +51,7 @@
<dropdownMenu <dropdownMenu
:file-list="fileList" :file-list="fileList"
:disabled="props.disabled" :disabled="props.disabled"
:accept="props.accept"
@link-file="associatedFile" @link-file="associatedFile"
@change="handleChange" @change="handleChange"
/> />
@ -186,7 +187,12 @@
</a-popover> </a-popover>
</div> </div>
<div v-else class="flex w-full items-center gap-[4px]"> <div v-else class="flex w-full items-center gap-[4px]">
<dropdownMenu :disabled="props.disabled" @link-file="associatedFile" @change="handleChange" /> <dropdownMenu
:accept="props.accept"
:disabled="props.disabled"
@link-file="associatedFile"
@change="handleChange"
/>
<a-input <a-input
v-model:model-value="inputFileName" v-model:model-value="inputFileName"
:disabled="props.disabled" :disabled="props.disabled"
@ -206,6 +212,7 @@
:get-list-request="getAssociatedFileListUrl" :get-list-request="getAssociatedFileListUrl"
:get-list-fun-params="getListFunParams" :get-list-fun-params="getListFunParams"
:selector-type="props.multiple ? 'checkbox' : 'radio'" :selector-type="props.multiple ? 'checkbox' : 'radio'"
:filetype="props.accept"
@save="saveSelectAssociatedFile" @save="saveSelectAssociatedFile"
/> />
</template> </template>
@ -218,7 +225,7 @@
import MsTag, { Size } from '@/components/pure/ms-tag/ms-tag.vue'; import MsTag, { Size } from '@/components/pure/ms-tag/ms-tag.vue';
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue'; import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
import MsUpload from '@/components/pure/ms-upload/index.vue'; import MsUpload from '@/components/pure/ms-upload/index.vue';
import type { MsFileItem } from '@/components/pure/ms-upload/types'; import type { MsFileItem, UploadType } from '@/components/pure/ms-upload/types';
import LinkFileDrawer from '@/components/business/ms-link-file/associatedFileDrawer.vue'; import LinkFileDrawer from '@/components/business/ms-link-file/associatedFileDrawer.vue';
import dropdownMenu from './dropdownMenu.vue'; import dropdownMenu from './dropdownMenu.vue';
import saveAsFilePopover from './saveAsFilePopover.vue'; import saveAsFilePopover from './saveAsFilePopover.vue';
@ -237,6 +244,7 @@
defineProps<{ defineProps<{
disabled?: boolean; disabled?: boolean;
mode?: 'button' | 'input'; mode?: 'button' | 'input';
accept?: UploadType;
multiple?: boolean; multiple?: boolean;
inputClass?: string; inputClass?: string;
inputSize?: 'small' | 'medium' | 'large' | 'mini'; inputSize?: 'small' | 'medium' | 'large' | 'mini';

View File

@ -73,6 +73,7 @@
:get-list-fun-params="props.getListFunParams" :get-list-fun-params="props.getListFunParams"
:selector-type="props.selectorType" :selector-type="props.selectorType"
:file-all-count-by-storage="fileAllCountByStorage" :file-all-count-by-storage="fileAllCountByStorage"
:filetype="props.filetype"
@init="handleModuleTableInit" @init="handleModuleTableInit"
/> />
</template> </template>
@ -105,6 +106,7 @@
getListRequest: (params: TableQueryParams) => Promise<CommonList<AssociatedList>>; // getListRequest: (params: TableQueryParams) => Promise<CommonList<AssociatedList>>; //
getListFunParams: TableQueryParams; // id getListFunParams: TableQueryParams; // id
selectorType?: 'none' | 'checkbox' | 'radio'; selectorType?: 'none' | 'checkbox' | 'radio';
filetype?: string;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{

View File

@ -6,7 +6,13 @@
><span class="ml-[4px] text-[var(--color-text-4)]">({{ moduleInfo.count }})</span></div ><span class="ml-[4px] text-[var(--color-text-4)]">({{ moduleInfo.count }})</span></div
> >
<div class="header-right"> <div class="header-right">
<a-select v-model="tableFileType" class="w-[240px]" :loading="fileTypeLoading" @change="searchList"> <a-select
v-model="tableFileType"
class="w-[240px]"
:loading="fileTypeLoading"
:disabled="!!props.filetype"
@change="searchList"
>
<a-option key="" value="">{{ t('common.all') }}</a-option> <a-option key="" value="">{{ t('common.all') }}</a-option>
<a-option v-for="item of tableFileTypeOptions" :key="item" :value="item"> <a-option v-for="item of tableFileTypeOptions" :key="item" :value="item">
{{ item }} {{ item }}
@ -91,6 +97,7 @@
getListFunParams: TableQueryParams; // getListFunParams: TableQueryParams; //
selectorType?: 'none' | 'checkbox' | 'radio'; selectorType?: 'none' | 'checkbox' | 'radio';
fileAllCountByStorage: number; fileAllCountByStorage: number;
filetype?: string;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'init', params: FileListQueryParams): void; (e: 'init', params: FileListQueryParams): void;
@ -98,7 +105,7 @@
}>(); }>();
const tableFileTypeOptions = ref<string[]>([]); const tableFileTypeOptions = ref<string[]>([]);
const tableFileType = ref(''); // const tableFileType = ref(props.filetype || ''); //
const keyword = ref(''); const keyword = ref('');
const fileTypeLoading = ref(false); const fileTypeLoading = ref(false);
const fileType = ref('module'); // / const fileType = ref('module'); // /
@ -249,7 +256,7 @@
} else { } else {
res = await getFileTypes(appStore.currentProjectId); res = await getFileTypes(appStore.currentProjectId);
} }
tableFileType.value = ''; tableFileType.value = props.filetype || '';
tableFileTypeOptions.value = res; tableFileTypeOptions.value = res;
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console

View File

@ -260,6 +260,7 @@
id: 'fileId', id: 'fileId',
name: 'fileAlias', name: 'fileAlias',
}" }"
:accept="columnConfig.accept"
:file-save-as-source-id="props.fileSaveAsSourceId" :file-save-as-source-id="props.fileSaveAsSourceId"
:file-save-as-api="props.fileSaveAsApi" :file-save-as-api="props.fileSaveAsApi"
:file-module-options-api="props.fileModuleOptionsApi" :file-module-options-api="props.fileModuleOptionsApi"
@ -280,7 +281,7 @@
/> />
</template> </template>
<!-- 文件 --> <!-- 文件 -->
<template #file="{ record, rowIndex }"> <template #file="{ record, rowIndex, columnConfig }">
<MsAddAttachment <MsAddAttachment
:file-list="[record.file]" :file-list="[record.file]"
:disabled="props.disabledParamValue" :disabled="props.disabledParamValue"
@ -290,6 +291,7 @@
id: 'fileId', id: 'fileId',
name: 'fileAlias', name: 'fileAlias',
}" }"
:accept="columnConfig.accept"
:file-save-as-source-id="props.fileSaveAsSourceId" :file-save-as-source-id="props.fileSaveAsSourceId"
:file-save-as-api="props.fileSaveAsApi" :file-save-as-api="props.fileSaveAsApi"
:file-module-options-api="props.fileModuleOptionsApi" :file-module-options-api="props.fileModuleOptionsApi"
@ -619,7 +621,7 @@
import { ActionsItem } from '@/components/pure/ms-table-more-action/types'; import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
import MsTagsGroup from '@/components/pure/ms-tag/ms-tag-group.vue'; import MsTagsGroup from '@/components/pure/ms-tag/ms-tag-group.vue';
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue'; import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
import { MsFileItem } from '@/components/pure/ms-upload/types'; import { MsFileItem, UploadType } from '@/components/pure/ms-upload/types';
import MsSelect from '@/components/business/ms-select/index'; import MsSelect from '@/components/business/ms-select/index';
import paramDescInput from './paramDescInput.vue'; import paramDescInput from './paramDescInput.vue';
import DomainModal from '@/views/project-management/environmental/components/envParams/popUp/domain.vue'; import DomainModal from '@/views/project-management/environmental/components/envParams/popUp/domain.vue';
@ -656,6 +658,7 @@
format?: RequestBodyFormat; // operation format?: RequestBodyFormat; // operation
addLineDisabled?: boolean; // addLineDisabled?: boolean; //
disabledColumn?: boolean; // disabledColumn?: boolean; //
accept?: UploadType; // accept
} }
const props = withDefaults( const props = withDefaults(

View File

@ -169,6 +169,7 @@
title: 'apiScenario.params.file', title: 'apiScenario.params.file',
dataIndex: 'file', dataIndex: 'file',
slotName: 'file', slotName: 'file',
accept: 'csv',
}, },
{ {
title: 'apiScenario.table.columns.status', title: 'apiScenario.table.columns.status',

View File

@ -30,6 +30,7 @@
{{ title }} {{ title }}
</div> </div>
<MsIcon <MsIcon
v-if="!props.step || !props.step.isQuoteScenarioStep"
type="icon-icon_edit_outlined" type="icon-icon_edit_outlined"
class="cursor-pointer hover:text-[rgb(var(--primary-5))]" class="cursor-pointer hover:text-[rgb(var(--primary-5))]"
@click="isShowEditStepNameInput = true" @click="isShowEditStepNameInput = true"

View File

@ -35,6 +35,7 @@
> >
</a-tooltip> </a-tooltip>
<MsIcon <MsIcon
v-if="!activeStep || !activeStep.isQuoteScenarioStep"
type="icon-icon_edit_outlined" type="icon-icon_edit_outlined"
class="cursor-pointer hover:text-[rgb(var(--primary-5))]" class="cursor-pointer hover:text-[rgb(var(--primary-5))]"
@click="showEditScriptNameInput" @click="showEditScriptNameInput"

View File

@ -480,7 +480,6 @@
import saveAsApiModal from '@/views/api-test/components/saveAsApiModal.vue'; import saveAsApiModal from '@/views/api-test/components/saveAsApiModal.vue';
import { addCase, getDefinitionDetail } from '@/api/modules/api-test/management'; import { addCase, getDefinitionDetail } from '@/api/modules/api-test/management';
import { getScenarioDetail, getScenarioStep } from '@/api/modules/api-test/scenario';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal'; import useModal from '@/hooks/useModal';
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
@ -495,7 +494,6 @@
import { import {
CreateStepAction, CreateStepAction,
Scenario, Scenario,
ScenarioStepConfig,
ScenarioStepDetails, ScenarioStepDetails,
ScenarioStepFileParams, ScenarioStepFileParams,
ScenarioStepItem, ScenarioStepItem,
@ -514,7 +512,6 @@
import useStepNodeEdit from './useStepNodeEdit'; import useStepNodeEdit from './useStepNodeEdit';
import useStepOperation from './useStepOperation'; import useStepOperation from './useStepOperation';
import { casePriorityOptions, caseStatusOptions } from '@/views/api-test/components/config'; import { casePriorityOptions, caseStatusOptions } from '@/views/api-test/components/config';
import { parseRequestBodyFiles } from '@/views/api-test/components/utils';
import getStepType from '@/views/api-test/scenario/components/common/stepType/utils'; import getStepType from '@/views/api-test/scenario/components/common/stepType/utils';
import { defaultStepItemCommon } from '@/views/api-test/scenario/components/config'; import { defaultStepItemCommon } from '@/views/api-test/scenario/components/config';
@ -728,151 +725,68 @@
return stepMoreActions; return stepMoreActions;
} }
const scenarioConfigForm = ref<
ScenarioStepConfig & {
refType: ScenarioStepRefType;
}
>({
refType: ScenarioStepRefType.REF,
enableScenarioEnv: false,
useOriginScenarioParamPreferential: true,
useOriginScenarioParam: false,
});
const showScenarioConfig = ref(false); const showScenarioConfig = ref(false);
// const scenarioConfigParamTip = computed(() => {
// if (!scenarioConfigForm.value.useOriginScenarioParam && !scenarioConfigForm.value.enableScenarioEnv) {
// // 使-
// return t('apiScenario.notSource');
// }
// if (!scenarioConfigForm.value.useOriginScenarioParam && scenarioConfigForm.value.enableScenarioEnv) {
// // 使-
// return t('apiScenario.notSourceParamAndSourceEnv');
// }
// if (
// scenarioConfigForm.value.useOriginScenarioParam &&
// scenarioConfigForm.value.useOriginScenarioParamPreferential &&
// !scenarioConfigForm.value.enableScenarioEnv
// ) {
// // 使-使
// return t('apiScenario.sourceParamAndSource');
// }
// if (
// scenarioConfigForm.value.useOriginScenarioParam &&
// scenarioConfigForm.value.useOriginScenarioParamPreferential &&
// scenarioConfigForm.value.enableScenarioEnv
// ) {
// // 使-使-
// return t('apiScenario.sourceParamAndSourceEnv');
// }
// if (
// scenarioConfigForm.value.useOriginScenarioParam &&
// !scenarioConfigForm.value.useOriginScenarioParamPreferential &&
// !scenarioConfigForm.value.enableScenarioEnv
// ) {
// // 使-使
// return t('apiScenario.currentParamAndSource');
// }
// if (
// scenarioConfigForm.value.useOriginScenarioParam &&
// !scenarioConfigForm.value.useOriginScenarioParamPreferential &&
// scenarioConfigForm.value.enableScenarioEnv
// ) {
// // 使-使-
// return t('apiScenario.currentParamAndSourceEnv');
// }
// });
//
function cancelScenarioConfig() {
showScenarioConfig.value = false;
scenarioConfigForm.value = {
refType: ScenarioStepRefType.REF,
enableScenarioEnv: false,
useOriginScenarioParamPreferential: true,
useOriginScenarioParam: false,
};
}
/** /**
* 刷新引用场景的步骤数据 * 处理apicase场景步骤名称编辑
*/ */
async function refreshScenarioStepInfo(step: ScenarioStepItem, id: string | number) { const showStepNameEditInputStepId = ref<string | number>('');
try { const tempStepName = ref('');
loading.value = true; /**
const res = await getScenarioDetail(id); * 处理非 apicase场景步骤名称编辑
if (step.children) { */
step.children = mapTree(res.steps || [], (child) => { const showStepDescEditInputStepId = ref<string | number>('');
child.uniqueId = getGenerateId(); const tempStepDesc = ref('');
child.isQuoteScenarioStep = true; // const importApiDrawerVisible = ref(false);
child.isRefScenarioStep = true; // const customCaseDrawerVisible = ref(false);
child.draggable = false; // const customApiDrawerVisible = ref(false);
if (selectedKeys.value.includes(step.uniqueId) && !selectedKeys.value.includes(child.uniqueId)) { const scriptOperationDrawerVisible = ref(false);
//
selectedKeys.value.push(child.uniqueId);
}
return child;
}) as ScenarioStepItem[];
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
loading.value = false;
}
}
// const { handleStepExpand, handleStepSelect, deleteStep, handleDrop, getStepDetail } = useStepOperation({
async function saveScenarioConfig() { scenario,
if (activeStep.value) { steps,
const realStep = findNodeByKey<ScenarioStepItem>(steps.value, activeStep.value.uniqueId, 'uniqueId'); stepDetails,
if (realStep) { activeStep,
realStep.refType = scenarioConfigForm.value.refType; // selectedKeys,
realStep.config = { customApiDrawerVisible,
...realStep.config, customCaseDrawerVisible,
...scenarioConfigForm.value, scriptOperationDrawerVisible,
}; loading,
if (scenarioConfigForm.value.refType === ScenarioStepRefType.REF) {
//
await refreshScenarioStepInfo(realStep as ScenarioStepItem, realStep.resourceId);
} else {
realStep.children = mapTree<ScenarioStepItem>(realStep.children || [], (child) => {
// -
child.isRefScenarioStep = false;
return child;
}); });
}
Message.success(t('apiScenario.setSuccess'));
scenario.value.unSaved = true;
cancelScenarioConfig();
}
}
}
async function getStepDetail(step: ScenarioStepItem) { const showQuickInput = ref(false);
try { const quickInputParamValue = ref<any>('');
appStore.showLoading(); const quickInputDataKey = ref('');
const res = await getScenarioStep(step.copyFromStepId || step.id);
let parseRequestBodyResult; const {
if (step.config.protocol === 'HTTP' && res.body) { setQuickInput,
parseRequestBodyResult = parseRequestBodyFiles(res.body); // id clearQuickInput,
} applyQuickInput,
stepDetails.value[step.id] = { handleStepDescClick,
...res, applyStepDescChange,
stepId: step.id, handleStepContentChange,
protocol: step.config.protocol || '', handleStepToggleEnable,
method: step.config.method || '', handleStepNameClick,
...parseRequestBodyResult, applyStepNameChange,
}; saveScenarioConfig,
scenario.value.stepFileParam[step.id] = { cancelScenarioConfig,
...parseRequestBodyResult, scenarioConfigForm,
}; } = useStepNodeEdit({
} catch (error) { steps,
// eslint-disable-next-line no-console scenario,
console.log(error); activeStep,
} finally { quickInputDataKey,
appStore.hideLoading(); quickInputParamValue,
} showQuickInput,
} treeRef,
tempStepDesc,
showStepDescEditInputStepId,
tempStepName,
showStepNameEditInputStepId,
loading,
selectedKeys,
showScenarioConfig,
});
const saveNewApiModalVisible = ref(false); const saveNewApiModalVisible = ref(false);
const tempApiDetail = ref<RequestParam>(); const tempApiDetail = ref<RequestParam>();
@ -1109,20 +1023,6 @@
treeRef.value?.checkAll(val); treeRef.value?.checkAll(val);
} }
/**
* 处理apicase场景步骤名称编辑
*/
const showStepNameEditInputStepId = ref<string | number>('');
const tempStepName = ref('');
/**
* 处理非 apicase场景步骤名称编辑
*/
const showStepDescEditInputStepId = ref<string | number>('');
const tempStepDesc = ref('');
const importApiDrawerVisible = ref(false);
const customCaseDrawerVisible = ref(false);
const customApiDrawerVisible = ref(false);
const scriptOperationDrawerVisible = ref(false);
const activeCreateAction = ref<CreateStepAction>(); // const activeCreateAction = ref<CreateStepAction>(); //
const currentStepDetail = computed<ScenarioStepDetails | undefined>(() => { const currentStepDetail = computed<ScenarioStepDetails | undefined>(() => {
if (activeStep.value) { if (activeStep.value) {
@ -1143,18 +1043,6 @@
scenario.value.unSaved = true; scenario.value.unSaved = true;
} }
const { handleStepExpand, handleStepSelect, deleteStep, handleDrop } = useStepOperation({
scenario,
steps,
stepDetails,
activeStep,
selectedKeys,
customApiDrawerVisible,
customCaseDrawerVisible,
scriptOperationDrawerVisible,
loading,
});
function handleReplaceStep(newStep: ScenarioStepItem) { function handleReplaceStep(newStep: ScenarioStepItem) {
if (activeStep.value) { if (activeStep.value) {
// //
@ -1343,14 +1231,13 @@
} }
if (activeStep.value) { if (activeStep.value) {
const _stepType = getStepType(activeStep.value); const _stepType = getStepType(activeStep.value);
if (_stepType.isQuoteCase || activeStep.value.isQuoteScenarioStep) { if (_stepType.isQuoteCase && !activeStep.value.isQuoteScenarioStep) {
// case
activeStep.value.name = request.stepName || request.name; activeStep.value.name = request.stepName || request.name;
stepDetails.value[activeStep.value.id] = request; // polymorphicName stepDetails.value[activeStep.value.id] = request; // polymorphicName
return; return;
} }
} }
if (activeStep.value) { if (activeStep.value && !activeStep.value.isQuoteScenarioStep) {
request.isNew = false; request.isNew = false;
stepDetails.value[activeStep.value.id] = request; stepDetails.value[activeStep.value.id] = request;
scenario.value.stepFileParam[activeStep.value?.id] = { scenario.value.stepFileParam[activeStep.value?.id] = {
@ -1363,10 +1250,9 @@
...activeStep.value.config, ...activeStep.value.config,
method: request.method, method: request.method,
}; };
activeStep.value.name = request.stepName || request.name;
emit('updateResource', request.uploadFileIds, request.linkFileIds); emit('updateResource', request.uploadFileIds, request.linkFileIds);
activeStep.value = undefined;
} }
activeStep.value = undefined;
} }
/** /**
@ -1408,7 +1294,8 @@
} }
function saveScriptStep(name: string, scriptProcessor: ExecuteConditionProcessor, unSaved = false) { function saveScriptStep(name: string, scriptProcessor: ExecuteConditionProcessor, unSaved = false) {
if (activeStep.value) { if (activeStep.value && !activeStep.value.isQuoteScenarioStep) {
//
stepDetails.value[activeStep.value.id] = cloneDeep(scriptProcessor); stepDetails.value[activeStep.value.id] = cloneDeep(scriptProcessor);
activeStep.value.name = name; activeStep.value.name = name;
activeStep.value = undefined; activeStep.value = undefined;
@ -1418,34 +1305,6 @@
} }
} }
const showQuickInput = ref(false);
const quickInputParamValue = ref<any>('');
const quickInputDataKey = ref('');
const {
setQuickInput,
clearQuickInput,
applyQuickInput,
handleStepDescClick,
applyStepDescChange,
handleStepContentChange,
handleStepToggleEnable,
handleStepNameClick,
applyStepNameChange,
} = useStepNodeEdit({
steps,
scenario,
activeStep,
quickInputDataKey,
quickInputParamValue,
showQuickInput,
treeRef,
tempStepDesc,
showStepDescEditInputStepId,
tempStepName,
showStepNameEditInputStepId,
});
const dbClick = ref({ const dbClick = ref({
e: null as MouseEvent | null, e: null as MouseEvent | null,
timeStamp: 0, timeStamp: 0,

View File

@ -1,8 +1,13 @@
import { Message } from '@arco-design/web-vue';
import MsTree from '@/components/business/ms-tree/index.vue'; import MsTree from '@/components/business/ms-tree/index.vue';
import { findNodeByKey } from '@/utils'; import { getScenarioDetail } from '@/api/modules/api-test/scenario';
import { t } from '@/hooks/useI18n';
import { findNodeByKey, getGenerateId, mapTree } from '@/utils';
import type { Scenario, ScenarioStepDetail, ScenarioStepItem } from '@/models/apiTest/scenario'; import type { Scenario, ScenarioStepConfig, ScenarioStepDetail, ScenarioStepItem } from '@/models/apiTest/scenario';
import { ScenarioStepRefType } from '@/enums/apiEnum';
/** /**
* *
@ -19,6 +24,9 @@ export default function useStepNodeEdit({
showStepDescEditInputStepId, showStepDescEditInputStepId,
tempStepName, tempStepName,
showStepNameEditInputStepId, showStepNameEditInputStepId,
loading,
selectedKeys,
showScenarioConfig,
}: { }: {
steps: Ref<ScenarioStepItem[]>; steps: Ref<ScenarioStepItem[]>;
scenario: Ref<Scenario>; scenario: Ref<Scenario>;
@ -31,6 +39,9 @@ export default function useStepNodeEdit({
showStepDescEditInputStepId: Ref<string | number>; showStepDescEditInputStepId: Ref<string | number>;
tempStepName: Ref<string>; tempStepName: Ref<string>;
showStepNameEditInputStepId: Ref<string | number>; showStepNameEditInputStepId: Ref<string | number>;
loading: Ref<boolean>;
selectedKeys: Ref<Array<string | number>>;
showScenarioConfig: Ref<boolean>;
}) { }) {
/** /**
* *
@ -162,6 +173,125 @@ export default function useStepNodeEdit({
scenario.value.unSaved = !!tempStepName.value; scenario.value.unSaved = !!tempStepName.value;
} }
const scenarioConfigForm = ref<
ScenarioStepConfig & {
refType: ScenarioStepRefType;
}
>({
refType: ScenarioStepRefType.REF,
enableScenarioEnv: false,
useOriginScenarioParamPreferential: true,
useOriginScenarioParam: false,
});
// const scenarioConfigParamTip = computed(() => {
// if (!scenarioConfigForm.value.useOriginScenarioParam && !scenarioConfigForm.value.enableScenarioEnv) {
// // 非使用原场景参数-非选择源场景环境
// return t('apiScenario.notSource');
// }
// if (!scenarioConfigForm.value.useOriginScenarioParam && scenarioConfigForm.value.enableScenarioEnv) {
// // 非使用原场景参数-选择源场景环境
// return t('apiScenario.notSourceParamAndSourceEnv');
// }
// if (
// scenarioConfigForm.value.useOriginScenarioParam &&
// scenarioConfigForm.value.useOriginScenarioParamPreferential &&
// !scenarioConfigForm.value.enableScenarioEnv
// ) {
// // 使用原场景参数-优先使用原场景参数
// return t('apiScenario.sourceParamAndSource');
// }
// if (
// scenarioConfigForm.value.useOriginScenarioParam &&
// scenarioConfigForm.value.useOriginScenarioParamPreferential &&
// scenarioConfigForm.value.enableScenarioEnv
// ) {
// // 使用原场景参数-优先使用原场景参数-选择源场景环境
// return t('apiScenario.sourceParamAndSourceEnv');
// }
// if (
// scenarioConfigForm.value.useOriginScenarioParam &&
// !scenarioConfigForm.value.useOriginScenarioParamPreferential &&
// !scenarioConfigForm.value.enableScenarioEnv
// ) {
// // 使用原场景参数-优先使用当前场景参数
// return t('apiScenario.currentParamAndSource');
// }
// if (
// scenarioConfigForm.value.useOriginScenarioParam &&
// !scenarioConfigForm.value.useOriginScenarioParamPreferential &&
// scenarioConfigForm.value.enableScenarioEnv
// ) {
// // 使用原场景参数-优先使用当前场景参数-选择源场景环境
// return t('apiScenario.currentParamAndSourceEnv');
// }
// });
// 关闭场景配置弹窗
function cancelScenarioConfig() {
showScenarioConfig.value = false;
scenarioConfigForm.value = {
refType: ScenarioStepRefType.REF,
enableScenarioEnv: false,
useOriginScenarioParamPreferential: true,
useOriginScenarioParam: false,
};
}
/**
*
*/
async function refreshScenarioStepInfo(step: ScenarioStepItem, id: string | number) {
try {
loading.value = true;
const res = await getScenarioDetail(id);
if (step.children) {
step.children = mapTree(res.steps || [], (child) => {
child.uniqueId = getGenerateId();
child.isQuoteScenarioStep = true; // 标记为引用场景下的子步骤
child.isRefScenarioStep = true; // 标记为完全引用场景
child.draggable = false; // 引用场景下的任何步骤不可拖拽
if (selectedKeys.value.includes(step.uniqueId) && !selectedKeys.value.includes(child.uniqueId)) {
// 如果有新增的子步骤,且当前步骤被选中,则这个新增的子步骤也要选中
selectedKeys.value.push(child.uniqueId);
}
return child;
}) as ScenarioStepItem[];
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
loading.value = false;
}
}
// 应用场景配置
async function saveScenarioConfig() {
if (activeStep.value) {
const realStep = findNodeByKey<ScenarioStepItem>(steps.value, activeStep.value.uniqueId, 'uniqueId');
if (realStep) {
realStep.refType = scenarioConfigForm.value.refType; // 更新场景引用类型
realStep.config = {
...realStep.config,
...scenarioConfigForm.value,
};
if (scenarioConfigForm.value.refType === ScenarioStepRefType.REF) {
// 更新子孙步骤完全引用
await refreshScenarioStepInfo(realStep as ScenarioStepItem, realStep.resourceId);
} else {
realStep.children = mapTree<ScenarioStepItem>(realStep.children || [], (child) => {
// 更新子孙步骤-步骤引用
child.isRefScenarioStep = false;
return child;
});
}
Message.success(t('apiScenario.setSuccess'));
scenario.value.unSaved = true;
cancelScenarioConfig();
}
}
}
return { return {
setQuickInput, setQuickInput,
clearQuickInput, clearQuickInput,
@ -172,5 +302,8 @@ export default function useStepNodeEdit({
handleStepToggleEnable, handleStepToggleEnable,
handleStepNameClick, handleStepNameClick,
applyStepNameChange, applyStepNameChange,
saveScenarioConfig,
cancelScenarioConfig,
scenarioConfigForm,
}; };
} }

View File

@ -241,6 +241,7 @@ export default function useStepOperation({
} }
return { return {
getStepDetail,
handleStepExpand, handleStepExpand,
handleStepSelect, handleStepSelect,
deleteStep, deleteStep,

View File

@ -317,7 +317,10 @@
const waitTingDebugSteps = filterTree(activeScenarioTab.value.steps, (node) => { const waitTingDebugSteps = filterTree(activeScenarioTab.value.steps, (node) => {
if (node.enable) { if (node.enable) {
node.executeStatus = ScenarioExecuteStatus.EXECUTING; node.executeStatus = ScenarioExecuteStatus.EXECUTING;
if (!node.isQuoteScenarioStep) {
//
waitingDebugStepDetails[node.id] = activeScenarioTab.value.stepDetails[node.id]; waitingDebugStepDetails[node.id] = activeScenarioTab.value.stepDetails[node.id];
}
} else { } else {
node.executeStatus = undefined; node.executeStatus = undefined;
} }