From 8e0ff36aefd4cdfa47e79deee7ec17301723bfe4 Mon Sep 17 00:00:00 2001 From: guoyuqi Date: Thu, 25 Jan 2024 19:51:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=8A=9F=E8=83=BD=E7=94=A8=E4=BE=8B):=20?= =?UTF-8?q?=E5=8F=98=E6=9B=B4=E5=8E=86=E5=8F=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FunctionalCaseController.java | 12 ++++++ .../service/FunctionalCaseService.java | 13 ++++++ .../service/XpackFunctionalCaseService.java | 19 +++++++++ .../config/CaseTestConfiguration.java | 4 ++ .../FunctionalCaseControllerTests.java | 42 ++++++++++++++++++- .../mapper/BaseOperationHistoryMapper.java | 2 + .../mapper/BaseOperationHistoryMapper.xml | 24 +++++++++++ .../service/OperationHistoryService.java | 17 ++++++++ 8 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 backend/services/case-management/src/main/java/io/metersphere/functional/service/XpackFunctionalCaseService.java diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseController.java b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseController.java index 0c399970f1..b1f4c03348 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseController.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseController.java @@ -17,6 +17,8 @@ import io.metersphere.project.dto.CustomFieldOptions; import io.metersphere.project.service.ProjectTemplateService; import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.constants.TemplateScene; +import io.metersphere.system.dto.OperationHistoryDTO; +import io.metersphere.system.dto.request.OperationHistoryRequest; import io.metersphere.system.dto.sdk.TemplateDTO; import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.log.annotation.Log; @@ -236,4 +238,14 @@ public class FunctionalCaseController { String organizationId = SessionUtils.getCurrentOrganizationId(); return functionalCaseFileService.importExcel(request, userId, file, organizationId); } + + @PostMapping("/operation-history") + @Operation(summary = "用例管理-功能用例-变更历史") + @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ) + @CheckOwner(resourceId = "#request.getSourceId()", resourceType = "functional_case") + public Pager> operationHistoryList(@Validated @RequestBody OperationHistoryRequest request) { + Page page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), + org.apache.commons.lang3.StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "create_time desc"); + return PageUtils.setPageInfo(page, functionalCaseService.operationHistoryList(request)); + } } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java index cf4339a139..c6652a0bf9 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java @@ -28,9 +28,12 @@ import io.metersphere.sdk.constants.HttpMethodConstants; import io.metersphere.sdk.constants.TemplateScene; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.BeanUtils; +import io.metersphere.sdk.util.CommonBeanFactory; import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.Translator; import io.metersphere.system.domain.CustomFieldOption; +import io.metersphere.system.dto.OperationHistoryDTO; +import io.metersphere.system.dto.request.OperationHistoryRequest; import io.metersphere.system.dto.sdk.BaseTreeNode; import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO; import io.metersphere.system.dto.sdk.TemplateDTO; @@ -116,6 +119,8 @@ public class FunctionalCaseService { private static final String UPDATE_FUNCTIONAL_CASE_FILE_LOG_URL = "/functional/case/update"; private static final String FUNCTIONAL_CASE_BATCH_COPY_FILE_LOG_URL = "/functional/case/batch/copy"; + private static final String CASE_TABLE = "functional_case"; + @Resource private FunctionalCaseDemandMapper functionalCaseDemandMapper; @Resource @@ -1030,4 +1035,12 @@ public class FunctionalCaseService { FunctionalCaseHistoryLogDTO historyLogDTO = new FunctionalCaseHistoryLogDTO(functionalCase, functionalCaseBlob, customFields, caseAttachments, fileAssociationList); return historyLogDTO; } + + public List operationHistoryList(OperationHistoryRequest request) { + XpackFunctionalCaseService functionalCaseService = CommonBeanFactory.getBean(XpackFunctionalCaseService.class); + if (functionalCaseService != null) { + return functionalCaseService.listHis(request, CASE_TABLE); + } + return List.of(); + } } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/XpackFunctionalCaseService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/XpackFunctionalCaseService.java new file mode 100644 index 0000000000..47052da5d4 --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/XpackFunctionalCaseService.java @@ -0,0 +1,19 @@ +package io.metersphere.functional.service; + +import io.metersphere.system.dto.OperationHistoryDTO; +import io.metersphere.system.dto.request.OperationHistoryRequest; + +import java.util.List; + +/** + * 用例管理Xpack功能接口 + */ +public interface XpackFunctionalCaseService { + + /** + * 功能用例变更历史分页列表 + * @param request 请求参数 + * @return 变更历史集合 + */ + List listHis(OperationHistoryRequest request,String table); +} diff --git a/backend/services/case-management/src/test/java/io/metersphere/functional/config/CaseTestConfiguration.java b/backend/services/case-management/src/test/java/io/metersphere/functional/config/CaseTestConfiguration.java index 9763a92dd6..4b2b022bf3 100644 --- a/backend/services/case-management/src/test/java/io/metersphere/functional/config/CaseTestConfiguration.java +++ b/backend/services/case-management/src/test/java/io/metersphere/functional/config/CaseTestConfiguration.java @@ -1,5 +1,6 @@ package io.metersphere.functional.config; +import io.metersphere.functional.service.XpackFunctionalCaseService; import io.metersphere.provider.BaseAssociateApiProvider; import io.metersphere.provider.BaseAssociateBugProvider; import io.metersphere.provider.BaseAssociateScenarioProvider; @@ -18,4 +19,7 @@ public class CaseTestConfiguration { @MockBean BaseAssociateBugProvider baseAssociateBugProvider; + @MockBean + XpackFunctionalCaseService xpackFunctionalCaseService; + } diff --git a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseControllerTests.java b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseControllerTests.java index 5a8047146e..2c73f0cc87 100644 --- a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseControllerTests.java +++ b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseControllerTests.java @@ -24,14 +24,18 @@ import io.metersphere.sdk.util.Translator; import io.metersphere.system.base.BaseTest; import io.metersphere.system.controller.handler.ResultHolder; import io.metersphere.system.domain.CustomField; +import io.metersphere.system.dto.OperationHistoryDTO; +import io.metersphere.system.dto.request.OperationHistoryRequest; import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO; import io.metersphere.system.dto.sdk.TemplateDTO; import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.mapper.CustomFieldMapper; import io.metersphere.system.notice.constants.NoticeConstants; +import io.metersphere.system.service.OperationHistoryService; import io.metersphere.system.uid.IDGenerator; import io.metersphere.system.utils.Pager; import jakarta.annotation.Resource; +import org.apache.commons.collections4.CollectionUtils; import org.junit.jupiter.api.*; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; @@ -73,6 +77,7 @@ public class FunctionalCaseControllerTests extends BaseTest { public static final String DOWNLOAD_EXCEL_TEMPLATE_URL = "/functional/case/download/excel/template/"; public static final String CHECK_EXCEL_URL = "/functional/case/pre-check/excel"; public static final String IMPORT_EXCEL_URL = "/functional/case/import/excel"; + public static final String OPERATION_HISTORY_URL = "/functional/case/operation-history"; @Resource private NotificationMapper notificationMapper; @@ -83,6 +88,11 @@ public class FunctionalCaseControllerTests extends BaseTest { private ProjectTemplateService projectTemplateService; @Resource private FunctionalCaseCustomFieldMapper functionalCaseCustomFieldMapper; + @Resource + private OperationHistoryService operationHistoryService; + + protected static String functionalCaseId; + @Test @Order(1) @@ -121,7 +131,6 @@ public class FunctionalCaseControllerTests extends BaseTest { String functionalCaseData = functionalCaseMvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8); ResultHolder functionalCaseResultHolder = JSON.parseObject(functionalCaseData, ResultHolder.class); FunctionalCase functionalCase = JSON.parseObject(JSON.toJSONString(functionalCaseResultHolder.getData()), FunctionalCase.class); - NotificationExample notificationExample = new NotificationExample(); notificationExample.createCriteria().andResourceNameEqualTo(functionalCase.getName()).andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK); List notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample); @@ -134,6 +143,7 @@ public class FunctionalCaseControllerTests extends BaseTest { paramMap.add("request", JSON.toJSONString(request)); paramMap.add("files", new LinkedMultiValueMap<>()); functionalCaseMvcResult = this.requestMultipartWithOkAndReturn(FUNCTIONAL_CASE_ADD_URL, paramMap); + functionalCaseId = functionalCase.getId(); // 获取返回值 returnData = functionalCaseMvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8); resultHolder = JSON.parseObject(returnData, ResultHolder.class); @@ -631,4 +641,34 @@ public class FunctionalCaseControllerTests extends BaseTest { paramMap.add("file", file2); this.requestMultipart(IMPORT_EXCEL_URL, paramMap); } + + @Test + @Order(22) + public void operationHistoryList() throws Exception { + OperationHistoryRequest request = new OperationHistoryRequest(); + request.setSourceId(functionalCaseId); + request.setProjectId(DEFAULT_PROJECT_ID); + request.setCurrent(1); + request.setPageSize(10); + request.setSort(Map.of("createTime", "asc")); + + MvcResult mvcResult = this.requestPostWithOkAndReturn(OPERATION_HISTORY_URL, request); + // 获取返回值 + String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8); + ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class); + // 返回请求正常 + Assertions.assertNotNull(resultHolder); + Pager pageData = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), Pager.class); + // 返回值不为空 + Assertions.assertNotNull(pageData); + // 返回值的页码和当前页码相同 + Assertions.assertEquals(pageData.getCurrent(), request.getCurrent()); + // 返回的数据量不超过规定要返回的数据量相同 + Assertions.assertTrue(JSON.parseArray(JSON.toJSONString(pageData.getList())).size() <= request.getPageSize()); + request.setSort(Map.of()); + this.requestPost(OPERATION_HISTORY_URL, request); + List operationHistoryDTOS = operationHistoryService.listWidthLimit(request, "functional_case"); + Assertions.assertTrue(CollectionUtils.isNotEmpty(operationHistoryDTOS)); + + } } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/mapper/BaseOperationHistoryMapper.java b/backend/services/system-setting/src/main/java/io/metersphere/system/mapper/BaseOperationHistoryMapper.java index 3f3477314f..91f5259eb9 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/mapper/BaseOperationHistoryMapper.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/mapper/BaseOperationHistoryMapper.java @@ -16,4 +16,6 @@ public interface BaseOperationHistoryMapper { void deleteByIds(@Param("sourceId") String sourceId, @Param("ids") List ids); List list(@Param("request") OperationHistoryRequest request); + + List listWidthLimit(@Param("request") OperationHistoryRequest request, @Param("table") String table); } \ No newline at end of file diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/mapper/BaseOperationHistoryMapper.xml b/backend/services/system-setting/src/main/java/io/metersphere/system/mapper/BaseOperationHistoryMapper.xml index b968992091..7d30d5317e 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/mapper/BaseOperationHistoryMapper.xml +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/mapper/BaseOperationHistoryMapper.xml @@ -40,4 +40,28 @@ + + diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/OperationHistoryService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/OperationHistoryService.java index b3d53d3d35..c88f5a5eac 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/OperationHistoryService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/OperationHistoryService.java @@ -46,6 +46,23 @@ public class OperationHistoryService { return list; } + + public List listWidthLimit(OperationHistoryRequest request, String table) { + List list = baseOperationHistoryMapper.listWidthLimit(request, table); + if (CollectionUtils.isNotEmpty(list)) { + List userIds = list.stream().distinct() + .map(OperationHistoryDTO::getCreateUser).toList(); + + Map userMap = baseUserMapper.selectUserOptionByIds(userIds).stream() + .collect(Collectors.toMap(OptionDTO::getId, OptionDTO::getName)); + + list.forEach(item -> item.setCreateUserName(userMap.getOrDefault(item.getCreateUser(), StringUtils.EMPTY))); + + } + return list; + } + + public void associationRefId(Long refLogId, Long logId) { OperationHistory operationHistory = operationHistoryMapper.selectByPrimaryKey(logId); operationHistory.setRefId(refLogId);