From d4f300266aaafa28a124a3bf9e2b72f957ccecf6 Mon Sep 17 00:00:00 2001 From: song-cc-rock Date: Mon, 25 Nov 2024 18:59:30 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E5=B7=A5=E4=BD=9C=E5=8F=B0):=20=E5=BE=85?= =?UTF-8?q?=E5=8A=9E=E8=AE=A1=E5=88=92=E5=88=97=E8=A1=A8=E7=AD=9B=E9=80=89?= =?UTF-8?q?=E6=9C=89=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1048995 --user=宋昌昌 【工作台】待办-测试计划列表-状态-筛选显示计划错误 https://www.tapd.cn/55049933/s/1617098 --- .../ExtTestPlanFunctionalCaseMapper.xml | 2 +- .../service/TestPlanManagementService.java | 51 ++++++++++++++++--- .../service/TestPlanStatisticsService.java | 11 ++-- 3 files changed, 53 insertions(+), 11 deletions(-) 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 eb3b9cc9b0..d18d343c12 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 @@ -111,7 +111,7 @@ functional_case.tags, test_plan_functional_case.execute_user as executeUser, test_plan_functional_case.last_exec_time as lastExecTime, - test_plan_functional_case.last_exec_result as lastExecResult, + if(test_plan_functional_case.last_exec_result = '', 'PENDING', test_plan_functional_case.last_exec_result) as lastExecResult, test_plan_functional_case.test_plan_id as testPlanId, test_plan_functional_case.id, project.name as projectName, diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanManagementService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanManagementService.java index 6e86d1a5bb..4adc0d2d7e 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanManagementService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanManagementService.java @@ -26,6 +26,7 @@ import io.metersphere.system.utils.Pager; import jakarta.annotation.Resource; import jakarta.validation.constraints.NotEmpty; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -324,14 +325,52 @@ public class TestPlanManagementService { * @return 已办计划ID集合 */ private List getDoneIds(String projectId) { - List completePlanOrGroupIds = selectTestPlanIdByProjectIdAndStatus(projectId, List.of((TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED))); - if (CollectionUtils.isEmpty(completePlanOrGroupIds)) { + List doneIds = new ArrayList<>(); + // 筛选出已完成/进行中的计划或计划组 + List completePlanOrGroupIds = selectTestPlanIdByProjectIdAndStatus(projectId, List.of(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)); + List underwayPlanOrGroupIds = selectTestPlanIdByProjectIdAndStatus(projectId, List.of(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)); + if (CollectionUtils.isEmpty(completePlanOrGroupIds) && CollectionUtils.isEmpty(underwayPlanOrGroupIds)) { return null; } - List completePlanOrGroupWithStatistics = testPlanStatisticsService.calculateRate(completePlanOrGroupIds); - return completePlanOrGroupWithStatistics.stream() - .filter(plan -> plan.getPassRate() >= plan.getPassThreshold()) - .map(TestPlanStatisticsResponse::getId).collect(Collectors.toList()); + TestPlanExample example = new TestPlanExample(); + example.createCriteria().andIdIn(ListUtils.union(completePlanOrGroupIds, underwayPlanOrGroupIds)); + List allPlans = testPlanMapper.selectByExample(example); + // 筛选出已完成且阈值达标的计划ID集合, 计划组除外 + List calculateIds = new ArrayList<>(); + List groupPlanIds = new ArrayList<>(); + allPlans.forEach(plan -> { + if (completePlanOrGroupIds.contains(plan.getId())) { + if (StringUtils.equals(plan.getType(), TestPlanConstants.TEST_PLAN_TYPE_PLAN)) { + // 已完成的计划, 待计算通过率比对 + calculateIds.add(plan.getId()); + } else { + // 已完成的计划组, 待获取下级子计划 + groupPlanIds.add(plan.getId()); + } + } else { + // 进行中的状态, 直接获取计划组下的子计划 + if (StringUtils.equals(plan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) { + groupPlanIds.add(plan.getId()); + } + } + }); + + // 处理计划组下级子计划 + List childPlans = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(groupPlanIds)) { + example.clear(); + example.createCriteria().andGroupIdIn(groupPlanIds); + childPlans = testPlanMapper.selectByExample(example); + } + calculateIds.addAll(childPlans.stream().map(TestPlan::getId).toList()); + List calcPlans = testPlanStatisticsService.calculateRate(calculateIds); + calcPlans.forEach(plan -> { + // 筛选出已完成的计划 && 子计划且通过率达到阈值 + if (plan.getPassRate() >= plan.getPassThreshold() && StringUtils.equals(plan.getStatus(), TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { + doneIds.add(plan.getId()); + } + }); + return doneIds; } } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanStatisticsService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanStatisticsService.java index b72d5f4f24..5c76a600c4 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanStatisticsService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanStatisticsService.java @@ -19,7 +19,10 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; /** @@ -167,17 +170,17 @@ public class TestPlanStatisticsService { private Map countApiScenarioExecResultMap(List apiScenarios) { return CollectionUtils.isEmpty(apiScenarios) ? new HashMap<>(16) : apiScenarios.stream().collect( - Collectors.groupingBy(apiScenario -> Optional.ofNullable(apiScenario.getLastExecResult()).orElse(ExecStatus.PENDING.name()), Collectors.counting())); + Collectors.groupingBy(apiScenario -> StringUtils.isEmpty(apiScenario.getLastExecResult()) ? ExecStatus.PENDING.name() : apiScenario.getLastExecResult(), Collectors.counting())); } private Map countApiTestCaseExecResultMap(List apiCases) { return CollectionUtils.isEmpty(apiCases) ? new HashMap<>(16) : apiCases.stream().collect( - Collectors.groupingBy(apiCase -> Optional.ofNullable(apiCase.getLastExecResult()).orElse(ExecStatus.PENDING.name()), Collectors.counting())); + Collectors.groupingBy(apiCase -> StringUtils.isEmpty(apiCase.getLastExecResult()) ? ExecStatus.PENDING.name() : apiCase.getLastExecResult(), Collectors.counting())); } private Map countFunctionalCaseExecResultMap(List functionalCases) { return CollectionUtils.isEmpty(functionalCases) ? new HashMap<>(16) : functionalCases.stream().collect( - Collectors.groupingBy(functionalCase -> Optional.ofNullable(functionalCase.getLastExecResult()).orElse(ExecStatus.PENDING.name()), Collectors.counting())); + Collectors.groupingBy(functionalCase -> StringUtils.isEmpty(functionalCase.getLastExecResult()) ? ExecStatus.PENDING.name() : functionalCase.getLastExecResult(), Collectors.counting())); } private TestPlanStatisticsResponse genTestPlanStatisticsResponse(TestPlan child,