From fd644b81a4e4b1733d1929e03a1540ad8206e7d5 Mon Sep 17 00:00:00 2001 From: WangXu10 Date: Tue, 7 Nov 2023 15:43:16 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E7=94=A8=E4=BE=8B=E7=AE=A1=E7=90=86):=20?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4=E7=94=A8=E4=BE=8B=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FunctionalCaseController.java | 10 +++ .../mapper/ExtFunctionalCaseMapper.java | 9 ++ .../mapper/ExtFunctionalCaseMapper.xml | 84 ++++++++++++++++++- .../request/FunctionalCaseBatchRequest.java | 24 ++++++ .../service/FunctionalCaseLogService.java | 32 +++++++ .../service/FunctionalCaseService.java | 28 ++++++- .../FunctionalCaseControllerTests.java | 30 +++++-- .../resources/dml/init_file_metadata_test.sql | 8 ++ 8 files changed, 211 insertions(+), 14 deletions(-) create mode 100644 backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseBatchRequest.java diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseController.java b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseController.java index 2edab05e63..00fe6cb1af 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseController.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseController.java @@ -134,4 +134,14 @@ public class FunctionalCaseController { StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "create_time desc"); return PageUtils.setPageInfo(page, functionalCaseService.getFunctionalCasePage(request, false)); } + + + @PostMapping("/batch/delete-to-gc") + @Operation(summary = "功能用例-批量删除用例") + @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_DELETE) + @Log(type = OperationLogType.DELETE, expression = "#msClass.batchDeleteFunctionalCaseLog(#request)", msClass = FunctionalCaseLogService.class) + public void batchDeleteFunctionalCaseToGc(@Validated @RequestBody FunctionalCaseBatchRequest request) { + String userId = SessionUtils.getUserId(); + functionalCaseService.batchDeleteFunctionalCaseToGc(request, userId); + } } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseMapper.java b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseMapper.java index 9a9322b41b..1742298a9f 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseMapper.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseMapper.java @@ -4,6 +4,7 @@ import io.metersphere.functional.domain.FunctionalCase; import io.metersphere.functional.dto.FunctionalCasePageDTO; import io.metersphere.functional.dto.FunctionalCaseVersionDTO; import io.metersphere.functional.request.FunctionalCasePageRequest; +import io.metersphere.system.dto.table.TableBatchProcessDTO; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -26,4 +27,12 @@ public interface ExtFunctionalCaseMapper { List checkCaseByModuleIds(@Param("moduleIds") List deleteIds); List list(@Param("request") FunctionalCasePageRequest request, @Param("deleted") boolean deleted); + + List getIds(@Param("request") TableBatchProcessDTO request, @Param("projectId") String projectId, @Param("deleted") boolean deleted); + + void batchDelete(@Param("ids") List ids, @Param("userId") String userId); + + List getLogInfo(@Param("ids") List ids); + + List getRefIds(@Param("ids") List ids); } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseMapper.xml b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseMapper.xml index 1f5e68e010..2ff47fba55 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseMapper.xml +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseMapper.xml @@ -98,7 +98,9 @@ or functional_case.tags like JSON_CONTAINS(tags, concat('["',#{request.keyword},'"]')) ) - + + + @@ -107,9 +109,9 @@ - - - + + + @@ -200,4 +202,78 @@ AND ${versionTable}.latest = 0 + + + + + + + + + + + + + + and ( + functional_case.name like concat('%', #{request.keyword},'%') + or functional_case.num like concat('%', #{request.keyword},'%') + or functional_case.tags like JSON_CONTAINS(tags, concat('["',#{request.keyword},'"]')) + ) + + + + + + + + + + + + + update functional_case + set deleted = 1, + delete_user = #{userId}, + delete_time = UNIX_TIMESTAMP()*1000 + where ref_id in + + #{id} + + and deleted = false + + + \ No newline at end of file diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseBatchRequest.java b/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseBatchRequest.java new file mode 100644 index 0000000000..65071415e6 --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseBatchRequest.java @@ -0,0 +1,24 @@ +package io.metersphere.functional.request; + +import io.metersphere.system.dto.table.TableBatchProcessDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * @author wx + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class FunctionalCaseBatchRequest extends TableBatchProcessDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED) + private String projectId; + + + +} diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseLogService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseLogService.java index 28d4c8eddc..eb21450d0a 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseLogService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseLogService.java @@ -1,8 +1,10 @@ package io.metersphere.functional.service; import io.metersphere.functional.domain.FunctionalCase; +import io.metersphere.functional.mapper.ExtFunctionalCaseMapper; import io.metersphere.functional.mapper.FunctionalCaseMapper; import io.metersphere.functional.request.FunctionalCaseAddRequest; +import io.metersphere.functional.request.FunctionalCaseBatchRequest; import io.metersphere.functional.request.FunctionalCaseDeleteRequest; import io.metersphere.functional.request.FunctionalCaseEditRequest; import io.metersphere.sdk.constants.HttpMethodConstants; @@ -12,6 +14,7 @@ import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.log.dto.LogDTO; import io.metersphere.system.log.service.OperationLogService; import jakarta.annotation.Resource; +import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -31,6 +34,10 @@ public class FunctionalCaseLogService { @Resource private OperationLogService operationLogService; + @Resource + private FunctionalCaseService functionalCaseService; + @Resource + private ExtFunctionalCaseMapper extFunctionalCaseMapper; //TODO 日志(需要修改) @@ -129,4 +136,29 @@ public class FunctionalCaseLogService { }); operationLogService.batchAdd(dtoList); } + + + public List batchDeleteFunctionalCaseLog(FunctionalCaseBatchRequest request) { + List ids = functionalCaseService.doSelectIds(request, request.getProjectId()); + List dtoList = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(ids)) { + List functionalCases = extFunctionalCaseMapper.getLogInfo(ids); + functionalCases.forEach(functionalCase -> { + LogDTO dto = new LogDTO( + functionalCase.getProjectId(), + null, + functionalCase.getId(), + null, + OperationLogType.DELETE.name(), + OperationLogModule.FUNCTIONAL_CASE, + functionalCase.getName()); + + dto.setPath("/functional/case/batch/deleteToGc"); + dto.setMethod(HttpMethodConstants.POST.name()); + dto.setOriginalValue(JSON.toJSONBytes(functionalCase)); + dtoList.add(dto); + }); + } + return dtoList; + } } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java index a7f5cf0928..ffab398eac 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java @@ -9,10 +9,7 @@ import io.metersphere.functional.mapper.ExtFunctionalCaseMapper; import io.metersphere.functional.mapper.FunctionalCaseBlobMapper; import io.metersphere.functional.mapper.FunctionalCaseFollowerMapper; import io.metersphere.functional.mapper.FunctionalCaseMapper; -import io.metersphere.functional.request.FunctionalCaseAddRequest; -import io.metersphere.functional.request.FunctionalCaseDeleteRequest; -import io.metersphere.functional.request.FunctionalCaseEditRequest; -import io.metersphere.functional.request.FunctionalCasePageRequest; +import io.metersphere.functional.request.*; import io.metersphere.functional.result.FunctionalCaseResultCode; import io.metersphere.project.service.ProjectTemplateService; import io.metersphere.sdk.constants.ApplicationNumScope; @@ -23,6 +20,7 @@ import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.BeanUtils; import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO; import io.metersphere.system.dto.sdk.TemplateDTO; +import io.metersphere.system.dto.table.TableBatchProcessDTO; import io.metersphere.system.uid.IDGenerator; import io.metersphere.system.uid.NumGenerator; import jakarta.annotation.Resource; @@ -387,4 +385,26 @@ public class FunctionalCaseService { return functionalCaseLists; } + + public void batchDeleteFunctionalCaseToGc(FunctionalCaseBatchRequest request, String userId) { + List ids = doSelectIds(request, request.getProjectId()); + if (CollectionUtils.isNotEmpty(ids)) { + List refId = extFunctionalCaseMapper.getRefIds(ids); + extFunctionalCaseMapper.batchDelete(refId, userId); + } + } + + + public List doSelectIds(T dto, String projectId) { + TableBatchProcessDTO request = (TableBatchProcessDTO) dto; + if (request.isSelectAll()) { + List ids = extFunctionalCaseMapper.getIds(request, projectId, false); + if (CollectionUtils.isNotEmpty(request.getExcludeIds())) { + ids.removeAll(request.getExcludeIds()); + } + return ids; + } else { + return request.getSelectIds(); + } + } } diff --git a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseControllerTests.java b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseControllerTests.java index 6910cad3d3..8910a4faad 100644 --- a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseControllerTests.java +++ b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseControllerTests.java @@ -44,6 +44,7 @@ public class FunctionalCaseControllerTests extends BaseTest { public static final String FUNCTIONAL_CASE_FOLLOWER_URL = "/functional/case/follower/"; public static final String FUNCTIONAL_CASE_DELETE_URL = "/functional/case/delete"; public static final String FUNCTIONAL_CASE_LIST_URL = "/functional/case/page"; + public static final String FUNCTIONAL_CASE_BATCH_DELETE_URL = "/functional/case/batch/delete-to-gc"; @Resource private NotificationMapper notificationMapper; @@ -266,12 +267,12 @@ public class FunctionalCaseControllerTests extends BaseTest { Assertions.assertNotNull(resultHolder); //自定义字段 测试 - Map map = new HashMap<>(); - map.put("customs",Arrays.asList(new LinkedHashMap(){{ - put("id","TEST_FIELD_ID"); - put("operator","in"); - put("value","222"); - put("type","List"); + Map map = new HashMap<>(); + map.put("customs", Arrays.asList(new LinkedHashMap() {{ + put("id", "TEST_FIELD_ID"); + put("operator", "in"); + put("value", "222"); + put("type", "List"); }})); request.setCombine(map); this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_LIST_URL, request); @@ -297,4 +298,21 @@ public class FunctionalCaseControllerTests extends BaseTest { request.setDeleteAll(true); this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_DELETE_URL, request); } + + + @Test + @Order(7) + public void testBatchDelete() throws Exception { + FunctionalCaseBatchRequest request = new FunctionalCaseBatchRequest(); + request.setProjectId(DEFAULT_PROJECT_ID); + request.setSelectAll(false); + this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_DELETE_URL, request); + + request.setSelectIds(Arrays.asList("TEST_FUNCTIONAL_CASE_ID_5", "TEST_FUNCTIONAL_CASE_ID_7")); + this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_DELETE_URL, request); + request.setSelectAll(true); + request.setExcludeIds(Arrays.asList("TEST_FUNCTIONAL_CASE_ID_2")); + this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_DELETE_URL, request); + } + } diff --git a/backend/services/case-management/src/test/resources/dml/init_file_metadata_test.sql b/backend/services/case-management/src/test/resources/dml/init_file_metadata_test.sql index 47b06ea55d..a38dfc646f 100644 --- a/backend/services/case-management/src/test/resources/dml/init_file_metadata_test.sql +++ b/backend/services/case-management/src/test/resources/dml/init_file_metadata_test.sql @@ -16,6 +16,14 @@ VALUES ('TEST_FUNCTIONAL_CASE_ID_3', 3, 'TEST_MOUDLE_ID', '100001100001', '10000 INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time) VALUES ('TEST_FUNCTIONAL_CASE_ID_4', 4, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL); +INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time) +VALUES ('TEST_FUNCTIONAL_CASE_ID_5', 5, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID_1', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL); + +INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time) +VALUES ('TEST_FUNCTIONAL_CASE_ID_6', 6, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID_1', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL); + +INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time) +VALUES ('TEST_FUNCTIONAL_CASE_ID_7', 7, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID_2', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL); INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_CASE_ID', 'STEP', '1111', NULL, NULL, 'TEST');