From b16dad62c2f4cc83cd91546cc6ccdd8ddb3061dc Mon Sep 17 00:00:00 2001 From: WangXu10 Date: Wed, 12 Jun 2024 17:45:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92):=20?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E7=94=A8=E4=BE=8B=E6=96=B0=E5=A2=9E=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E9=9B=86=E8=A7=86=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TestPlanApiScenarioController.java | 2 +- .../TestPlanFunctionalCaseController.java | 8 +- .../request/TestPlanCaseModuleRequest.java | 17 ++++ ...eRequest.java => TestPlanTreeRequest.java} | 2 +- .../ExtTestPlanFunctionalCaseMapper.java | 3 + .../ExtTestPlanFunctionalCaseMapper.xml | 13 +++ .../service/TestPlanApiScenarioService.java | 2 +- .../TestPlanFunctionalCaseService.java | 79 +++++++++++++++++-- .../TestPlanApiScenarioControllerTests.java | 2 +- .../TestPlanCaseControllerTests.java | 22 +++++- 10 files changed, 132 insertions(+), 18 deletions(-) create mode 100644 backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanCaseModuleRequest.java rename backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/{TestPlanApiScenarioTreeRequest.java => TestPlanTreeRequest.java} (91%) diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanApiScenarioController.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanApiScenarioController.java index c222d914e2..77e357e82c 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanApiScenarioController.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanApiScenarioController.java @@ -71,7 +71,7 @@ public class TestPlanApiScenarioController { @Operation(summary = "测试计划-已关联场景用例列表模块树") @RequiresPermissions(PermissionConstants.TEST_PLAN_READ) @CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan") - public List getTree(@Validated @RequestBody TestPlanApiScenarioTreeRequest request) { + public List getTree(@Validated @RequestBody TestPlanTreeRequest request) { return testPlanApiScenarioService.getTree(request); } 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 59a08f213b..af78051ba5 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 @@ -65,19 +65,19 @@ public class TestPlanFunctionalCaseController { return PageUtils.setPageInfo(page, testPlanFunctionalCaseService.getFunctionalCasePage(request, false)); } - @GetMapping("/tree/{testPlanId}") + @PostMapping("/tree") @Operation(summary = "测试计划-已关联功能用例列表模块树") @RequiresPermissions(PermissionConstants.TEST_PLAN_READ) @CheckOwner(resourceId = "#testPlanId", resourceType = "test_plan") - public List getTree(@PathVariable String testPlanId) { - return testPlanFunctionalCaseService.getTree(testPlanId); + public List getTree(@Validated @RequestBody TestPlanTreeRequest request) { + return testPlanFunctionalCaseService.getTree(request); } @PostMapping("/module/count") @Operation(summary = "测试计划-已关联功能用例模块数量") @RequiresPermissions(PermissionConstants.TEST_PLAN_READ) @CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan") - public Map moduleCount(@Validated @RequestBody TestPlanCaseRequest request) { + public Map moduleCount(@Validated @RequestBody TestPlanCaseModuleRequest request) { return testPlanFunctionalCaseService.moduleCount(request); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanCaseModuleRequest.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanCaseModuleRequest.java new file mode 100644 index 0000000000..62405f6903 --- /dev/null +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanCaseModuleRequest.java @@ -0,0 +1,17 @@ +package io.metersphere.plan.dto.request; + +import io.metersphere.plan.constants.TreeTypeEnums; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** + * @author wx + */ +@Data +public class TestPlanCaseModuleRequest extends TestPlanCaseRequest{ + + @Schema(description = "类型:模块/计划集", allowableValues = {"MODULE","COLLECTION"},requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{test_plan.type.not_blank}") + private String treeType = TreeTypeEnums.COLLECTION; +} \ No newline at end of file diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanApiScenarioTreeRequest.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanTreeRequest.java similarity index 91% rename from backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanApiScenarioTreeRequest.java rename to backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanTreeRequest.java index b906bf0241..66d32a4a51 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanApiScenarioTreeRequest.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanTreeRequest.java @@ -12,7 +12,7 @@ import java.io.Serializable; * @author wx */ @Data -public class TestPlanApiScenarioTreeRequest implements Serializable { +public class TestPlanTreeRequest implements Serializable { @Serial private static final long serialVersionUID = 1L; diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.java index 254dd7f135..a08fec9571 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.java @@ -10,6 +10,7 @@ import io.metersphere.plan.dto.request.BasePlanCaseBatchRequest; import io.metersphere.plan.dto.request.TestPlanCaseRequest; import io.metersphere.plan.dto.response.TestPlanCasePageResponse; import io.metersphere.project.dto.DropNode; +import io.metersphere.project.dto.ModuleCountDTO; import io.metersphere.project.dto.NodeSortQueryParam; import org.apache.ibatis.annotations.Param; @@ -60,4 +61,6 @@ public interface ExtTestPlanFunctionalCaseMapper { List selectCaseExecResultCount(String testPlanId); Long getMaxPosByCollectionId(String collectionId); + + List collectionCountByRequest(@Param("testPlanId") String testPlanId); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.xml b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.xml index 38024a3280..92517beb0b 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.xml +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.xml @@ -538,4 +538,17 @@ WHERE test_plan_collection_id = #{0} + \ No newline at end of file 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 19f07ba842..247295a83f 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 @@ -423,7 +423,7 @@ public class TestPlanApiScenarioService extends TestPlanResourceService implemen return apiScenarioModuleService.buildTreeAndCountResource(nodeByNodeIds, moduleCountDTOList, true, Translator.get("functional_case.module.default.name")); } - public List getTree(TestPlanApiScenarioTreeRequest request) { + public List getTree(TestPlanTreeRequest request) { switch (request.getTreeType()) { case TreeTypeEnums.MODULE: return getModuleTree(request.getTestPlanId()); 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 76656b6543..c8f453fc4f 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 @@ -18,6 +18,7 @@ import io.metersphere.functional.service.FunctionalCaseAttachmentService; import io.metersphere.functional.service.FunctionalCaseModuleService; import io.metersphere.functional.service.FunctionalCaseService; import io.metersphere.plan.constants.AssociateCaseType; +import io.metersphere.plan.constants.TreeTypeEnums; import io.metersphere.plan.domain.*; import io.metersphere.plan.dto.ResourceLogInsertModule; import io.metersphere.plan.dto.TestPlanCaseRunResultCount; @@ -33,10 +34,7 @@ import io.metersphere.project.dto.MoveNodeSortDTO; import io.metersphere.provider.BaseAssociateBugProvider; import io.metersphere.request.AssociateBugPageRequest; import io.metersphere.request.BugPageProviderRequest; -import io.metersphere.sdk.constants.CaseType; -import io.metersphere.sdk.constants.ExecStatus; -import io.metersphere.sdk.constants.HttpMethodConstants; -import io.metersphere.sdk.constants.TestPlanResourceConstants; +import io.metersphere.sdk.constants.*; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.JSON; @@ -269,7 +267,42 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService { .collect(Collectors.toSet()); } - public List getTree(String testPlanId) { + public List getTree(TestPlanTreeRequest request) { + switch (request.getTreeType()) { + case TreeTypeEnums.MODULE: + return getModuleTree(request.getTestPlanId()); + case TreeTypeEnums.COLLECTION: + return getCollectionTree(request.getTestPlanId()); + default: + return new ArrayList<>(); + } + } + + /** + * 已关联接口用例规划视图树 + * + * @param testPlanId + * @return + */ + private List getCollectionTree(String testPlanId) { + List returnList = new ArrayList<>(); + TestPlanCollectionExample collectionExample = new TestPlanCollectionExample(); + collectionExample.createCriteria().andTypeEqualTo(CaseType.FUNCTIONAL_CASE.getKey()).andParentIdNotEqualTo(ModuleConstants.ROOT_NODE_PARENT_ID).andTestPlanIdEqualTo(testPlanId); + List testPlanCollections = testPlanCollectionMapper.selectByExample(collectionExample); + testPlanCollections.forEach(item -> { + BaseTreeNode baseTreeNode = new BaseTreeNode(item.getId(), item.getName(), CaseType.FUNCTIONAL_CASE.getKey()); + returnList.add(baseTreeNode); + }); + return returnList; + } + + /** + * 模块树 + * + * @param testPlanId + * @return + */ + private List getModuleTree(String testPlanId) { List returnList = new ArrayList<>(); List rootIds = extTestPlanFunctionalCaseMapper.selectRootIdByTestPlanId(testPlanId); Map> projectRootMap = rootIds.stream().collect(Collectors.groupingBy(ProjectOptionDTO::getName)); @@ -299,7 +332,41 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService { } - public Map moduleCount(TestPlanCaseRequest request) { + public Map moduleCount(TestPlanCaseModuleRequest request) { + switch (request.getTreeType()) { + case TreeTypeEnums.MODULE: + return getModuleCount(request); + case TreeTypeEnums.COLLECTION: + return getCollectionCount(request); + default: + return new HashMap<>(); + } + } + + /** + * 已关联接口用例规划视图统计 + * + * @param request + * @return + */ + private Map getCollectionCount(TestPlanCaseModuleRequest request) { + Map projectModuleCountMap = new HashMap<>(); + List list = extTestPlanFunctionalCaseMapper.collectionCountByRequest(request.getTestPlanId()); + list.forEach(item -> { + projectModuleCountMap.put(item.getModuleId(), (long) item.getDataCount()); + }); + long allCount = extTestPlanFunctionalCaseMapper.caseCount(request, false); + projectModuleCountMap.put(CASE_MODULE_COUNT_ALL, allCount); + return projectModuleCountMap; + } + + /** + * 已关联接口用例模块树统计 + * + * @param request + * @return + */ + private Map getModuleCount(TestPlanCaseModuleRequest request) { //查出每个模块节点下的资源数量。 不需要按照模块进行筛选 request.setModuleIds(null); List projectModuleCountDTOList = extTestPlanFunctionalCaseMapper.countModuleIdByRequest(request, false); diff --git a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanApiScenarioControllerTests.java b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanApiScenarioControllerTests.java index 4044f2d21c..a5d79943ab 100644 --- a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanApiScenarioControllerTests.java +++ b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanApiScenarioControllerTests.java @@ -317,7 +317,7 @@ public class TestPlanApiScenarioControllerTests extends BaseTest { @Test @Order(5) public void testApiScenarioModuleTree() throws Exception { - TestPlanApiScenarioTreeRequest request = new TestPlanApiScenarioTreeRequest(); + TestPlanTreeRequest request = new TestPlanTreeRequest(); request.setTestPlanId("wxxx_plan_1"); request.setTreeType("MODULE"); this.requestPostWithOkAndReturn(API_SCENARIO_TREE, request); 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 015ecf83b0..687c6fb732 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 @@ -47,7 +47,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. public class TestPlanCaseControllerTests extends BaseTest { public static final String FUNCTIONAL_CASE_LIST_URL = "/test-plan/functional/case/page"; - public static final String FUNCTIONAL_CASE_TREE_URL = "/test-plan/functional/case/tree/"; + public static final String FUNCTIONAL_CASE_TREE_URL = "/test-plan/functional/case/tree"; public static final String FUNCTIONAL_CASE_TREE_COUNT_URL = "/test-plan/functional/case/module/count"; public static final String FUNCTIONAL_CASE_DISASSOCIATE_URL = "/test-plan/functional/case/disassociate"; public static final String FUNCTIONAL_CASE_BATCH_DISASSOCIATE_URL = "/test-plan/functional/case/batch/disassociate"; @@ -98,26 +98,40 @@ public class TestPlanCaseControllerTests extends BaseTest { @Test @Order(2) public void testGetFunctionalCaseTree() throws Exception { - MvcResult mvcResult = this.requestGetWithOkAndReturn(FUNCTIONAL_CASE_TREE_URL + "plan_1"); + TestPlanTreeRequest request = new TestPlanTreeRequest(); + request.setTestPlanId("plan_1"); + request.setTreeType("MODULE"); + this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_TREE_URL, request); + request.setTestPlanId("plan_2"); + MvcResult mvcResult = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_TREE_URL, request); String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8); ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class); Assertions.assertNotNull(resultHolder); - this.requestGetWithOkAndReturn(FUNCTIONAL_CASE_TREE_URL + "plan_2"); + request.setTestPlanId("plan_2"); + request.setTreeType("COLLECTION"); + MvcResult mvcResult1 = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_TREE_URL, request); + String returnData1 = mvcResult1.getResponse().getContentAsString(StandardCharsets.UTF_8); + ResultHolder resultHolder1 = JSON.parseObject(returnData1, ResultHolder.class); + Assertions.assertNotNull(resultHolder1); } @Test @Order(3) public void testGetFunctionalCaseTreeCount() throws Exception { - TestPlanCaseRequest request = new TestPlanCaseRequest(); + TestPlanCaseModuleRequest request = new TestPlanCaseModuleRequest(); request.setProjectId("123"); request.setCurrent(1); request.setPageSize(10); request.setTestPlanId("plan_1"); + request.setTreeType("MODULE"); MvcResult mvcResult = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_TREE_COUNT_URL, request); String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8); ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class); Assertions.assertNotNull(resultHolder); + + request.setTreeType("COLLECTION"); + this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_TREE_COUNT_URL, request); }