feat(用例管理): 增加脑图点击模块获取用例接口
This commit is contained in:
parent
4a7cef668a
commit
46afc6c124
|
@ -5,6 +5,9 @@ ALTER TABLE user_key MODIFY COLUMN description VARCHAR(1000);
|
|||
|
||||
ALTER TABLE api_definition_mock ADD COLUMN status_code INT(50) ;
|
||||
|
||||
CREATE INDEX idx_scene ON custom_field (scene);
|
||||
CREATE INDEX idx_internal ON custom_field (internal);
|
||||
|
||||
-- set innodb lock wait timeout to default
|
||||
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
||||
|
|
@ -1,13 +1,10 @@
|
|||
package io.metersphere.functional.controller;
|
||||
|
||||
import com.alibaba.excel.util.StringUtils;
|
||||
import io.metersphere.functional.dto.FunctionalMinderTreeDTO;
|
||||
import io.metersphere.functional.request.FunctionalCasePageRequest;
|
||||
import io.metersphere.functional.request.MinderReviewFunctionalCasePageRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseMindRequest;
|
||||
import io.metersphere.functional.service.FunctionalCaseMinderService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.system.security.CheckOwner;
|
||||
import io.metersphere.system.utils.SessionUtils;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
|
@ -18,6 +15,8 @@ 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 guoyuqi
|
||||
*/
|
||||
|
@ -30,23 +29,11 @@ public class FunctionalCaseMinderController {
|
|||
private FunctionalCaseMinderService functionalCaseMinderService;
|
||||
|
||||
@PostMapping("/list")
|
||||
@Operation(summary = "用例管理-功能用例-脑图用例列表查询")
|
||||
@Operation(summary = "用例管理-功能用例-脑图用例跟根据模块ID查询列表")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_MINDER)
|
||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||
public FunctionalMinderTreeDTO getFunctionalCaseMinderTree(@Validated @RequestBody FunctionalCasePageRequest request) {
|
||||
return functionalCaseMinderService.getFunctionalCasePage(request, false);
|
||||
}
|
||||
|
||||
@PostMapping("/review/list")
|
||||
@Operation(summary = "用例管理-用例评审-脑图用例列表查询")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_MINDER)
|
||||
@CheckOwner(resourceId = "#request.getReviewId()", resourceType = "case_review")
|
||||
public FunctionalMinderTreeDTO getFunctionalReviewCaseMinderTree(@Validated @RequestBody MinderReviewFunctionalCasePageRequest request) {
|
||||
String userId = StringUtils.EMPTY;
|
||||
if (request.isViewFlag()) {
|
||||
userId = SessionUtils.getUserId();
|
||||
}
|
||||
return functionalCaseMinderService.getReviewFunctionalCasePage(request, false, userId);
|
||||
@CheckOwner(resourceId = "#projectId()", resourceType = "project")
|
||||
public List<FunctionalMinderTreeDTO> getFunctionalCaseMinderTree(@Validated @RequestBody FunctionalCaseMindRequest request) {
|
||||
return functionalCaseMinderService.getMindFunctionalCase(request, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package io.metersphere.functional.dto;
|
||||
|
||||
import io.metersphere.validation.groups.Created;
|
||||
import io.metersphere.validation.groups.Updated;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class FunctionalCaseMindDTO {
|
||||
|
||||
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{functional_case.id.not_blank}", groups = {Updated.class})
|
||||
@Size(min = 1, max = 50, message = "{functional_case.id.length_range}", groups = {Created.class, Updated.class})
|
||||
private String id;
|
||||
|
||||
@Schema(description = "模块ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{functional_case.module_id.not_blank}", groups = {Created.class})
|
||||
@Size(min = 1, max = 50, message = "{functional_case.module_id.length_range}", groups = {Created.class, Updated.class})
|
||||
private String moduleId;
|
||||
|
||||
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{functional_case.project_id.not_blank}", groups = {Created.class})
|
||||
@Size(min = 1, max = 50, message = "{functional_case.project_id.length_range}", groups = {Created.class, Updated.class})
|
||||
private String projectId;
|
||||
|
||||
@Schema(description = "模板ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{functional_case.template_id.not_blank}", groups = {Created.class})
|
||||
@Size(min = 1, max = 50, message = "{functional_case.template_id.length_range}", groups = {Created.class, Updated.class})
|
||||
private String templateId;
|
||||
|
||||
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{functional_case.name.not_blank}", groups = {Created.class})
|
||||
@Size(min = 1, max = 255, message = "{functional_case.name.length_range}", groups = {Created.class, Updated.class})
|
||||
private String name;
|
||||
|
||||
@Schema(description = "评审状态:未评审/评审中/通过/不通过/重新提审", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{functional_case.review_status.not_blank}", groups = {Created.class})
|
||||
@Size(min = 1, max = 64, message = "{functional_case.review_status.length_range}", groups = {Created.class, Updated.class})
|
||||
private String reviewStatus;
|
||||
|
||||
@Schema(description = "用例等级")
|
||||
private String priority;
|
||||
|
||||
@Schema(description = "用例步骤(JSON),step_model 为 Step 时启用")
|
||||
private byte[] steps;
|
||||
|
||||
@Schema(description = "预期结果,step_model 为 Text 时启用")
|
||||
private byte[] expectedResult;
|
||||
|
||||
@Schema(description = "前置条件")
|
||||
private byte[] prerequisite;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private byte[] description;
|
||||
|
||||
|
||||
}
|
|
@ -3,9 +3,11 @@ package io.metersphere.functional.mapper;
|
|||
import io.metersphere.dto.TestCaseProviderDTO;
|
||||
import io.metersphere.functional.domain.FunctionalCase;
|
||||
import io.metersphere.functional.dto.BaseFunctionalCaseBatchDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseMindDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCasePageDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseVersionDTO;
|
||||
import io.metersphere.functional.request.FunctionalCaseBatchMoveRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseMindRequest;
|
||||
import io.metersphere.functional.request.FunctionalCasePageRequest;
|
||||
import io.metersphere.project.dto.ModuleCountDTO;
|
||||
import io.metersphere.request.AssociateOtherCaseRequest;
|
||||
|
@ -63,18 +65,25 @@ public interface ExtFunctionalCaseMapper {
|
|||
|
||||
/**
|
||||
* 获取缺陷未关联的功能用例列表
|
||||
*
|
||||
* @param request provider参数
|
||||
* @param deleted 是否删除状态
|
||||
* @param sort 排序
|
||||
* @param sort 排序
|
||||
* @return 通用的列表Case集合
|
||||
*/
|
||||
List<TestCaseProviderDTO> listUnRelatedCaseWithBug(@Param("request") TestCasePageProviderRequest request, @Param("deleted") boolean deleted, @Param("sort") String sort);
|
||||
|
||||
/**
|
||||
* 根据关联条件获取关联的用例ID
|
||||
*
|
||||
* @param request 关联参数
|
||||
* @param deleted 是否删除状态
|
||||
* @return 关联的用例ID集合
|
||||
*/
|
||||
List<String> getSelectIdsByAssociateParam(@Param("request")AssociateOtherCaseRequest request, @Param("deleted") boolean deleted);
|
||||
List<String> getSelectIdsByAssociateParam(@Param("request") AssociateOtherCaseRequest request, @Param("deleted") boolean deleted);
|
||||
|
||||
/**
|
||||
* 根据模块ID获取脑图展示数据
|
||||
*/
|
||||
List<FunctionalCaseMindDTO> getMinderCaseList(@Param("request") FunctionalCaseMindRequest request, @Param("deleted") boolean deleted);
|
||||
}
|
||||
|
|
|
@ -779,4 +779,26 @@
|
|||
</foreach>
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
<select id="getMinderCaseList" resultType="io.metersphere.functional.dto.FunctionalCaseMindDTO">
|
||||
SELECT
|
||||
fc.id, fc.name, fc.project_id, fc.module_id, fc.template_id, fc.review_status,
|
||||
fcb.steps, fcb.expected_result, fcb.prerequisite, fcb.description, fccf.value as priority
|
||||
FROM
|
||||
functional_case fc
|
||||
LEFT JOIN functional_case_blob fcb ON fcb.id = fc.id
|
||||
LEFT JOIN functional_case_custom_field fccf ON fccf.case_id = fc.id
|
||||
LEFT JOIN custom_field cf ON cf.id = fccf.field_id
|
||||
WHERE
|
||||
fc.deleted = false
|
||||
AND
|
||||
fc.project_Id = #{request.projectId}
|
||||
AND
|
||||
fc.module_id = #{request.moduleId}
|
||||
AND
|
||||
cf.name = 'functional_priority'
|
||||
AND cf.scene = 'FUNCTIONAL'
|
||||
AND cf.internal= true
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.functional.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FunctionalCaseMindRequest {
|
||||
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{functional_case.project_id.not_blank}")
|
||||
private String projectId;
|
||||
|
||||
@Schema(description = "模块ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{file_module.id.not_blank}")
|
||||
private String moduleId;
|
||||
}
|
|
@ -1,26 +1,19 @@
|
|||
package io.metersphere.functional.service;
|
||||
|
||||
import io.metersphere.functional.constants.CaseReviewPassRule;
|
||||
import io.metersphere.functional.constants.MinderLabel;
|
||||
import io.metersphere.functional.domain.CaseReview;
|
||||
import io.metersphere.functional.domain.FunctionalCase;
|
||||
import io.metersphere.functional.dto.*;
|
||||
import io.metersphere.functional.mapper.CaseReviewMapper;
|
||||
import io.metersphere.functional.request.FunctionalCasePageRequest;
|
||||
import io.metersphere.functional.request.MinderReviewFunctionalCasePageRequest;
|
||||
import io.metersphere.sdk.constants.ModuleConstants;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
import io.metersphere.functional.dto.FunctionalCaseMindDTO;
|
||||
import io.metersphere.functional.dto.FunctionalMinderTreeDTO;
|
||||
import io.metersphere.functional.dto.FunctionalMinderTreeNodeDTO;
|
||||
import io.metersphere.functional.mapper.ExtFunctionalCaseMapper;
|
||||
import io.metersphere.functional.request.FunctionalCaseMindRequest;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 功能用例脑图
|
||||
|
@ -32,217 +25,70 @@ import java.util.stream.Collectors;
|
|||
public class FunctionalCaseMinderService {
|
||||
|
||||
@Resource
|
||||
private FunctionalCaseService functionalCaseService;
|
||||
@Resource
|
||||
private FunctionalCaseModuleService functionalCaseModuleService;
|
||||
@Resource
|
||||
private CaseReviewFunctionalCaseService caseReviewFunctionalCaseService;
|
||||
@Resource
|
||||
private CaseReviewMapper caseReviewMapper;
|
||||
private ExtFunctionalCaseMapper extFunctionalCaseMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 功能用例-脑图用例列表查询
|
||||
*
|
||||
* @param request FunctionalCasePageRequest
|
||||
* @param deleted 用例是否删除
|
||||
* @return FunctionalMinderTreeDTO
|
||||
*/
|
||||
public FunctionalMinderTreeDTO getFunctionalCasePage(FunctionalCasePageRequest request, boolean deleted) {
|
||||
//根据查询条件查询出所有符合的功能用例
|
||||
List<FunctionalCasePageDTO> functionalCasePage = functionalCaseService.getFunctionalCasePage(request, deleted);
|
||||
//根据功能用例的模块ID,查出每个模块id父级直到根节点
|
||||
List<String> moduleIds = functionalCasePage.stream().map(FunctionalCase::getModuleId).distinct().toList();
|
||||
Map<String, List<FunctionalCasePageDTO>> moduleCaseMap = functionalCasePage.stream().collect(Collectors.groupingBy(FunctionalCasePageDTO::getModuleId));
|
||||
List<BaseTreeNode> baseTreeNodes = getBaseTreeNodes(moduleIds);
|
||||
//判断虚拟节点有无数据
|
||||
if (moduleCaseMap.get(ModuleConstants.DEFAULT_NODE_ID) == null && CollectionUtils.isEmpty(baseTreeNodes.get(0).getChildren())) {
|
||||
baseTreeNodes.remove(0);
|
||||
public List<FunctionalMinderTreeDTO> getMindFunctionalCase(FunctionalCaseMindRequest request, boolean deleted) {
|
||||
List<FunctionalMinderTreeDTO> list = new ArrayList<>();
|
||||
//查出当前模块下的所有用例
|
||||
List<FunctionalCaseMindDTO> functionalCaseMindDTOList = extFunctionalCaseMapper.getMinderCaseList(request, deleted);
|
||||
//构造父子级数据
|
||||
for (FunctionalCaseMindDTO functionalCaseMindDTO : functionalCaseMindDTOList) {
|
||||
FunctionalMinderTreeDTO root = new FunctionalMinderTreeDTO();
|
||||
FunctionalMinderTreeNodeDTO rootData = new FunctionalMinderTreeNodeDTO();
|
||||
rootData.setId(functionalCaseMindDTO.getId());
|
||||
rootData.setText(functionalCaseMindDTO.getName());
|
||||
rootData.setPriority(functionalCaseMindDTO.getPriority());
|
||||
rootData.setStatus(functionalCaseMindDTO.getReviewStatus());
|
||||
rootData.setResource(List.of(MinderLabel.CASE.toString(), functionalCaseMindDTO.getPriority()));
|
||||
List<FunctionalMinderTreeDTO> children = buildChildren(functionalCaseMindDTO);
|
||||
root.setChildren(children);
|
||||
root.setData(rootData);
|
||||
list.add(root);
|
||||
}
|
||||
//构建返回数据,主层级应与模块树层级相同
|
||||
List<FunctionalMinderTreeDTO> functionalMinderTreeNodeDTOs = new ArrayList<>();
|
||||
buildCaseTree(baseTreeNodes, moduleCaseMap, functionalMinderTreeNodeDTOs);
|
||||
return getRoot(functionalMinderTreeNodeDTOs);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static FunctionalMinderTreeDTO getRoot(List<FunctionalMinderTreeDTO> functionalMinderTreeDTOs) {
|
||||
FunctionalMinderTreeDTO root = new FunctionalMinderTreeDTO();
|
||||
private List<FunctionalMinderTreeDTO> buildChildren(FunctionalCaseMindDTO functionalCaseMindDTO) {
|
||||
List<FunctionalMinderTreeDTO> children = new ArrayList<>();
|
||||
if (functionalCaseMindDTO.getSteps() != null) {
|
||||
String stepText = new String(functionalCaseMindDTO.getSteps(), StandardCharsets.UTF_8);
|
||||
FunctionalMinderTreeDTO stepFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(stepText, MinderLabel.TEXT_DESCRIPTION.toString());
|
||||
children.add(stepFunctionalMinderTreeDTO);
|
||||
}
|
||||
if (functionalCaseMindDTO.getExpectedResult() != null) {
|
||||
String expectedResultText = new String(functionalCaseMindDTO.getExpectedResult(), StandardCharsets.UTF_8);
|
||||
FunctionalMinderTreeDTO expectedResultFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(expectedResultText, MinderLabel.EXPECTED_RESULT.toString());
|
||||
children.add(expectedResultFunctionalMinderTreeDTO);
|
||||
}
|
||||
if (functionalCaseMindDTO.getPrerequisite() != null) {
|
||||
String prerequisiteText = new String(functionalCaseMindDTO.getPrerequisite(), StandardCharsets.UTF_8);
|
||||
FunctionalMinderTreeDTO prerequisiteFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(prerequisiteText, MinderLabel.PREREQUISITE.toString());
|
||||
children.add(prerequisiteFunctionalMinderTreeDTO);
|
||||
}
|
||||
if (functionalCaseMindDTO.getDescription() != null) {
|
||||
String descriptionText = new String(functionalCaseMindDTO.getDescription(), StandardCharsets.UTF_8);
|
||||
FunctionalMinderTreeDTO descriptionFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(descriptionText, MinderLabel.DESCRIPTION.toString());
|
||||
children.add(descriptionFunctionalMinderTreeDTO);
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static FunctionalMinderTreeDTO getFunctionalMinderTreeDTO(String text, String resource) {
|
||||
FunctionalMinderTreeDTO functionalMinderTreeDTO = new FunctionalMinderTreeDTO();
|
||||
FunctionalMinderTreeNodeDTO rootData = new FunctionalMinderTreeNodeDTO();
|
||||
rootData.setResource(List.of(MinderLabel.MODULE.toString()));
|
||||
rootData.setText(Translator.get("case.minder.all.case"));
|
||||
root.setChildren(functionalMinderTreeDTOs);
|
||||
root.setData(rootData);
|
||||
return root;
|
||||
rootData.setText(text);
|
||||
rootData.setResource(List.of(resource));
|
||||
functionalMinderTreeDTO.setChildren(new ArrayList<>());
|
||||
functionalMinderTreeDTO.setData(rootData);
|
||||
return functionalMinderTreeDTO;
|
||||
}
|
||||
|
||||
private List<BaseTreeNode> getBaseTreeNodes(List<String> moduleIds) {
|
||||
List<BaseTreeNode> nodeByNodeIds = functionalCaseModuleService.getNodeByNodeIds(moduleIds);
|
||||
//根据模块节点构造模块树
|
||||
return functionalCaseModuleService.buildTreeAndCountResource(nodeByNodeIds, true, Translator.get("functional_case.module.default.name"));
|
||||
}
|
||||
|
||||
private static void buildCaseTree(List<BaseTreeNode> baseTreeNodes, Map<String, List<FunctionalCasePageDTO>> moduleCaseMap, List<FunctionalMinderTreeDTO> functionalMinderTreeNodeDTOs) {
|
||||
baseTreeNodes.forEach(t -> {
|
||||
//构建根节点
|
||||
FunctionalMinderTreeDTO functionalMinderTreeDTO = new FunctionalMinderTreeDTO();
|
||||
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeDTO = getFunctionalMinderTreeNodeDTO(t);
|
||||
functionalMinderTreeDTO.setData(functionalMinderTreeNodeDTO);
|
||||
|
||||
List<FunctionalMinderTreeDTO> children = new ArrayList<>();
|
||||
//如果当前节点有用例,则用例是他的子节点
|
||||
buildCaseChild(moduleCaseMap, t, children);
|
||||
//查询当前节点下的子模块节点
|
||||
buildModuleChild(moduleCaseMap, t, children);
|
||||
functionalMinderTreeDTO.setChildren(children);
|
||||
functionalMinderTreeNodeDTOs.add(functionalMinderTreeDTO);
|
||||
});
|
||||
}
|
||||
|
||||
private static FunctionalMinderTreeNodeDTO getFunctionalMinderTreeNodeDTO(BaseTreeNode t) {
|
||||
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeDTO = new FunctionalMinderTreeNodeDTO();
|
||||
functionalMinderTreeNodeDTO.setId(t.getId());
|
||||
functionalMinderTreeNodeDTO.setText(t.getName());
|
||||
functionalMinderTreeNodeDTO.setResource(List.of(MinderLabel.MODULE.toString()));
|
||||
return functionalMinderTreeNodeDTO;
|
||||
}
|
||||
|
||||
private static void buildCaseChild(Map<String, List<FunctionalCasePageDTO>> moduleCaseMap, BaseTreeNode t, List<FunctionalMinderTreeDTO> children) {
|
||||
if (moduleCaseMap.get(t.getId()) != null && CollectionUtils.isNotEmpty(moduleCaseMap.get(t.getId()))) {
|
||||
List<FunctionalCasePageDTO> functionalCasePageDTOS = moduleCaseMap.get(t.getId());
|
||||
functionalCasePageDTOS.forEach(functionalCasePageDTO -> {
|
||||
FunctionalMinderTreeDTO functionalMinderTreeChild = new FunctionalMinderTreeDTO();
|
||||
//加载用例为children
|
||||
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeChild = new FunctionalMinderTreeNodeDTO();
|
||||
functionalMinderTreeNodeChild.setId(functionalCasePageDTO.getId());
|
||||
functionalMinderTreeNodeChild.setText(functionalCasePageDTO.getName());
|
||||
if (CollectionUtils.isNotEmpty(functionalCasePageDTO.getCustomFields())) {
|
||||
List<FunctionalCaseCustomFieldDTO> list = functionalCasePageDTO.getCustomFields().stream().filter(customField -> customField.getFieldName().equals(Translator.get("custom_field.functional_priority"))).toList();
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
functionalMinderTreeNodeChild.setPriority(list.get(0).getDefaultValue());
|
||||
}
|
||||
}
|
||||
functionalMinderTreeNodeChild.setResource(List.of(MinderLabel.CASE.toString()));
|
||||
functionalMinderTreeChild.setData(functionalMinderTreeNodeChild);
|
||||
//将用例的blob记为Case的children
|
||||
children.add(functionalMinderTreeChild);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildModuleChild(Map<String, List<FunctionalCasePageDTO>> moduleCaseMap, BaseTreeNode t, List<FunctionalMinderTreeDTO> children) {
|
||||
if (CollectionUtils.isNotEmpty(t.getChildren())) {
|
||||
t.getChildren().forEach(child -> {
|
||||
FunctionalMinderTreeDTO functionalMinderTreeDTOChild = new FunctionalMinderTreeDTO();
|
||||
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeDTOChild = getFunctionalMinderTreeNodeDTO(child);
|
||||
functionalMinderTreeDTOChild.setData(functionalMinderTreeNodeDTOChild);
|
||||
|
||||
List<FunctionalMinderTreeDTO> childChildren = new ArrayList<>();
|
||||
buildCaseChild(moduleCaseMap, child, childChildren);
|
||||
functionalMinderTreeDTOChild.setChildren(childChildren);
|
||||
children.add(functionalMinderTreeDTOChild);
|
||||
buildModuleChild(moduleCaseMap, child, childChildren);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 用例评审-脑图用例列表查询
|
||||
*
|
||||
* @param request MinderReviewFunctionalCasePageRequest
|
||||
* @param deleted 用例是否删除
|
||||
* @param userId userId 只看我的
|
||||
* @return FunctionalMinderTreeDTO
|
||||
*/
|
||||
public FunctionalMinderTreeDTO getReviewFunctionalCasePage(MinderReviewFunctionalCasePageRequest request, boolean deleted, String userId) {
|
||||
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(request.getReviewId());
|
||||
List<ReviewFunctionalCaseDTO> page = caseReviewFunctionalCaseService.page(request, deleted, userId, null);
|
||||
List<String> caseIds = page.stream().map(ReviewFunctionalCaseDTO::getCaseId).toList();
|
||||
List<String> moduleIds = page.stream().map(ReviewFunctionalCaseDTO::getModuleId).toList();
|
||||
List<BaseTreeNode> baseTreeNodes = getBaseTreeNodes(moduleIds);
|
||||
//判断虚拟节点有无数据
|
||||
Map<String, List<ReviewFunctionalCaseDTO>> moduleCaseMap = page.stream().collect(Collectors.groupingBy(ReviewFunctionalCaseDTO::getModuleId));
|
||||
if (moduleCaseMap.get(ModuleConstants.DEFAULT_NODE_ID) == null && CollectionUtils.isEmpty(baseTreeNodes.get(0).getChildren())) {
|
||||
baseTreeNodes.remove(0);
|
||||
}
|
||||
//自定义字段
|
||||
Map<String, List<FunctionalCaseCustomFieldDTO>> caseCustomFiledMap = functionalCaseService.getCaseCustomFiledMap(caseIds,request.getProjectId());
|
||||
//构建返回数据,主层级应与模块树层级相同
|
||||
MinderSearchDTO minderSearchDTO = new MinderSearchDTO();
|
||||
minderSearchDTO.setBaseTreeNodes(baseTreeNodes);
|
||||
minderSearchDTO.setModuleCaseMap(moduleCaseMap);
|
||||
minderSearchDTO.setCustomFieldMap(caseCustomFiledMap);
|
||||
minderSearchDTO.setReviewPassRule(caseReview.getReviewPassRule());
|
||||
minderSearchDTO.setViewFlag(request.isViewFlag());
|
||||
minderSearchDTO.setViewResult(request.isViewResult());
|
||||
List<FunctionalMinderTreeDTO> functionalMinderTreeDTOs = buildReviewCaseTree(minderSearchDTO);
|
||||
return getRoot(functionalMinderTreeDTOs);
|
||||
|
||||
}
|
||||
|
||||
private List<FunctionalMinderTreeDTO> buildReviewCaseTree(MinderSearchDTO minderSearchDTO) {
|
||||
List<FunctionalMinderTreeDTO> functionalMinderTreeNodeDTOs = new ArrayList<>();
|
||||
minderSearchDTO.getBaseTreeNodes().forEach(t -> {
|
||||
//构建根节点
|
||||
FunctionalMinderTreeDTO functionalMinderTreeDTO = new FunctionalMinderTreeDTO();
|
||||
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeDTO = getFunctionalMinderTreeNodeDTO(t);
|
||||
functionalMinderTreeDTO.setData(functionalMinderTreeNodeDTO);
|
||||
|
||||
List<FunctionalMinderTreeDTO> children = new ArrayList<>();
|
||||
//如果当前节点有用例,则用例是他的子节点
|
||||
minderSearchDTO.setBaseTreeNode(t);
|
||||
buildReviewCaseChild(minderSearchDTO, children);
|
||||
//查询当前节点下的子模块节点
|
||||
buildReviewModuleChild(minderSearchDTO, children);
|
||||
functionalMinderTreeDTO.setChildren(children);
|
||||
functionalMinderTreeNodeDTOs.add(functionalMinderTreeDTO);
|
||||
});
|
||||
return functionalMinderTreeNodeDTOs;
|
||||
}
|
||||
|
||||
private void buildReviewModuleChild(MinderSearchDTO minderSearchDTO, List<FunctionalMinderTreeDTO> children) {
|
||||
List<BaseTreeNode> baseTreeNodes = minderSearchDTO.getBaseTreeNode().getChildren();
|
||||
if (CollectionUtils.isNotEmpty(baseTreeNodes)) {
|
||||
baseTreeNodes.forEach(child -> {
|
||||
FunctionalMinderTreeDTO functionalMinderTreeDTOChild = new FunctionalMinderTreeDTO();
|
||||
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeDTOChild = getFunctionalMinderTreeNodeDTO(child);
|
||||
functionalMinderTreeDTOChild.setData(functionalMinderTreeNodeDTOChild);
|
||||
minderSearchDTO.setBaseTreeNode(child);
|
||||
List<FunctionalMinderTreeDTO> childChildren = new ArrayList<>();
|
||||
buildReviewCaseChild(minderSearchDTO, childChildren);
|
||||
functionalMinderTreeDTOChild.setChildren(childChildren);
|
||||
children.add(functionalMinderTreeDTOChild);
|
||||
buildReviewModuleChild(minderSearchDTO, childChildren);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void buildReviewCaseChild(MinderSearchDTO minderSearchDTO, List<FunctionalMinderTreeDTO> children) {
|
||||
Map<String, List<ReviewFunctionalCaseDTO>> moduleCaseMap = minderSearchDTO.getModuleCaseMap();
|
||||
BaseTreeNode baseTreeNode = minderSearchDTO.getBaseTreeNode();
|
||||
String baseTreeNodeId = baseTreeNode.getId();
|
||||
if (moduleCaseMap.get(baseTreeNodeId) != null && CollectionUtils.isNotEmpty(moduleCaseMap.get(baseTreeNodeId))) {
|
||||
List<ReviewFunctionalCaseDTO> reviewFunctionalCaseDTOS = moduleCaseMap.get(baseTreeNodeId);
|
||||
reviewFunctionalCaseDTOS.forEach(reviewFunctionalCaseDTO -> {
|
||||
FunctionalMinderTreeDTO functionalMinderTreeChild = new FunctionalMinderTreeDTO();
|
||||
//加载用例为children
|
||||
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeChild = new FunctionalMinderTreeNodeDTO();
|
||||
functionalMinderTreeNodeChild.setId(reviewFunctionalCaseDTO.getCaseId());
|
||||
functionalMinderTreeNodeChild.setText(reviewFunctionalCaseDTO.getName());
|
||||
List<FunctionalCaseCustomFieldDTO> functionalCaseCustomFieldDTOS = minderSearchDTO.getCustomFieldMap().get(reviewFunctionalCaseDTO.getCaseId());
|
||||
if (CollectionUtils.isNotEmpty(functionalCaseCustomFieldDTOS)) {
|
||||
List<FunctionalCaseCustomFieldDTO> list = functionalCaseCustomFieldDTOS.stream().filter(customField -> customField.getFieldName().equals(Translator.get("custom_field.functional_priority"))).toList();
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
functionalMinderTreeNodeChild.setPriority(list.get(0).getDefaultValue());
|
||||
}
|
||||
}
|
||||
if (minderSearchDTO.isViewFlag() && minderSearchDTO.isViewResult() && StringUtils.equalsIgnoreCase(minderSearchDTO.getReviewPassRule(), CaseReviewPassRule.MULTIPLE.toString())) {
|
||||
functionalMinderTreeNodeChild.setStatus(reviewFunctionalCaseDTO.getStatus());
|
||||
}
|
||||
functionalMinderTreeNodeChild.setResource(List.of(MinderLabel.CASE.toString()));
|
||||
functionalMinderTreeChild.setData(functionalMinderTreeNodeChild);
|
||||
children.add(functionalMinderTreeChild);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package io.metersphere.functional.controller;
|
||||
|
||||
import io.metersphere.functional.dto.FunctionalMinderTreeDTO;
|
||||
import io.metersphere.functional.request.FunctionalCasePageRequest;
|
||||
import io.metersphere.functional.request.MinderReviewFunctionalCasePageRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseMindRequest;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.controller.handler.ResultHolder;
|
||||
|
@ -14,76 +13,30 @@ import org.springframework.test.context.jdbc.SqlConfig;
|
|||
import org.springframework.test.web.servlet.MvcResult;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
@AutoConfigureMockMvc
|
||||
public class FunctionalCaseMinderControllerTest extends BaseTest {
|
||||
|
||||
|
||||
public static final String FUNCTIONAL_CASE_LIST_URL = "/functional/mind/case/list";
|
||||
public static final String REViEW_FUNCTIONAL_CASE_LIST_URL = "/functional/mind/case/review/list";
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
@Sql(scripts = {"/dml/init_file_minder_test.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
|
||||
public void testGetPageList() throws Exception {
|
||||
FunctionalCasePageRequest request = new FunctionalCasePageRequest();
|
||||
FunctionalCaseMindRequest request = new FunctionalCaseMindRequest();
|
||||
request.setProjectId("project-case-minder-test");
|
||||
request.setCurrent(1);
|
||||
request.setPageSize(10);
|
||||
request.setSort(new HashMap<>() {{
|
||||
put("createTime", "desc");
|
||||
}});
|
||||
request.setModuleId("TEST_MINDER_MODULE_ID_GYQ");
|
||||
MvcResult mvcResultPage = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_LIST_URL, request);
|
||||
String contentAsString = mvcResultPage.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
|
||||
FunctionalMinderTreeDTO baseTreeNodes = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), FunctionalMinderTreeDTO.class);
|
||||
List<FunctionalMinderTreeDTO> baseTreeNodes = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), FunctionalMinderTreeDTO.class);
|
||||
Assertions.assertNotNull(baseTreeNodes);
|
||||
String jsonString = JSON.toJSONString(baseTreeNodes);
|
||||
System.out.println(jsonString);
|
||||
Assertions.assertEquals(2,baseTreeNodes.size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
public void testGetReviewPageList() throws Exception {
|
||||
/* Map<String, Object> map = new HashMap<>();
|
||||
map.put("customs", Arrays.asList(new LinkedHashMap() {{
|
||||
put("id", "TEST_FIELD_ID");
|
||||
put("operator", "in");
|
||||
put("value", "222");
|
||||
put("type", "List");
|
||||
}}));
|
||||
request.setCombine(map);*/
|
||||
MinderReviewFunctionalCasePageRequest request = new MinderReviewFunctionalCasePageRequest();
|
||||
request.setProjectId("project-case-minder-test");
|
||||
request.setCurrent(1);
|
||||
request.setPageSize(10);
|
||||
request.setSort(new HashMap<>() {{
|
||||
put("createTime", "desc");
|
||||
}});
|
||||
request.setReviewId("TEST_MINDER_REVIEW_ID_GYQ");
|
||||
request.setViewFlag(true);
|
||||
request.setViewResult(true);
|
||||
|
||||
MvcResult mvcResultPage = this.requestPostWithOkAndReturn(REViEW_FUNCTIONAL_CASE_LIST_URL, request);
|
||||
String contentAsString = mvcResultPage.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
|
||||
FunctionalMinderTreeDTO baseTreeNodes = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), FunctionalMinderTreeDTO.class);
|
||||
Assertions.assertNotNull(baseTreeNodes);
|
||||
//String jsonString = JSON.toJSONString(baseTreeNodes);
|
||||
//System.out.println(jsonString);
|
||||
request.setReviewId("TEST_MINDER_REVIEW_ID_GYQ2");
|
||||
mvcResultPage = this.requestPostWithOkAndReturn(REViEW_FUNCTIONAL_CASE_LIST_URL, request);
|
||||
contentAsString = mvcResultPage.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
|
||||
baseTreeNodes = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), FunctionalMinderTreeDTO.class);
|
||||
Assertions.assertNotNull(baseTreeNodes);
|
||||
//jsonString = JSON.toJSONString(baseTreeNodes);
|
||||
//System.out.println(jsonString);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@ VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_1', 1, 'TEST_MINDER_MODULE_ID_GYQ', 'pro
|
|||
|
||||
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_1', NULL, NULL, NULL, NULL, NULL);
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_2', NULL, NULL, NULL, NULL, NULL);
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_2', 0x504B03041400080808002B826D58000000000000000000000000030000007A69708BAE56CA2BCD55B232D0514A492D4E56B2527A366DC3D3DDBB9E4F59F1645FB7B1A1311AF7E9A495682826CF100A62F262F29E4DD909444A3A4A45A9C5A5392584CD5BDFF67C412384CCCD05998030CF10661CD4D05A1DA8630DE18E353236343246B60DC83532040A2AD5C60200504B0708159DEE336E000000DB000000504B010214001400080808002B826D58159DEE336E000000DB0000000300000000000000000000000000000000007A6970504B05060000000001000100310000009F0000000000, 0x504B03041400080808002B826D58000000000000000000000000030000007A69700300504B0708000000000200000000000000504B010214001400080808002B826D580000000002000000000000000300000000000000000000000000000000007A6970504B0506000000000100010031000000330000000000, 0x504B03041400080808002B826D58000000000000000000000000030000007A69700300504B0708000000000200000000000000504B010214001400080808002B826D580000000002000000000000000300000000000000000000000000000000007A6970504B0506000000000100010031000000330000000000, 0x504B03041400080808002B826D58000000000000000000000000030000007A69700300504B0708000000000200000000000000504B010214001400080808002B826D580000000002000000000000000300000000000000000000000000000000007A6970504B0506000000000100010031000000330000000000, 0x504B03041400080808002B826D58000000000000000000000000030000007A69700300504B0708000000000200000000000000504B010214001400080808002B826D580000000002000000000000000300000000000000000000000000000000007A6970504B0506000000000100010031000000330000000000);
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_3', NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
|
||||
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_1', 'custom_field_minder_gyq_id_3', 'P0');
|
||||
|
||||
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_2', 'custom_field_minder_gyq_id_3', 'P3');
|
||||
|
||||
|
||||
INSERT INTO functional_case_module(id, project_id, name, parent_id, pos, create_time, update_time, create_user, update_user)
|
||||
|
@ -29,7 +29,7 @@ VALUES
|
|||
|
||||
|
||||
INSERT INTO custom_field (id, name, scene, type, remark, internal, scope_type, create_time, update_time, create_user, scope_id) VALUE
|
||||
('custom_field_minder_gyq_id_3', '用例等级', 'FUNCTIONAL', 'SELECT', '', 0, 'ORGANIZATION', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', '100001');
|
||||
('custom_field_minder_gyq_id_3', 'functional_priority', 'FUNCTIONAL', 'SELECT', '', true, 'ORGANIZATION', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', '100001');
|
||||
|
||||
|
||||
INSERT INTO case_review(id, num, name, module_id, project_id, status, review_pass_rule, pos, start_time, end_time, case_count, pass_rate, tags, description, create_time, create_user, update_time, update_user)
|
||||
|
|
Loading…
Reference in New Issue