diff --git a/backend/framework/provider/src/main/java/io/metersphere/dto/BugProviderDTO.java b/backend/framework/provider/src/main/java/io/metersphere/dto/BugProviderDTO.java index ae482bb236..897a96b5fe 100644 --- a/backend/framework/provider/src/main/java/io/metersphere/dto/BugProviderDTO.java +++ b/backend/framework/provider/src/main/java/io/metersphere/dto/BugProviderDTO.java @@ -22,10 +22,10 @@ public class BugProviderDTO implements Serializable { private String name; @Schema(description = "处理人") - private String createUser; + private String handleUser; @Schema(description = "处理人姓名") - private String createUserName; + private String handleUserName; @Schema(description = "缺陷状态") private String status; diff --git a/backend/framework/provider/src/main/java/io/metersphere/dto/BugRelateCaseDTO.java b/backend/framework/provider/src/main/java/io/metersphere/dto/BugRelateCaseDTO.java new file mode 100644 index 0000000000..6ee5fbafc9 --- /dev/null +++ b/backend/framework/provider/src/main/java/io/metersphere/dto/BugRelateCaseDTO.java @@ -0,0 +1,23 @@ +package io.metersphere.dto; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author wx + */ +@Data +public class BugRelateCaseDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private String id; + + private String title; + + private String status; + +} diff --git a/backend/framework/provider/src/main/java/io/metersphere/provider/BaseAssociateBugProvider.java b/backend/framework/provider/src/main/java/io/metersphere/provider/BaseAssociateBugProvider.java index f0776e4432..0b7e31de43 100644 --- a/backend/framework/provider/src/main/java/io/metersphere/provider/BaseAssociateBugProvider.java +++ b/backend/framework/provider/src/main/java/io/metersphere/provider/BaseAssociateBugProvider.java @@ -1,6 +1,7 @@ package io.metersphere.provider; import io.metersphere.dto.BugProviderDTO; +import io.metersphere.request.AssociateBugPageRequest; import io.metersphere.request.AssociateBugRequest; import io.metersphere.request.BugPageProviderRequest; @@ -48,4 +49,12 @@ public interface BaseAssociateBugProvider { * @param id */ void disassociateBug(String id); + + /** + * 获取用例已关联缺陷列表 + * + * @param request + * @return + */ + List hasAssociateBugPage(AssociateBugPageRequest request); } diff --git a/backend/framework/provider/src/main/java/io/metersphere/request/AssociateBugPageRequest.java b/backend/framework/provider/src/main/java/io/metersphere/request/AssociateBugPageRequest.java new file mode 100644 index 0000000000..375dce4292 --- /dev/null +++ b/backend/framework/provider/src/main/java/io/metersphere/request/AssociateBugPageRequest.java @@ -0,0 +1,55 @@ +package io.metersphere.request; + +import com.google.common.base.CaseFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +import java.util.Map; + +/** + * @author wx + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class AssociateBugPageRequest extends BaseProviderCondition { + + @Schema(description = "用例id", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{functional_case.id.not_blank}") + private String caseId; + + + @Min(value = 1, message = "当前页码必须大于0") + @Schema(description = "当前页码") + private int current; + + @Min(value = 5, message = "每页显示条数必须不小于5") + @Max(value = 500, message = "每页显示条数不能大于500") + @Schema(description = "每页显示条数") + private int pageSize; + + @Schema(description = "排序字段(model中的字段 : asc/desc)") + private Map<@Valid @Pattern(regexp = "^[A-Za-z]+$") String, @Valid @NotBlank String> sort; + + + public String getSortString() { + if (sort == null || sort.isEmpty()) { + return null; + } + StringBuilder sb = new StringBuilder(); + for (Map.Entry entry : sort.entrySet()) { + String column = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entry.getKey()); + sb.append(column) + .append(StringUtils.SPACE) + .append(StringUtils.equalsIgnoreCase(entry.getValue(), "DESC") ? "DESC" : "ASC") + .append(","); + } + return sb.substring(0, sb.length() - 1); + } +} diff --git a/backend/services/bug-management/src/main/java/io/metersphere/bug/mapper/ExtBugMapper.xml b/backend/services/bug-management/src/main/java/io/metersphere/bug/mapper/ExtBugMapper.xml index 8d036af212..28f06428ff 100644 --- a/backend/services/bug-management/src/main/java/io/metersphere/bug/mapper/ExtBugMapper.xml +++ b/backend/services/bug-management/src/main/java/io/metersphere/bug/mapper/ExtBugMapper.xml @@ -193,7 +193,7 @@ SELECT b.id id, b.title title, - b.create_user createUser, + b.handle_user handleUser, u.`name` name, b.`status` status, b.tag tag, diff --git a/backend/services/bug-management/src/main/java/io/metersphere/bug/mapper/ExtBugRelateCaseMapper.java b/backend/services/bug-management/src/main/java/io/metersphere/bug/mapper/ExtBugRelateCaseMapper.java index b98d3e9c08..2eb769641c 100644 --- a/backend/services/bug-management/src/main/java/io/metersphere/bug/mapper/ExtBugRelateCaseMapper.java +++ b/backend/services/bug-management/src/main/java/io/metersphere/bug/mapper/ExtBugRelateCaseMapper.java @@ -3,6 +3,8 @@ package io.metersphere.bug.mapper; import io.metersphere.bug.dto.request.BugRelatedCasePageRequest; import io.metersphere.bug.dto.response.BugRelateCaseCountDTO; import io.metersphere.bug.dto.response.BugRelateCaseDTO; +import io.metersphere.dto.BugProviderDTO; +import io.metersphere.request.AssociateBugPageRequest; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -25,4 +27,6 @@ public interface ExtBugRelateCaseMapper { * @return 缺陷关联用例列表 */ List list(@Param("request") BugRelatedCasePageRequest request); + + List getAssociateBugs(@Param("request") AssociateBugPageRequest request); } diff --git a/backend/services/bug-management/src/main/java/io/metersphere/bug/mapper/ExtBugRelateCaseMapper.xml b/backend/services/bug-management/src/main/java/io/metersphere/bug/mapper/ExtBugRelateCaseMapper.xml index 85524a645d..6d8a2bc63d 100644 --- a/backend/services/bug-management/src/main/java/io/metersphere/bug/mapper/ExtBugRelateCaseMapper.xml +++ b/backend/services/bug-management/src/main/java/io/metersphere/bug/mapper/ExtBugRelateCaseMapper.xml @@ -19,4 +19,27 @@ and fc.name like concat('%', #{request.keyword}, '%') + + + + + + and brc.case_id = #{request.caseId} + + + and b.title like concat('%', #{request.keyword},'%') + + \ No newline at end of file diff --git a/backend/services/bug-management/src/main/java/io/metersphere/bug/provider/AssociateBugProvider.java b/backend/services/bug-management/src/main/java/io/metersphere/bug/provider/AssociateBugProvider.java index b348f36dee..272dce40a5 100644 --- a/backend/services/bug-management/src/main/java/io/metersphere/bug/provider/AssociateBugProvider.java +++ b/backend/services/bug-management/src/main/java/io/metersphere/bug/provider/AssociateBugProvider.java @@ -4,9 +4,11 @@ package io.metersphere.bug.provider; import io.metersphere.bug.domain.BugRelationCase; import io.metersphere.bug.mapper.BugRelationCaseMapper; import io.metersphere.bug.mapper.ExtBugMapper; +import io.metersphere.bug.mapper.ExtBugRelateCaseMapper; import io.metersphere.bug.service.BugRelateCaseService; import io.metersphere.dto.BugProviderDTO; import io.metersphere.provider.BaseAssociateBugProvider; +import io.metersphere.request.AssociateBugPageRequest; import io.metersphere.request.AssociateBugRequest; import io.metersphere.request.BugPageProviderRequest; import io.metersphere.system.uid.IDGenerator; @@ -26,11 +28,14 @@ public class AssociateBugProvider implements BaseAssociateBugProvider { private BugRelationCaseMapper bugRelationCaseMapper; @Resource private BugRelateCaseService bugRelateCaseService; + @Resource + private ExtBugRelateCaseMapper extBugRelateCaseMapper; @Override public List getBugList(String sourceType, String sourceName, String bugColumnName, BugPageProviderRequest bugPageProviderRequest) { return extBugMapper.listByProviderRequest(sourceType, sourceName, bugColumnName, bugPageProviderRequest, false); + //TODO 需要转义状态和处理人属性 } @Override @@ -67,4 +72,10 @@ public class AssociateBugProvider implements BaseAssociateBugProvider { public void disassociateBug(String id) { bugRelateCaseService.unRelate(id); } + + @Override + public List hasAssociateBugPage(AssociateBugPageRequest request) { + return extBugRelateCaseMapper.getAssociateBugs(request); + //TODO 需要转义状态和处理人属性 + } } diff --git a/backend/services/bug-management/src/test/java/io/metersphere/bug/controller/AssociateBugProviderTests.java b/backend/services/bug-management/src/test/java/io/metersphere/bug/controller/AssociateBugProviderTests.java index 6e8bd8c80a..6becb8d9c2 100644 --- a/backend/services/bug-management/src/test/java/io/metersphere/bug/controller/AssociateBugProviderTests.java +++ b/backend/services/bug-management/src/test/java/io/metersphere/bug/controller/AssociateBugProviderTests.java @@ -2,6 +2,7 @@ package io.metersphere.bug.controller; import io.metersphere.bug.provider.AssociateBugProvider; import io.metersphere.dto.BugProviderDTO; +import io.metersphere.request.AssociateBugPageRequest; import io.metersphere.request.AssociateBugRequest; import io.metersphere.request.BugPageProviderRequest; import io.metersphere.sdk.util.JSON; @@ -76,4 +77,14 @@ public class AssociateBugProviderTests extends BaseTest { public void testDisassociateBug() throws Exception { associateBugProvider.disassociateBug("wx_test_id_1"); } + + @Test + @Order(5) + public void testAssociateBugPage() throws Exception { + AssociateBugPageRequest request = new AssociateBugPageRequest(); + request.setCurrent(1); + request.setPageSize(10); + request.setCaseId("123"); + associateBugProvider.hasAssociateBugPage(request); + } } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseRelationshipController.java b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseRelationshipController.java index a98b97279b..b2e528324d 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseRelationshipController.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseRelationshipController.java @@ -38,14 +38,19 @@ public class FunctionalCaseRelationshipController { @Resource private FunctionalCaseRelationshipEdgeService functionalCaseRelationshipEdgeService; + @GetMapping("/get-ids/{caseId}") + @Operation(summary = "用例管理-功能用例-评审列表-评审详情-获取已关联用例id集合(关联用例弹窗前调用)") + @CheckOwner(resourceId = "#reviewId", resourceType = "case_review") + public List getCaseIds(@PathVariable String caseId) { + return functionalCaseRelationshipEdgeService.getExcludeIds(caseId); + } + @PostMapping("/relate/page") @Operation(summary = "用例管理-功能用例-用例详情-前后置关系-弹窗获取用例列表") @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ) @CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project") public Pager> getFunctionalCasePage(@Validated @RequestBody RelationshipPageRequest request) { - List excludeIds = functionalCaseRelationshipEdgeService.getExcludeIds(request.getId()); - request.setExcludeIds(excludeIds); Page page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "pos desc"); return PageUtils.setPageInfo(page, functionalCaseService.getFunctionalCasePage(request, false)); diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalTestCaseController.java b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalTestCaseController.java index 602a8cb1f1..13a941b9c6 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalTestCaseController.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalTestCaseController.java @@ -120,4 +120,14 @@ public class FunctionalTestCaseController { functionalTestCaseService.disassociateBug(id); } + + @PostMapping("/has/associate/bug/page") + @Operation(summary = "用例管理-功能用例-关联其他用例-获取已关联的缺陷列表") + @RequiresPermissions(value = {PermissionConstants.FUNCTIONAL_CASE_READ_ADD, PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, PermissionConstants.FUNCTIONAL_CASE_READ_DELETE}, logical = Logical.OR) + @CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project") + public Pager> getAssociateBugList(@Validated @RequestBody AssociateBugPageRequest request) { + Page page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), + StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "create_time desc"); + return PageUtils.setPageInfo(page, functionalTestCaseService.hasAssociateBugPage(request)); + } } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseMapper.xml b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseMapper.xml index 77eda27cf5..e7ea766fcc 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseMapper.xml +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseMapper.xml @@ -585,6 +585,12 @@ ) + + AND id not in + + #{excludeId} + + GROUP BY module_id diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseRelationshipEdgeService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseRelationshipEdgeService.java index d5a755f802..94b5c9405c 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseRelationshipEdgeService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseRelationshipEdgeService.java @@ -47,6 +47,7 @@ public class FunctionalCaseRelationshipEdgeService { List relationshipEdges = getRelationshipEdges(id); List ids = relationshipEdges.stream().map(FunctionalCaseRelationshipEdge::getTargetId).collect(Collectors.toList()); ids.addAll(relationshipEdges.stream().map(FunctionalCaseRelationshipEdge::getSourceId).collect(Collectors.toList())); + ids.add(id); List list = ids.stream().distinct().toList(); return list; } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalTestCaseService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalTestCaseService.java index 17f9c22549..e105c6eb42 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalTestCaseService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalTestCaseService.java @@ -199,4 +199,8 @@ public class FunctionalTestCaseService { public void disassociateBug(String id) { baseAssociateBugProvider.disassociateBug(id); } + + public List hasAssociateBugPage(AssociateBugPageRequest request) { + return baseAssociateBugProvider.hasAssociateBugPage(request); + } } diff --git a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseRelationshipControllerTests.java b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseRelationshipControllerTests.java index f830f9d108..bce49ca207 100644 --- a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseRelationshipControllerTests.java +++ b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseRelationshipControllerTests.java @@ -27,6 +27,7 @@ public class FunctionalCaseRelationshipControllerTests extends BaseTest { public static final String ADD = "/functional/case/relationship/add"; public static final String PAGE = "/functional/case/relationship/page"; public static final String DELETE = "/functional/case/relationship/delete/"; + public static final String IDS = "/functional/case/relationship/get-ids/"; @Test @@ -93,6 +94,9 @@ public class FunctionalCaseRelationshipControllerTests extends BaseTest { request.setType("POST"); request.setSelectIds(List.of("wx_relationship_6")); this.requestPostWithOkAndReturn(ADD, request); + + request.setSelectIds(null); + this.requestPostWithOkAndReturn(ADD, request); } @@ -148,4 +152,17 @@ public class FunctionalCaseRelationshipControllerTests extends BaseTest { assertErrorCode(this.requestGet(DELETE + "test"), MsHttpResultCode.FAILED); } + @Test + @Order(5) + public void testIds() throws Exception { + MvcResult postResult = this.requestGetWithOkAndReturn(IDS + "123"); + // 获取返回值 + String postReturnData = postResult.getResponse().getContentAsString(StandardCharsets.UTF_8); + ResultHolder postResultHolder = JSON.parseObject(postReturnData, ResultHolder.class); + // 返回请求正常 + Assertions.assertNotNull(postResultHolder); + + //异常覆盖 + assertErrorCode(this.requestGet(DELETE + "test"), MsHttpResultCode.FAILED); + } } diff --git a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalTestCaseControllerTests.java b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalTestCaseControllerTests.java index 8115cdf4e7..d92bd616cc 100644 --- a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalTestCaseControllerTests.java +++ b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalTestCaseControllerTests.java @@ -60,6 +60,7 @@ public class FunctionalTestCaseControllerTests extends BaseTest { private static final String URL_BUG_PAGE = "/functional/case/test/associate/bug/page"; private static final String URL_ASSOCIATE_BUG = "/functional/case/test/associate/bug"; private static final String URL_DISASSOCIATE_BUG = "/functional/case/test/disassociate/bug/"; + private static final String URL_ASSOCIATE_BUG_PAGE = "/functional/case/test/has/associate/bug/page"; @Resource @@ -300,7 +301,7 @@ public class FunctionalTestCaseControllerTests extends BaseTest { functionalCase.setCreateTime(System.currentTimeMillis()); functionalCase.setUpdateUser("gyq"); functionalCase.setUpdateTime(System.currentTimeMillis()); - Listtags = new ArrayList<>(); + List tags = new ArrayList<>(); tags.add("111"); tags.add("222"); functionalCase.setTags(tags); @@ -358,4 +359,32 @@ public class FunctionalTestCaseControllerTests extends BaseTest { this.requestGetWithOkAndReturn(URL_DISASSOCIATE_BUG + "TEST"); this.requestGetWithOkAndReturn(URL_DISASSOCIATE_BUG + "1234"); } + + @Test + @Order(11) + public void testAssociateBugPage() throws Exception { + AssociateBugPageRequest request = new AssociateBugPageRequest(); + request.setCurrent(1); + request.setPageSize(10); + request.setCaseId("wx_2"); + List list = new ArrayList<>(); + BugProviderDTO bugProviderDTO = new BugProviderDTO(); + bugProviderDTO.setId("123"); + bugProviderDTO.setName("测试返回数据"); + bugProviderDTO.setHandleUser("wx"); + bugProviderDTO.setStatus("进行中"); + bugProviderDTO.setHandleUserName("wx"); + list.add(bugProviderDTO); + Mockito.when(baseAssociateBugProvider.hasAssociateBugPage(request)).thenReturn(list); + MvcResult mvcResult = this.requestPostWithOkAndReturn(URL_ASSOCIATE_BUG_PAGE, request); + String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8); + ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class); + List bugProviderDTOS = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), BugProviderDTO.class); + Assertions.assertNotNull(bugProviderDTOS); + + request.setSort(new HashMap<>() {{ + put("createTime", "desc"); + }}); + this.requestPostWithOkAndReturn(URL_ASSOCIATE_BUG_PAGE, request); + } }