refactor(用例管理): 脑图获取节点下用例数据

This commit is contained in:
guoyuqi 2024-04-30 11:53:12 +08:00 committed by 刘瑞斌
parent 2ff25735da
commit e55d654bb2
12 changed files with 186 additions and 13 deletions

View File

@ -0,0 +1,26 @@
package io.metersphere.functional.config;
import io.metersphere.functional.dto.FunctionalCaseMindDTO;
import io.metersphere.sdk.util.CompressUtils;
import io.metersphere.system.utils.MybatisInterceptorConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class FunctionalCaseManageInterceptor {
@Bean
public List<MybatisInterceptorConfig> functionalCaseManageCompressConfigs() {
List<MybatisInterceptorConfig> configList = new ArrayList<>();
configList.add(new MybatisInterceptorConfig(FunctionalCaseMindDTO.class, "steps", CompressUtils.class, "zip", "unzip"));
configList.add(new MybatisInterceptorConfig(FunctionalCaseMindDTO.class, "textDescription", CompressUtils.class, "zip", "unzip"));
configList.add(new MybatisInterceptorConfig(FunctionalCaseMindDTO.class, "expectedResult", CompressUtils.class, "zip", "unzip"));
configList.add(new MybatisInterceptorConfig(FunctionalCaseMindDTO.class, "prerequisite", CompressUtils.class, "zip", "unzip"));
configList.add(new MybatisInterceptorConfig(FunctionalCaseMindDTO.class, "description", CompressUtils.class, "zip", "unzip"));
return configList;
}
}

View File

@ -13,9 +13,15 @@ public enum MinderLabel {
* 前置条件标签
*/
PREREQUISITE,
/**
* 步骤描述标签
*/
STEPS,
/**
* 文本描述标签
*/
TEXT_DESCRIPTION,
/**
* 预期结果标签

View File

@ -4,6 +4,7 @@ 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.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -45,9 +46,16 @@ public class FunctionalCaseMindDTO {
@Schema(description = "用例等级")
private String priority;
@Schema(description = "自定义排序间隔5000", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{functional_case.pos.not_blank}", groups = {Created.class})
private Long pos;
@Schema(description = "用例步骤JSON)step_model 为 Step 时启用")
private byte[] steps;
@Schema(description = "步骤描述step_model 为 Text 时启用")
private byte[] textDescription;
@Schema(description = "预期结果step_model 为 Text 时启用")
private byte[] expectedResult;

View File

@ -0,0 +1,12 @@
package io.metersphere.functional.dto;
import io.swagger.v3.oas.annotations.media.Schema;
public class FunctionalCaseReviewMindDTO extends FunctionalCaseMindDTO{
@Schema(description = "用例评审ID--用例评审脑图")
private String reviewId;
@Schema(description = "功能用例ID--用例评审脑图")
private String caseId;
}

View File

@ -5,6 +5,8 @@ import lombok.Data;
@Data
public class FunctionalCaseStepDTO {
private String id;
private Integer num;
private String desc;

View File

@ -13,6 +13,9 @@ public class FunctionalMinderTreeNodeDTO {
@Schema(description = "节点ID")
private String id;
@Schema(description = "节点顺序")
private Long pos;
@Schema(description = "节点名称")
private String text;

View File

@ -9,6 +9,7 @@ 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.functional.request.FunctionalCaseReviewMindRequest;
import io.metersphere.project.dto.ModuleCountDTO;
import io.metersphere.request.AssociateOtherCaseRequest;
import io.metersphere.request.TestCasePageProviderRequest;
@ -86,4 +87,10 @@ public interface ExtFunctionalCaseMapper {
* 根据模块ID获取脑图展示数据
*/
List<FunctionalCaseMindDTO> getMinderCaseList(@Param("request") FunctionalCaseMindRequest request, @Param("deleted") boolean deleted);
/**
* 根据模块ID获取用例评审脑图展示数据
*/
List<FunctionalCaseMindDTO> getMinderCaseReviewList(@Param("request") FunctionalCaseReviewMindRequest request, @Param("deleted") boolean delete, @Param("userId") String userId, @Param("viewStatusUserId") boolean viewStatusUserId);
}

View File

