feat(工作台): 新增根据项目id查询计划组与子计划及联关系

This commit is contained in:
guoyuqi 2024-12-02 11:59:10 +08:00 committed by 刘瑞斌
parent 49e65c16ee
commit a56a3b1582
12 changed files with 189 additions and 19 deletions

View File

@ -0,0 +1 @@
select database();

View File

@ -0,0 +1,8 @@
-- set innodb lock wait timeout
SET SESSION innodb_lock_wait_timeout = 7200;
CREATE INDEX idx_type_project_id
ON test_plan (type, project_id);
-- set innodb lock wait timeout to default
SET SESSION innodb_lock_wait_timeout = DEFAULT;

View File

@ -0,0 +1,6 @@
-- set innodb lock wait timeout
SET SESSION innodb_lock_wait_timeout = 7200;
-- set innodb lock wait timeout to default
SET SESSION innodb_lock_wait_timeout = DEFAULT;

View File

@ -8,6 +8,7 @@ import io.metersphere.bug.service.BugCommonService;
import io.metersphere.bug.service.BugService; import io.metersphere.bug.service.BugService;
import io.metersphere.dashboard.dto.LayoutDTO; import io.metersphere.dashboard.dto.LayoutDTO;
import io.metersphere.dashboard.request.DashboardFrontPageRequest; import io.metersphere.dashboard.request.DashboardFrontPageRequest;
import io.metersphere.dashboard.response.CascadeChildrenDTO;
import io.metersphere.dashboard.response.OverViewCountDTO; import io.metersphere.dashboard.response.OverViewCountDTO;
import io.metersphere.dashboard.response.StatisticsDTO; import io.metersphere.dashboard.response.StatisticsDTO;
import io.metersphere.dashboard.service.DashboardService; import io.metersphere.dashboard.service.DashboardService;
@ -215,4 +216,11 @@ public class DashboardController {
return bugService.getHeaderOption(projectId); return bugService.getHeaderOption(projectId);
} }
@GetMapping("/plan/option/{projectId}")
@Operation(summary = "获取测试计划列表")
@CheckOwner(resourceId = "#projectId", resourceType = "project")
public List<CascadeChildrenDTO> getPlanOption(@PathVariable String projectId) {
return dashboardService.getPlanOption(projectId);
}
} }

View File

@ -0,0 +1,23 @@
package io.metersphere.dashboard.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CascadeDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "值/id")
private String value;
@Schema(description = "名称/标签")
private String label;
}

View File

@ -0,0 +1,26 @@
package io.metersphere.dashboard.response;
import io.metersphere.dashboard.dto.CascadeDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CascadeChildrenDTO {
@Schema(description = "值/id")
private String value;
@Schema(description = "名称/标签")
private String label;
@Schema(description = "关联子集")
private List<CascadeDTO> children;
}

View File

