diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanFunctionalCaseController.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanFunctionalCaseController.java index 289310bbf9..c7bc4567d7 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanFunctionalCaseController.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanFunctionalCaseController.java @@ -6,6 +6,7 @@ import io.metersphere.dto.BugProviderDTO; import io.metersphere.plan.constants.TestPlanResourceConfig; import io.metersphere.plan.dto.request.*; import io.metersphere.plan.dto.response.TestPlanAssociationResponse; +import io.metersphere.plan.dto.response.TestPlanCaseExecHistoryResponse; import io.metersphere.plan.dto.response.TestPlanCasePageResponse; import io.metersphere.plan.dto.response.TestPlanResourceSortResponse; import io.metersphere.plan.service.TestPlanCaseLogService; @@ -161,4 +162,12 @@ public class TestPlanFunctionalCaseController { } + @PostMapping("/exec/history") + @Operation(summary = "测试计划-计划详情-功能用例-执行历史") + @RequiresPermissions(PermissionConstants.TEST_PLAN_READ) + @CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan") + public List executeHistory(@Validated @RequestBody TestPlanCaseExecHistoryRequest request) { + return testPlanFunctionalCaseService.getCaseExecHistory(request); + } + } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanCaseExecHistoryRequest.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanCaseExecHistoryRequest.java new file mode 100644 index 0000000000..06319933e0 --- /dev/null +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanCaseExecHistoryRequest.java @@ -0,0 +1,30 @@ +package io.metersphere.plan.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author wx + */ +@Data +public class TestPlanCaseExecHistoryRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "测试计划id",requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{test_plan.id.not_blank}") + private String testPlanId; + + @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{id.not_blank}") + private String id; + + @Schema(description = "用例id") + @NotBlank(message = "{case_id.not_blank}") + private String caseId; +} diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanCaseExecHistoryResponse.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanCaseExecHistoryResponse.java new file mode 100644 index 0000000000..8e01e540de --- /dev/null +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanCaseExecHistoryResponse.java @@ -0,0 +1,44 @@ +package io.metersphere.plan.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author wx + */ +@Data +public class TestPlanCaseExecHistoryResponse implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "id") + private String status; + + @Schema(description = "评论内容") + private byte[] content; + + @Schema(description = "评审解析内容") + private String contentText; + + @Schema(description = "步骤结果") + private String stepsExecResult; + + @Schema(description = "执行人") + private String createUser; + + @Schema(description = "执行人姓名") + private String userName; + + @Schema(description = "执行人头像") + private String userLogo; + + @Schema(description = "执行人邮箱") + private String email; + + @Schema(description = "执行时间") + private String steps; +} diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCaseExecuteHistoryMapper.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCaseExecuteHistoryMapper.java index cda9244009..fa07ff3e36 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCaseExecuteHistoryMapper.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCaseExecuteHistoryMapper.java @@ -1,5 +1,7 @@ package io.metersphere.plan.mapper; +import io.metersphere.plan.dto.request.TestPlanCaseExecHistoryRequest; +import io.metersphere.plan.dto.response.TestPlanCaseExecHistoryResponse; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -7,4 +9,6 @@ import java.util.List; public interface ExtTestPlanCaseExecuteHistoryMapper { void updateDeleted(@Param("testPlanCaseIds") List testPlanCaseIds, @Param("deleted") boolean deleted); + + List getCaseExecHistory(@Param("request") TestPlanCaseExecHistoryRequest request); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCaseExecuteHistoryMapper.xml b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCaseExecuteHistoryMapper.xml index 50b6b55c3c..0bef3aa093 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCaseExecuteHistoryMapper.xml +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCaseExecuteHistoryMapper.xml @@ -12,4 +12,25 @@ + + + \ No newline at end of file diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java index b28357ab03..6cbc4accd7 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java @@ -10,12 +10,14 @@ import io.metersphere.bug.mapper.ExtBugRelateCaseMapper; import io.metersphere.dto.BugProviderDTO; import io.metersphere.functional.constants.CaseFileSourceType; import io.metersphere.functional.domain.FunctionalCase; +import io.metersphere.functional.domain.FunctionalCaseBlob; import io.metersphere.functional.domain.FunctionalCaseExample; import io.metersphere.functional.domain.FunctionalCaseModule; import io.metersphere.functional.dto.FunctionalCaseCustomFieldDTO; import io.metersphere.functional.dto.FunctionalCaseModuleCountDTO; import io.metersphere.functional.dto.FunctionalCaseModuleDTO; import io.metersphere.functional.dto.ProjectOptionDTO; +import io.metersphere.functional.mapper.FunctionalCaseBlobMapper; import io.metersphere.functional.mapper.FunctionalCaseMapper; import io.metersphere.functional.service.FunctionalCaseAttachmentService; import io.metersphere.functional.service.FunctionalCaseModuleService; @@ -29,6 +31,7 @@ import io.metersphere.plan.dto.ResourceLogInsertModule; import io.metersphere.plan.dto.TestPlanResourceAssociationParam; import io.metersphere.plan.dto.request.*; import io.metersphere.plan.dto.response.TestPlanAssociationResponse; +import io.metersphere.plan.dto.response.TestPlanCaseExecHistoryResponse; import io.metersphere.plan.dto.response.TestPlanCasePageResponse; import io.metersphere.plan.dto.response.TestPlanResourceSortResponse; import io.metersphere.plan.mapper.*; @@ -69,6 +72,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -116,6 +120,8 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService { private FunctionalCaseMapper functionalCaseMapper; @Resource private OperationLogService operationLogService; + @Resource + private FunctionalCaseBlobMapper functionalCaseBlobMapper; private static final String CASE_MODULE_COUNT_ALL = "all"; @Override @@ -398,7 +404,7 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService { executeHistory.setCaseId(request.getCaseId()); executeHistory.setStatus(request.getLastExecResult()); executeHistory.setContent(request.getContent().getBytes()); - executeHistory.setSteps(request.getStepsExecResult().getBytes()); + executeHistory.setSteps(StringUtils.defaultIfBlank(request.getStepsExecResult(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); executeHistory.setDeleted(false); executeHistory.setNotifier(request.getNotifier()); executeHistory.setCreateUser(operator); @@ -522,4 +528,18 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService { extTestPlanFunctionalCaseMapper.batchUpdateExecutor(ids, request.getUserId()); } } + + public List getCaseExecHistory(TestPlanCaseExecHistoryRequest request) { + FunctionalCaseBlob caseBlob = functionalCaseBlobMapper.selectByPrimaryKey(request.getCaseId()); + List list = extTestPlanCaseExecuteHistoryMapper.getCaseExecHistory(request); + list.forEach(item -> { + if (item.getContent() != null) { + item.setContentText(new String(item.getContent(), StandardCharsets.UTF_8)); + } + if (caseBlob.getSteps() != null) { + item.setSteps(new String(caseBlob.getSteps(), StandardCharsets.UTF_8)); + } + }); + return list; + } } diff --git a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCaseControllerTests.java b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCaseControllerTests.java index fae33ee59f..ff1deb68cc 100644 --- a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCaseControllerTests.java +++ b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCaseControllerTests.java @@ -43,6 +43,7 @@ public class TestPlanCaseControllerTests extends BaseTest { public static final String FUNCTIONAL_CASE_RUN_URL = "/test-plan/functional/case/run"; public static final String FUNCTIONAL_CASE_BATCH_RUN_URL = "/test-plan/functional/case/batch/run"; public static final String FUNCTIONAL_CASE_BATCH_UPDATE_EXECUTOR_URL = "/test-plan/functional/case/batch/update/executor"; + public static final String FUNCTIONAL_CASE_EXEC_HISTORY_URL = "/test-plan/functional/case/exec/history"; @Resource private TestPlanFunctionalCaseMapper testPlanFunctionalCaseMapper; @Resource @@ -194,7 +195,6 @@ public class TestPlanCaseControllerTests extends BaseTest { } - @Test @Order(12) public void testFunctionalCaseBatchRun() throws Exception { @@ -228,4 +228,15 @@ public class TestPlanCaseControllerTests extends BaseTest { this.requestPostWithOk(FUNCTIONAL_CASE_BATCH_UPDATE_EXECUTOR_URL, request); } + + + @Test + @Order(14) + public void testExecHistory() throws Exception { + TestPlanCaseExecHistoryRequest request = new TestPlanCaseExecHistoryRequest(); + request.setId("relate_case_1"); + request.setTestPlanId("plan_1"); + request.setCaseId("fc_1"); + this.requestPostWithOk(FUNCTIONAL_CASE_EXEC_HISTORY_URL, request); + } } diff --git a/backend/services/test-plan/src/test/resources/dml/init_test_plan_case_relate_bug.sql b/backend/services/test-plan/src/test/resources/dml/init_test_plan_case_relate_bug.sql index ca6b3d1300..c067286ae2 100644 --- a/backend/services/test-plan/src/test/resources/dml/init_test_plan_case_relate_bug.sql +++ b/backend/services/test-plan/src/test/resources/dml/init_test_plan_case_relate_bug.sql @@ -43,3 +43,8 @@ VALUES ('t_1', '123', '计划模块', 'NONE', 256, 1714124231051, 1714124231051, '728495172886645', '728495172886645'); +INSERT INTO `test_plan_case_execute_history`(`id`, `test_plan_case_id`, `case_id`, `status`, `content`, `steps`, `deleted`, `notifier`, `create_user`, `create_time`) +VALUES + ('123445', 'relate_case_1', 'fc_1', 'PASSED', '1234', '2132134', b'0', '', 'admin', 1715828421525); +INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('fc_1', 'STEP', '1111', '', '', 'TEST'); +