@ -782,8 +782,8 @@
<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
fc.id, fc.name, fc.project_id, fc.module_id, fc.template_id, fc.review_status, fc.pos,
fcb.steps, fcb.text_description, 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
@ -801,4 +801,42 @@
AND cf.internal= true
</select>
<select id="getMinderCaseReviewList" resultType="io.metersphere.functional.dto.FunctionalCaseReviewMindDTO">
SELECT
crfc.id as id,
crfc.review_id as reviewId,
crfc.case_id as caseId,
history.`status` as status,
fc.module_id as moduleId,
fc.name as name,
fcb.steps, fcb.expected_result, fcb.prerequisite, fcb.description, fccf.value as priority
FROM
case_review_functional_case crfc
LEFT JOIN functional_case fc ON crfc.case_id = fc.id
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
LEFT JOIN ( SELECT crh.case_id, crh.`status`, crh.`create_user` from case_review_history crh where crh.review_id = #{request.reviewId}
<if test="viewStatusUserId != null and viewStatusUserId != ''">
AND crh.user_id = #{viewStatusUserId}
</if>
order by crh.create_time desc limit 1 ) as history ON history.case_id = crfc.case_id
WHERE
review_id = #{request.reviewId}
AND functional_case.deleted = #{deleted}
<if test="userId != null and userId != ''">
AND crfc.case_id in (select crfcu.case_id from case_review_functional_case_user crfcu where crfcu.review_id = #{request.reviewId} and crfcu.user_id = #{userId})
</if>
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>

View File

@ -0,0 +1,20 @@
package io.metersphere.functional.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class FunctionalCaseReviewMindRequest extends FunctionalCaseMindRequest {
@Schema(description = "评审id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{case_review.case_review_id.not_blank}")
private String reviewId;
@Schema(description = "是否只看我的", requiredMode = Schema.RequiredMode.REQUIRED)
private boolean viewFlag;
@Schema(description = "我的评审结果", requiredMode = Schema.RequiredMode.REQUIRED)
private boolean viewStatusFlag;
}

View File

@ -2,10 +2,12 @@ package io.metersphere.functional.service;
import io.metersphere.functional.constants.MinderLabel;
import io.metersphere.functional.dto.FunctionalCaseMindDTO;
import io.metersphere.functional.dto.FunctionalCaseStepDTO;
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 io.metersphere.sdk.util.JSON;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
@ -43,6 +45,7 @@ public class FunctionalCaseMinderService {
FunctionalMinderTreeDTO root = new FunctionalMinderTreeDTO();
FunctionalMinderTreeNodeDTO rootData = new FunctionalMinderTreeNodeDTO();
rootData.setId(functionalCaseMindDTO.getId());
rootData.setPos(functionalCaseMindDTO.getPos());
rootData.setText(functionalCaseMindDTO.getName());
rootData.setPriority(functionalCaseMindDTO.getPriority());
rootData.setStatus(functionalCaseMindDTO.getReviewStatus());
@ -57,34 +60,49 @@ public class FunctionalCaseMinderService {
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.getTextDescription() != null) {
String textDescription = new String(functionalCaseMindDTO.getTextDescription(), StandardCharsets.UTF_8);
FunctionalMinderTreeDTO stepFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(textDescription, MinderLabel.TEXT_DESCRIPTION.toString(), 0L);
if (functionalCaseMindDTO.getExpectedResult() != null) {
String expectedResultText = new String(functionalCaseMindDTO.getExpectedResult(), StandardCharsets.UTF_8);
FunctionalMinderTreeDTO expectedResultFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(expectedResultText, MinderLabel.EXPECTED_RESULT.toString());
children.add(expectedResultFunctionalMinderTreeDTO);
FunctionalMinderTreeDTO expectedResultFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(expectedResultText, MinderLabel.EXPECTED_RESULT.toString(), 0L);
stepFunctionalMinderTreeDTO.getChildren().add(expectedResultFunctionalMinderTreeDTO);
}
children.add(stepFunctionalMinderTreeDTO);
}
if (functionalCaseMindDTO.getSteps() != null) {
String stepText = new String(functionalCaseMindDTO.getSteps(), StandardCharsets.UTF_8);
List<FunctionalCaseStepDTO> functionalCaseStepDTOS = JSON.parseArray(stepText, FunctionalCaseStepDTO.class);
for (FunctionalCaseStepDTO functionalCaseStepDTO : functionalCaseStepDTOS) {
FunctionalMinderTreeDTO stepFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(functionalCaseStepDTO.getDesc(), MinderLabel.STEPS.toString(), Long.valueOf(functionalCaseStepDTO.getNum()));
if (functionalCaseMindDTO.getExpectedResult() != null) {
FunctionalMinderTreeDTO expectedResultFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(functionalCaseStepDTO.getResult(), MinderLabel.EXPECTED_RESULT.toString(), 0L);
stepFunctionalMinderTreeDTO.getChildren().add(expectedResultFunctionalMinderTreeDTO);
}
children.add(stepFunctionalMinderTreeDTO);
}
}
if (functionalCaseMindDTO.getPrerequisite() != null) {
String prerequisiteText = new String(functionalCaseMindDTO.getPrerequisite(), StandardCharsets.UTF_8);
FunctionalMinderTreeDTO prerequisiteFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(prerequisiteText, MinderLabel.PREREQUISITE.toString());
FunctionalMinderTreeDTO prerequisiteFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(prerequisiteText, MinderLabel.PREREQUISITE.toString(), 0L);
children.add(prerequisiteFunctionalMinderTreeDTO);
}
if (functionalCaseMindDTO.getDescription() != null) {
String descriptionText = new String(functionalCaseMindDTO.getDescription(), StandardCharsets.UTF_8);
FunctionalMinderTreeDTO descriptionFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(descriptionText, MinderLabel.DESCRIPTION.toString());
FunctionalMinderTreeDTO descriptionFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(descriptionText, MinderLabel.DESCRIPTION.toString(), 0L);
children.add(descriptionFunctionalMinderTreeDTO);
}
return children;
}
@NotNull
private static FunctionalMinderTreeDTO getFunctionalMinderTreeDTO(String text, String resource) {
private static FunctionalMinderTreeDTO getFunctionalMinderTreeDTO(String text, String resource, Long pos) {
FunctionalMinderTreeDTO functionalMinderTreeDTO = new FunctionalMinderTreeDTO();
FunctionalMinderTreeNodeDTO rootData = new FunctionalMinderTreeNodeDTO();
rootData.setText(text);
rootData.setPos(pos);
rootData.setResource(List.of(resource));
functionalMinderTreeDTO.setChildren(new ArrayList<>());
functionalMinderTreeDTO.setData(rootData);

View File

@ -1,10 +1,14 @@
package io.metersphere.functional.controller;
import io.metersphere.functional.domain.FunctionalCaseBlob;
import io.metersphere.functional.dto.FunctionalCaseStepDTO;
import io.metersphere.functional.dto.FunctionalMinderTreeDTO;
import io.metersphere.functional.mapper.FunctionalCaseBlobMapper;
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;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
@ -13,6 +17,7 @@ import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MvcResult;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
@ -21,11 +26,40 @@ import java.util.List;
public class FunctionalCaseMinderControllerTest extends BaseTest {
public static final String FUNCTIONAL_CASE_LIST_URL = "/functional/mind/case/list";
@Resource
private FunctionalCaseBlobMapper functionalCaseBlobMapper;
@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 {
List<FunctionalCaseStepDTO> list = new ArrayList<>();
FunctionalCaseStepDTO functionalCaseStepDTO = new FunctionalCaseStepDTO();
functionalCaseStepDTO.setId("12455");
functionalCaseStepDTO.setNum(0);
functionalCaseStepDTO.setDesc("步骤一");
functionalCaseStepDTO.setResult("步骤一结果");
list.add(functionalCaseStepDTO);
functionalCaseStepDTO = new FunctionalCaseStepDTO();
functionalCaseStepDTO.setId("12ddd455");
functionalCaseStepDTO.setNum(1);
functionalCaseStepDTO.setDesc("步骤二");
functionalCaseStepDTO.setResult("步骤二结果");
list.add(functionalCaseStepDTO);
String textDescription = "hahahahah这是文本描述";
String expectedResult = "文本描述的结果";
String prerequisite = "前置条件";
String description = "备注";
FunctionalCaseBlob functionalCaseBlob = new FunctionalCaseBlob();
functionalCaseBlob.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_2");
functionalCaseBlob.setSteps(JSON.toJSONString(list).getBytes(StandardCharsets.UTF_8));
functionalCaseBlob.setTextDescription(textDescription.getBytes(StandardCharsets.UTF_8));
functionalCaseBlob.setExpectedResult(expectedResult.getBytes(StandardCharsets.UTF_8));
functionalCaseBlob.setPrerequisite(prerequisite.getBytes(StandardCharsets.UTF_8));
functionalCaseBlob.setDescription(description.getBytes(StandardCharsets.UTF_8));
functionalCaseBlobMapper.insert(functionalCaseBlob);
FunctionalCaseMindRequest request = new FunctionalCaseMindRequest();
request.setProjectId("project-case-minder-test");
request.setModuleId("TEST_MINDER_MODULE_ID_GYQ");

View File

@ -11,7 +11,6 @@ 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', 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);