diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanFunctionalCaseController.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanFunctionalCaseController.java index af78051ba5..b94523ea06 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanFunctionalCaseController.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanFunctionalCaseController.java @@ -191,4 +191,13 @@ public class TestPlanFunctionalCaseController { @RequestParam(value = "keyword", required = false) String keyword) { return testPlanFunctionalCaseService.getExecUserList(projectId, keyword); } + + @PostMapping("/batch/move") + @Operation(summary = "测试计划-计划详情-功能用例-批量移动") + @RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE) + @CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan") + @Log(type = OperationLogType.UPDATE, expression = "#msClass.batchMove(#request)", msClass = TestPlanCaseLogService.class) + public void batchMove(@Validated @RequestBody BaseBatchMoveRequest request) { + testPlanFunctionalCaseService.batchMove(request); + } } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/BaseBatchMoveRequest.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/BaseBatchMoveRequest.java new file mode 100644 index 0000000000..b6be3cb2ba --- /dev/null +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/BaseBatchMoveRequest.java @@ -0,0 +1,17 @@ +package io.metersphere.plan.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** + * @author wx + */ +@Data +public class BaseBatchMoveRequest extends BasePlanCaseBatchRequest { + + @Schema(description = "目标计划集id", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{targetCollectionId.not_blank}") + private String targetCollectionId; + +} diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java index 0aeb1c8dce..476a807e79 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java @@ -559,6 +559,8 @@ public class TestPlanApiCaseService extends TestPlanResourceService implements G TestPlanApiCaseExample apiCaseExample = new TestPlanApiCaseExample(); apiCaseExample.createCriteria().andTestPlanIdEqualTo(planId); apiBatchMapper.updateByExampleSelective(record, apiCaseExample); + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); } public TestPlanOperationResponse sortNode(ResourceSortRequest request, LogInsertModule logInsertModule) { diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java index e3f37965e4..d99be2e503 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java @@ -226,6 +226,8 @@ public class TestPlanApiScenarioService extends TestPlanResourceService implemen TestPlanApiScenarioExample scenarioCaseExample = new TestPlanApiScenarioExample(); scenarioCaseExample.createCriteria().andTestPlanIdEqualTo(planId); scenarioBatchMapper.updateByExampleSelective(record, scenarioCaseExample); + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); } /** diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanCaseLogService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanCaseLogService.java index 80f6f1320f..5209f84d22 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanCaseLogService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanCaseLogService.java @@ -5,10 +5,12 @@ import io.metersphere.functional.domain.FunctionalCaseExample; import io.metersphere.functional.mapper.FunctionalCaseMapper; import io.metersphere.plan.domain.TestPlanFunctionalCase; import io.metersphere.plan.domain.TestPlanFunctionalCaseExample; +import io.metersphere.plan.dto.request.BaseBatchMoveRequest; import io.metersphere.plan.dto.request.TestPlanCaseUpdateRequest; import io.metersphere.plan.mapper.TestPlanFunctionalCaseMapper; import io.metersphere.sdk.constants.HttpMethodConstants; import io.metersphere.sdk.util.JSON; +import io.metersphere.sdk.util.Translator; import io.metersphere.system.log.constants.OperationLogModule; import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.log.dto.LogDTO; @@ -65,6 +67,40 @@ public class TestPlanCaseLogService { } } + + public void batchMove(BaseBatchMoveRequest request) { + List ids = testPlanFunctionalCaseService.doSelectIds(request); + if (CollectionUtils.isNotEmpty(ids)) { + TestPlanFunctionalCaseExample example = new TestPlanFunctionalCaseExample(); + example.createCriteria().andIdIn(ids); + List caseList = testPlanFunctionalCaseMapper.selectByExample(example); + List functionalCaseIds = caseList.stream().map(TestPlanFunctionalCase::getFunctionalCaseId).collect(Collectors.toList()); + FunctionalCaseExample caseExample = new FunctionalCaseExample(); + caseExample.createCriteria().andIdIn(functionalCaseIds); + List functionalCases = functionalCaseMapper.selectByExample(caseExample); + Map caseMap = functionalCases.stream().collect(Collectors.toMap(FunctionalCase::getId, FunctionalCase::getName)); + List dtoList = new ArrayList<>(); + caseList.forEach(item -> { + LogDTO dto = new LogDTO( + null, + null, + item.getFunctionalCaseId(), + null, + OperationLogType.UPDATE.name(), + OperationLogModule.TEST_PLAN, + Translator.get("move") + ":" + caseMap.get(item.getFunctionalCaseId())); + dto.setPath("/test-plan/functional/case/batch/move"); + dto.setMethod(HttpMethodConstants.POST.name()); + dto.setOriginalValue(JSON.toJSONBytes(item)); + TestPlanFunctionalCase testPlanFunctionalCase = new TestPlanFunctionalCase(); + testPlanFunctionalCase.setId(item.getId()); + testPlanFunctionalCase.setTestPlanCollectionId(request.getTargetCollectionId()); + dto.setModifiedValue(JSON.toJSONBytes(testPlanFunctionalCase)); + dtoList.add(dto); + }); + } + } + } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java index c8f453fc4f..94cf0f8cfb 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java @@ -65,6 +65,7 @@ import org.springframework.validation.annotation.Validated; import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -773,6 +774,34 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService { TestPlanFunctionalCaseExample functionalCaseExample = new TestPlanFunctionalCaseExample(); functionalCaseExample.createCriteria().andTestPlanIdEqualTo(planId); functionalBatchMapper.updateByExampleSelective(record, functionalCaseExample); + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); } + /** + * 批量移动 + * @param request + */ + public void batchMove(BaseBatchMoveRequest request) { + List ids = doSelectIds(request); + if (CollectionUtils.isNotEmpty(ids)) { + moveCaseToCollection(ids,request.getTargetCollectionId()); + } + } + + private void moveCaseToCollection(List ids, String targetCollectionId) { + AtomicLong nextOrder = new AtomicLong(getNextOrder(targetCollectionId)); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + TestPlanFunctionalCaseMapper functionalBatchMapper = sqlSession.getMapper(TestPlanFunctionalCaseMapper.class); + ids.forEach(id ->{ + TestPlanFunctionalCase testPlanFunctionalCase = new TestPlanFunctionalCase(); + testPlanFunctionalCase.setId(id); + testPlanFunctionalCase.setPos(nextOrder.get()); + testPlanFunctionalCase.setTestPlanCollectionId(targetCollectionId); + nextOrder.addAndGet(DEFAULT_NODE_INTERVAL_POS); + functionalBatchMapper.updateByPrimaryKeySelective(testPlanFunctionalCase); + }); + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); + } } diff --git a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCaseControllerTests.java b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCaseControllerTests.java index 687c6fb732..ac04473cf6 100644 --- a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCaseControllerTests.java +++ b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCaseControllerTests.java @@ -61,6 +61,7 @@ public class TestPlanCaseControllerTests extends BaseTest { public static final String FUNCTIONAL_CASE_EXEC_HISTORY_URL = "/test-plan/functional/case/exec/history"; public static final String USER_URL = "/test-plan/functional/case/user-option/"; + public static final String FUNCTIONAL_CASE_BATCH_MOVE_URL = "/test-plan/functional/case/batch/move"; @Resource private TestPlanFunctionalCaseMapper testPlanFunctionalCaseMapper; @Resource @@ -364,4 +365,15 @@ public class TestPlanCaseControllerTests extends BaseTest { collectionAssociates.put(AssociateCaseType.FUNCTIONAL, baseCollectionAssociateRequests); testPlanFunctionalCaseService.associateCollection("plan_1", collectionAssociates, "wx"); } + + @Test + @Order(18) + public void testFunctionalBatchMove() throws Exception { + BaseBatchMoveRequest request = new BaseBatchMoveRequest(); + request.setTestPlanId("plan_1"); + request.setTargetCollectionId("wxxx_1"); + request.setSelectAll(true); + this.requestPostWithOk(FUNCTIONAL_CASE_BATCH_MOVE_URL, request); + } + }