@ -18,11 +18,9 @@ import io.metersphere.bug.mapper.ExtBugMapper;
import io.metersphere.bug.service.BugCommonService; import io.metersphere.bug.service.BugCommonService;
import io.metersphere.bug.service.BugStatusService; import io.metersphere.bug.service.BugStatusService;
import io.metersphere.dashboard.constants.DashboardUserLayoutKeys; import io.metersphere.dashboard.constants.DashboardUserLayoutKeys;
import io.metersphere.dashboard.dto.LayoutDTO; import io.metersphere.dashboard.dto.*;
import io.metersphere.dashboard.dto.NameArrayDTO;
import io.metersphere.dashboard.dto.NameCountDTO;
import io.metersphere.dashboard.dto.StatusPercentDTO;
import io.metersphere.dashboard.request.DashboardFrontPageRequest; import io.metersphere.dashboard.request.DashboardFrontPageRequest;
import io.metersphere.dashboard.response.CascadeChildrenDTO;
import io.metersphere.dashboard.response.OverViewCountDTO; import io.metersphere.dashboard.response.OverViewCountDTO;
import io.metersphere.dashboard.response.StatisticsDTO; import io.metersphere.dashboard.response.StatisticsDTO;
import io.metersphere.functional.constants.CaseReviewStatus; import io.metersphere.functional.constants.CaseReviewStatus;
@ -33,7 +31,11 @@ import io.metersphere.functional.mapper.ExtCaseReviewMapper;
import io.metersphere.functional.mapper.ExtFunctionalCaseMapper; import io.metersphere.functional.mapper.ExtFunctionalCaseMapper;
import io.metersphere.functional.request.CaseReviewPageRequest; import io.metersphere.functional.request.CaseReviewPageRequest;
import io.metersphere.functional.service.CaseReviewService; import io.metersphere.functional.service.CaseReviewService;
import io.metersphere.plan.domain.TestPlan;
import io.metersphere.plan.domain.TestPlanExample;
import io.metersphere.plan.dto.TestPlanAndGroupInfoDTO;
import io.metersphere.plan.mapper.ExtTestPlanMapper; import io.metersphere.plan.mapper.ExtTestPlanMapper;
import io.metersphere.plan.mapper.TestPlanMapper;
import io.metersphere.plugin.platform.dto.SelectOption; import io.metersphere.plugin.platform.dto.SelectOption;
import io.metersphere.project.domain.Project; import io.metersphere.project.domain.Project;
import io.metersphere.project.dto.ProjectCountDTO; import io.metersphere.project.dto.ProjectCountDTO;
@ -120,6 +122,8 @@ public class DashboardService {
@Resource @Resource
private UserLayoutMapper userLayoutMapper; private UserLayoutMapper userLayoutMapper;
@Resource @Resource
private TestPlanMapper testPlanMapper;
@Resource
private BugCommonService bugCommonService; private BugCommonService bugCommonService;
@Resource @Resource
private BugStatusService bugStatusService; private BugStatusService bugStatusService;
@ -1512,6 +1516,37 @@ public class DashboardService {
} }
return extSystemProjectMapper.getMemberByProjectId(projectId, keyword); return extSystemProjectMapper.getMemberByProjectId(projectId, keyword);
} }
public List<CascadeChildrenDTO> getPlanOption(String projectId) {
List<CascadeChildrenDTO> cascadeDTOList = new ArrayList<>();
List<TestPlanAndGroupInfoDTO> groupAndPlanInfo = extTestPlanMapper.getGroupAndPlanInfo(projectId);
TestPlanExample testPlanExample = new TestPlanExample();
testPlanExample.createCriteria().andProjectIdEqualTo(projectId).andTypeEqualTo(TestPlanConstants.TEST_PLAN_TYPE_PLAN).andGroupIdEqualTo("NONE");
List<TestPlan> testPlans = testPlanMapper.selectByExample(testPlanExample);
Map<String, List<TestPlanAndGroupInfoDTO>> groupMap = groupAndPlanInfo.stream().collect(Collectors.groupingBy(TestPlanAndGroupInfoDTO::getGroupId));
groupMap.forEach((t, list)->{
CascadeChildrenDTO father = new CascadeChildrenDTO();
father.setValue(t);
father.setLabel(list.getFirst().getGroupName());
List<CascadeDTO> children = new ArrayList<>();
for (TestPlanAndGroupInfoDTO testPlanAndGroupInfoDTO : list) {
CascadeDTO cascadeChildrenDTO = new CascadeDTO();
cascadeChildrenDTO.setValue(testPlanAndGroupInfoDTO.getId());
cascadeChildrenDTO.setLabel(testPlanAndGroupInfoDTO.getName());
children.add(cascadeChildrenDTO);
}
father.setChildren(children);
cascadeDTOList.add(father);
});
for (TestPlan testPlan : testPlans) {
CascadeChildrenDTO father = new CascadeChildrenDTO();
father.setValue(testPlan.getId());
father.setLabel(testPlan.getName());
cascadeDTOList.add(father);
}
return cascadeDTOList;
}
} }

View File

