diff --git a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/constants/DashboardUserLayoutKeys.java b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/constants/DashboardUserLayoutKeys.java index 7b888c2acf..dfdd39df56 100644 --- a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/constants/DashboardUserLayoutKeys.java +++ b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/constants/DashboardUserLayoutKeys.java @@ -26,6 +26,7 @@ public enum DashboardUserLayoutKeys { */ TEST_PLAN_COUNT,//测试计划数量统计 PLAN_LEGACY_BUG,//计划遗留bug统计 + PROJECT_PLAN_VIEW,//测试计划概览 /** * bug */ diff --git a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/dto/LayoutDTO.java b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/dto/LayoutDTO.java index c42b555e57..6036c162a8 100644 --- a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/dto/LayoutDTO.java +++ b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/dto/LayoutDTO.java @@ -32,5 +32,7 @@ public class LayoutDTO implements Serializable { private boolean selectAll; @Schema(description = "人员集合") private List handleUsers; + @Schema(description = "测试计划ID") + private String planId; } diff --git a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardFrontPageRequest.java b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardFrontPageRequest.java index 01f858572c..5b3a241494 100644 --- a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardFrontPageRequest.java +++ b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardFrontPageRequest.java @@ -30,6 +30,9 @@ public class DashboardFrontPageRequest extends DashboardBaseRequest{ @Schema(description = "人员集合") private List handleUsers; + @Schema(description = "测试计划ID") + private String planId; + public Long getToStartTime() { if (startTime == null && dayNumber>0) { diff --git a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/response/CascadeChildrenDTO.java b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/response/CascadeChildrenDTO.java index 77833eb3e2..ead59bdde0 100644 --- a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/response/CascadeChildrenDTO.java +++ b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/response/CascadeChildrenDTO.java @@ -20,6 +20,9 @@ public class CascadeChildrenDTO { @Schema(description = "名称/标签") private String label; + @Schema(description = "创建时间") + private Long createTime; + @Schema(description = "关联子集") private List children; diff --git a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/service/DashboardService.java b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/service/DashboardService.java index 5bb2d38e2e..faff5544f3 100644 --- a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/service/DashboardService.java +++ b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/service/DashboardService.java @@ -473,9 +473,17 @@ public class DashboardService { Set hasReadProjectIds = permissionModuleProjectIdMap.get(PermissionConstants.PROJECT_API_SCENARIO_READ); checkHasPermissionProject(layoutDTO, hasReadProjectIds); } else if (StringUtils.equalsIgnoreCase(layoutDTO.getKey(), DashboardUserLayoutKeys.TEST_PLAN_COUNT.toString()) - || StringUtils.equalsIgnoreCase(layoutDTO.getKey(), DashboardUserLayoutKeys.PLAN_LEGACY_BUG.toString())) { + || StringUtils.equalsIgnoreCase(layoutDTO.getKey(), DashboardUserLayoutKeys.PLAN_LEGACY_BUG.toString()) + || StringUtils.equalsIgnoreCase(layoutDTO.getKey(), DashboardUserLayoutKeys.PROJECT_PLAN_VIEW.toString())) { Set hasReadProjectIds = permissionModuleProjectIdMap.get(PermissionConstants.TEST_PLAN_READ); checkHasPermissionProject(layoutDTO, hasReadProjectIds); + if (StringUtils.equalsIgnoreCase(layoutDTO.getKey(), DashboardUserLayoutKeys.PROJECT_PLAN_VIEW.toString())) { + TestPlan testPlan = testPlanMapper.selectByPrimaryKey(layoutDTO.getPlanId()); + if (testPlan == null || StringUtils.equalsIgnoreCase(testPlan.getStatus(),TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED)) { + TestPlan latestPlan = extTestPlanMapper.getLatestPlan(layoutDTO.getProjectIds().getFirst()); + layoutDTO.setPlanId(latestPlan.getId()); + } + } } else if (StringUtils.equalsIgnoreCase(layoutDTO.getKey(), DashboardUserLayoutKeys.BUG_COUNT.toString()) || StringUtils.equalsIgnoreCase(layoutDTO.getKey(), DashboardUserLayoutKeys.CREATE_BUG_BY_ME.toString()) || StringUtils.equalsIgnoreCase(layoutDTO.getKey(), DashboardUserLayoutKeys.HANDLE_BUG_BY_ME.toString()) @@ -738,25 +746,33 @@ public class DashboardService { private static List getReviewList(Map> reviewStatusMap, List statisticListByProjectId) { List reviewList = new ArrayList<>(); List unReviewList = reviewStatusMap.get(FunctionalCaseReviewStatus.UN_REVIEWED.toString()); + List underReviewList = reviewStatusMap.get(FunctionalCaseReviewStatus.UNDER_REVIEWED.toString()); + List reReviewedList = reviewStatusMap.get(FunctionalCaseReviewStatus.RE_REVIEWED.toString()); if (CollectionUtils.isEmpty(unReviewList)) { unReviewList = new ArrayList<>(); } + if (CollectionUtils.isEmpty(underReviewList)) { + underReviewList = new ArrayList<>(); + } + if (CollectionUtils.isEmpty(reReviewedList)) { + reReviewedList = new ArrayList<>(); + } NameCountDTO reviewRate = new NameCountDTO(); reviewRate.setName(Translator.get("functional_case.reviewRate")); if (CollectionUtils.isEmpty(statisticListByProjectId)) { reviewRate.setCount(0); } else { - BigDecimal divide = BigDecimal.valueOf(statisticListByProjectId.size() - unReviewList.size()).divide(BigDecimal.valueOf(statisticListByProjectId.size()), 2, RoundingMode.HALF_UP); + BigDecimal divide = BigDecimal.valueOf(statisticListByProjectId.size() - unReviewList.size() - underReviewList.size() - reReviewedList.size()).divide(BigDecimal.valueOf(statisticListByProjectId.size()), 2, RoundingMode.HALF_UP); reviewRate.setCount(getTurnCount(divide)); } reviewList.add(reviewRate); NameCountDTO hasReview = new NameCountDTO(); hasReview.setName(Translator.get("functional_case.hasReview")); - hasReview.setCount(statisticListByProjectId.size() - unReviewList.size()); + hasReview.setCount(statisticListByProjectId.size() - unReviewList.size() - underReviewList.size() - reReviewedList.size()); reviewList.add(hasReview); NameCountDTO unReview = new NameCountDTO(); unReview.setName(Translator.get("functional_case.unReview")); - unReview.setCount(unReviewList.size()); + unReview.setCount(unReviewList.size() + underReviewList.size() + reReviewedList.size()); reviewList.add(unReview); return reviewList; } @@ -1522,14 +1538,17 @@ public class DashboardService { List groupAndPlanInfo = extTestPlanMapper.getGroupAndPlanInfo(projectId); TestPlanExample testPlanExample = new TestPlanExample(); testPlanExample.createCriteria().andProjectIdEqualTo(projectId).andTypeEqualTo(TestPlanConstants.TEST_PLAN_TYPE_PLAN).andGroupIdEqualTo("NONE"); + testPlanExample.setOrderByClause(" create_time DESC "); List testPlans = testPlanMapper.selectByExample(testPlanExample); - Map> groupMap = groupAndPlanInfo.stream().collect(Collectors.groupingBy(TestPlanAndGroupInfoDTO::getGroupId)); - groupMap.forEach((t, list)->{ + Map> groupMap = groupAndPlanInfo.stream().sorted(Comparator.comparing(TestPlanAndGroupInfoDTO::getGroupCreateTime).reversed()).collect(Collectors.groupingBy(TestPlanAndGroupInfoDTO::getGroupId)); + groupMap.forEach((t, list) -> { CascadeChildrenDTO father = new CascadeChildrenDTO(); father.setValue(t); father.setLabel(list.getFirst().getGroupName()); + father.setCreateTime(list.getFirst().getCreateTime()); List children = new ArrayList<>(); - for (TestPlanAndGroupInfoDTO testPlanAndGroupInfoDTO : list) { + List sortList = list.stream().sorted(Comparator.comparing(TestPlanAndGroupInfoDTO::getCreateTime).reversed()).toList(); + for (TestPlanAndGroupInfoDTO testPlanAndGroupInfoDTO : sortList) { CascadeDTO cascadeChildrenDTO = new CascadeDTO(); cascadeChildrenDTO.setValue(testPlanAndGroupInfoDTO.getId()); cascadeChildrenDTO.setLabel(testPlanAndGroupInfoDTO.getName()); @@ -1542,9 +1561,10 @@ public class DashboardService { CascadeChildrenDTO father = new CascadeChildrenDTO(); father.setValue(testPlan.getId()); father.setLabel(testPlan.getName()); + father.setCreateTime(testPlan.getCreateTime()); cascadeDTOList.add(father); } - return cascadeDTOList; + return cascadeDTOList.stream().sorted(Comparator.comparing(CascadeChildrenDTO::getCreateTime).reversed()).toList(); } } diff --git a/backend/services/dashboard/src/test/java/io/metersphere/dashboard/controller/DashboardFrontPageControllerTests.java b/backend/services/dashboard/src/test/java/io/metersphere/dashboard/controller/DashboardFrontPageControllerTests.java index 45c7ce6879..07c05747f2 100644 --- a/backend/services/dashboard/src/test/java/io/metersphere/dashboard/controller/DashboardFrontPageControllerTests.java +++ b/backend/services/dashboard/src/test/java/io/metersphere/dashboard/controller/DashboardFrontPageControllerTests.java @@ -260,6 +260,8 @@ public class DashboardFrontPageControllerTests extends BaseTest { layoutDTO.add(layoutDTO9); LayoutDTO layoutDTOz = getLayoutDTO(12, DashboardUserLayoutKeys.PLAN_LEGACY_BUG, "计划遗留bug统计"); layoutDTO.add(layoutDTOz); + LayoutDTO layoutDTOg = getLayoutDTO(17, DashboardUserLayoutKeys.PROJECT_PLAN_VIEW, "测试计划概览"); + layoutDTO.add(layoutDTOg); LayoutDTO layoutDTOx = getLayoutDTO(13, DashboardUserLayoutKeys.BUG_COUNT, "缺陷数量统计"); layoutDTO.add(layoutDTOx); LayoutDTO layoutDTOv = getLayoutDTO(14, DashboardUserLayoutKeys.CREATE_BUG_BY_ME, "我创建的缺陷"); @@ -312,6 +314,7 @@ public class DashboardFrontPageControllerTests extends BaseTest { layoutDTOb.setProjectIds(projects); layoutDTOb.setHandleUsers(new ArrayList<>()); layoutDTOb.setFullScreen(false); + layoutDTOb.setPlanId(""); return layoutDTOb; } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/TestPlanAndGroupInfoDTO.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/TestPlanAndGroupInfoDTO.java index 2fbbc331d5..0c9851467a 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/TestPlanAndGroupInfoDTO.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/TestPlanAndGroupInfoDTO.java @@ -11,10 +11,14 @@ public class TestPlanAndGroupInfoDTO { private String id; @Schema(description = "计划名称") private String name; + @Schema(description = "计划名称") + private Long createTime; @Schema(description = "计划组ID") private String groupId; @Schema(description = "计划组名称") private String groupName; + @Schema(description = "计划组创建时间") + private Long groupCreateTime; @Schema(description = "项目ID") private String projectId; diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java index f123adcf38..78d1def96c 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java @@ -104,4 +104,7 @@ public interface ExtTestPlanMapper { * 获取项目下计划组和计划的名称 */ List getGroupAndPlanInfo(@Param("projectId") String projectId); + + TestPlan getLatestPlan(@Param("projectId") String projectId); + } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml index 1a162218c9..2c010691ae 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml @@ -940,12 +940,17 @@ +