From 2440342d04e13043dc7f14a5828fee82ae2ecc77 Mon Sep 17 00:00:00 2001 From: song-cc-rock Date: Thu, 7 Nov 2024 17:15:03 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=B7=A5=E4=BD=9C=E5=8F=B0):=20=E8=A1=A5?= =?UTF-8?q?=E5=85=85=E6=88=91=E7=9A=84=E5=88=9B=E5=BB=BA&=E6=88=91?= =?UTF-8?q?=E7=9A=84=E5=85=B3=E6=B3=A8=E6=8E=A5=E5=8F=A3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --task=1016866 --user=宋昌昌 我的工作台-我创建&关注&待办-后端 https://www.tapd.cn/55049933/s/1607311 --- .../controller/MyViewController.java | 141 ++++++++++++++++++ .../DashboardViewApiCaseTableRequest.java | 18 +++ .../DashboardViewPlanTableRequest.java | 17 +++ .../request/DashboardViewTableRequest.java | 18 +++ .../controller/MyViewControllerTests.java | 102 +++++++++++++ 5 files changed, 296 insertions(+) create mode 100644 backend/services/dashboard/src/main/java/io/metersphere/dashboard/controller/MyViewController.java create mode 100644 backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardViewApiCaseTableRequest.java create mode 100644 backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardViewPlanTableRequest.java create mode 100644 backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardViewTableRequest.java create mode 100644 backend/services/dashboard/src/test/java/io/metersphere/dashboard/controller/MyViewControllerTests.java diff --git a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/controller/MyViewController.java b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/controller/MyViewController.java new file mode 100644 index 0000000000..a4e0490368 --- /dev/null +++ b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/controller/MyViewController.java @@ -0,0 +1,141 @@ +package io.metersphere.dashboard.controller; + +import com.alibaba.excel.util.StringUtils; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import io.metersphere.api.dto.definition.ApiTestCaseDTO; +import io.metersphere.api.dto.definition.ApiTestCasePageRequest; +import io.metersphere.api.dto.scenario.ApiScenarioDTO; +import io.metersphere.api.dto.scenario.ApiScenarioPageRequest; +import io.metersphere.api.service.definition.ApiTestCaseService; +import io.metersphere.api.service.scenario.ApiScenarioService; +import io.metersphere.bug.dto.request.BugPageRequest; +import io.metersphere.bug.dto.response.BugDTO; +import io.metersphere.bug.service.BugService; +import io.metersphere.dashboard.request.DashboardViewApiCaseTableRequest; +import io.metersphere.dashboard.request.DashboardViewPlanTableRequest; +import io.metersphere.dashboard.request.DashboardViewTableRequest; +import io.metersphere.functional.dto.CaseReviewDTO; +import io.metersphere.functional.dto.FunctionalCasePageDTO; +import io.metersphere.functional.request.CaseReviewPageRequest; +import io.metersphere.functional.request.FunctionalCasePageRequest; +import io.metersphere.functional.service.CaseReviewService; +import io.metersphere.functional.service.FunctionalCaseService; +import io.metersphere.plan.dto.request.TestPlanTableRequest; +import io.metersphere.plan.dto.response.TestPlanResponse; +import io.metersphere.plan.dto.response.TestPlanStatisticsResponse; +import io.metersphere.plan.service.TestPlanManagementService; +import io.metersphere.plan.service.TestPlanStatisticsService; +import io.metersphere.sdk.util.BeanUtils; +import io.metersphere.system.security.CheckOwner; +import io.metersphere.system.utils.PageUtils; +import io.metersphere.system.utils.Pager; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * @author song-cc-rock + */ + +@Tag(name = "工作台-我的", description = "前端视图ID传参(viewId): {关注: 'my_follow', 创建: 'my_create'}") +@RestController +@RequestMapping("/dashboard/my") +public class MyViewController { + + @Resource + private TestPlanManagementService testPlanManagementService; + @Resource + private TestPlanStatisticsService testPlanStatisticsService; + @Resource + private FunctionalCaseService functionalCaseService; + @Resource + private CaseReviewService caseReviewService; + @Resource + private ApiTestCaseService apiTestCaseService; + @Resource + private ApiScenarioService apiScenarioService; + @Resource + private BugService bugService; + + @PostMapping("/plan/page") + @Operation(summary = "我的-测试计划-列表分页查询") + @CheckOwner(resourceId = "#viewRequest.getProjectId()", resourceType = "project") + public Pager> page(@Validated @RequestBody DashboardViewPlanTableRequest viewRequest) { + return testPlanManagementService.page(buildTargetRequest(new TestPlanTableRequest(), viewRequest)); + } + + @PostMapping("/plan/statistics") + @Operation(summary = "我的-测试计划-获取列表详情统计 {通过率, 执行进度}") + @Parameter(name = "ids", description = "计划ID集合", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) + public List selectTestPlanMetricById(@RequestBody List ids) { + return testPlanStatisticsService.calculateRate(ids); + } + + @PostMapping("/functional/page") + @Operation(summary = "我的-测试用例-列表分页查询") + @CheckOwner(resourceId = "#viewRequest.getProjectId()", resourceType = "project") + public Pager> getFunctionalCasePage(@Validated @RequestBody DashboardViewTableRequest viewRequest) { + Page page = PageHelper.startPage(viewRequest.getCurrent(), viewRequest.getPageSize(), + StringUtils.isNotBlank(viewRequest.getSortString()) ? viewRequest.getSortString() : "pos desc"); + return PageUtils.setPageInfo(page, functionalCaseService.getFunctionalCasePage(buildTargetRequest(new FunctionalCasePageRequest(), viewRequest), false, true)); + } + + @PostMapping("/review/page") + @Operation(summary = "我的-用例评审-列表分页查询") + @CheckOwner(resourceId = "#viewRequest.getProjectId()", resourceType = "project") + public Pager> getCaseReviewPage(@Validated @RequestBody DashboardViewTableRequest viewRequest) { + Page page = PageHelper.startPage(viewRequest.getCurrent(), viewRequest.getPageSize(), + StringUtils.isNotBlank(viewRequest.getSortString()) ? viewRequest.getSortString() : "pos desc"); + return PageUtils.setPageInfo(page, caseReviewService.getCaseReviewPage(buildTargetRequest(new CaseReviewPageRequest(), viewRequest))); + } + + @PostMapping(value = "/api/page") + @Operation(summary = "我的-接口用例-列表分页查询") + @CheckOwner(resourceId = "#viewRequest.getProjectId()", resourceType = "project") + public Pager> page(@Validated @RequestBody DashboardViewApiCaseTableRequest viewRequest) { + Page page = PageHelper.startPage(viewRequest.getCurrent(), viewRequest.getPageSize(), + StringUtils.isNotBlank(viewRequest.getSortString("id")) ? viewRequest.getSortString("id") : "pos desc, id desc"); + return PageUtils.setPageInfo(page, apiTestCaseService.page(buildTargetRequest(new ApiTestCasePageRequest(), viewRequest), false, true, null)); + } + + @PostMapping("/scenario/page") + @Operation(summary = "我的-接口场景-列表分页查询") + @CheckOwner(resourceId = "#viewRequest.getProjectId()", resourceType = "project") + public Pager> getPage(@Validated @RequestBody DashboardViewTableRequest viewRequest) { + Page page = PageHelper.startPage(viewRequest.getCurrent(), viewRequest.getPageSize(), + StringUtils.isNotBlank(viewRequest.getSortString("id")) ? viewRequest.getSortString("id") : "pos desc, id desc"); + return PageUtils.setPageInfo(page, apiScenarioService.getScenarioPage(buildTargetRequest(new ApiScenarioPageRequest(), viewRequest), true, null)); + } + + @PostMapping("/bug/page") + @Operation(summary = "我的-缺陷-列表分页查询") + @CheckOwner(resourceId = "#viewRequest.getProjectId()", resourceType = "project") + public Pager> page(@Validated @RequestBody DashboardViewTableRequest viewRequest) { + Page page = PageHelper.startPage(viewRequest.getCurrent(), viewRequest.getPageSize(), + StringUtils.isNotBlank(viewRequest.getSortString()) ? viewRequest.getSortString() : "pos desc"); + BugPageRequest targetRequest = buildTargetRequest(new BugPageRequest(), viewRequest); + targetRequest.setUseTrash(false); + return PageUtils.setPageInfo(page, bugService.list(targetRequest)); + } + + /** + * 解析工作台通用的列表视图参数=>各个模块的分页参数 + * @param targetRequest 目标模块的分页参数 + * @param viewRequest 通用的列表视图参数 + * @return 目标模块的分页参数 + */ + private R buildTargetRequest(R targetRequest, S viewRequest) { + BeanUtils.copyBean(targetRequest, viewRequest); + return targetRequest; + } +} diff --git a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardViewApiCaseTableRequest.java b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardViewApiCaseTableRequest.java new file mode 100644 index 0000000000..fa510095a7 --- /dev/null +++ b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardViewApiCaseTableRequest.java @@ -0,0 +1,18 @@ +package io.metersphere.dashboard.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author song-cc-rock + */ + +@Data +public class DashboardViewApiCaseTableRequest extends DashboardViewTableRequest { + + @Schema(description = "接口协议", requiredMode = Schema.RequiredMode.REQUIRED) + private List protocols = new ArrayList<>(); +} diff --git a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardViewPlanTableRequest.java b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardViewPlanTableRequest.java new file mode 100644 index 0000000000..20fbc0dc0f --- /dev/null +++ b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardViewPlanTableRequest.java @@ -0,0 +1,17 @@ +package io.metersphere.dashboard.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** + * @author song-cc-rock + */ + +@Data +public class DashboardViewPlanTableRequest extends DashboardViewTableRequest { + + @Schema(description = "类型", allowableValues = {"ALL", "TEST_PLAN", "GROUP"}, requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{test_plan.type.not_blank}") + private String type; +} diff --git a/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardViewTableRequest.java b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardViewTableRequest.java new file mode 100644 index 0000000000..6a14022e1e --- /dev/null +++ b/backend/services/dashboard/src/main/java/io/metersphere/dashboard/request/DashboardViewTableRequest.java @@ -0,0 +1,18 @@ +package io.metersphere.dashboard.request; + +import io.metersphere.system.dto.sdk.BasePageRequest; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** + * @author song-cc-rock + */ + +@Data +public class DashboardViewTableRequest extends BasePageRequest { + + @Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{project.id.not_blank}") + private String projectId; +} diff --git a/backend/services/dashboard/src/test/java/io/metersphere/dashboard/controller/MyViewControllerTests.java b/backend/services/dashboard/src/test/java/io/metersphere/dashboard/controller/MyViewControllerTests.java new file mode 100644 index 0000000000..89a642cbe4 --- /dev/null +++ b/backend/services/dashboard/src/test/java/io/metersphere/dashboard/controller/MyViewControllerTests.java @@ -0,0 +1,102 @@ +package io.metersphere.dashboard.controller; + +import io.metersphere.dashboard.request.DashboardViewApiCaseTableRequest; +import io.metersphere.dashboard.request.DashboardViewPlanTableRequest; +import io.metersphere.dashboard.request.DashboardViewTableRequest; +import io.metersphere.sdk.util.BeanUtils; +import io.metersphere.system.base.BaseTest; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; +import java.util.Map; + +@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT) +@AutoConfigureMockMvc +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class MyViewControllerTests extends BaseTest { + + private static final String PLAN_PAGE = "/plan/page"; + private static final String PLAN_STATISTICS = "/plan/statistics"; + private static final String FUNCTIONAL_PAGE = "/functional/page"; + private static final String REVIEW_PAGE = "/review/page"; + private static final String API_PAGE = "/api/page"; + private static final String SCENARIO_PAGE = "/scenario/page"; + private static final String BUG_PAGE = "/bug/page"; + + @Override + public String getBasePath() { + return "/dashboard/my"; + } + + @Test + @Order(0) + void plan() throws Exception{ + DashboardViewTableRequest viewRequest = buildCorrectParam(); + DashboardViewPlanTableRequest planRequest = new DashboardViewPlanTableRequest(); + BeanUtils.copyBean(planRequest, viewRequest); + planRequest.setType("ALL"); + this.requestPostWithOk(PLAN_PAGE, planRequest); + this.requestPost(PLAN_STATISTICS, List.of("no-exist-id")); + } + + @Test + @Order(1) + void functional() throws Exception{ + DashboardViewTableRequest viewRequest = buildCorrectParam(); + this.requestPostWithOk(FUNCTIONAL_PAGE, viewRequest); + viewRequest.setSort(Map.of("id", "desc")); + this.requestPostWithOk(FUNCTIONAL_PAGE, viewRequest); + } + + @Test + @Order(2) + void review() throws Exception{ + DashboardViewTableRequest viewRequest = buildCorrectParam(); + this.requestPostWithOk(REVIEW_PAGE, viewRequest); + viewRequest.setSort(Map.of("id", "desc")); + this.requestPostWithOk(REVIEW_PAGE, viewRequest); + } + + @Test + @Order(3) + void api() throws Exception{ + DashboardViewTableRequest viewRequest = buildCorrectParam(); + DashboardViewApiCaseTableRequest apiRequest = new DashboardViewApiCaseTableRequest(); + BeanUtils.copyBean(apiRequest, viewRequest); + apiRequest.setProtocols(List.of("HTTP")); + this.requestPostWithOk(API_PAGE, apiRequest); + apiRequest.setSort(Map.of("id", "desc")); + this.requestPostWithOk(API_PAGE, apiRequest); + } + + @Test + @Order(4) + void scenario() throws Exception{ + DashboardViewTableRequest viewRequest = buildCorrectParam(); + this.requestPostWithOk(SCENARIO_PAGE, viewRequest); + viewRequest.setSort(Map.of("id", "desc")); + this.requestPostWithOk(SCENARIO_PAGE, viewRequest); + } + + @Test + @Order(5) + void bug() throws Exception{ + DashboardViewTableRequest viewRequest = buildCorrectParam(); + this.requestPostWithOk(BUG_PAGE, viewRequest); + viewRequest.setSort(Map.of("id", "desc")); + this.requestPostWithOk(BUG_PAGE, viewRequest); + } + + private DashboardViewTableRequest buildCorrectParam() { + DashboardViewTableRequest correctParam = new DashboardViewTableRequest(); + correctParam.setProjectId(DEFAULT_PROJECT_ID); + correctParam.setCurrent(1); + correctParam.setPageSize(10); + return correctParam; + } +}