@ -9,6 +9,7 @@ import io.metersphere.bug.service.BugStatusService;
import io.metersphere.dashboard.constants.DashboardUserLayoutKeys; import io.metersphere.dashboard.constants.DashboardUserLayoutKeys;
import io.metersphere.dashboard.dto.LayoutDTO; import io.metersphere.dashboard.dto.LayoutDTO;
import io.metersphere.dashboard.request.DashboardFrontPageRequest; import io.metersphere.dashboard.request.DashboardFrontPageRequest;
import io.metersphere.dashboard.response.CascadeChildrenDTO;
import io.metersphere.dashboard.response.OverViewCountDTO; import io.metersphere.dashboard.response.OverViewCountDTO;
import io.metersphere.dashboard.response.StatisticsDTO; import io.metersphere.dashboard.response.StatisticsDTO;
import io.metersphere.dashboard.service.DashboardService; import io.metersphere.dashboard.service.DashboardService;
@ -105,6 +106,9 @@ public class DashboardFrontPageControllerTests extends BaseTest {
private static final String PROJECT_MEMBER_USER_LIST = "/dashboard/member/get-project-member/option/"; private static final String PROJECT_MEMBER_USER_LIST = "/dashboard/member/get-project-member/option/";
private static final String PROJECT_PLAN_LIST = "/dashboard/plan/option/";
@Test @Test
@Order(1) @Order(1)
@Sql(scripts = {"/dml/init_dashboard.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED)) @Sql(scripts = {"/dml/init_dashboard.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
@ -591,6 +595,22 @@ public class DashboardFrontPageControllerTests extends BaseTest {
Assertions.assertNotNull(list); Assertions.assertNotNull(list);
} }
@Test
@Order(7)
public void testProjectPlanList() throws Exception {
MvcResult mvcResult = this.requestGetWithOkAndReturn(PROJECT_PLAN_LIST + DEFAULT_PROJECT_ID);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
List<CascadeChildrenDTO> list = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), CascadeChildrenDTO.class);
Assertions.assertNotNull(list);
mvcResult = this.requestGetWithOkAndReturn(PROJECT_MEMBER_USER_LIST + "id");
returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
resultHolder = JSON.parseObject(returnData, ResultHolder.class);
list = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), CascadeChildrenDTO.class);
Assertions.assertNotNull(list);
}
private void enableDefaultPlatformConfig() { private void enableDefaultPlatformConfig() {
ProjectApplication record = new ProjectApplication(); ProjectApplication record = new ProjectApplication();
record.setTypeValue("true"); record.setTypeValue("true");

View File

@ -121,6 +121,14 @@ INSERT INTO test_plan(id, num, project_id, group_id, module_id, name, status, ty
VALUE ('dashboard_test-plan-id', 500, '100001100001', 'NONE', 'case_plan_module', 'test_plan_associate_case_name_three', 'NOT_ARCHIVED', 'TEST_PLAN', null, UNIX_TIMESTAMP() * 1000,'admin', VALUE ('dashboard_test-plan-id', 500, '100001100001', 'NONE', 'case_plan_module', 'test_plan_associate_case_name_three', 'NOT_ARCHIVED', 'TEST_PLAN', null, UNIX_TIMESTAMP() * 1000,'admin',
UNIX_TIMESTAMP() * 1000,'admin',UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, null); UNIX_TIMESTAMP() * 1000,'admin',UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, null);
INSERT INTO test_plan(id, num, project_id, group_id, module_id, name, status, type, tags, create_time, create_user, update_time, update_user, planned_start_time, planned_end_time, actual_start_time, actual_end_time, description)
VALUE ('dashboard_test-plan-id2', 500, '100001100001', 'dashboard_group-plan', 'case_plan_module', 'test_plan_name_three', 'NOT_ARCHIVED', 'TEST_PLAN', null, UNIX_TIMESTAMP() * 1000,'admin',
UNIX_TIMESTAMP() * 1000,'admin',UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, null);
INSERT INTO test_plan(id, num, project_id, group_id, module_id, name, status, type, tags, create_time, create_user, update_time, update_user, planned_start_time, planned_end_time, actual_start_time, actual_end_time, description)
VALUE ('dashboard_group-plan', 500, '100001100001', 'NONE', 'case_plan_module', 'test_plan_group_name_three', 'NOT_ARCHIVED', 'GROUP', null, UNIX_TIMESTAMP() * 1000,'admin',
UNIX_TIMESTAMP() * 1000,'admin',UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, null);
INSERT INTO project_application (project_id, type, type_value) VALUES INSERT INTO project_application (project_id, type, type_value) VALUES
('100001100001', 'BUG_SYNC_BUG_PLATFORM_CONFIG', '{"jiraKey":"TES","jiraBugTypeId":"10009"}'), ('100001100001', 'BUG_SYNC_BUG_PLATFORM_CONFIG', '{"jiraKey":"TES","jiraBugTypeId":"10009"}'),
('100001100001', 'BUG_SYNC_PLATFORM_KEY', 'jira'), ('100001100001', 'BUG_SYNC_PLATFORM_KEY', 'jira'),

View File

@ -0,0 +1,21 @@
package io.metersphere.plan.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class TestPlanAndGroupInfoDTO {
@Schema(description = "计划id")
private String id;
@Schema(description = "计划名称")
private String name;
@Schema(description = "计划组ID")
private String groupId;
@Schema(description = "计划组名称")
private String groupName;
@Schema(description = "项目ID")
private String projectId;
}

View File

@ -1,6 +1,7 @@
package io.metersphere.plan.mapper; package io.metersphere.plan.mapper;
import io.metersphere.plan.domain.TestPlan; import io.metersphere.plan.domain.TestPlan;
import io.metersphere.plan.dto.TestPlanAndGroupInfoDTO;
import io.metersphere.plan.dto.TestPlanExecuteHisDTO; import io.metersphere.plan.dto.TestPlanExecuteHisDTO;
import io.metersphere.plan.dto.TestPlanGroupCountDTO; import io.metersphere.plan.dto.TestPlanGroupCountDTO;
import io.metersphere.plan.dto.TestPlanQueryConditions; import io.metersphere.plan.dto.TestPlanQueryConditions;
@ -97,4 +98,10 @@ public interface ExtTestPlanMapper {
List<SelectOption> getPlanBugList(@Param("projectId") String projectId, @Param("type") String type, @Param("platforms") List<String> platform, @Param("statusList") List<String> statusList); List<SelectOption> getPlanBugList(@Param("projectId") String projectId, @Param("type") String type, @Param("platforms") List<String> platform, @Param("statusList") List<String> statusList);
List<TestPlan> selectIdAndStatusByProjectIdAndCreateTimeRangeAndType(@Param("projectId") String projectId, @Param("startTime") Long startTime, @Param("endTime") Long endTime, @Param("type") String testPlanTypePlan); List<TestPlan> selectIdAndStatusByProjectIdAndCreateTimeRangeAndType(@Param("projectId") String projectId, @Param("startTime") Long startTime, @Param("endTime") Long endTime, @Param("type") String testPlanTypePlan);
/**
* @param projectId 项目
* 获取项目下计划组和计划的名称
*/
List<TestPlanAndGroupInfoDTO> getGroupAndPlanInfo(@Param("projectId") String projectId);
} }

View File

@ -939,6 +939,13 @@
</foreach> </foreach>
</if> </if>
</select> </select>
<select id="getGroupAndPlanInfo" resultType="io.metersphere.plan.dto.TestPlanAndGroupInfoDTO">
select son.id, son.name, son.group_id, son.project_id, father.name as groupName
from test_plan son
left join test_plan father on father.id = son.group_id
where son.type = 'TEST_PLAN'
and father.type = 'GROUP' and son.project_id = #{projectId};
</select>
<sql id="queryMyFollowGroupByTableRequest"> <sql id="queryMyFollowGroupByTableRequest">