refactor(接口测试): 优化场景资源文件存储逻辑

This commit is contained in:
AgAngle 2024-03-28 19:52:08 +08:00 committed by Craftsman
parent 5769ba327f
commit 229c99d280
14 changed files with 257 additions and 108 deletions

View File

@ -56,6 +56,7 @@ public class DefaultRepositoryDir {
*/
private static final String PROJECT_API_DEBUG_DIR = PROJECT_DIR + "/api-debug/%s";
private static final String PROJECT_API_SCENARIO_DIR = PROJECT_DIR + "/api-scenario/%s";
private static final String PROJECT_API_SCENARIO_STEP_DIR = PROJECT_API_SCENARIO_DIR + "/step/%s";
private static final String PROJECT_BUG_DIR = PROJECT_DIR + "/bug/%s";
/**
@ -126,4 +127,12 @@ public class DefaultRepositoryDir {
public static String getApiScenarioDir(String projectId, String apiScenarioId) {
return String.format(PROJECT_API_SCENARIO_DIR, projectId, apiScenarioId);
}
public static String getApiScenarioStepDir(String projectId, String apiScenarioId, String stepId) {
return String.format(PROJECT_API_SCENARIO_STEP_DIR, projectId, apiScenarioId, stepId);
}
public static String getProjectDir(String projectId) {
return String.format(PROJECT_DIR, projectId);
}
}

View File

@ -0,0 +1,26 @@
package io.metersphere.api.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* @Author: jianxing
* @CreateTime: 2024-03-26 17:53
*/
@Data
public class ResourceAddFileParam {
/**
* 新上传的文件ID
* 创建时先按ID创建目录再把文件放入目录
*/
@Schema(description = "新上传的文件ID")
private List<String> uploadFileIds;
/**
* 新关联的文件ID
*/
@Schema(description = "关联文件ID")
private List<String> linkFileIds;
}

View File

@ -0,0 +1,22 @@
package io.metersphere.api.dto;
import lombok.Data;
import java.util.List;
/**
* @Author: jianxing
* @CreateTime: 2024-03-26 17:53
*/
@Data
public class ResourceUpdateFileParam extends ResourceAddFileParam {
/**
* 删除本地上传的文件ID
*/
private List<String> deleteFileIds;
/**
* 删除关联的文件ID
*/
private List<String> unLinkFileIds;
}

View File

@ -1,6 +1,7 @@
package io.metersphere.api.dto.scenario;
import io.metersphere.api.constants.ApiScenarioStatus;
import io.metersphere.api.dto.ResourceAddFileParam;
import io.metersphere.system.valid.EnumValue;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
@ -73,15 +74,16 @@ public class ApiScenarioAddRequest {
private Map<String, Object> stepDetails;
/**
* 新上传的文件ID
* 创建时先按ID创建目录再把文件放入目录
* 步骤文件操作相关参数
* key 为步骤ID
* 值为文件参数
*/
@Schema(description = "新上传的文件ID")
private List<String> uploadFileIds;
@Schema(description = "步骤文件操作相关参数")
private Map<String, ResourceAddFileParam> stepFileParam;
/**
* 新关联的文件ID
* 步骤文件操作相关参数
*/
@Schema(description = "关联文件ID")
private List<String> linkFileIds;
@Schema(description = "场景文件操作相关参数")
private ResourceAddFileParam fileParam;
}

View File

@ -1,6 +1,7 @@
package io.metersphere.api.dto.scenario;
import io.metersphere.api.constants.ApiScenarioStatus;
import io.metersphere.api.dto.ResourceUpdateFileParam;
import io.metersphere.system.valid.EnumValue;
import io.metersphere.validation.groups.Created;
import io.metersphere.validation.groups.Updated;
@ -71,25 +72,16 @@ public class ApiScenarioUpdateRequest {
private Map<String, Object> stepDetails;
/**
* 新上传的文件ID
* 创建时先按ID创建目录再把文件放入目录
* 步骤文件操作相关参数
* key 为步骤ID
* 值为文件参数
*/
@Schema(description = "新上传的文件ID")
private List<String> uploadFileIds;
@Schema(description = "步骤文件操作相关参数")
private Map<String, ResourceUpdateFileParam> stepFileParam;
/**
* 新关联的文件ID
* 步骤文件操作相关参数
*/
@Schema(description = "关联文件ID")
private List<String> linkFileIds;
/**
* 删除本地上传的文件ID
*/
private List<String> deleteFileIds;
/**
* 删除关联的文件ID
*/
private List<String> unLinkFileIds;
@Schema(description = "场景文件操作相关参数")
private ResourceUpdateFileParam fileParam;
}

View File

@ -234,6 +234,53 @@ public class ApiFileResourceService {
fileAssociationService.deleteBySourceIds(List.of(resourceId), fileLogRecord);
}
/**
* 删除资源下所有的文件或者关联关系
*
* @param dirPrefix 本地上传文件目录前缀
* @param resourceIds 资源ID
* @param projectId 项目ID
* @param operator 操作人
*/
public void deleteByResourceIds(String dirPrefix, List<String> resourceIds, String projectId, String operator, String logModule) {
// 处理本地上传的文件
List<ApiFileResource> apiFileResources = getByResourceIds(resourceIds);
List<String> hasFileResourceIds = apiFileResources.stream()
.map(ApiFileResource::getResourceId)
.toList();
deleteByResourceIds(hasFileResourceIds);
for (String resourceId : hasFileResourceIds) {
// 删除文件
FileRequest request = new FileRequest();
request.setFolder(dirPrefix + resourceId);
try {
FileCenter.getDefaultRepository().deleteFolder(request);
} catch (Exception e) {
LogUtils.error(e);
}
}
// 处理关联文件
FileLogRecord fileLogRecord = FileLogRecord.builder()
.logModule(logModule)
.operator(operator)
.projectId(projectId)
.build();
fileAssociationService.deleteBySourceIds(resourceIds, fileLogRecord);
}
private void deleteByResourceIds(List<String> resourceIds) {
if (CollectionUtils.isEmpty(resourceIds)) {
return;
}
ApiFileResourceExample example = new ApiFileResourceExample();
example.createCriteria().andResourceIdIn(resourceIds);
apiFileResourceMapper.deleteByExample(example);
}
public List<ApiFileResource> getByResourceId(String resourceId) {
ApiFileResourceExample example = new ApiFileResourceExample();
example.createCriteria()
@ -242,6 +289,9 @@ public class ApiFileResourceService {
}
public List<ApiFileResource> getByResourceIds(List<String> resourceIds) {
if (CollectionUtils.isEmpty(resourceIds)) {
return List.of();
}
ApiFileResourceExample example = new ApiFileResourceExample();
example.createCriteria()
.andResourceIdIn(resourceIds);

View File

@ -19,6 +19,7 @@ import io.metersphere.system.service.CleanupProjectResourceService;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotEmpty;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@ -126,13 +127,13 @@ public class CleanupApiResourceServiceImpl implements CleanupProjectResourceServ
List<String> scenarioIds = extApiScenarioMapper.selectByProjectId(projectId);
if (CollectionUtils.isNotEmpty(scenarioIds)) {
SubListUtils.dealForSubList(scenarioIds, 500, subList -> {
cascadeDelete(subList, OperationLogConstants.SYSTEM);
cascadeDelete(subList, projectId, OperationLogConstants.SYSTEM);
});
}
}
public void cascadeDelete(@NotEmpty List<String> subList, String operator) {
public void cascadeDelete(@NotEmpty List<String> subList, String projectId, String operator) {
ApiScenarioBlobExample example = new ApiScenarioBlobExample();
example.createCriteria().andIdIn(subList);
//删除blob
@ -148,18 +149,9 @@ public class CleanupApiResourceServiceImpl implements CleanupProjectResourceServ
blobExample.createCriteria().andScenarioIdIn(subList);
apiScenarioStepBlobMapper.deleteByExample(blobExample);
ApiScenarioExample apiScenarioExample = new ApiScenarioExample();
apiScenarioExample.createCriteria().andIdIn(subList);
List<ApiScenario> scenarioList = apiScenarioMapper.selectByExample(apiScenarioExample);
scenarioList.forEach(scenario -> {
//删除文件
String scenarioDir = DefaultRepositoryDir.getApiDebugDir(scenario.getProjectId(), scenario.getId());
try {
apiFileResourceService.deleteByResourceId(scenarioDir, scenario.getId(), scenario.getProjectId(), operator, OperationLogModule.API_TEST_DEBUG_MANAGEMENT_DEBUG);
} catch (Exception ignore) {
}
String scenarioDirPrefix = DefaultRepositoryDir.getApiScenarioDir(projectId, StringUtils.EMPTY);
apiFileResourceService.deleteByResourceIds(scenarioDirPrefix, subList, projectId, operator, OperationLogModule.API_SCENARIO_MANAGEMENT_SCENARIO);
});
//删除csv
ApiScenarioCsvExample csvExample = new ApiScenarioCsvExample();
csvExample.createCriteria().andScenarioIdIn(subList);
@ -172,7 +164,10 @@ public class CleanupApiResourceServiceImpl implements CleanupProjectResourceServ
apiScenarioCsvStepMapper.deleteByExample(csvStepExample);
}
apiScenarioCsvMapper.deleteByExample(csvExample);
//删除场景
ApiScenarioExample apiScenarioExample = new ApiScenarioExample();
apiScenarioExample.createCriteria().andIdIn(subList);
apiScenarioMapper.deleteByExample(apiScenarioExample);
}
@ -230,10 +225,11 @@ public class CleanupApiResourceServiceImpl implements CleanupProjectResourceServ
private void deleteCase(List<String> ids, String projectId) {
deleteCaseFollows(ids);
ids.forEach(id -> {
String apiCaseDir = DefaultRepositoryDir.getApiCaseDir(projectId, id);
apiFileResourceService.deleteByResourceId(apiCaseDir, id, projectId, OperationLogConstants.SYSTEM, OperationLogModule.API_TEST_MANAGEMENT_CASE);
});
// 批量删除文件
String apiCaseDirPrefix = DefaultRepositoryDir.getApiCaseDir(projectId, StringUtils.EMPTY);
apiFileResourceService.deleteByResourceIds(apiCaseDirPrefix, ids, projectId, OperationLogConstants.SYSTEM, OperationLogModule.API_TEST_MANAGEMENT_CASE);
ApiTestCaseExample example = new ApiTestCaseExample();
example.createCriteria().andIdIn(ids);
apiTestCaseMapper.deleteByExample(example);
@ -243,10 +239,9 @@ public class CleanupApiResourceServiceImpl implements CleanupProjectResourceServ
}
private void deleteMock(List<String> ids, String projectId) {
ids.forEach(id -> {
String apiCaseDir = DefaultRepositoryDir.getApiDefinitionDir(projectId, id);
apiFileResourceService.deleteByResourceId(apiCaseDir, id, projectId, OperationLogConstants.SYSTEM, OperationLogModule.API_TEST_MANAGEMENT_CASE);
});
String apiDefinitionDir = DefaultRepositoryDir.getApiDefinitionDir(projectId, StringUtils.EMPTY);
apiFileResourceService.deleteByResourceIds(apiDefinitionDir, ids, projectId, OperationLogConstants.SYSTEM, OperationLogModule.API_TEST_MANAGEMENT_MOCK);
ApiDefinitionMockConfigExample configExample = new ApiDefinitionMockConfigExample();
configExample.createCriteria().andIdIn(ids);
apiDefinitionMockConfigMapper.deleteByExample(configExample);
@ -257,10 +252,9 @@ public class CleanupApiResourceServiceImpl implements CleanupProjectResourceServ
private void deleteApi(List<String> ids, String projectId) {
deleteApiFollows(ids);
ids.forEach(id -> {
String apiDefinitionDir = DefaultRepositoryDir.getApiDefinitionDir(projectId, id);
apiFileResourceService.deleteByResourceId(apiDefinitionDir, id, projectId, OperationLogConstants.SYSTEM, OperationLogModule.API_TEST_MANAGEMENT_DEFINITION);
});
String apiDefinitionDir = DefaultRepositoryDir.getApiDefinitionDir(projectId, StringUtils.EMPTY);
apiFileResourceService.deleteByResourceIds(apiDefinitionDir, ids, projectId, OperationLogConstants.SYSTEM, OperationLogModule.API_TEST_MANAGEMENT_DEFINITION);
ApiDefinitionExample example = new ApiDefinitionExample();
example.createCriteria().andIdIn(ids);
apiDefinitionMapper.deleteByExample(example);

View File

@ -211,10 +211,9 @@ public class ApiDebugModuleService extends ModuleTreeService {
blobExample.createCriteria().andIdIn(apiDebugIds);
apiDebugBlobMapper.deleteByExample(blobExample);
//删除文件关联关系
apiDebugs.forEach(apiDebug -> {
String apiDebugDir = DefaultRepositoryDir.getApiDebugDir(apiDebug.getProjectId(), apiDebug.getId());
apiFileResourceService.deleteByResourceId(apiDebugDir, apiDebug.getId(), projectId, currentUser, OperationLogModule.API_TEST_DEBUG_MANAGEMENT_DEBUG);
});
String apiDebugDir = DefaultRepositoryDir.getApiDebugDir(projectId, StringUtils.EMPTY);
apiFileResourceService.deleteByResourceIds(apiDebugDir, apiDebugIds, projectId, currentUser, OperationLogModule.API_TEST_DEBUG_MANAGEMENT_DEBUG);
apiDebugModuleLogService.saveDeleteDataLog(apiDebugs, currentUser, projectId);
}

View File

@ -30,6 +30,7 @@ import io.metersphere.system.uid.NumGenerator;
import io.metersphere.system.utils.ServiceUtils;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -255,19 +256,16 @@ public class ApiDefinitionMockService {
apiDefinitionMockMapper.updateByPrimaryKeySelective(update);
}
public void deleteByApiIds(List<String> apiIds, String userId) {
public void deleteByApiIds(List<String> apiIds, String userId, String projectId) {
ApiDefinitionMockExample apiDefinitionMockExample = new ApiDefinitionMockExample();
apiDefinitionMockExample.createCriteria().andApiDefinitionIdIn(apiIds);
List<ApiDefinitionMock> apiDefinitionMocks = apiDefinitionMockMapper.selectByExample(apiDefinitionMockExample);
if (!apiDefinitionMocks.isEmpty()) {
apiDefinitionMocks.forEach(item -> {
String apiDefinitionMockDir = DefaultRepositoryDir.getApiDefinitionDir(item.getProjectId(), item.getId());
apiFileResourceService.deleteByResourceId(apiDefinitionMockDir, item.getId(), item.getProjectId(), userId, OperationLogModule.API_TEST_MANAGEMENT_MOCK);
});
List<String> mockIds = apiDefinitionMocks.stream().map(ApiDefinitionMock::getId).toList();
String apiDefinitionMockDir = DefaultRepositoryDir.getApiDefinitionDir(projectId, StringUtils.EMPTY);
apiFileResourceService.deleteByResourceIds(apiDefinitionMockDir, mockIds, projectId, userId, OperationLogModule.API_TEST_MANAGEMENT_MOCK);
ApiDefinitionMockConfigExample apiDefinitionMockConfigExample = new ApiDefinitionMockConfigExample();
apiDefinitionMockConfigExample.createCriteria().andIdIn(mockIds);

View File

@ -806,6 +806,9 @@ public class ApiDefinitionService extends MoveNodeService {
if (CollectionUtils.isNotEmpty(ids)) {
handleTrashDelApiDefinition(ids, userId, request.getProjectId(), true);
}
String apiDefinitionDirPrefix = DefaultRepositoryDir.getApiDefinitionDir(request.getProjectId(), StringUtils.EMPTY);
apiFileResourceService.deleteByResourceIds(apiDefinitionDirPrefix, ids, request.getProjectId(), userId, OperationLogModule.API_TEST_MANAGEMENT_DEFINITION);
}
private void handleTrashDelApiDefinition(List<String> ids, String userId, String projectId, boolean isBatch) {
@ -817,10 +820,9 @@ public class ApiDefinitionService extends MoveNodeService {
private void doTrashDel(List<String> ids, String userId, String projectId, boolean isBatch) {
if (CollectionUtils.isNotEmpty(ids)) {
// 删除上传的文件
ids.forEach(id -> {
String apiDefinitionDir = DefaultRepositoryDir.getApiDefinitionDir(projectId, id);
apiFileResourceService.deleteByResourceId(apiDefinitionDir, id, projectId, userId, OperationLogModule.API_TEST_MANAGEMENT_DEFINITION);
});
String apiDefinitionDir = DefaultRepositoryDir.getApiDefinitionDir(projectId, StringUtils.EMPTY);
apiFileResourceService.deleteByResourceIds(apiDefinitionDir, ids, projectId, userId, OperationLogModule.API_TEST_MANAGEMENT_DEFINITION);
// 删除接口关注人
ApiDefinitionFollowerExample apiDefinitionFollowerExample = new ApiDefinitionFollowerExample();
apiDefinitionFollowerExample.createCriteria().andApiDefinitionIdIn(ids).andUserIdEqualTo(userId);
@ -851,7 +853,7 @@ public class ApiDefinitionService extends MoveNodeService {
}
// 删除 mock
apiDefinitionMockService.deleteByApiIds(apiIds, userId);
apiDefinitionMockService.deleteByApiIds(apiIds, userId, projectId);
}
// 获取批量操作选中的ID

View File

@ -368,11 +368,11 @@ public class ApiTestCaseService extends MoveNodeService {
public void deleteResourceByIds(List<String> ids, String projectId, String userId) {
deleteFollows(ids);
List<ApiTestCase> caseLists = extApiTestCaseMapper.getCaseInfoByIds(ids, true);
//删除文件关联关系
ids.forEach(id -> {
String apiCaseDir = DefaultRepositoryDir.getApiCaseDir(projectId, id);
apiFileResourceService.deleteByResourceId(apiCaseDir, id, projectId, userId, OperationLogModule.API_TEST_MANAGEMENT_CASE);
});
// 批量删除关联文件
String apiCaseDirPrefix = DefaultRepositoryDir.getApiCaseDir(projectId, StringUtils.EMPTY);
apiFileResourceService.deleteByResourceIds(apiCaseDirPrefix, ids, projectId, userId, OperationLogModule.API_TEST_MANAGEMENT_CASE);
ApiTestCaseExample example = new ApiTestCaseExample();
example.createCriteria().andIdIn(ids);
apiTestCaseMapper.deleteByExample(example);

View File

@ -434,17 +434,40 @@ public class ApiScenarioService extends MoveNodeService {
saveStepCsv(steps, csvSteps);
}
// 处理文件
// 处理步骤文件
handleStepFiles(request, creator, scenario);
// 处理场景文件csv等
handScenarioFiles(request, creator, scenario);
return scenario;
}
private void handScenarioFiles(ApiScenarioAddRequest request, String creator, ApiScenario scenario) {
ResourceAddFileParam fileParam = request.getFileParam();
if (fileParam == null) {
return;
}
ApiFileResourceUpdateRequest resourceUpdateRequest = getApiFileResourceUpdateRequest(scenario.getId(), scenario.getProjectId(), creator);
resourceUpdateRequest.setUploadFileIds(request.getUploadFileIds());
resourceUpdateRequest.setLinkFileIds(request.getLinkFileIds());
resourceUpdateRequest.setUploadFileIds(fileParam.getUploadFileIds());
resourceUpdateRequest.setLinkFileIds(fileParam.getLinkFileIds());
apiFileResourceService.addFileResource(resourceUpdateRequest);
//处理csv变量
if (request.getScenarioConfig() != null
&& request.getScenarioConfig().getVariable() != null) {
saveCsv(request.getScenarioConfig().getVariable().getCsvVariables(), resourceUpdateRequest);
}
return scenario;
}
private void handleStepFiles(ApiScenarioAddRequest request, String creator, ApiScenario scenario) {
Map<String, ResourceAddFileParam> stepFileParam = request.getStepFileParam();
if (MapUtils.isNotEmpty(stepFileParam)) {
stepFileParam.forEach((stepId, fileParam) -> {
// 处理步骤文件
ApiFileResourceUpdateRequest resourceUpdateRequest = getApiFileResourceUpdateRequest(stepId, scenario.getProjectId(), creator);
resourceUpdateRequest.setUploadFileIds(fileParam.getUploadFileIds());
resourceUpdateRequest.setLinkFileIds(fileParam.getLinkFileIds());
apiFileResourceService.addFileResource(resourceUpdateRequest);
});
}
}
private void saveStepCsv(List<ApiScenarioStep> steps, List<ApiScenarioCsvStep> csvSteps) {
@ -639,17 +662,28 @@ public class ApiScenarioService extends MoveNodeService {
apiScenarioBlobMapper.updateByPrimaryKeyWithBLOBs(apiScenarioBlob);
}
// 更新场景步骤
updateApiScenarioStep(request, scenario);
ApiScenario originScenario = apiScenarioMapper.selectByPrimaryKey(request.getId());
// 处理文件
ApiFileResourceUpdateRequest resourceUpdateRequest = getApiFileResourceUpdateRequest(scenario.getId(), originScenario.getProjectId(), updater);
resourceUpdateRequest.setUploadFileIds(request.getUploadFileIds());
resourceUpdateRequest.setLinkFileIds(request.getLinkFileIds());
resourceUpdateRequest.setUnLinkFileIds(request.getUnLinkFileIds());
resourceUpdateRequest.setDeleteFileIds(request.getDeleteFileIds());
apiFileResourceService.updateFileResource(resourceUpdateRequest);
// 处理步骤文件
handleStepFiles(request, updater, originScenario);
// 处理场景文件
handleScenarioFiles(request, updater, originScenario);
// 更新场景步骤
updateApiScenarioStep(request, originScenario, updater);
return scenario;
}
private void handleScenarioFiles(ApiScenarioUpdateRequest request, String updater, ApiScenario scenario) {
// 处理场景文件
ApiFileResourceUpdateRequest resourceUpdateRequest = getApiFileResourceUpdateRequest(scenario.getId(), scenario.getProjectId(), updater);
ResourceAddFileParam fileParam = request.getFileParam();
if (fileParam != null) {
resourceUpdateRequest = BeanUtils.copyBean(resourceUpdateRequest, fileParam);
apiFileResourceService.updateFileResource(resourceUpdateRequest);
}
//处理csv变量
if (request.getScenarioConfig() != null
@ -658,13 +692,24 @@ public class ApiScenarioService extends MoveNodeService {
} else {
saveCsv(new ArrayList<>(), resourceUpdateRequest);
}
return scenario;
}
private void handleStepFiles(ApiScenarioUpdateRequest request, String updater, ApiScenario scenario) {
Map<String, ResourceUpdateFileParam> stepFileParam = request.getStepFileParam();
if (MapUtils.isNotEmpty(stepFileParam)) {
stepFileParam.forEach((stepId, fileParam) -> {
// 处理步骤文件
ApiFileResourceUpdateRequest resourceUpdateRequest = getApiFileResourceUpdateRequest(stepId, scenario.getProjectId(), updater);
resourceUpdateRequest = BeanUtils.copyBean(resourceUpdateRequest, fileParam);
apiFileResourceService.addFileResource(resourceUpdateRequest);
});
}
}
/**
* 更新场景步骤
*/
private void updateApiScenarioStep(ApiScenarioUpdateRequest request, ApiScenario scenario) {
private void updateApiScenarioStep(ApiScenarioUpdateRequest request, ApiScenario scenario, String userId) {
// steps 不为 null 则修改
if (request.getSteps() != null) {
if (CollectionUtils.isEmpty(request.getSteps())) {
@ -697,6 +742,9 @@ public class ApiScenarioService extends MoveNodeService {
ApiScenarioStepBlobExample stepBlobExample = new ApiScenarioStepBlobExample();
stepBlobExample.createCriteria().andIdIn(subIds);
apiScenarioStepBlobMapper.deleteByExample(stepBlobExample);
// 批量删除关联文件
String scenarioStepDirPrefix = DefaultRepositoryDir.getApiScenarioStepDir(scenario.getProjectId(), scenario.getId(), StringUtils.EMPTY);
apiFileResourceService.deleteByResourceIds(scenarioStepDirPrefix, subIds, scenario.getProjectId(), userId, OperationLogModule.API_SCENARIO_MANAGEMENT_SCENARIO);
});
// 查询原有的步骤详情
@ -1004,7 +1052,7 @@ public class ApiScenarioService extends MoveNodeService {
return enableSteps;
}
private static ApiFileResourceUpdateRequest getApiFileResourceUpdateRequest(String sourceId, String projectId, String operator) {
private ApiFileResourceUpdateRequest getApiFileResourceUpdateRequest(String sourceId, String projectId, String operator) {
String apiScenarioDir = DefaultRepositoryDir.getApiScenarioDir(projectId, sourceId);
ApiFileResourceUpdateRequest resourceUpdateRequest = new ApiFileResourceUpdateRequest();
resourceUpdateRequest.setProjectId(projectId);
@ -1033,7 +1081,7 @@ public class ApiScenarioService extends MoveNodeService {
apiScenarioMapper.deleteByPrimaryKey(id);
}
public ApiScenarioBatchOperationResponse delete(@NotEmpty List<String> idList, String operator) {
public ApiScenarioBatchOperationResponse delete(@NotEmpty List<String> idList, String projectId, String operator) {
ApiScenarioBatchOperationResponse response = new ApiScenarioBatchOperationResponse();
ApiScenarioExample example = new ApiScenarioExample();
@ -1041,7 +1089,7 @@ public class ApiScenarioService extends MoveNodeService {
List<ApiScenario> scenarioList = apiScenarioMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(scenarioList)) {
apiScenarioMapper.deleteByExample(example);
cascadeDelete(scenarioList, operator);
cascadeDelete(scenarioList, projectId, operator);
}
//构建返回值
@ -1064,7 +1112,7 @@ public class ApiScenarioService extends MoveNodeService {
//删除文件
String scenarioDir = DefaultRepositoryDir.getApiScenarioDir(scenario.getProjectId(), scenario.getId());
try {
apiFileResourceService.deleteByResourceId(scenarioDir, scenario.getId(), scenario.getProjectId(), operator, OperationLogModule.API_TEST_DEBUG_MANAGEMENT_DEBUG);
apiFileResourceService.deleteByResourceId(scenarioDir, scenario.getId(), scenario.getProjectId(), operator, OperationLogModule.API_SCENARIO_MANAGEMENT_SCENARIO);
} catch (Exception ignore) {
}
@ -1088,7 +1136,7 @@ public class ApiScenarioService extends MoveNodeService {
}
//级联删除
public void cascadeDelete(@NotEmpty List<ApiScenario> scenarioList, String operator) {
public void cascadeDelete(@NotEmpty List<ApiScenario> scenarioList, String projectId, String operator) {
List<String> scenarioIdList = scenarioList.stream().map(ApiScenario::getId).toList();
ApiScenarioBlobExample example = new ApiScenarioBlobExample();
example.createCriteria().andIdIn(scenarioIdList);
@ -1106,17 +1154,12 @@ public class ApiScenarioService extends MoveNodeService {
blobExample.createCriteria().andScenarioIdIn(scenarioIdList);
apiScenarioStepBlobMapper.deleteByExample(blobExample);
scenarioList.forEach(scenario -> {
//删除文件
String scenarioDir = DefaultRepositoryDir.getApiScenarioDir(scenario.getProjectId(), scenario.getId());
try {
apiFileResourceService.deleteByResourceId(scenarioDir, scenario.getId(), scenario.getProjectId(), operator, OperationLogModule.API_TEST_DEBUG_MANAGEMENT_DEBUG);
//删除定时任务
scheduleService.deleteByResourceId(scenario.getId(), ApiScenarioScheduleJob.class.getName());
} catch (Exception ignore) {
}
//删除文件
String scenarioDir = DefaultRepositoryDir.getApiScenarioDir(projectId, StringUtils.EMPTY);
apiFileResourceService.deleteByResourceIds(scenarioDir, scenarioIdList, projectId, operator, OperationLogModule.API_SCENARIO_MANAGEMENT_SCENARIO);
//删除定时任务
scheduleService.deleteByResourceIds(scenarioIdList, ApiScenarioScheduleJob.class.getName());
});
//删除csv
ApiScenarioCsvExample csvExample = new ApiScenarioCsvExample();
csvExample.createCriteria().andScenarioIdIn(scenarioIdList);
@ -2309,7 +2352,7 @@ public class ApiScenarioService extends MoveNodeService {
ApiScenarioBatchOperationResponse response = ApiScenarioBatchOperationUtils.executeWithBatchOperationResponse(
scenarioIds,
sublist -> delete(sublist, logInsertModule.getOperator()));
sublist -> delete(sublist, request.getProjectId(), logInsertModule.getOperator()));
apiScenarioLogService.saveBatchOperationLog(response, request.getProjectId(), OperationLogType.DELETE.name(), logInsertModule);
return response;
}

View File

@ -5,6 +5,7 @@ import io.metersphere.api.domain.*;
import io.metersphere.api.dto.ApiFile;
import io.metersphere.api.dto.ApiRunModeRequest;
import io.metersphere.api.dto.ReferenceRequest;
import io.metersphere.api.dto.ResourceAddFileParam;
import io.metersphere.api.dto.assertion.MsAssertionConfig;
import io.metersphere.api.dto.debug.ModuleCreateRequest;
import io.metersphere.api.dto.definition.*;
@ -328,7 +329,8 @@ public class ApiScenarioControllerTests extends BaseTest {
request.setStepDetails(steptDetailMap);
request.setScenarioConfig(getScenarioConfig());
String fileId = doUploadTempFile(getMockMultipartFile());
request.setUploadFileIds(List.of(fileId));
request.setFileParam(new ResourceAddFileParam());
request.getFileParam().setUploadFileIds(List.of(fileId));
MvcResult mvcResult = this.requestPostWithOkAndReturn(DEFAULT_ADD, request);
ApiScenario resultData = getResultData(mvcResult, ApiScenario.class);
this.addApiScenario = apiScenarioMapper.selectByPrimaryKey(resultData.getId());
@ -336,7 +338,7 @@ public class ApiScenarioControllerTests extends BaseTest {
assertUpdateSteps(steps, steptDetailMap);
request.setName("anOther name");
request.setUploadFileIds(List.of());
request.getFileParam().setUploadFileIds(List.of());
request.setGrouped(true);
request.setEnvironmentId(envGroupId);
ApiScenarioStepRequest stepRequest = new ApiScenarioStepRequest();

View File

@ -6,11 +6,10 @@ import io.metersphere.project.domain.ProjectTestResourcePool;
import io.metersphere.project.domain.ProjectTestResourcePoolExample;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.project.mapper.ProjectTestResourcePoolMapper;
import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.constants.InternalUserRole;
import io.metersphere.sdk.constants.OperationLogConstants;
import io.metersphere.sdk.constants.UserRoleType;
import io.metersphere.sdk.constants.*;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.file.FileCenter;
import io.metersphere.sdk.file.FileRequest;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.LogUtils;
@ -556,6 +555,17 @@ public class CommonProjectService {
projectMapper.deleteByPrimaryKey(project.getId());
LogDTO logDTO = new LogDTO(OperationLogConstants.SYSTEM, project.getOrganizationId(), project.getId(), Translator.get("scheduled_tasks"), OperationLogType.DELETE.name(), OperationLogModule.SETTING_ORGANIZATION_PROJECT, Translator.get("delete") + Translator.get("project") + ": " + project.getName());
setLog(logDTO, StringUtils.EMPTY, StringUtils.EMPTY, logDTOList);
// 删除项目目录避免资源删除有遗漏
String projectDir = DefaultRepositoryDir.getProjectDir(project.getId());
FileRequest request = new FileRequest();
request.setFolder(projectDir);
try {
FileCenter.getDefaultRepository().deleteFolder(request);
} catch (Exception e) {
LogUtils.error(e);
}
});
operationLogService.batchAdd(logDTOList);
}