feat(接口测试): 场景复制步骤&复制场景文件
This commit is contained in:
parent
e83985a2f5
commit
0608840cb0
|
@ -36,6 +36,7 @@ import {
|
|||
ScenarioAssociateExportUrl,
|
||||
ScenarioBatchEditScheduleUrl,
|
||||
ScenarioBatchExportLogUrl,
|
||||
ScenarioCopyStepFilesUrl,
|
||||
ScenarioExportLogUrl,
|
||||
ScenarioHistoryUrl,
|
||||
ScenarioPageUrl,
|
||||
|
@ -71,6 +72,7 @@ import {
|
|||
ExecuteHistoryItem,
|
||||
ExecutePageParams,
|
||||
type ExportScenarioParams,
|
||||
type GetScenarioUnSaveStepParams,
|
||||
GetSystemRequestParams,
|
||||
type ImportScenarioParams,
|
||||
ImportSystemData,
|
||||
|
@ -376,3 +378,11 @@ export function scenarioBatchEditSchedule(data: ApiScenarioBatchScheduleConfig)
|
|||
export function getScenarioStatistics(data: string[]) {
|
||||
return MSR.post<ScenarioStatisticsItem[]>({ url: ScenarioStatisticsUrl, data });
|
||||
}
|
||||
|
||||
// 复制步骤时复制文件
|
||||
export function scenarioCopyStepFiles(data: GetScenarioUnSaveStepParams) {
|
||||
return MSR.post<Record<string, any>>({
|
||||
url: ScenarioCopyStepFilesUrl,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ export const BatchRunScenarioUrl = '/api/scenario/batch-operation/run'; // 批
|
|||
export const UpdateScenarioPriorityUrl = '/api/scenario/update-priority'; // 场景更新等级
|
||||
export const UpdateScenarioStatusUrl = '/api/scenario/update-status'; // 场景更新状态
|
||||
export const ScenarioStatisticsUrl = '/api/scenario/statistics'; // 场景执行率统计
|
||||
export const ScenarioCopyStepFilesUrl = '/api/scenario/step/file/copy'; // 复制步骤时复制文件
|
||||
|
||||
// 场景导入导出相关
|
||||
export const ImportScenarioUrl = '/api/scenario/import'; // 导入场景
|
||||
|
|
|
@ -571,3 +571,13 @@ export interface ScenarioStatisticsItem {
|
|||
id: string;
|
||||
execPassRate: string;
|
||||
}
|
||||
|
||||
// 场景未保存步骤请求参数
|
||||
export interface GetScenarioUnSaveStepParams {
|
||||
copyFromStepId?: string;
|
||||
resourceId?: string;
|
||||
stepType?: string;
|
||||
refType: string;
|
||||
isTempFile: boolean; // 复制未保存的步骤时 true
|
||||
fileIds?: string[]; // 未保存的步骤文件 id,复制未加载/修改过详情的步骤时无需传
|
||||
}
|
||||
|
|
|
@ -31,12 +31,17 @@ export interface ParseResult {
|
|||
/**
|
||||
* 解析接口请求/Mock body 内的文件列表
|
||||
* @param body body 参数对象
|
||||
* @param response 响应列表
|
||||
* @param saveUploadFileIds 已保存的上传文件 id 集合
|
||||
* @param saveLinkFileIds 已保存的关联文件 id 集合
|
||||
* @param newFileMap 新文件 id 映射
|
||||
*/
|
||||
export function parseRequestBodyFiles(
|
||||
body: ExecuteBody | MockBody,
|
||||
response?: ResponseDefinition[],
|
||||
saveUploadFileIds?: string[],
|
||||
saveLinkFileIds?: string[]
|
||||
saveLinkFileIds?: string[],
|
||||
newFileMap?: Record<string, string>
|
||||
): ParseResult {
|
||||
const { binaryBody } = body;
|
||||
const uploadFileIds = new Set<string>(); // 存储本地上传的文件 id 集合
|
||||
|
@ -45,49 +50,58 @@ export function parseRequestBodyFiles(
|
|||
const tempSaveLinkFileIds = new Set<string>(); // 临时存储 body 内已保存的关联文件 id 集合,用于对比 saveLinkFileIds 以判断有哪些文件被取消关联
|
||||
// 获取上传文件和关联文件
|
||||
const formValues =
|
||||
((body as ExecuteBody).formDataBody?.formValues || (body as MockBody).formDataBody?.matchRules || []).filter(
|
||||
(e) => e
|
||||
) || [];
|
||||
(body as ExecuteBody).formDataBody?.formValues || (body as MockBody).formDataBody?.matchRules || [] || [];
|
||||
for (let i = 0; i < formValues.length; i++) {
|
||||
const item = formValues[i];
|
||||
if (item.paramType === RequestParamsType.FILE) {
|
||||
if (item.files) {
|
||||
for (let j = 0; j < item.files.length; j++) {
|
||||
const file = item.files[j];
|
||||
if (file.local) {
|
||||
// 本地上传的文件
|
||||
if (saveUploadFileIds) {
|
||||
// 如果有已保存的上传文件id集合
|
||||
if (saveUploadFileIds.includes(file.fileId)) {
|
||||
// 当前文件是已保存的文件,存入 tempSaveUploadFileIds
|
||||
tempSaveUploadFileIds.add(file.fileId);
|
||||
if (item) {
|
||||
if (item.paramType === RequestParamsType.FILE) {
|
||||
if (item.files) {
|
||||
for (let j = 0; j < item.files.length; j++) {
|
||||
const file = item.files[j];
|
||||
let { fileId } = file;
|
||||
if (newFileMap && newFileMap[fileId]) {
|
||||
fileId = newFileMap[fileId];
|
||||
file.fileId = fileId;
|
||||
}
|
||||
if (file.local) {
|
||||
// 本地上传的文件
|
||||
if (saveUploadFileIds) {
|
||||
// 如果有已保存的上传文件id集合
|
||||
if (saveUploadFileIds.includes(fileId)) {
|
||||
// 当前文件是已保存的文件,存入 tempSaveUploadFileIds
|
||||
tempSaveUploadFileIds.add(fileId);
|
||||
} else {
|
||||
// 当前文件不是已保存的文件,存入 uploadFileIds
|
||||
uploadFileIds.add(fileId);
|
||||
}
|
||||
} else {
|
||||
// 没有已保存的文件id集合,直接存入 uploadFileIds
|
||||
uploadFileIds.add(fileId);
|
||||
}
|
||||
} else if (saveLinkFileIds) {
|
||||
// 如果有已保存的关联文件id集合
|
||||
if (saveLinkFileIds.includes(fileId)) {
|
||||
// 当前文件是已保存的文件,存入
|
||||
tempSaveLinkFileIds.add(fileId);
|
||||
} else {
|
||||
// 当前文件不是已保存的文件,存入 uploadFileIds
|
||||
uploadFileIds.add(file.fileId);
|
||||
linkFileIds.add(fileId);
|
||||
}
|
||||
} else {
|
||||
// 没有已保存的文件id集合,直接存入 uploadFileIds
|
||||
uploadFileIds.add(file.fileId);
|
||||
// 关联的文件
|
||||
linkFileIds.add(fileId);
|
||||
}
|
||||
} else if (saveLinkFileIds) {
|
||||
// 如果有已保存的关联文件id集合
|
||||
if (saveLinkFileIds.includes(file.fileId)) {
|
||||
// 当前文件是已保存的文件,存入
|
||||
tempSaveLinkFileIds.add(file.fileId);
|
||||
} else {
|
||||
// 当前文件不是已保存的文件,存入 uploadFileIds
|
||||
linkFileIds.add(file.fileId);
|
||||
}
|
||||
} else {
|
||||
// 关联的文件
|
||||
linkFileIds.add(file.fileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (binaryBody && binaryBody.file) {
|
||||
const { fileId } = binaryBody.file;
|
||||
let { fileId } = binaryBody.file;
|
||||
if (newFileMap && newFileMap[fileId]) {
|
||||
fileId = newFileMap[fileId];
|
||||
binaryBody.file.fileId = fileId;
|
||||
}
|
||||
if (binaryBody.file?.local) {
|
||||
if (saveUploadFileIds) {
|
||||
// 如果有已保存的上传文件id集合
|
||||
|
@ -119,7 +133,11 @@ export function parseRequestBodyFiles(
|
|||
if (response) {
|
||||
response.forEach((res) => {
|
||||
if (res.body.binaryBody && res.body.binaryBody.file) {
|
||||
const { fileId } = res.body.binaryBody.file;
|
||||
let { fileId } = res.body.binaryBody.file;
|
||||
if (newFileMap && newFileMap[fileId]) {
|
||||
fileId = newFileMap[fileId];
|
||||
res.body.binaryBody.file.fileId = fileId;
|
||||
}
|
||||
if (res.body.binaryBody.file?.local) {
|
||||
if (saveUploadFileIds) {
|
||||
// 如果有已保存的上传文件id集合
|
||||
|
|
|
@ -375,7 +375,12 @@
|
|||
|
||||
import { getPluginScript, getProtocolList } from '@/api/modules/api-test/common';
|
||||
import { getDefinitionDetail } from '@/api/modules/api-test/management';
|
||||
import { getTransferOptions, stepTransferFile, uploadTempFile } from '@/api/modules/api-test/scenario';
|
||||
import {
|
||||
getTransferOptions,
|
||||
scenarioCopyStepFiles,
|
||||
stepTransferFile,
|
||||
uploadTempFile,
|
||||
} from '@/api/modules/api-test/scenario';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import { getGenerateId, parseQueryParams } from '@/utils';
|
||||
|
@ -403,6 +408,7 @@
|
|||
RequestComposition,
|
||||
RequestMethods,
|
||||
ResponseComposition,
|
||||
ScenarioStepRefType,
|
||||
ScenarioStepType,
|
||||
} from '@/enums/apiEnum';
|
||||
|
||||
|
@ -564,6 +570,7 @@
|
|||
};
|
||||
|
||||
const requestVModel = ref<RequestParam>(defaultApiParams);
|
||||
const copyStepFileIdsMap = ref<Record<string, any>>({});
|
||||
// 步骤类型判断
|
||||
const _stepType = computed(() => {
|
||||
if (props.step) {
|
||||
|
@ -994,7 +1001,8 @@
|
|||
requestVModel.value.body,
|
||||
undefined,
|
||||
props.fileParams?.uploadFileIds || requestVModel.value.uploadFileIds, // 外面解析详情的时候传入,或引用 api 在requestVModel内存储
|
||||
props.fileParams?.linkFileIds || requestVModel.value.linkFileIds // 外面解析详情的时候传入,或引用 api 在requestVModel内存储
|
||||
props.fileParams?.linkFileIds || requestVModel.value.linkFileIds, // 外面解析详情的时候传入,或引用 api 在requestVModel内存储
|
||||
copyStepFileIdsMap.value
|
||||
);
|
||||
requestParams = {
|
||||
authConfig: requestVModel.value.authConfig,
|
||||
|
@ -1208,7 +1216,20 @@
|
|||
const res = await getDefinitionDetail(props.step?.resourceId || '');
|
||||
let parseRequestBodyResult;
|
||||
if (res.protocol === 'HTTP') {
|
||||
parseRequestBodyResult = parseRequestBodyFiles(res.request.body, res.response); // 解析请求体中的文件,将详情中的文件 id 集合收集,更新时以判断文件是否删除以及是否新上传的文件
|
||||
if ((props.step?.copyFromStepId || props.step?.refType === ScenarioStepRefType.COPY) && props.step?.isNew) {
|
||||
// 复制的步骤需要复制文件
|
||||
copyStepFileIdsMap.value = await scenarioCopyStepFiles({
|
||||
copyFromStepId: props.step?.copyFromStepId,
|
||||
resourceId: props.step?.resourceId,
|
||||
stepType: props.step?.stepType,
|
||||
refType: props.step?.refType,
|
||||
isTempFile: false, // 复制未保存的步骤时 true
|
||||
fileIds: Object.values(parseRequestBodyFiles(res.request.body, [], [], [])).flat(),
|
||||
});
|
||||
parseRequestBodyFiles(res.body, [], [], [], copyStepFileIdsMap.value);
|
||||
} else {
|
||||
parseRequestBodyResult = parseRequestBodyFiles(res.request.body, [], [], [], copyStepFileIdsMap.value); // 解析请求体中的文件,将详情中的文件 id 集合收集,更新时以判断文件是否删除以及是否新上传的文件
|
||||
}
|
||||
}
|
||||
requestVModel.value = {
|
||||
executeLoading: false,
|
||||
|
|
|
@ -482,6 +482,7 @@
|
|||
import saveAsApiModal from '@/views/api-test/components/saveAsApiModal.vue';
|
||||
|
||||
import { addCase, getDefinitionDetail } from '@/api/modules/api-test/management';
|
||||
import { scenarioCopyStepFiles } from '@/api/modules/api-test/scenario';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
@ -514,6 +515,7 @@
|
|||
import useStepNodeEdit from './useStepNodeEdit';
|
||||
import useStepOperation from './useStepOperation';
|
||||
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 { defaultStepItemCommon } from '@/views/api-test/scenario/components/config';
|
||||
|
||||
|
@ -919,73 +921,101 @@
|
|||
* 复制步骤
|
||||
* @param node 复制的节点
|
||||
*/
|
||||
function copyStep(node: MsTreeNodeData) {
|
||||
const id = getGenerateId();
|
||||
const stepDetail = stepDetails.value[node.id];
|
||||
const stepFileParam = scenario.value.stepFileParam[node.id];
|
||||
const { isQuoteScenario } = getStepType(node as ScenarioStepItem);
|
||||
if (stepDetail) {
|
||||
// 如果复制的步骤还有详情数据,则也复制详情数据
|
||||
stepDetails.value[id] = cloneDeep({
|
||||
...stepDetail,
|
||||
stepId: id,
|
||||
uniqueId: id,
|
||||
});
|
||||
}
|
||||
if (stepFileParam) {
|
||||
// 如果复制的步骤还有详情数据,则也复制详情数据
|
||||
scenario.value.stepFileParam[id] = cloneDeep(stepFileParam);
|
||||
}
|
||||
insertNodes<ScenarioStepItem>(
|
||||
steps.value,
|
||||
node.uniqueId,
|
||||
{
|
||||
...cloneDeep(
|
||||
mapTree<ScenarioStepItem>(node, (childNode) => {
|
||||
const childId = getGenerateId();
|
||||
const childStepDetail = stepDetails.value[childNode.id];
|
||||
const childStepFileParam = scenario.value.stepFileParam[childNode.id];
|
||||
let childCopyFromStepId = childNode.id;
|
||||
if (childStepDetail) {
|
||||
// 如果复制的步骤下子步骤还有详情数据,则也复制详情数据
|
||||
stepDetails.value[childId] = cloneDeep(childStepDetail);
|
||||
}
|
||||
if (childStepFileParam) {
|
||||
// 如果复制的步骤下子步骤还有详情数据,则也复制详情数据
|
||||
scenario.value.stepFileParam[childNode.id] = cloneDeep(childStepFileParam);
|
||||
}
|
||||
if (!isQuoteScenario) {
|
||||
// 非引用场景才处理复制来源 id
|
||||
if (childStepDetail || (childNode.isNew && childNode.stepRefType === ScenarioStepRefType.REF)) {
|
||||
// 如果子步骤查看过详情,则复制来源直接取它的 id
|
||||
// 如果子步骤没有查看过详情,且是新建的步骤,且子步骤是引用的步骤,则还是取它本身的 id
|
||||
childCopyFromStepId = childNode.id;
|
||||
} else if (childNode.isNew && childNode.stepRefType === ScenarioStepRefType.COPY) {
|
||||
// 如果子步骤没有查看过详情,且是新建的步骤,且子步骤是复制的步骤,则取它的来源 id
|
||||
childCopyFromStepId = childNode.copyFromStepId;
|
||||
async function copyStep(node: MsTreeNodeData) {
|
||||
loading.value = true;
|
||||
try {
|
||||
const id = getGenerateId();
|
||||
const stepDetail = stepDetails.value[node.id];
|
||||
const { isQuoteScenario } = getStepType(node as ScenarioStepItem);
|
||||
let { copyFromStepId } = node;
|
||||
if (stepDetail || node.isNew !== true || !node.copyFromStepId) {
|
||||
// 如果复制的步骤查看过详情,则复制来源直接取它的 id
|
||||
// 如果复制的步骤没有查看过详情,且是新建的步骤,则取它本身的 id
|
||||
copyFromStepId = node.id;
|
||||
}
|
||||
let parseRequestBodyResult: Record<string, any> = {
|
||||
uploadFileIds: [],
|
||||
linkFileIds: [],
|
||||
deleteFileIds: [], // 存储对比已保存的文件后,需要删除的文件 id 集合
|
||||
unLinkFileIds: [], // 存储对比已保存的文件后,需要取消关联的文件 id 集合
|
||||
};
|
||||
let newFileRes;
|
||||
if (node.config.protocol === 'HTTP' && (stepDetail as RequestParam)?.body) {
|
||||
if (node.copyFromStepId || node.refType === ScenarioStepRefType.COPY) {
|
||||
// 复制的步骤需要复制文件
|
||||
newFileRes = await scenarioCopyStepFiles({
|
||||
copyFromStepId,
|
||||
resourceId: node.resourceId,
|
||||
stepType: node.stepType,
|
||||
refType: node.refType,
|
||||
isTempFile: !!stepDetail, // 复制未保存的步骤时 true
|
||||
fileIds: Object.values(parseRequestBodyFiles((stepDetail as RequestParam).body, [], [], [])).flat(),
|
||||
});
|
||||
parseRequestBodyFiles((stepDetail as RequestParam).body, [], [], [], newFileRes);
|
||||
} else {
|
||||
parseRequestBodyResult = parseRequestBodyFiles((stepDetail as RequestParam).body, [], [], [], newFileRes); // 解析请求体中的文件,将详情中的文件 id 集合收集,更新时以判断文件是否删除以及是否新上传的文件
|
||||
}
|
||||
}
|
||||
if (stepDetail) {
|
||||
// 如果复制的步骤还有详情数据,则也复制详情数据
|
||||
stepDetails.value[id] = cloneDeep({
|
||||
...stepDetail,
|
||||
stepId: id,
|
||||
uniqueId: id,
|
||||
...parseRequestBodyResult,
|
||||
});
|
||||
}
|
||||
insertNodes<ScenarioStepItem>(
|
||||
steps.value,
|
||||
node.uniqueId,
|
||||
{
|
||||
...cloneDeep(
|
||||
mapTree<ScenarioStepItem>(node, (childNode) => {
|
||||
const childId = getGenerateId();
|
||||
const childStepDetail = stepDetails.value[childNode.id];
|
||||
let childCopyFromStepId = childNode.id;
|
||||
if (childStepDetail) {
|
||||
// 如果复制的步骤下子步骤还有详情数据,则也复制详情数据
|
||||
stepDetails.value[childId] = cloneDeep(childStepDetail);
|
||||
}
|
||||
}
|
||||
return {
|
||||
...cloneDeep(childNode),
|
||||
executeStatus: undefined,
|
||||
copyFromStepId: childCopyFromStepId,
|
||||
id: childId,
|
||||
uniqueId: childId,
|
||||
};
|
||||
})[0]
|
||||
),
|
||||
name: `copy_${node.name}`.substring(0, 255),
|
||||
copyFromStepId: stepDetail || node.isNew !== true ? node.id : node.copyFromStepId,
|
||||
sort: node.sort + 1,
|
||||
isNew: true,
|
||||
id,
|
||||
uniqueId: id,
|
||||
},
|
||||
'after',
|
||||
selectedIfNeed,
|
||||
'uniqueId'
|
||||
);
|
||||
scenario.value.unSaved = true;
|
||||
if (!isQuoteScenario) {
|
||||
// 非引用场景才处理复制来源 id
|
||||
if (childStepDetail || (childNode.isNew && childNode.stepRefType === ScenarioStepRefType.REF)) {
|
||||
// 如果子步骤查看过详情,则复制来源直接取它的 id
|
||||
// 如果子步骤没有查看过详情,且是新建的步骤,且子步骤是引用的步骤,则还是取它本身的 id
|
||||
childCopyFromStepId = childNode.id;
|
||||
} else if (childNode.isNew && childNode.stepRefType === ScenarioStepRefType.COPY) {
|
||||
// 如果子步骤没有查看过详情,且是新建的步骤,且子步骤是复制的步骤,则取它的来源 id
|
||||
childCopyFromStepId = childNode.copyFromStepId;
|
||||
}
|
||||
}
|
||||
return {
|
||||
...cloneDeep(childNode),
|
||||
executeStatus: undefined,
|
||||
copyFromStepId: childCopyFromStepId,
|
||||
id: childId,
|
||||
uniqueId: childId,
|
||||
};
|
||||
})[0]
|
||||
),
|
||||
name: `copy_${node.name}`.substring(0, 255),
|
||||
copyFromStepId,
|
||||
sort: node.sort + 1,
|
||||
isNew: true,
|
||||
id,
|
||||
uniqueId: id,
|
||||
},
|
||||
'after',
|
||||
selectedIfNeed,
|
||||
'uniqueId'
|
||||
);
|
||||
scenario.value.unSaved = true;
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStepMoreActionSelect(item: ActionsItem, node: MsTreeNodeData) {
|
||||
|
@ -1189,6 +1219,14 @@
|
|||
appStore.currentProjectId
|
||||
);
|
||||
const insertSteps = insertApiSteps.concat(insertCaseSteps).concat(insertScenarioSteps);
|
||||
insertSteps.forEach((step) => {
|
||||
scenario.value.stepFileParam[step.id] = {
|
||||
linkFileIds: [],
|
||||
uploadFileIds: [],
|
||||
deleteFileIds: [],
|
||||
unLinkFileIds: [],
|
||||
};
|
||||
});
|
||||
if (activeStepByCreate.value && activeCreateAction.value) {
|
||||
handleCreateSteps(
|
||||
activeStepByCreate.value,
|
||||
|
|
|
@ -3,7 +3,7 @@ import { cloneDeep } from 'lodash-es';
|
|||
|
||||
import type { MsTreeExpandedData, MsTreeNodeData } from '@/components/business/ms-tree/types';
|
||||
|
||||
import { getScenarioStep } from '@/api/modules/api-test/scenario';
|
||||
import { getScenarioStep, scenarioCopyStepFiles } from '@/api/modules/api-test/scenario';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
@ -12,6 +12,7 @@ import { deleteNode, findNodeByKey, handleTreeDragDrop, mapTree } from '@/utils'
|
|||
import type { Scenario, ScenarioStepItem } from '@/models/apiTest/scenario';
|
||||
import { ScenarioStepRefType, ScenarioStepType } from '@/enums/apiEnum';
|
||||
|
||||
import type { RequestParam } from '../common/customApiDrawer.vue';
|
||||
import getStepType from '../common/stepType/utils';
|
||||
import { parseRequestBodyFiles } from '@/views/api-test/components/utils';
|
||||
|
||||
|
@ -57,9 +58,28 @@ export default function useStepOperation({
|
|||
try {
|
||||
appStore.showLoading();
|
||||
const res = await getScenarioStep(step.copyFromStepId || step.id);
|
||||
let parseRequestBodyResult;
|
||||
let parseRequestBodyResult: Record<string, any> = {
|
||||
uploadFileIds: [],
|
||||
linkFileIds: [],
|
||||
deleteFileIds: [], // 存储对比已保存的文件后,需要删除的文件 id 集合
|
||||
unLinkFileIds: [], // 存储对比已保存的文件后,需要取消关联的文件 id 集合
|
||||
};
|
||||
let newFileRes;
|
||||
if (step.config.protocol === 'HTTP' && res.body) {
|
||||
parseRequestBodyResult = parseRequestBodyFiles(res.body); // 解析请求体中的文件,将详情中的文件 id 集合收集,更新时以判断文件是否删除以及是否新上传的文件
|
||||
if ((step.copyFromStepId || step.refType === ScenarioStepRefType.COPY) && step.isNew) {
|
||||
// 复制的步骤需要复制文件
|
||||
newFileRes = await scenarioCopyStepFiles({
|
||||
copyFromStepId: step.copyFromStepId,
|
||||
resourceId: step.resourceId,
|
||||
stepType: step.stepType,
|
||||
refType: step.refType,
|
||||
isTempFile: false, // 复制未保存的步骤时 true
|
||||
fileIds: Object.values(parseRequestBodyFiles((res as RequestParam).body, [], [], [])).flat(),
|
||||
});
|
||||
parseRequestBodyFiles(res.body, [], [], [], newFileRes);
|
||||
} else {
|
||||
parseRequestBodyResult = parseRequestBodyFiles(res.body, [], [], [], newFileRes); // 解析请求体中的文件,将详情中的文件 id 集合收集,更新时以判断文件是否删除以及是否新上传的文件
|
||||
}
|
||||
}
|
||||
stepDetails.value[step.id] = {
|
||||
...res,
|
||||
|
@ -68,9 +88,12 @@ export default function useStepOperation({
|
|||
method: step.config.method || '',
|
||||
...parseRequestBodyResult,
|
||||
};
|
||||
scenario.value.stepFileParam[step.id] = {
|
||||
...parseRequestBodyResult,
|
||||
};
|
||||
if (!step.copyFromStepId && step.refType !== ScenarioStepRefType.COPY) {
|
||||
// 复制的步骤文件都是新的,不需要记录,等详情抽屉关闭时会处理
|
||||
scenario.value.stepFileParam[step.id] = {
|
||||
...parseRequestBodyResult,
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
|
|
|
@ -153,7 +153,7 @@
|
|||
import router from '@/router';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useCacheStore from '@/store/modules/cache/cache';
|
||||
import { filterTree, getGenerateId, mapTree } from '@/utils';
|
||||
import { filterTree, getGenerateId, mapTree, traverseTree } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { RequestResult } from '@/models/apiTest/common';
|
||||
|
@ -425,6 +425,7 @@
|
|||
if (isCopy) {
|
||||
// 场景被复制,递归处理节点,增加copyFromStepId
|
||||
copySteps = mapTree(defaultScenarioInfo.steps, (node) => {
|
||||
node.isNew = true;
|
||||
node.copyFromStepId = node.id;
|
||||
if (
|
||||
node.parent &&
|
||||
|
@ -677,6 +678,10 @@
|
|||
}),
|
||||
});
|
||||
}
|
||||
traverseTree(activeScenarioTab.value.steps, (node) => {
|
||||
node.isNew = false;
|
||||
});
|
||||
activeScenarioTab.value.stepFileParam = {};
|
||||
refreshTree(tempTableQueryParams.value);
|
||||
Message.success(activeScenarioTab.value.isNew ? t('common.createSuccess') : t('common.saveSuccess'));
|
||||
activeScenarioTab.value.unSaved = false;
|
||||
|
|
Loading…
Reference in New Issue