From 5784ac55a0a106cac9c9a991a13d2f2dbfa4cf69 Mon Sep 17 00:00:00 2001 From: guoyuqi Date: Thu, 16 May 2024 12:34:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E7=94=A8=E4=BE=8B=E7=AE=A1=E7=90=86):=20?= =?UTF-8?q?=E8=84=91=E5=9B=BE=E5=AD=97=E6=AE=B5=E7=BB=9F=E4=B8=80=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FunctionalCaseMinderController.java | 61 +- .../functional/dto/MinderOptionDTO.java | 5 +- .../request/FunctionalCaseChangeRequest.java | 71 ++ .../FunctionalCaseMinderEditRequest.java | 25 +- .../FunctionalCaseModuleEditRequest.java | 41 + .../service/FunctionalCaseLogService.java | 119 +-- .../service/FunctionalCaseMinderService.java | 878 ++++++++++++------ .../service/FunctionalCaseModuleService.java | 2 +- .../service/FunctionalCaseNoticeService.java | 41 - .../FunctionalCaseMinderControllerTest.java | 289 ++---- .../resources/dml/init_file_minder_test.sql | 7 +- 11 files changed, 808 insertions(+), 731 deletions(-) create mode 100644 backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseChangeRequest.java create mode 100644 backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseModuleEditRequest.java diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseMinderController.java b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseMinderController.java index 8b9f968a94..c1b7adceb4 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseMinderController.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseMinderController.java @@ -2,28 +2,23 @@ package io.metersphere.functional.controller; import com.alibaba.excel.util.StringUtils; import io.metersphere.functional.dto.FunctionalMinderTreeDTO; -import io.metersphere.functional.dto.MinderOptionDTO; import io.metersphere.functional.request.FunctionalCaseMindRequest; import io.metersphere.functional.request.FunctionalCaseMinderEditRequest; -import io.metersphere.functional.request.FunctionalCaseMinderRemoveRequest; import io.metersphere.functional.request.FunctionalCaseReviewMindRequest; -import io.metersphere.functional.service.FunctionalCaseLogService; import io.metersphere.functional.service.FunctionalCaseMinderService; -import io.metersphere.functional.service.FunctionalCaseNoticeService; import io.metersphere.sdk.constants.PermissionConstants; -import io.metersphere.system.log.annotation.Log; -import io.metersphere.system.log.constants.OperationLogType; -import io.metersphere.system.notice.annotation.SendNotice; -import io.metersphere.system.notice.constants.NoticeConstants; 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.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; +import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +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; @@ -46,46 +41,18 @@ public class FunctionalCaseMinderController { return functionalCaseMinderService.getMindFunctionalCase(request, false); } - @PostMapping("/update/source/name") - @Operation(summary = "脑图更新资源名称") - @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE) - @Log(type = OperationLogType.UPDATE, expression = "#msClass.updateMinderFunctionalCaseLog(#request)", msClass = FunctionalCaseLogService.class) - @SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.UPDATE, target = "#targetClass.getMainFunctionalCaseMinderDTO(#request)", targetClass = FunctionalCaseNoticeService.class) - @CheckOwner(resourceId = "#request.getId()", resourceType = "functional_case") - public void updateFunctionalCaseName(@Validated @RequestBody FunctionalCaseMinderEditRequest request) { + @PostMapping("/edit") + @Operation(summary = "脑图保存") + @RequiresPermissions(value = { + PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, + PermissionConstants.FUNCTIONAL_CASE_READ_DELETE, + PermissionConstants.FUNCTIONAL_CASE_READ_ADD, + }, logical = Logical.OR) + public void editFunctionalCaseBatch(@Validated @RequestBody FunctionalCaseMinderEditRequest request) { String userId = SessionUtils.getUserId(); - functionalCaseMinderService.updateFunctionalCase(request, userId); + functionalCaseMinderService.editFunctionalCaseBatch(request, userId); } - @PostMapping("/update/source/priority") - @Operation(summary = "脑图更新用例等级") - @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE) - @Log(type = OperationLogType.UPDATE, expression = "#msClass.updateMinderFunctionalCaseLog(#request)", msClass = FunctionalCaseLogService.class) - @SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.UPDATE, target = "#targetClass.getMainFunctionalCaseMinderDTO(#request)", targetClass = FunctionalCaseNoticeService.class) - @CheckOwner(resourceId = "#request.getId()", resourceType = "functional_case") - public void updateFunctionalCasePriority(@Validated @RequestBody FunctionalCaseMinderEditRequest request) { - String userId = SessionUtils.getUserId(); - functionalCaseMinderService.updateFunctionalCase(request, userId); - } - - @PostMapping("/batch/remove") - @Operation(summary = "脑图批量移动(移动到某个节点下或者移动排序)") - @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE) - public void removeFunctionalCaseBatch(@Validated @RequestBody FunctionalCaseMinderRemoveRequest request) { - String userId = SessionUtils.getUserId(); - functionalCaseMinderService.removeFunctionalCaseBatch(request, userId); - } - - @PostMapping("/batch/delete/{projectId}") - @Operation(summary = "脑图批量删除") - @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_DELETE) - @Log(type = OperationLogType.DELETE, expression = "#msClass.deleteBatchMinderFunctionalCaseLog(#resourceList)", msClass = FunctionalCaseLogService.class) - public void deleteFunctionalCaseBatch(@PathVariable String projectId, @Validated @RequestBody @Schema(description = "节点和节点类型的集合", requiredMode = Schema.RequiredMode.REQUIRED) List resourceList) { - String userId = SessionUtils.getUserId(); - functionalCaseMinderService.deleteFunctionalCaseBatch(projectId, resourceList, userId); - } - - @PostMapping("/review/list") @Operation(summary = "用例管理-功能用例-脑图用例跟根据模块ID查询列表") @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_MINDER) diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/dto/MinderOptionDTO.java b/backend/services/case-management/src/main/java/io/metersphere/functional/dto/MinderOptionDTO.java index 9d350b7686..a3e84e9125 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/dto/MinderOptionDTO.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/dto/MinderOptionDTO.java @@ -14,7 +14,7 @@ import lombok.NoArgsConstructor; @NoArgsConstructor public class MinderOptionDTO { - @Schema(description = "节点ID,如果是用例的子节点,比如 前置条件,步骤描述,等传其父节点ID") + @Schema(description = "节点ID(用例/模块的id)") @NotBlank(message = "{functional_case.id.not_blank}") private String id; @@ -22,7 +22,4 @@ public class MinderOptionDTO { @NotBlank(message = "{functional_case_test.test_type.not_blank}") private String type; - @Schema(description = "节点顺序") - @NotBlank(message = "{functional_case.pos.not_blank}") - private Long pos; } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseChangeRequest.java b/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseChangeRequest.java new file mode 100644 index 0000000000..2f39b1afe2 --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseChangeRequest.java @@ -0,0 +1,71 @@ +package io.metersphere.functional.request; + +import io.metersphere.functional.dto.CaseCustomFieldDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * @author wx + */ +@Data +public class FunctionalCaseChangeRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "用例id(新增的时候前端传UUid,更新的时候必填)", requiredMode = Schema.RequiredMode.REQUIRED) + private String id; + + @Schema(description = "模板id", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{functional_case.template_id.not_blank}") + private String templateId; + + @Schema(description = "操作类型(新增(ADD)/更新(UPDATE))", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{fake_error.relation.not_blank}") + private String type; + + @Schema(description = "用例名称", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{functional_case.name.not_blank}") + private String name; + + @Schema(description = "模块id", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{functional_case.module_id.not_blank}") + private String moduleId; + + @Schema(description = "移动方式(节点移动或新增时需要)", requiredMode = Schema.RequiredMode.REQUIRED) + private String moveMode; + + @Schema(description = "移动目标(节点移动或新增时需要)", requiredMode = Schema.RequiredMode.REQUIRED) + private String targetId; + + @Schema(description = "前置条件", defaultValue = "") + private String prerequisite; + + @Schema(description = "编辑模式", allowableValues = {"STEP", "TEXT"}, requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{functional_case.case_edit_type.not_blank}") + private String caseEditType; + + @Schema(description = "用例步骤", defaultValue = "") + private String steps; + + @Schema(description = "步骤描述", defaultValue = "") + private String textDescription; + + @Schema(description = "预期结果", defaultValue = "") + private String expectedResult; + + @Schema(description = "备注", defaultValue = "") + private String description; + + @Schema(description = "标签") + private List tags; + + @Schema(description = "自定义字段集合") + private List customFields; + +} diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseMinderEditRequest.java b/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseMinderEditRequest.java index 390d264dba..f4c5ae9149 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseMinderEditRequest.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseMinderEditRequest.java @@ -1,33 +1,32 @@ package io.metersphere.functional.request; +import io.metersphere.functional.dto.MinderOptionDTO; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Data; +import java.util.List; + /** - * @author wx + * @author guoyuqi */ @Data public class FunctionalCaseMinderEditRequest{ - @Schema(description = "用例id/模块ID(其他类型比如前置给用例ID)", requiredMode = Schema.RequiredMode.REQUIRED) - @NotBlank(message = "{functional_case.id.not_blank}") - private String id; - @Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED) @NotBlank(message = "{functional_case.project_id.not_blank}") private String projectId; - @Schema(description = "资源名称(更新节点的名称包括前置的编辑)") - private String name; + @Schema(description = "版本id") + private String versionId; - @Schema(description = "步骤描述及其预期结果的排序(更新步骤描述时必填)") - private Long pos; + @Schema(description = "新增/修改的用例对象集合", requiredMode = Schema.RequiredMode.REQUIRED) + private List updateCaseList; - @Schema(description = "资源类型") - private String type; + @Schema(description = "新增/修改的模块集合(只记录操作的节点,节点下的子节点不需要记录)", requiredMode = Schema.RequiredMode.REQUIRED) + private List updateModuleList; - @Schema(description = "用例等级(只更新用例的等级时传)") - private String priority; + @Schema(description = "删除的模块/用例的集合", requiredMode = Schema.RequiredMode.REQUIRED) + private List deleteResourceList; } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseModuleEditRequest.java b/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseModuleEditRequest.java new file mode 100644 index 0000000000..aed0f84d7b --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseModuleEditRequest.java @@ -0,0 +1,41 @@ +package io.metersphere.functional.request; + +import io.metersphere.sdk.constants.ModuleConstants; +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 guoyuqi + */ +@Data +public class FunctionalCaseModuleEditRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "模块id(新增的时候前端给一个uuid)", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{file_module.id.not_blank}") + private String id; + + @Schema(description = "模块名称", requiredMode = Schema.RequiredMode.REQUIRED) + private String name; + + @Schema(description = "父模块ID", requiredMode = Schema.RequiredMode.REQUIRED) + private String parentId = ModuleConstants.ROOT_NODE_PARENT_ID; + + @Schema(description = "操作类型(新增(ADD)/更新(UPDATE))", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{fake_error.relation.not_blank}") + private String type; + + @Schema(description = "移动方式(节点移动或新增时需要)", requiredMode = Schema.RequiredMode.REQUIRED) + private String moveMode; + + @Schema(description = "移动目标(节点移动或新增时需要)", requiredMode = Schema.RequiredMode.REQUIRED) + private String targetId; + +} + diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseLogService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseLogService.java index 83d755cc48..a39ecd984c 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseLogService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseLogService.java @@ -7,25 +7,19 @@ import io.metersphere.bug.mapper.BugRelationCaseMapper; import io.metersphere.functional.domain.*; import io.metersphere.functional.dto.BaseFunctionalCaseBatchDTO; import io.metersphere.functional.dto.FunctionalCaseHistoryLogDTO; -import io.metersphere.functional.dto.MinderOptionDTO; import io.metersphere.functional.mapper.*; import io.metersphere.functional.request.*; import io.metersphere.project.domain.FileAssociation; import io.metersphere.project.domain.FileAssociationExample; import io.metersphere.project.mapper.FileAssociationMapper; import io.metersphere.sdk.constants.HttpMethodConstants; -import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.JSON; -import io.metersphere.sdk.util.Translator; -import io.metersphere.system.domain.CustomField; -import io.metersphere.system.domain.CustomFieldExample; import io.metersphere.system.log.constants.OperationLogModule; import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.log.dto.LogDTO; import io.metersphere.system.mapper.CustomFieldMapper; 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; @@ -33,9 +27,6 @@ import org.springframework.web.multipart.MultipartFile; import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; /** * @author wx @@ -196,86 +187,7 @@ public class FunctionalCaseLogService { } return dtoList; } - - public List batchUpdateFunctionalCaseLogByIds(List ids, String path) { - List dtoList = new ArrayList<>(); - if (CollectionUtils.isNotEmpty(ids)) { - List functionalCases = extFunctionalCaseMapper.getLogInfo(ids, false); - functionalCases.forEach(functionalCase -> { - LogDTO dto = new LogDTO( - functionalCase.getProjectId(), - null, - functionalCase.getId(), - null, - OperationLogType.UPDATE.name(), - OperationLogModule.FUNCTIONAL_CASE, - functionalCase.getName()); - - dto.setPath(path); - dto.setMethod(HttpMethodConstants.POST.name()); - dto.setOriginalValue(JSON.toJSONBytes(functionalCase)); - dtoList.add(dto); - }); - } - return dtoList; - } - - public List deleteBatchMinderFunctionalCaseLog(List resourceList) { - if (CollectionUtils.isEmpty(resourceList)) { - return new ArrayList<>(); - } - String path = "/functional/mind/case/batch/delete/"; - List caseAllIds = new ArrayList<>(); - Map> resourceMap = resourceList.stream().collect(Collectors.groupingBy(MinderOptionDTO::getType)); - List caseOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.case")); - if (CollectionUtils.isNotEmpty(caseOptionDTOS)) { - List caseIds = caseOptionDTOS.stream().map(MinderOptionDTO::getId).toList(); - caseAllIds.addAll(caseIds); - } - List moduleOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.module")); - if (CollectionUtils.isNotEmpty(moduleOptionDTOS)) { - List moduleIds = moduleOptionDTOS.stream().map(MinderOptionDTO::getId).toList(); - List functionalCaseByModuleIds = getFunctionalCaseByModuleIds(moduleIds, new ArrayList<>()); - List list = functionalCaseByModuleIds.stream().map(FunctionalCase::getId).toList(); - caseAllIds.addAll(list); - } - - Set strings = resourceMap.keySet(); - ListlogDTOS = new ArrayList<>(); - Listids = new ArrayList<>(); - for (String key : strings) { - if (StringUtils.equalsIgnoreCase(key, Translator.get("minder_extra_node.case")) || StringUtils.equalsIgnoreCase(key, Translator.get("minder_extra_node.module"))) { - List logDTOS1 = batchDeleteFunctionalCaseLogByIds(caseAllIds, path); - logDTOS.addAll(logDTOS1); - } else { - //更新 - List keyOptionDTOS = resourceMap.get(key); - if (CollectionUtils.isNotEmpty(keyOptionDTOS)) { - List list = keyOptionDTOS.stream().map(MinderOptionDTO::getId).toList(); - ids.addAll(list); - } - } - } - List logDTOS1 = batchUpdateFunctionalCaseLogByIds(ids, path); - logDTOS.addAll(logDTOS1); - return logDTOS; - } - - public List getFunctionalCaseByModuleIds(List deleteIds, List functionalCases) { - if (CollectionUtils.isEmpty(deleteIds)) { - return functionalCases; - } - List functionalCaseList = extFunctionalCaseMapper.checkCaseByModuleIds(deleteIds); - if (CollectionUtils.isNotEmpty(functionalCaseList)) { - functionalCases.addAll(functionalCaseList); - } - List childrenIds = extFunctionalCaseModuleMapper.selectChildrenIdsByParentIds(deleteIds); - if (CollectionUtils.isNotEmpty(childrenIds)) { - getFunctionalCaseByModuleIds(childrenIds, functionalCases); - } - return functionalCases; - } - + /** * 恢复项目 * @@ -507,35 +419,6 @@ public class FunctionalCaseLogService { return null; } - public LogDTO updateMinderFunctionalCaseLog(FunctionalCaseMinderEditRequest request) { - if (StringUtils.equalsIgnoreCase(request.getType(), Translator.get("minder_extra_node.module"))) { - return null; - } - FunctionalCaseHistoryLogDTO historyLogDTO = getOriginalValue(request.getId()); - LogDTO dto = getUpdateLogDTO(request.getProjectId(), request.getId(), request.getName(), "/functional/case/update"); - dto.setOriginalValue(JSON.toJSONBytes(historyLogDTO)); - FunctionalCaseHistoryLogDTO newDto = new FunctionalCaseHistoryLogDTO(); - BeanUtils.copyBean(newDto, historyLogDTO); - if (StringUtils.isNotBlank(request.getName())) { - newDto.getFunctionalCase().setName(request.getName()); - } - if (StringUtils.isNotBlank(request.getPriority())) { - List functionalCaseCustomFields = newDto.getCustomFields(); - CustomFieldExample example = new CustomFieldExample(); - example.createCriteria().andNameEqualTo("functional_priority").andSceneEqualTo("FUNCTIONAL").andScopeIdEqualTo(request.getProjectId()); - List customFields = customFieldMapper.selectByExample(example); - String field = customFields.get(0).getId(); - for (FunctionalCaseCustomField customField : functionalCaseCustomFields) { - if (StringUtils.equalsIgnoreCase(customField.getFieldId(), field)) { - customField.setValue(request.getPriority()); - } - } - newDto.setCustomFields(functionalCaseCustomFields); - } - dto.setModifiedValue(JSON.toJSONBytes(newDto)); - return dto; - } - @NotNull private static LogDTO getUpdateLogDTO(String projectId, String sourceId, String content, String path) { LogDTO dto = new LogDTO( diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseMinderService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseMinderService.java index 190a639046..e1c2311fa0 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseMinderService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseMinderService.java @@ -1,21 +1,36 @@ package io.metersphere.functional.service; +import io.metersphere.functional.constants.FunctionalCaseReviewStatus; import io.metersphere.functional.constants.FunctionalCaseTypeConstants; import io.metersphere.functional.domain.*; import io.metersphere.functional.dto.*; import io.metersphere.functional.mapper.*; import io.metersphere.functional.request.*; +import io.metersphere.project.domain.Project; +import io.metersphere.project.mapper.ExtBaseProjectVersionMapper; +import io.metersphere.project.mapper.ProjectMapper; +import io.metersphere.project.utils.NodeSortUtils; +import io.metersphere.sdk.constants.FunctionalCaseExecuteResult; +import io.metersphere.sdk.constants.HttpMethodConstants; import io.metersphere.sdk.exception.MSException; +import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.Translator; import io.metersphere.system.domain.CustomField; import io.metersphere.system.domain.CustomFieldExample; import io.metersphere.system.domain.User; +import io.metersphere.system.dto.sdk.OptionDTO; import io.metersphere.system.dto.sdk.enums.MoveTypeEnum; +import io.metersphere.system.log.constants.OperationLogModule; +import io.metersphere.system.log.constants.OperationLogType; +import io.metersphere.system.log.dto.LogDTO; +import io.metersphere.system.log.service.OperationLogService; import io.metersphere.system.mapper.CustomFieldMapper; import io.metersphere.system.mapper.ExtCheckOwnerMapper; import io.metersphere.system.mapper.UserMapper; import io.metersphere.system.notice.constants.NoticeConstants; +import io.metersphere.system.service.CommonNoticeSendService; +import io.metersphere.system.uid.IDGenerator; import jakarta.annotation.Resource; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -28,9 +43,7 @@ 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.*; import java.util.stream.Collectors; /** @@ -42,6 +55,9 @@ import java.util.stream.Collectors; @Transactional(rollbackFor = Exception.class) public class FunctionalCaseMinderService { + protected static final long LIMIT_POS = NodeSortUtils.DEFAULT_NODE_INTERVAL_POS; + + @Resource private FunctionalCaseMapper functionalCaseMapper; @@ -52,15 +68,9 @@ public class FunctionalCaseMinderService { @Resource private FunctionalCaseBlobMapper functionalCaseBlobMapper; - @Resource - private ExtFunctionalCaseBlobMapper extFunctionalCaseBlobMapper; - @Resource private FunctionalCaseModuleMapper functionalCaseModuleMapper; - @Resource - private ExtFunctionalCaseModuleMapper extFunctionalCaseModuleMapper; - @Resource private CustomFieldMapper customFieldMapper; @@ -77,17 +87,36 @@ public class FunctionalCaseMinderService { private FunctionalCaseModuleService functionalCaseModuleService; @Resource - private FunctionalCaseNoticeService functionalCaseNoticeService; + private ExtBaseProjectVersionMapper extBaseProjectVersionMapper; + + @Resource + private CommonNoticeSendService commonNoticeSendService; + + @Resource + private OperationLogService operationLogService; @Resource private UserMapper userMapper; + @Resource + private ProjectMapper projectMapper; + @Resource SqlSessionFactory sqlSessionFactory; + @Resource + private ExtFunctionalCaseModuleMapper extFunctionalCaseModuleMapper; + + @Resource + private FunctionalCaseLogService functionalCaseLogService; + + @Resource + private FunctionalCaseNoticeService functionalCaseNoticeService; + private static final String FUNCTIONAL_CASE = "functional_case"; private static final String FUNCTIONAL_CASE_MODULE = "functional_case_module"; - private static final String CHECK_OWNER_CASE = "check_owner_case"; + private static final String CHECK_OWNER_CASE = "check_owner_case"; + /** * 功能用例-脑图用例列表查询 * @@ -103,6 +132,24 @@ public class FunctionalCaseMinderService { return list; } + private void buildList(List functionalCaseMindDTOList, List list) { + //构造父子级数据 + for (FunctionalCaseMindDTO functionalCaseMindDTO : functionalCaseMindDTOList) { + 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()); + rootData.setResource(List.of(Translator.get("minder_extra_node.case"))); + List children = buildChildren(functionalCaseMindDTO); + root.setChildren(children); + root.setData(rootData); + list.add(root); + } + } + private List buildChildren(FunctionalCaseMindDTO functionalCaseMindDTO) { List children = new ArrayList<>(); if (functionalCaseMindDTO.getPrerequisite() != null) { @@ -144,7 +191,6 @@ public class FunctionalCaseMinderService { } } - if (functionalCaseMindDTO.getDescription() != null) { String descriptionText = new String(functionalCaseMindDTO.getDescription(), StandardCharsets.UTF_8); FunctionalMinderTreeDTO descriptionFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(descriptionText, Translator.get("minder_extra_node.description"), (long) (i + 1)); @@ -165,301 +211,546 @@ public class FunctionalCaseMinderService { return functionalMinderTreeDTO; } - public void updateFunctionalCase(FunctionalCaseMinderEditRequest request, String userId) { - if (StringUtils.isNotBlank(request.getName())) { - if (StringUtils.equalsIgnoreCase(request.getType(), Translator.get("minder_extra_node.case"))) { - FunctionalCase functionalCase = new FunctionalCase(); - functionalCase.setName(request.getName()); - buildUpdateCaseParam(request.getId(), userId, functionalCase); - functionalCaseMapper.updateByPrimaryKeySelective(functionalCase); - } - if (StringUtils.equalsIgnoreCase(request.getType(), Translator.get("minder_extra_node.module"))) { - FunctionalCaseModule functionalCaseModule = new FunctionalCaseModule(); - functionalCaseModule.setName(request.getName()); - buildUpdateCaseModuleParam(request.getId(), userId, functionalCaseModule); - functionalCaseModuleMapper.updateByPrimaryKeySelective(functionalCaseModule); - } - if (StringUtils.equalsIgnoreCase(request.getType(), Translator.get("minder_extra_node.prerequisite"))) { - FunctionalCaseBlob functionalCaseBlob = new FunctionalCaseBlob(); - functionalCaseBlob.setId(request.getId()); - functionalCaseBlob.setPrerequisite(StringUtils.defaultIfBlank(request.getName(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); - functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob); - } - if (StringUtils.equalsIgnoreCase(request.getType(), Translator.get("minder_extra_node.steps"))) { - FunctionalCaseBlob functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey(request.getId()); - updateSteps(request, functionalCaseBlob); - } - if (StringUtils.equalsIgnoreCase(request.getType(), Translator.get("minder_extra_node.steps_expected_result"))) { - FunctionalCaseBlob functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey(request.getId()); - updateStepResult(request, functionalCaseBlob); - } - if (StringUtils.equalsIgnoreCase(request.getType(), Translator.get("minder_extra_node.text_description"))) { - FunctionalCaseBlob functionalCaseBlob = new FunctionalCaseBlob(); - functionalCaseBlob.setId(request.getId()); - functionalCaseBlob.setTextDescription(StringUtils.defaultIfBlank(request.getName(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); - functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob); - } - if (StringUtils.equalsIgnoreCase(request.getType(), Translator.get("minder_extra_node.text_expected_result"))) { - FunctionalCaseBlob functionalCaseBlob = new FunctionalCaseBlob(); - functionalCaseBlob.setId(request.getId()); - functionalCaseBlob.setExpectedResult(StringUtils.defaultIfBlank(request.getName(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); - functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob); - } - if (StringUtils.equalsIgnoreCase(request.getType(), Translator.get("minder_extra_node.steps_expected_result"))) { - FunctionalCaseBlob functionalCaseBlob = new FunctionalCaseBlob(); - functionalCaseBlob.setId(request.getId()); - functionalCaseBlob.setExpectedResult(StringUtils.defaultIfBlank(request.getName(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); - functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob); - } - if (StringUtils.equalsIgnoreCase(request.getType(), Translator.get("minder_extra_node.description"))) { - FunctionalCaseBlob functionalCaseBlob = new FunctionalCaseBlob(); - functionalCaseBlob.setId(request.getId()); - functionalCaseBlob.setDescription(StringUtils.defaultIfBlank(request.getName(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); - functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob); - } - } - if (StringUtils.isNotBlank(request.getPriority())) { - CustomFieldExample example = new CustomFieldExample(); - example.createCriteria().andNameEqualTo("functional_priority").andSceneEqualTo("FUNCTIONAL").andScopeIdEqualTo(request.getProjectId()); - List customFields = customFieldMapper.selectByExample(example); - String field = customFields.get(0).getId(); - FunctionalCaseCustomField customField = new FunctionalCaseCustomField(); - customField.setCaseId(request.getId()); - customField.setFieldId(field); - customField.setValue(request.getPriority()); - functionalCaseCustomFieldMapper.updateByPrimaryKeySelective(customField); - FunctionalCase functionalCase = new FunctionalCase(); - buildUpdateCaseParam(request.getId(), userId, functionalCase); - functionalCaseMapper.updateByPrimaryKeySelective(functionalCase); - } - } - - private void updateStepResult(FunctionalCaseMinderEditRequest request, FunctionalCaseBlob functionalCaseBlob) { - String stepText = new String(functionalCaseBlob.getSteps(), StandardCharsets.UTF_8); - List functionalCaseStepDTOS = JSON.parseArray(stepText, FunctionalCaseStepDTO.class); - for (FunctionalCaseStepDTO functionalCaseStepDTO : functionalCaseStepDTOS) { - if (functionalCaseStepDTO.getNum() == request.getPos().intValue()) { - functionalCaseStepDTO.setResult(request.getName()); - } - } - functionalCaseBlob.setSteps(StringUtils.defaultIfBlank(JSON.toJSONString(functionalCaseStepDTOS), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); - functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob); - } - - private void updateSteps(FunctionalCaseMinderEditRequest request, FunctionalCaseBlob functionalCaseBlob) { - if (functionalCaseBlob.getSteps() != null) { - String stepText = new String(functionalCaseBlob.getSteps(), StandardCharsets.UTF_8); - List functionalCaseStepDTOS = JSON.parseArray(stepText, FunctionalCaseStepDTO.class); - for (FunctionalCaseStepDTO functionalCaseStepDTO : functionalCaseStepDTOS) { - if (functionalCaseStepDTO.getNum() == request.getPos().intValue()) { - functionalCaseStepDTO.setDesc(request.getName()); - } - } - functionalCaseBlob.setSteps(StringUtils.defaultIfBlank(JSON.toJSONString(functionalCaseStepDTOS), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); - functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob); - } - } - - private void buildUpdateCaseModuleParam(String id, String userId, FunctionalCaseModule functionalCaseModule) { - functionalCaseModule.setId(id); - functionalCaseModule.setUpdateUser(userId); - functionalCaseModule.setUpdateTime(System.currentTimeMillis()); - } - - private void buildUpdateCaseParam(String id, String userId, FunctionalCase functionalCase) { - functionalCase.setId(id); - functionalCase.setUpdateUser(userId); - functionalCase.setUpdateTime(System.currentTimeMillis()); - } - - public void removeFunctionalCaseBatch(FunctionalCaseMinderRemoveRequest request, String userId) { - List resourceList = request.getResourceList(); - if (CollectionUtils.isEmpty(resourceList)) { - throw new MSException(Translator.get("node.not_blank")); - } - Map> resourceMap = resourceList.stream().collect(Collectors.groupingBy(MinderOptionDTO::getType)); - MinderTargetDTO caseMinderTargetDTO = request.getCaseMinderTargetDTO(); - MinderTargetDTO moduleMinderTargetDTO = request.getModuleMinderTargetDTO(); - List caseOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.case")); - List caseIds = new ArrayList<>(); - caseIds = checkPermission(caseOptionDTOS, caseIds, FUNCTIONAL_CASE, userId); - List moduleIds = new ArrayList<>(); - List moduleOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.module")); - moduleIds = checkPermission(moduleOptionDTOS, moduleIds, FUNCTIONAL_CASE_MODULE, userId); - if (StringUtils.isNotBlank(request.getParentTargetId()) ) { - //移动到某节点下 - if (!extCheckOwnerMapper.checkoutOwner(FUNCTIONAL_CASE_MODULE, userId, List.of(request.getParentTargetId()))) { - throw new MSException(Translator.get(CHECK_OWNER_CASE)); - } - if (CollectionUtils.isNotEmpty(caseIds)) { - //拖拽到别的节点 - FunctionalCaseBatchMoveRequest functionalCaseBatchMoveRequest = new FunctionalCaseBatchMoveRequest(); - functionalCaseBatchMoveRequest.setModuleId(request.getParentTargetId()); - functionalCaseBatchMoveRequest.setProjectId(request.getProjectId()); - functionalCaseService.batchMoveFunctionalCaseByIds(functionalCaseBatchMoveRequest, userId, caseIds); - moveSortCase(userId, caseMinderTargetDTO, caseIds); - } - if (CollectionUtils.isNotEmpty(moduleIds)) { - //处理模块拖拽以及移动 - //拖拽到别的节点 - extFunctionalCaseModuleMapper.batchUpdateStringColumn("parent_id", moduleIds, request.getParentTargetId()); - moveSortModule(request.getProjectId(), userId, moduleMinderTargetDTO, moduleIds); - } - } else if ( CollectionUtils.isNotEmpty(caseIds)) { - //直接给用例排序 - moveSortCase(userId, caseMinderTargetDTO, caseIds); - - } else if (CollectionUtils.isNotEmpty(moduleIds)) { - //直接给模块排序 - moveSortModule(request.getProjectId(), userId, moduleMinderTargetDTO, moduleIds); - } - updateSteps(request, resourceList); - - } - - private List checkPermission(List caseOptionDTOS, List caseIds, String functionalCase, String userId) { - if (CollectionUtils.isNotEmpty(caseOptionDTOS)) { - caseIds = caseOptionDTOS.stream().map(MinderOptionDTO::getId).toList(); - if (!extCheckOwnerMapper.checkoutOwner(functionalCase, userId, caseIds)) { + private void checkPermission(List sourceIds, String tableName, String userId) { + if (CollectionUtils.isNotEmpty(sourceIds)) { + if (!extCheckOwnerMapper.checkoutOwner(tableName, userId, sourceIds)) { throw new MSException(Translator.get(CHECK_OWNER_CASE)); } } - return caseIds; } - private void moveSortModule(String projectId, String userId, MinderTargetDTO moduleMinderTargetDTO, List moduleIds) { - if (moduleMinderTargetDTO != null && StringUtils.isNotBlank(moduleMinderTargetDTO.getTargetId())) { - //排序 - String targetId = moduleMinderTargetDTO.getTargetId(); - FunctionalCaseModule functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey(targetId); - if (functionalCaseModule != null){ - FunctionalCaseModuleExample functionalCaseModuleExample = new FunctionalCaseModuleExample(); - functionalCaseModuleExample.createCriteria().andProjectIdEqualTo(projectId); - List functionalCaseModules = functionalCaseModuleMapper.selectByExample(functionalCaseModuleExample); - List ids = new ArrayList<>(functionalCaseModules.stream().map(FunctionalCaseModule::getId).toList()); - List finalIds = getFinalIds(moduleMinderTargetDTO, moduleIds, ids, targetId); - SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); - FunctionalCaseModuleMapper moduleMapper = sqlSession.getMapper(FunctionalCaseModuleMapper.class); - for (int i = 0; i < finalIds.size(); i++) { - FunctionalCaseModule updateModule = new FunctionalCaseModule(); - updateModule.setId(finalIds.get(i)); - updateModule.setPos(5000L * i); - updateModule.setUpdateUser(userId); - updateModule.setUpdateTime(System.currentTimeMillis()); - moduleMapper.updateByPrimaryKeySelective(updateModule); + public void editFunctionalCaseBatch(FunctionalCaseMinderEditRequest request, String userId) { + //处理删除的模块和用例 + deleteResource(request, userId); + + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + FunctionalCaseMapper caseMapper = sqlSession.getMapper(FunctionalCaseMapper.class); + FunctionalCaseBlobMapper caseBlobMapper = sqlSession.getMapper(FunctionalCaseBlobMapper.class); + FunctionalCaseCustomFieldMapper caseCustomFieldMapper = sqlSession.getMapper(FunctionalCaseCustomFieldMapper.class); + FunctionalCaseModuleMapper moduleMapper = sqlSession.getMapper(FunctionalCaseModuleMapper.class); + + List addLogDTOS = new ArrayList<>(); + List noticeList = new ArrayList<>(); + List updateNoticeList = new ArrayList<>(); + List updateLogDTOS = new ArrayList<>(); + //处理用例 + if (CollectionUtils.isNotEmpty(request.getUpdateCaseList())) { + Map> resourceMap = request.getUpdateCaseList().stream().collect(Collectors.groupingBy(FunctionalCaseChangeRequest::getType)); + //处理新增 + Map customFieldNameMap = getCustomFieldNameMap(request); + List addList = resourceMap.get(OperationLogType.ADD.toString()); + List updatePosList = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(addList)) { + Map> moduleCaseMap = getModuleCaseMap(addList); + for (FunctionalCaseChangeRequest functionalCaseChangeRequest : addList) { + FunctionalCase functionalCase = addCase(request, userId, functionalCaseChangeRequest, caseMapper); + String caseId = functionalCase.getId(); + //附属表 + FunctionalCaseBlob functionalCaseBlob = addCaseBlob(functionalCaseChangeRequest, caseId, caseBlobMapper); + //保存自定义字段 + List functionalCaseCustomFields = addCustomFields(functionalCaseChangeRequest, caseId, caseCustomFieldMapper); + //排序 + reSetMap(functionalCaseChangeRequest, moduleCaseMap, functionalCase); + FunctionalCaseHistoryLogDTO historyLogDTO = new FunctionalCaseHistoryLogDTO(functionalCase, functionalCaseBlob, functionalCaseCustomFields, new ArrayList<>(), new ArrayList<>()); + addLog(request, userId, caseId, historyLogDTO, addLogDTOS, null); + FunctionalCaseDTO functionalCaseDTO = getFunctionalCaseDTO(functionalCase, functionalCaseCustomFields, customFieldNameMap); + noticeList.add(functionalCaseDTO); } - sqlSession.flushStatements(); - SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); + moduleCaseMap.forEach((k, v) -> { + updatePosList.addAll(v); + }); } - } - } - - private void moveSortCase(String userId, MinderTargetDTO caseMinderTargetDTO, List caseIds) { - if (caseMinderTargetDTO != null && StringUtils.isNotBlank(caseMinderTargetDTO.getTargetId())) { - String targetId = caseMinderTargetDTO.getTargetId(); - //排序 - FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(targetId); - if (functionalCase != null && !functionalCase.getDeleted()) { + //处理更新 + List updateList = resourceMap.get(OperationLogType.UPDATE.toString()); + if (CollectionUtils.isNotEmpty(updateList)) { + List caseIds = updateList.stream().map(FunctionalCaseChangeRequest::getId).toList(); + FunctionalCaseCustomFieldExample example = new FunctionalCaseCustomFieldExample(); + example.createCriteria().andCaseIdIn(caseIds); + List allFields = functionalCaseCustomFieldMapper.selectByExample(example); + Map> caseCustomFieldMap = allFields.stream().collect(Collectors.groupingBy(FunctionalCaseCustomField::getCaseId)); + Map> moduleCaseMap = getModuleCaseMap(updateList); FunctionalCaseExample functionalCaseExample = new FunctionalCaseExample(); - functionalCaseExample.createCriteria().andDeletedEqualTo(false).andModuleIdEqualTo(functionalCase.getModuleId()).andProjectIdEqualTo(functionalCase.getProjectId()); - List functionalCases = functionalCaseMapper.selectByExample(functionalCaseExample); - List ids = new ArrayList<>(functionalCases.stream().map(FunctionalCase::getId).toList()); - List finalIds = getFinalIds(caseMinderTargetDTO, caseIds, ids, targetId); - SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); - FunctionalCaseMapper caseMapper = sqlSession.getMapper(FunctionalCaseMapper.class); - for (int i = 0; i < finalIds.size(); i++) { - FunctionalCase updateCase = new FunctionalCase(); - updateCase.setId(finalIds.get(i)); - updateCase.setPos(5000L * i); - updateCase.setUpdateUser(userId); - updateCase.setUpdateTime(System.currentTimeMillis()); - caseMapper.updateByPrimaryKeySelective(updateCase); + functionalCaseExample.createCriteria().andIdIn(caseIds); + List oldCase = functionalCaseMapper.selectByExample(functionalCaseExample); + Map oldCaseMap = oldCase.stream().collect(Collectors.toMap(FunctionalCase::getId, t -> t)); + FunctionalCaseBlobExample functionalCaseBlobExample = new FunctionalCaseBlobExample(); + List functionalCaseBlobs = functionalCaseBlobMapper.selectByExample(functionalCaseBlobExample); + Map oldBlobMap = functionalCaseBlobs.stream().collect(Collectors.toMap(FunctionalCaseBlob::getId, t -> t)); + + for (FunctionalCaseChangeRequest functionalCaseChangeRequest : updateList) { + //基本信息 + String caseId = functionalCaseChangeRequest.getId(); + FunctionalCase functionalCase = updateCase(request, userId, caseMapper); + //更新附属表信息 + FunctionalCaseBlob functionalCaseBlob = updateBlob(functionalCaseChangeRequest, caseId, caseBlobMapper); + //更新自定义字段 + List functionalCaseCustomFields = updateCustomFields(functionalCaseChangeRequest, caseCustomFieldMap, caseId, caseCustomFieldMapper); + //排序 + if (StringUtils.isNotBlank(functionalCaseChangeRequest.getMoveMode())) { + reSetMap(functionalCaseChangeRequest, moduleCaseMap, functionalCase); + } + FunctionalCaseHistoryLogDTO historyLogDTO = new FunctionalCaseHistoryLogDTO(functionalCase, functionalCaseBlob, caseCustomFieldMap.get(caseId), new ArrayList<>(), new ArrayList<>()); + FunctionalCaseHistoryLogDTO old = new FunctionalCaseHistoryLogDTO(oldCaseMap.get(caseId), oldBlobMap.get(caseId), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); + addLog(request, userId, caseId, historyLogDTO, updateLogDTOS, old); + FunctionalCaseDTO functionalCaseDTO = getFunctionalCaseDTO(functionalCase, functionalCaseCustomFields, customFieldNameMap); + updateNoticeList.add(functionalCaseDTO); + } - sqlSession.flushStatements(); - SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); + moduleCaseMap.forEach((k, v) -> { + updatePosList.addAll(v); + }); + } + //批量排序 + batchSort(updatePosList, caseMapper); + + } + + //处理模块 + if (CollectionUtils.isNotEmpty(request.getUpdateModuleList())) { + List updatePosList = new ArrayList<>(); + //处理新增 + Map> resourceMap = request.getUpdateModuleList().stream().collect(Collectors.groupingBy(FunctionalCaseModuleEditRequest::getType)); + List addList = resourceMap.get(OperationLogType.ADD.toString()); + if (CollectionUtils.isNotEmpty(addList)) { + Map> parentModuleMap = getParentModuleMap(addList); + for (FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest : addList) { + checkModules(functionalCaseModuleEditRequest, parentModuleMap); + FunctionalCaseModule functionalCaseModule = addModule(request, userId, functionalCaseModuleEditRequest, moduleMapper); + reSetModuleMap(functionalCaseModuleEditRequest, parentModuleMap, functionalCaseModule); + } + parentModuleMap.forEach((k, v) -> { + updatePosList.addAll(v); + }); + + } + //处理更新 + List updateList = resourceMap.get(OperationLogType.UPDATE.toString()); + if (CollectionUtils.isNotEmpty(updateList)) { + Map> parentModuleMap = getParentModuleMap(addList); + for (FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest : updateList) { + checkModules(functionalCaseModuleEditRequest, parentModuleMap); + FunctionalCaseModule updateModule = updateModule(userId, functionalCaseModuleEditRequest); + reSetModuleMap(functionalCaseModuleEditRequest, parentModuleMap, updateModule); + } + parentModuleMap.forEach((k, v) -> { + updatePosList.addAll(v); + }); + } + //批量排序 + batchSortModule(updatePosList, moduleMapper); + } + + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); + + Project project = projectMapper.selectByPrimaryKey(request.getProjectId()); + for (LogDTO addLogDTO : addLogDTOS) { + addLogDTO.setOrganizationId(project.getOrganizationId()); + } + for (LogDTO updateLogDTO : updateLogDTOS) { + updateLogDTO.setOrganizationId(project.getOrganizationId()); + } + operationLogService.batchAdd(addLogDTOS); + operationLogService.batchAdd(updateLogDTOS); + User user = userMapper.selectByPrimaryKey(userId); + List resources = new ArrayList<>(); + resources.addAll(JSON.parseArray(JSON.toJSONString(noticeList), Map.class)); + commonNoticeSendService.sendNotice(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, NoticeConstants.Event.CREATE, resources, user, request.getProjectId()); + resources = new ArrayList<>(); + resources.addAll(JSON.parseArray(JSON.toJSONString(updateNoticeList), Map.class)); + commonNoticeSendService.sendNotice(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, NoticeConstants.Event.UPDATE, resources, user, request.getProjectId()); + } + + private static void batchSortModule(List updatePosList, FunctionalCaseModuleMapper moduleMapper) { + for (FunctionalCaseModule functionalCaseModule : updatePosList) { + FunctionalCaseModule functionalCaseModuleUpdatePos = new FunctionalCaseModule(); + functionalCaseModuleUpdatePos.setId(functionalCaseModule.getId()); + functionalCaseModuleUpdatePos.setPos(functionalCaseModule.getPos()); + moduleMapper.updateByPrimaryKeySelective(functionalCaseModuleUpdatePos); + } + } + + private static void batchSort(List updatePosList, FunctionalCaseMapper caseMapper) { + if (CollectionUtils.isEmpty(updatePosList)) { + return; + } + for (FunctionalCase functionalCase : updatePosList) { + FunctionalCase functionalCaseUpdatePos = new FunctionalCase(); + functionalCaseUpdatePos.setId(functionalCase.getId()); + functionalCaseUpdatePos.setPos(functionalCase.getPos()); + caseMapper.updateByPrimaryKeySelective(functionalCaseUpdatePos); + } + } + + private static void checkModules(FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest, Map> parentModuleMap) { + List functionalCaseModules = parentModuleMap.get(functionalCaseModuleEditRequest.getParentId()); + List sameNameList = functionalCaseModules.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getName(), functionalCaseModuleEditRequest.getName())).toList(); + if (CollectionUtils.isNotEmpty(sameNameList)) { + throw new MSException(Translator.get("node.name.repeat")); + } + } + + /** + * 获取页面改动的自定义字段 + */ + @NotNull + private Map getCustomFieldNameMap(FunctionalCaseMinderEditRequest request) { + List caseCustomFieldDTOS = new ArrayList<>(); + for (FunctionalCaseChangeRequest caseChangeRequest : request.getUpdateCaseList()) { + if (CollectionUtils.isNotEmpty(caseChangeRequest.getCustomFields())){ + caseCustomFieldDTOS.addAll(caseChangeRequest.getCustomFields()); } } + if (CollectionUtils.isEmpty(caseCustomFieldDTOS)){ + return new HashMap<>(); + } + List caseCustomFields = caseCustomFieldDTOS.stream().map(CaseCustomFieldDTO::getFieldId).toList(); + CustomFieldExample customFieldExample = new CustomFieldExample(); + customFieldExample.createCriteria().andIdIn(caseCustomFields); + + List customFields = customFieldMapper.selectByExample(customFieldExample); + return customFields.stream().collect(Collectors.toMap(CustomField::getId, CustomField::getName)); } @NotNull - private static List getFinalIds(MinderTargetDTO minderTargetDTO, List paramIds, List selectIds, String targetId) { - List finalIds = new ArrayList<>(); - int i1 = selectIds.indexOf(targetId); - List beforeIds; - List afterIds; - if (StringUtils.equals(minderTargetDTO.getMoveMode(), MoveTypeEnum.AFTER.name())) { - beforeIds = selectIds.subList(0, i1 + 1); - afterIds = selectIds.subList(i1 + 1, selectIds.size()); + private static FunctionalCaseDTO getFunctionalCaseDTO(FunctionalCase functionalCase, List functionalCaseCustomFields, Map customFieldNameMap) { + FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO(); + BeanUtils.copyBean(functionalCaseDTO, functionalCase); + functionalCaseDTO.setTriggerMode(NoticeConstants.TriggerMode.MANUAL_EXECUTION); + List fields = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(functionalCaseCustomFields)) { + for (FunctionalCaseCustomField customFieldDTO : functionalCaseCustomFields) { + OptionDTO optionDTO = new OptionDTO(); + String name = customFieldNameMap.get(customFieldDTO.getFieldId()); + if (StringUtils.isBlank(name)) { + continue; + } + optionDTO.setId(name); + optionDTO.setName(customFieldDTO.getValue()); + fields.add(optionDTO); + } + } + functionalCaseDTO.setFields(fields); + return functionalCaseDTO; + } + + private static void addLog(FunctionalCaseMinderEditRequest request, String userId, String caseId, FunctionalCaseHistoryLogDTO historyLogDTO, List addLogDTOS, FunctionalCaseHistoryLogDTO old) { + LogDTO dto = new LogDTO( + request.getProjectId(), + null, + caseId, + userId, + OperationLogType.ADD.name(), + OperationLogModule.FUNCTIONAL_CASE, + historyLogDTO.getFunctionalCase().getName()); + dto.setHistory(true); + dto.setPath("/functional/mind/case/edit"); + dto.setMethod(HttpMethodConstants.POST.name()); + dto.setModifiedValue(JSON.toJSONBytes(historyLogDTO)); + dto.setOriginalValue(JSON.toJSONBytes(old)); + addLogDTOS.add(dto); + } + + @NotNull + private FunctionalCaseModule addModule(FunctionalCaseMinderEditRequest request, String userId, FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest, FunctionalCaseModuleMapper moduleMapper) { + FunctionalCaseModule functionalCaseModule = new FunctionalCaseModule(); + functionalCaseModule.setId(IDGenerator.nextStr()); + functionalCaseModule.setName(functionalCaseModuleEditRequest.getName()); + functionalCaseModule.setParentId(functionalCaseModuleEditRequest.getParentId()); + functionalCaseModule.setProjectId(request.getProjectId()); + functionalCaseModule.setCreateTime(System.currentTimeMillis()); + functionalCaseModule.setUpdateTime(functionalCaseModule.getCreateTime()); + functionalCaseModule.setPos(this.countPos(functionalCaseModule.getParentId())); + functionalCaseModule.setCreateUser(userId); + functionalCaseModule.setUpdateUser(userId); + moduleMapper.insert(functionalCaseModule); + return functionalCaseModule; + } + + @NotNull + private FunctionalCaseModule updateModule(String userId, FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest) { + FunctionalCaseModule updateModule = new FunctionalCaseModule(); + updateModule.setId(functionalCaseModuleEditRequest.getId()); + updateModule.setName(functionalCaseModuleEditRequest.getName()); + updateModule.setUpdateTime(System.currentTimeMillis()); + updateModule.setUpdateUser(userId); + updateModule.setCreateUser(null); + updateModule.setCreateTime(null); + functionalCaseModuleMapper.updateByPrimaryKeySelective(updateModule); + return updateModule; + } + + @NotNull + private Map> getParentModuleMap(List addList) { + List targetIds = addList.stream().map(FunctionalCaseModuleEditRequest::getTargetId).distinct().toList(); + FunctionalCaseModuleExample functionalCaseModuleExample = new FunctionalCaseModuleExample(); + functionalCaseModuleExample.createCriteria().andIdIn(targetIds); + List functionalCaseModules = functionalCaseModuleMapper.selectByExample(functionalCaseModuleExample); + List parentIds = functionalCaseModules.stream().map(FunctionalCaseModule::getParentId).distinct().toList(); + functionalCaseModuleExample = new FunctionalCaseModuleExample(); + functionalCaseModuleExample.createCriteria().andParentIdIn(parentIds); + functionalCaseModules = functionalCaseModuleMapper.selectByExample(functionalCaseModuleExample); + return functionalCaseModules.stream().collect(Collectors.groupingBy(FunctionalCaseModule::getParentId)); + } + + private Long countPos(String parentId) { + Long maxPos = extFunctionalCaseModuleMapper.getMaxPosByParentId(parentId); + if (maxPos == null) { + return LIMIT_POS; } else { - beforeIds = selectIds.subList(0, i1); - afterIds = selectIds.subList(i1, selectIds.size()); - } - finalIds.addAll(beforeIds); - finalIds.addAll(paramIds); - finalIds.addAll(afterIds); - return finalIds.stream().distinct().toList(); - } - - private void updateSteps(FunctionalCaseMinderRemoveRequest request, List resourceList) { - if (StringUtils.isNotBlank(request.getSteps())) { - List functionalCaseStepDTOS = JSON.parseArray(request.getSteps(), FunctionalCaseStepDTO.class); - for (int i = 0; i < functionalCaseStepDTOS.size(); i++) { - functionalCaseStepDTOS.get(i).setNum(i); - } - byte[] bytes = StringUtils.defaultIfBlank(JSON.toJSONString(functionalCaseStepDTOS), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8); - extFunctionalCaseBlobMapper.batchUpdateColumn("steps", List.of(resourceList.get(0).getId()), bytes); + return maxPos + LIMIT_POS; } } - - public void deleteFunctionalCaseBatch(String projectId, List resourceList, String userId) { - if (CollectionUtils.isEmpty(resourceList)) { - throw new MSException(Translator.get("node.not_blank")); + private void reSetModuleMap(FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest, Map> parentModuleMap, FunctionalCaseModule functionalCaseModule) { + List functionalCaseModuleInDbList = parentModuleMap.get(functionalCaseModule.getParentId()); + if (CollectionUtils.isEmpty(functionalCaseModuleInDbList)) { + return; } - Map> resourceMap = resourceList.stream().collect(Collectors.groupingBy(MinderOptionDTO::getType)); - User user = userMapper.selectByPrimaryKey(userId); - - List caseOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.case")); - if (CollectionUtils.isNotEmpty(caseOptionDTOS)) { - List caseIds = caseOptionDTOS.stream().map(MinderOptionDTO::getId).toList(); - if (!extCheckOwnerMapper.checkoutOwner(FUNCTIONAL_CASE, userId, caseIds)) { - throw new MSException(Translator.get(CHECK_OWNER_CASE)); - } - functionalCaseService.handDeleteFunctionalCase(caseIds, false, userId, projectId); + List sortList = functionalCaseModuleInDbList.stream().sorted(Comparator.comparing(FunctionalCaseModule::getPos)).toList(); + int j = getModuleIndex(functionalCaseModuleEditRequest, sortList); + List functionalCaseModules = getFunctionalCaseModules(functionalCaseModuleEditRequest, functionalCaseModule, sortList, j); + for (int i = 0; i < functionalCaseModules.size(); i++) { + functionalCaseModules.get(i).setPos(5000L * i); } - List caseModuleOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.module")); - if (CollectionUtils.isNotEmpty(caseModuleOptionDTOS)) { - List moduleIds = caseModuleOptionDTOS.stream().map(MinderOptionDTO::getId).toList(); - if (!extCheckOwnerMapper.checkoutOwner(FUNCTIONAL_CASE_MODULE, userId, moduleIds)) { - throw new MSException(Translator.get(CHECK_OWNER_CASE)); - } - List functionalCases = functionalCaseModuleService.deleteModuleByIds(moduleIds, new ArrayList<>(), userId); - functionalCaseModuleService.batchDelLog(functionalCases, projectId); - } - List prerequisiteOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.prerequisite")); - updateBlob(userId, "prerequisite", prerequisiteOptionDTOS, projectId, user); - List descriptionOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.description")); - updateBlob(userId, "description", descriptionOptionDTOS, projectId, user); - List stepOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.steps")); - if (CollectionUtils.isNotEmpty(stepOptionDTOS)) { - List stepResultOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.steps_expected_result")); - stepOptionDTOS.addAll(stepResultOptionDTOS); - updateBlob(userId, "steps", stepOptionDTOS, projectId, user); - } - List textOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.text_description")); - updateBlob(userId, "text_description", textOptionDTOS, projectId, user); - List resultOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.text_expected_result")); - updateBlob(userId, "expected_result", resultOptionDTOS, projectId, user); + parentModuleMap.put(functionalCaseModule.getParentId(), functionalCaseModules); } - private void updateBlob(String userId, String column, List preRequisiteOptionDTOS, String projectId, User user) { - if (CollectionUtils.isNotEmpty(preRequisiteOptionDTOS)) { - List caseIds = preRequisiteOptionDTOS.stream().map(MinderOptionDTO::getId).distinct().toList(); - if (!extCheckOwnerMapper.checkoutOwner(FUNCTIONAL_CASE, userId, caseIds)) { - throw new MSException(Translator.get(CHECK_OWNER_CASE)); + @NotNull + private static List getFunctionalCaseModules(FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest, FunctionalCaseModule functionalCaseModule, List sortList, int j) { + List finallyModules = new ArrayList<>(); + List beforeModules; + List afterModules; + if (StringUtils.equals(functionalCaseModuleEditRequest.getMoveMode(), MoveTypeEnum.AFTER.name())) { + beforeModules = sortList.subList(0, j + 1); + afterModules = sortList.subList(j + 1, sortList.size()); + } else { + beforeModules = sortList.subList(0, j); + afterModules = sortList.subList(j, sortList.size()); + } + finallyModules.addAll(beforeModules); + finallyModules.add(functionalCaseModule); + finallyModules.addAll(afterModules); + return finallyModules; + } + + private static int getModuleIndex(FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest, List sortList) { + int j = 0; + for (int i = 0; i < sortList.size(); i++) { + if (StringUtils.equalsIgnoreCase(sortList.get(i).getId(), functionalCaseModuleEditRequest.getTargetId())) { + j = i; + break; + } + } + return j; + } + + + private void reSetMap(FunctionalCaseChangeRequest functionalCaseChangeRequest, Map> moduleCaseMap, FunctionalCase functionalCase) { + List functionalCaseInDbList = moduleCaseMap.get(functionalCase.getModuleId()); + if (CollectionUtils.isEmpty(functionalCaseInDbList)) { + return; + } + List sortList = functionalCaseInDbList.stream().sorted(Comparator.comparing(FunctionalCase::getPos)).toList(); + int j = 0; + j = getIndex(functionalCaseChangeRequest, sortList, j); + List functionalCases = getFunctionalCases(functionalCaseChangeRequest, sortList, j, functionalCase); + for (int i = 0; i < functionalCases.size(); i++) { + functionalCases.get(i).setPos(5000L * i); + } + moduleCaseMap.put(functionalCase.getModuleId(), functionalCases); + } + + @NotNull + private Map> getModuleCaseMap(List addList) { + List list = addList.stream().map(FunctionalCaseChangeRequest::getTargetId).distinct().toList(); + FunctionalCaseExample functionalCaseExample = new FunctionalCaseExample(); + functionalCaseExample.createCriteria().andIdIn(list); + List functionalCases = functionalCaseMapper.selectByExample(functionalCaseExample); + List targetModuleIds = functionalCases.stream().map(FunctionalCase::getModuleId).distinct().toList(); + if (CollectionUtils.isEmpty(targetModuleIds)) { + return new HashMap<>(); + } + functionalCaseExample = new FunctionalCaseExample(); + functionalCaseExample.createCriteria().andModuleIdIn(targetModuleIds); + List functionalCasesByModule = functionalCaseMapper.selectByExample(functionalCaseExample); + return functionalCasesByModule.stream().collect(Collectors.groupingBy(FunctionalCase::getModuleId)); + } + + private FunctionalCase updateCase(FunctionalCaseMinderEditRequest request, String userId, FunctionalCaseMapper caseMapper) { + FunctionalCase functionalCase = new FunctionalCase(); + BeanUtils.copyBean(functionalCase, request); + functionalCase.setUpdateUser(userId); + functionalCase.setUpdateTime(System.currentTimeMillis()); + //更新用例 + caseMapper.updateByPrimaryKeySelective(functionalCase); + return functionalCase; + } + + private FunctionalCaseBlob updateBlob(FunctionalCaseChangeRequest functionalCaseChangeRequest, String caseId, FunctionalCaseBlobMapper caseBlobMapper) { + FunctionalCaseBlob functionalCaseBlob = new FunctionalCaseBlob(); + functionalCaseBlob.setId(caseId); + functionalCaseBlob.setSteps(StringUtils.defaultIfBlank(functionalCaseChangeRequest.getSteps(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); + functionalCaseBlob.setTextDescription(StringUtils.defaultIfBlank(functionalCaseChangeRequest.getTextDescription(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); + functionalCaseBlob.setExpectedResult(StringUtils.defaultIfBlank(functionalCaseChangeRequest.getExpectedResult(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); + functionalCaseBlob.setPrerequisite(StringUtils.defaultIfBlank(functionalCaseChangeRequest.getPrerequisite(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); + functionalCaseBlob.setDescription(StringUtils.defaultIfBlank(functionalCaseChangeRequest.getDescription(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); + caseBlobMapper.updateByPrimaryKeyWithBLOBs(functionalCaseBlob); + return functionalCaseBlob; + } + + private List updateCustomFields(FunctionalCaseChangeRequest functionalCaseChangeRequest, Map> caseCustomFieldMap, String caseId, FunctionalCaseCustomFieldMapper caseCustomFieldMapper) { + List total = new ArrayList<>(); + List functionalCaseCustomFields = caseCustomFieldMap.get(caseId); + List customFields = functionalCaseChangeRequest.getCustomFields(); + if (CollectionUtils.isNotEmpty(customFields)) { + customFields = customFields.stream().distinct().collect(Collectors.toList()); + List fieldIds = customFields.stream().map(CaseCustomFieldDTO::getFieldId).collect(Collectors.toList()); + Map collect = functionalCaseCustomFields.stream().filter(t -> fieldIds.contains(t.getFieldId())).collect(Collectors.toMap(FunctionalCaseCustomField::getFieldId, (item) -> item)); + List addFields = new ArrayList<>(); + List updateFields = new ArrayList<>(); + customFields.forEach(customField -> { + if (collect.containsKey(customField.getFieldId())) { + updateFields.add(customField); + } else { + addFields.add(customField); + } + }); + if (CollectionUtils.isNotEmpty(addFields)) { + List functionalCaseCustomFields1 = saveCustomField(caseId, caseCustomFieldMapper, addFields); + total.addAll(functionalCaseCustomFields1); + } + ; + if (CollectionUtils.isNotEmpty(updateFields)) { + List functionalCaseCustomFields1 = updateField(updateFields, caseId, caseCustomFieldMapper); + total.addAll(functionalCaseCustomFields1); + } + } + return total; + } + + @NotNull + private static List getFunctionalCases(FunctionalCaseChangeRequest functionalCaseChangeRequest, List sortList, int j, FunctionalCase functionalCase) { + List finallyCases = new ArrayList<>(); + List beforeCases; + List afterCases; + if (StringUtils.equals(functionalCaseChangeRequest.getMoveMode(), MoveTypeEnum.AFTER.name())) { + beforeCases = sortList.subList(0, j + 1); + afterCases = sortList.subList(j + 1, sortList.size()); + } else { + beforeCases = sortList.subList(0, j); + afterCases = sortList.subList(j, sortList.size()); + } + finallyCases.addAll(beforeCases); + finallyCases.add(functionalCase); + finallyCases.addAll(afterCases); + return finallyCases; + } + + private static int getIndex(FunctionalCaseChangeRequest functionalCaseChangeRequest, List sortList, int j) { + for (int i = 0; i < sortList.size(); i++) { + if (StringUtils.equalsIgnoreCase(sortList.get(i).getId(), functionalCaseChangeRequest.getTargetId())) { + j = i; + break; + } + } + return j; + } + + private List updateField(List updateFields, String caseId, FunctionalCaseCustomFieldMapper caseCustomFieldMapper) { + List caseCustomFields = new ArrayList<>(); + updateFields.forEach(custom -> { + FunctionalCaseCustomField customField = new FunctionalCaseCustomField(); + customField.setCaseId(caseId); + customField.setFieldId(custom.getFieldId()); + customField.setValue(custom.getValue()); + caseCustomFieldMapper.updateByPrimaryKeySelective(customField); + caseCustomFields.add(customField); + }); + return caseCustomFields; + } + + private List addCustomFields(FunctionalCaseChangeRequest functionalCaseChangeRequest, String caseId, FunctionalCaseCustomFieldMapper caseCustomFieldMapper) { + List customFields = functionalCaseChangeRequest.getCustomFields(); + List caseCustomFields = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(customFields)) { + customFields = customFields.stream().distinct().collect(Collectors.toList()); + caseCustomFields = saveCustomField(caseId, caseCustomFieldMapper, customFields); + } + return caseCustomFields; + } + + private List saveCustomField(String caseId, FunctionalCaseCustomFieldMapper caseCustomFieldMapper, List customFields) { + List caseCustomFields = new ArrayList<>(); + customFields.forEach(custom -> { + FunctionalCaseCustomField customField = new FunctionalCaseCustomField(); + customField.setCaseId(caseId); + customField.setFieldId(custom.getFieldId()); + customField.setValue(custom.getValue()); + caseCustomFieldMapper.insertSelective(customField); + caseCustomFields.add(customField); + }); + return caseCustomFields; + } + + private FunctionalCaseBlob addCaseBlob(FunctionalCaseChangeRequest functionalCaseChangeRequest, String caseId, FunctionalCaseBlobMapper caseBlobMapper) { + FunctionalCaseBlob functionalCaseBlob = new FunctionalCaseBlob(); + functionalCaseBlob.setId(caseId); + functionalCaseBlob.setSteps(StringUtils.defaultIfBlank(functionalCaseChangeRequest.getSteps(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); + functionalCaseBlob.setTextDescription(StringUtils.defaultIfBlank(functionalCaseChangeRequest.getTextDescription(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); + functionalCaseBlob.setExpectedResult(StringUtils.defaultIfBlank(functionalCaseChangeRequest.getExpectedResult(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); + functionalCaseBlob.setPrerequisite(StringUtils.defaultIfBlank(functionalCaseChangeRequest.getPrerequisite(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); + functionalCaseBlob.setDescription(StringUtils.defaultIfBlank(functionalCaseChangeRequest.getDescription(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8)); + caseBlobMapper.insertSelective(functionalCaseBlob); + return functionalCaseBlob; + } + + @NotNull + private FunctionalCase addCase(FunctionalCaseMinderEditRequest request, String userId, FunctionalCaseChangeRequest functionalCaseChangeRequest, FunctionalCaseMapper caseMapper) { + FunctionalCase functionalCase = new FunctionalCase(); + BeanUtils.copyBean(functionalCase, functionalCaseChangeRequest); + String caseId = IDGenerator.nextStr(); + functionalCase.setId(caseId); + functionalCase.setProjectId(request.getProjectId()); + functionalCase.setVersionId(request.getVersionId()); + functionalCase.setNum(functionalCaseService.getNextNum(request.getProjectId())); + functionalCase.setReviewStatus(FunctionalCaseReviewStatus.UN_REVIEWED.name()); + functionalCase.setPos(functionalCaseService.getNextOrder(functionalCase.getProjectId())); + functionalCase.setRefId(caseId); + functionalCase.setLastExecuteResult(FunctionalCaseExecuteResult.PENDING.name()); + functionalCase.setLatest(true); + functionalCase.setCreateUser(userId); + functionalCase.setUpdateUser(userId); + functionalCase.setCreateTime(System.currentTimeMillis()); + functionalCase.setUpdateTime(System.currentTimeMillis()); + functionalCase.setVersionId(StringUtils.defaultIfBlank(request.getVersionId(), extBaseProjectVersionMapper.getDefaultVersion(request.getProjectId()))); + functionalCase.setTags(functionalCaseChangeRequest.getTags()); + caseMapper.insertSelective(functionalCase); + return functionalCase; + } + + private void deleteResource(FunctionalCaseMinderEditRequest request, String userId) { + if (CollectionUtils.isNotEmpty(request.getDeleteResourceList())) { + User user = userMapper.selectByPrimaryKey(userId); + Map> resourceMap = request.getDeleteResourceList().stream().collect(Collectors.groupingBy(MinderOptionDTO::getType)); + List caseOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.case")); + if (CollectionUtils.isNotEmpty(caseOptionDTOS)) { + List caseIds = caseOptionDTOS.stream().map(MinderOptionDTO::getId).toList(); + checkPermission(caseIds, FUNCTIONAL_CASE, userId); + functionalCaseService.handDeleteFunctionalCase(caseIds, false, userId, request.getProjectId()); + functionalCaseLogService.batchDeleteFunctionalCaseLogByIds(caseIds, "/functional/mind/case/edit"); + functionalCaseNoticeService.batchSendNotice(request.getProjectId(), caseIds, user, NoticeConstants.Event.DELETE); + + } + List caseModuleOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.module")); + if (CollectionUtils.isNotEmpty(caseModuleOptionDTOS)) { + List moduleIds = caseModuleOptionDTOS.stream().map(MinderOptionDTO::getId).toList(); + checkPermission(moduleIds, FUNCTIONAL_CASE_MODULE, userId); + List functionalCases = functionalCaseModuleService.deleteModuleByIds(moduleIds, new ArrayList<>(), userId); + functionalCaseModuleService.batchDelLog(functionalCases, request.getProjectId()); + functionalCaseNoticeService.batchSendNotice(request.getProjectId(), functionalCases.stream().map(FunctionalCase::getId).toList(), user, NoticeConstants.Event.DELETE); + } - extFunctionalCaseBlobMapper.batchUpdateColumn(column, caseIds, null); - functionalCaseNoticeService.batchSendNotice(projectId, caseIds, user, NoticeConstants.Event.UPDATE); } } @@ -474,23 +765,4 @@ public class FunctionalCaseMinderService { } - - private void buildList(List functionalCaseMindDTOList, List list) { - //构造父子级数据 - for (FunctionalCaseMindDTO functionalCaseMindDTO : functionalCaseMindDTOList) { - 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()); - rootData.setResource(List.of(Translator.get("minder_extra_node.case"))); - List children = buildChildren(functionalCaseMindDTO); - root.setChildren(children); - root.setData(rootData); - list.add(root); - } - } - } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseModuleService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseModuleService.java index ec999b1066..e84b1629b7 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseModuleService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseModuleService.java @@ -132,7 +132,7 @@ public class FunctionalCaseModuleService extends ModuleTreeService { batchDelLog(functionalCases, deleteModule.getProjectId()); List ids = functionalCases.stream().map(FunctionalCase::getId).toList(); User user = userMapper.selectByPrimaryKey(userId); - functionalCaseNoticeService.batchSendNotice(deleteModule.getProjectId(), ids, user, NoticeConstants.Event.UPDATE); + functionalCaseNoticeService.batchSendNotice(deleteModule.getProjectId(), ids, user, NoticeConstants.Event.DELETE); } } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseNoticeService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseNoticeService.java index f00de1cdc4..19ba593341 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseNoticeService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseNoticeService.java @@ -10,7 +10,6 @@ import io.metersphere.functional.mapper.FunctionalCaseMapper; import io.metersphere.functional.request.FunctionalCaseAddRequest; import io.metersphere.functional.request.FunctionalCaseCommentRequest; import io.metersphere.functional.request.FunctionalCaseEditRequest; -import io.metersphere.functional.request.FunctionalCaseMinderEditRequest; import io.metersphere.plan.domain.TestPlan; import io.metersphere.plan.domain.TestPlanExample; import io.metersphere.plan.domain.TestPlanFunctionalCase; @@ -19,7 +18,6 @@ import io.metersphere.plan.mapper.TestPlanFunctionalCaseMapper; import io.metersphere.plan.mapper.TestPlanMapper; import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.JSON; -import io.metersphere.sdk.util.Translator; import io.metersphere.system.domain.CustomField; import io.metersphere.system.domain.CustomFieldExample; import io.metersphere.system.domain.User; @@ -309,45 +307,6 @@ public class FunctionalCaseNoticeService { return dtoList; } - public FunctionalCaseDTO getMainFunctionalCaseMinderDTO(FunctionalCaseMinderEditRequest request) { - FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO(); - if (StringUtils.equalsIgnoreCase(request.getType(), Translator.get("minder_extra_node.module"))) { - return functionalCaseDTO; - } - FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(request.getId()); - BeanUtils.copyBean(functionalCaseDTO, functionalCase); - setReviewName(request.getId(), functionalCaseDTO); - setPlanName(request.getId(), functionalCaseDTO); - functionalCaseDTO.setTriggerMode(NoticeConstants.TriggerMode.MANUAL_EXECUTION); - List fields = new ArrayList<>(); - FunctionalCaseCustomFieldExample fieldExample = new FunctionalCaseCustomFieldExample(); - fieldExample.createCriteria().andCaseIdEqualTo(request.getId()); - List functionalCaseCustomFields = functionalCaseCustomFieldMapper.selectByExample(fieldExample); - CustomFieldExample example = new CustomFieldExample(); - example.createCriteria().andNameEqualTo("functional_priority").andSceneEqualTo("FUNCTIONAL").andScopeIdEqualTo(request.getProjectId()); - List customFields = customFieldMapper.selectByExample(example); - String field = customFields.get(0).getId(); - - if (CollectionUtils.isNotEmpty(functionalCaseCustomFields)) { - for (FunctionalCaseCustomField customFieldDTO : functionalCaseCustomFields) { - OptionDTO optionDTO = new OptionDTO(); - CustomField customField = customFieldMapper.selectByPrimaryKey(customFieldDTO.getFieldId()); - if (customField == null) { - continue; - } - optionDTO.setId(customField.getName()); - if (StringUtils.equalsIgnoreCase(customField.getId(), field) && StringUtils.isNotBlank(request.getPriority())) { - optionDTO.setName(request.getPriority()); - } else { - optionDTO.setName(customFieldDTO.getValue()); - } - fields.add(optionDTO); - } - } - functionalCaseDTO.setFields(fields); - return functionalCaseDTO; - - } public void batchSendNotice(String projectId, List ids, User user, String event) { int amount = 100;//每次读取的条数 diff --git a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseMinderControllerTest.java b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseMinderControllerTest.java index e6298f5a98..a02f72df70 100644 --- a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseMinderControllerTest.java +++ b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseMinderControllerTest.java @@ -1,24 +1,21 @@ package io.metersphere.functional.controller; import io.metersphere.functional.domain.*; +import io.metersphere.functional.dto.CaseCustomFieldDTO; import io.metersphere.functional.dto.FunctionalCaseStepDTO; import io.metersphere.functional.dto.FunctionalMinderTreeDTO; import io.metersphere.functional.dto.MinderOptionDTO; -import io.metersphere.functional.dto.MinderTargetDTO; import io.metersphere.functional.mapper.FunctionalCaseBlobMapper; import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper; import io.metersphere.functional.mapper.FunctionalCaseMapper; import io.metersphere.functional.mapper.FunctionalCaseModuleMapper; -import io.metersphere.functional.request.FunctionalCaseMindRequest; -import io.metersphere.functional.request.FunctionalCaseMinderEditRequest; -import io.metersphere.functional.request.FunctionalCaseMinderRemoveRequest; -import io.metersphere.functional.request.FunctionalCaseReviewMindRequest; +import io.metersphere.functional.request.*; import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.Translator; import io.metersphere.system.base.BaseTest; import io.metersphere.system.controller.handler.ResultHolder; -import io.metersphere.system.dto.sdk.enums.MoveTypeEnum; 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; @@ -30,29 +27,21 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @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 FUNCTIONAL_CASE_UPDATE_NAME_URL = "/functional/mind/case/update/source/name"; + public static final String FUNCTIONAL_CASE_EDIT_URL = "/functional/mind/case/edit"; - public static final String FUNCTIONAL_CASE_UPDATE_PRIORITY_URL = "/functional/mind/case/update/source/priority"; - - public static final String FUNCTIONAL_CASE_BATCH_DELETE = "/functional/mind/case/batch/delete/"; - - public static final String FUNCTIONAL_CASE_BATCH_MOVE = "/functional/mind/case/batch/remove"; //评审 public static final String FUNCTIONAL_CASE_REVIEW_LIST_URL = "/functional/mind/case/review/list"; - - @Resource private FunctionalCaseBlobMapper functionalCaseBlobMapper; @Resource @@ -117,200 +106,96 @@ public class FunctionalCaseMinderControllerTest extends BaseTest { @Test @Order(2) - public void testUpdateCase() throws Exception { - + public void testEditList() throws Exception { FunctionalCaseMinderEditRequest request = new FunctionalCaseMinderEditRequest(); request.setProjectId("project-case-minder-test"); - request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - request.setName("TEST_FUNCTIONAL_MINDER_CASE_ID_Change_Name"); - request.setType(Translator.get("minder_extra_node.case")); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); - FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - Assertions.assertEquals(functionalCase.getName(), "TEST_FUNCTIONAL_MINDER_CASE_ID_Change_Name"); - request.setName("TEST_MINDER_MODULE_ID_GYQ5_Change_Name"); - request.setId("TEST_MINDER_MODULE_ID_GYQ5"); - request.setType(Translator.get("minder_extra_node.module")); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); - FunctionalCaseModule functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey("TEST_MINDER_MODULE_ID_GYQ5"); - Assertions.assertEquals(functionalCaseModule.getName(), "TEST_MINDER_MODULE_ID_GYQ5_Change_Name"); - - request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - request.setName("前置哈哈哈"); - request.setType(Translator.get("minder_extra_node.prerequisite")); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); - FunctionalCaseBlob functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - Assertions.assertEquals(new String(functionalCaseBlob.getPrerequisite(), StandardCharsets.UTF_8), "前置哈哈哈"); - - FunctionalCaseBlob functionalCaseBlobInDB = new FunctionalCaseBlob(); - functionalCaseBlobInDB.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - String steps = "[{\"id\":\"aa159262-baf9-4a11-91b9-0ab50a9f199e\",\"num\":0,\"desc\":\"点点滴滴\",\"result\":\"点点滴滴的\"},{\"id\":\"2bf16247-96a2-44c4-92c8-f620f85eb351\",\"num\":1,\"desc\":\"d d d\",\"result\":\" 得到的\"}]"; - functionalCaseBlobInDB.setSteps(steps.getBytes(StandardCharsets.UTF_8)); - functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlobInDB); - request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - request.setName("步骤哈哈哈"); - request.setType(Translator.get("minder_extra_node.steps")); - request.setPos(1L); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); - functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - - List functionalCaseStepDTOS = JSON.parseArray(new String(functionalCaseBlob.getSteps(), StandardCharsets.UTF_8), FunctionalCaseStepDTO.class); - functionalCaseStepDTOS.forEach(t->{ - if (t.getNum()==1) { - Assertions.assertEquals(t.getDesc(), "步骤哈哈哈"); - } - }); - request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - request.setName("步骤结果哈哈哈"); - request.setType(Translator.get("minder_extra_node.steps_expected_result")); - request.setPos(1L); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); - functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - - functionalCaseStepDTOS = JSON.parseArray(new String(functionalCaseBlob.getSteps(), StandardCharsets.UTF_8), FunctionalCaseStepDTO.class); - functionalCaseStepDTOS.forEach(t->{ - if (t.getNum()==1) { - Assertions.assertEquals(t.getResult(), "步骤结果哈哈哈"); - } - }); - request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - request.setName("文本哈哈哈"); - request.setType(Translator.get("minder_extra_node.text_description")); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); - functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - Assertions.assertEquals(new String(functionalCaseBlob.getTextDescription(), StandardCharsets.UTF_8), "文本哈哈哈");request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - request.setName("预期哈哈哈"); - request.setType(Translator.get("minder_extra_node.text_expected_result")); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); - functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - Assertions.assertEquals(new String(functionalCaseBlob.getExpectedResult(), StandardCharsets.UTF_8), "预期哈哈哈"); - request.setName("备注哈哈哈"); - request.setType(Translator.get("minder_extra_node.description")); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); - functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - Assertions.assertEquals(new String(functionalCaseBlob.getDescription(), StandardCharsets.UTF_8), "备注哈哈哈"); + request.setVersionId("ffff"); + List caseChangeRequests = new ArrayList<>(); + FunctionalCaseChangeRequest caseChangeRequest = new FunctionalCaseChangeRequest(); + caseChangeRequest.setId("12344"); + caseChangeRequest.setName("新增用例"); + caseChangeRequest.setModuleId("TEST_MINDER_MODULE_ID_GYQ2"); + caseChangeRequest.setMoveMode("AFTER"); + caseChangeRequest.setTargetId("TEST_FUNCTIONAL_MINDER_CASE_ID_3"); + caseChangeRequest.setTemplateId("100001"); + caseChangeRequest.setType("ADD"); + caseChangeRequest.setPrerequisite("前置条件"); + caseChangeRequest.setCaseEditType("TEXT"); + List customFields = new ArrayList<>(); + CaseCustomFieldDTO customFieldDTO = new CaseCustomFieldDTO(); + customFieldDTO.setFieldId("custom_field_minder_gyq_id_3"); + customFieldDTO.setValue("P0"); + customFields.add(customFieldDTO); + caseChangeRequest.setCustomFields(customFields); + caseChangeRequests.add(caseChangeRequest); + caseChangeRequest = new FunctionalCaseChangeRequest(); + caseChangeRequest.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_1"); + caseChangeRequest.setName("TEST_MINDER_MODULE_ID_GYQ_更新"); + caseChangeRequest.setModuleId("TEST_MINDER_MODULE_ID_GYQ"); + caseChangeRequest.setTemplateId("100001"); + caseChangeRequest.setMoveMode("BEFORE"); + caseChangeRequest.setTargetId("TEST_FUNCTIONAL_MINDER_CASE_ID_2"); + caseChangeRequest.setType("UPDATE"); + caseChangeRequest.setPrerequisite("前置条件"); + caseChangeRequest.setCaseEditType("TEXT"); + customFields = new ArrayList<>(); + customFieldDTO = new CaseCustomFieldDTO(); + customFieldDTO.setFieldId("custom_field_minder_gyq_id_3"); + customFieldDTO.setValue("P3"); + customFields.add(customFieldDTO); + caseChangeRequest.setCustomFields(customFields); + caseChangeRequests.add(caseChangeRequest); + request.setUpdateCaseList(caseChangeRequests); + List functionalCaseModuleEditRequests = new ArrayList<>(); + FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest = new FunctionalCaseModuleEditRequest(); + functionalCaseModuleEditRequest.setId("uuuId"); + functionalCaseModuleEditRequest.setType("ADD"); + functionalCaseModuleEditRequest.setMoveMode("AFTER"); + functionalCaseModuleEditRequest.setTargetId("TEST_MINDER_MODULE_ID_GYQ8"); + functionalCaseModuleEditRequest.setName("新增9"); + functionalCaseModuleEditRequest.setParentId("TEST_MINDER_MODULE_ID_GYQ"); + functionalCaseModuleEditRequests.add(functionalCaseModuleEditRequest); + functionalCaseModuleEditRequest = new FunctionalCaseModuleEditRequest(); + functionalCaseModuleEditRequest.setId("TEST_MINDER_MODULE_ID_GYQ7"); + functionalCaseModuleEditRequest.setType("UPDATE"); + functionalCaseModuleEditRequest.setMoveMode("BEFORE"); + functionalCaseModuleEditRequest.setTargetId("TEST_MINDER_MODULE_ID_GYQ8"); + functionalCaseModuleEditRequest.setName("移动7"); + functionalCaseModuleEditRequest.setParentId("TEST_MINDER_MODULE_ID_GYQ"); + functionalCaseModuleEditRequests.add(functionalCaseModuleEditRequest); + request.setUpdateModuleList(functionalCaseModuleEditRequests); + List deleteResourceList = new ArrayList<>(); + MinderOptionDTO minderOptionDTO = new MinderOptionDTO(); + minderOptionDTO.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_9"); + minderOptionDTO.setType(Translator.get("minder_extra_node.case")); + deleteResourceList.add(minderOptionDTO); + minderOptionDTO = new MinderOptionDTO(); + minderOptionDTO.setId("TEST_MINDER_MODULE_ID_GYQ9"); + minderOptionDTO.setType(Translator.get("minder_extra_node.module")); + deleteResourceList.add(minderOptionDTO); + request.setDeleteResourceList(deleteResourceList); + this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_EDIT_URL, request); + FunctionalCaseExample functionalCaseExample = new FunctionalCaseExample(); + functionalCaseExample.createCriteria().andNameEqualTo("新增用例"); + List functionalCases = functionalCaseMapper.selectByExample(functionalCaseExample); + Assertions.assertTrue(CollectionUtils.isNotEmpty(functionalCases)); + Assertions.assertTrue(functionalCases.get(0).getPos()>0L); + FunctionalCaseModuleExample functionalCaseModuleExample = new FunctionalCaseModuleExample(); + functionalCaseModuleExample.createCriteria().andNameEqualTo("新增9"); + List functionalCaseModules = functionalCaseModuleMapper.selectByExample(functionalCaseModuleExample); + Assertions.assertTrue(CollectionUtils.isNotEmpty(functionalCaseModules)); + Assertions.assertTrue(functionalCaseModules.get(0).getPos()>0L); request = new FunctionalCaseMinderEditRequest(); request.setProjectId("project-case-minder-test"); - request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - request.setPriority("P0"); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_PRIORITY_URL, request); - FunctionalCaseCustomFieldExample customField = new FunctionalCaseCustomFieldExample(); - customField.createCriteria().andCaseIdEqualTo(request.getId()).andFieldIdEqualTo("custom_field_minder_gyq_id_3"); - List functionalCaseCustomFields = functionalCaseCustomFieldMapper.selectByExample(customField); - Assertions.assertEquals(functionalCaseCustomFields.get(0).getValue(), "P0"); - request = new FunctionalCaseMinderEditRequest(); - request.setProjectId("project-case-minder-test"); - request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_PRIORITY_URL, request); + request.setVersionId("ffff"); + this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_EDIT_URL, request); + functionalCases = functionalCaseMapper.selectByExample(functionalCaseExample); + Assertions.assertTrue(CollectionUtils.isNotEmpty(functionalCases)); } + @Test @Order(3) - public void testDeleteCase() throws Exception{ - List resourceList = new ArrayList<>(); - this.requestPost(FUNCTIONAL_CASE_BATCH_DELETE+"/project-case-minder-test", resourceList).andExpect(status().is5xxServerError()); - MinderOptionDTO optionDTO = new MinderOptionDTO("TEST_MINDER_MODULE_ID_GYQ6", Translator.get("minder_extra_node.module"), 5000L); - resourceList.add(optionDTO); - this.requestPost(FUNCTIONAL_CASE_BATCH_DELETE+"/project-case-minder-test-xxx", resourceList).andExpect(status().is5xxServerError()); - resourceList = new ArrayList<>(); - optionDTO = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_7", Translator.get("minder_extra_node.case"), 1000L); - resourceList.add(optionDTO); - this.requestPost(FUNCTIONAL_CASE_BATCH_DELETE+"/project-case-minder-test-xxx", resourceList).andExpect(status().is5xxServerError()); - resourceList = new ArrayList<>(); - MinderOptionDTO optionDTOCase = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_6", Translator.get("minder_extra_node.case"), 600L); - MinderOptionDTO optionDTOModule = new MinderOptionDTO("TEST_MINDER_MODULE_ID_GYQ", Translator.get("minder_extra_node.module"), 1200L); - resourceList.add(optionDTOModule); - resourceList.add(optionDTOCase); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_DELETE+"/project-case-minder-test", resourceList); - FunctionalCase functionalCaseOne = functionalCaseMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_2"); - Assertions.assertTrue(functionalCaseOne.getDeleted()); - FunctionalCase functionalCaseTwo = functionalCaseMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); - Assertions.assertTrue(functionalCaseTwo.getDeleted()); - resourceList = new ArrayList<>(); - optionDTOCase = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", Translator.get("minder_extra_node.case"), 600L); - resourceList.add(optionDTOCase); - MinderOptionDTO optionDTOPrerequisite = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", Translator.get("minder_extra_node.prerequisite").toString(), 0L); - MinderOptionDTO optionDTODescription = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", Translator.get("minder_extra_node.description").toString(), 3L); - MinderOptionDTO optionDTOStep = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", Translator.get("minder_extra_node.steps").toString(), 2L); - MinderOptionDTO optionDTOStepExpectedResult = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", Translator.get("minder_extra_node.steps_expected_result").toString(), 2L); - MinderOptionDTO optionDTOText = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", Translator.get("minder_extra_node.text_description").toString(), 2L); - MinderOptionDTO optionDTOTextExpectedResult = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", Translator.get("minder_extra_node.text_expected_result").toString(), 2L); - resourceList.add(optionDTOPrerequisite); - resourceList.add(optionDTODescription); - resourceList.add(optionDTOStep); - resourceList.add(optionDTOStepExpectedResult); - resourceList.add(optionDTOText); - resourceList.add(optionDTOTextExpectedResult); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_DELETE+"/project-case-minder-test", resourceList); - resourceList = new ArrayList<>(); - optionDTOText = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_7", Translator.get("minder_extra_node.text_description").toString(), 2L); - resourceList.add(optionDTOText); - optionDTOTextExpectedResult = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_7", Translator.get("minder_extra_node.text_expected_result").toString(), 2L); - resourceList.add(optionDTOTextExpectedResult); - this.requestPost(FUNCTIONAL_CASE_BATCH_DELETE+"/project-case-minder-test", resourceList).andExpect(status().is5xxServerError()); - - } - @Test - @Order(4) - public void testRemoveCase() throws Exception{ - FunctionalCaseMinderRemoveRequest functionalCaseMinderRemoveRequest = new FunctionalCaseMinderRemoveRequest(); - functionalCaseMinderRemoveRequest.setProjectId("project-case-minder-test"); - functionalCaseMinderRemoveRequest.setParentTargetId("TEST_MINDER_MODULE_ID_GYQ2"); - MinderTargetDTO caseMinderTargetDTO = new MinderTargetDTO(); - caseMinderTargetDTO.setTargetId("TEST_FUNCTIONAL_MINDER_CASE_ID_8"); - caseMinderTargetDTO.setMoveMode(MoveTypeEnum.AFTER.name()); - functionalCaseMinderRemoveRequest.setCaseMinderTargetDTO(caseMinderTargetDTO); - MinderTargetDTO moduleMinderTargetDTO = new MinderTargetDTO(); - moduleMinderTargetDTO.setTargetId("TEST_MINDER_MODULE_ID_GYQ2"); - moduleMinderTargetDTO.setMoveMode(MoveTypeEnum.AFTER.name()); - functionalCaseMinderRemoveRequest.setModuleMinderTargetDTO(moduleMinderTargetDTO); - functionalCaseMinderRemoveRequest.setResourceList(new ArrayList<>()); - this.requestPost(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest).andExpect(status().is5xxServerError()); - List resourceList = new ArrayList<>(); - MinderOptionDTO optionDTOCase = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_8", Translator.get("minder_extra_node.case"), 600L); - resourceList.add(optionDTOCase); - MinderOptionDTO optionDTOModule = new MinderOptionDTO("TEST_MINDER_MODULE_ID_GYQ5", Translator.get("minder_extra_node.module"), 600L); - resourceList.add(optionDTOModule); - functionalCaseMinderRemoveRequest.setResourceList(resourceList); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest); - FunctionalCaseModule functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey("TEST_MINDER_MODULE_ID_GYQ5"); - Assertions.assertTrue(functionalCaseModule.getPos() !=0); - functionalCaseMinderRemoveRequest.setParentTargetId(null); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest); - functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey("TEST_MINDER_MODULE_ID_GYQ5"); - functionalCaseMinderRemoveRequest.setSteps("[{\"id\":\"aa159262-baf9-4a11-91b9-0ab50a9f199e\",\"num\":0,\"desc\":\"点点滴滴\",\"result\":\"点点滴滴的\"},{\"id\":\"2bf16247-96a2-44c4-92c8-f620f85eb351\",\"num\":1,\"desc\":\"d d d\",\"result\":\" 得到的\"}]"); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest); - Assertions.assertTrue(functionalCaseModule.getPos() !=0); - caseMinderTargetDTO = new MinderTargetDTO(); - caseMinderTargetDTO.setTargetId("TEST_FUNCTIONAL_MINDER_CASE_ID_8"); - caseMinderTargetDTO.setMoveMode(MoveTypeEnum.BEFORE.name()); - functionalCaseMinderRemoveRequest.setCaseMinderTargetDTO(caseMinderTargetDTO); - moduleMinderTargetDTO = new MinderTargetDTO(); - moduleMinderTargetDTO.setTargetId("TEST_MINDER_MODULE_ID_GYQ2"); - moduleMinderTargetDTO.setMoveMode(MoveTypeEnum.BEFORE.name()); - functionalCaseMinderRemoveRequest.setModuleMinderTargetDTO(moduleMinderTargetDTO); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest); - functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey("TEST_MINDER_MODULE_ID_GYQ5"); - Assertions.assertTrue(functionalCaseModule.getPos()==5000); - functionalCaseMinderRemoveRequest.setCaseMinderTargetDTO(null); - functionalCaseMinderRemoveRequest.setModuleMinderTargetDTO(null); - this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest); - functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey("TEST_MINDER_MODULE_ID_GYQ5"); - Assertions.assertTrue(functionalCaseModule.getPos()==5000); - functionalCaseMinderRemoveRequest.setParentTargetId("TEST_MINDER_MODULE_ID_GYQ6"); - this.requestPost(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest).andExpect(status().is5xxServerError()); - resourceList = new ArrayList<>(); - optionDTOCase = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_7", Translator.get("minder_extra_node.case"), 600L); - resourceList.add(optionDTOCase); - this.requestPost(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest).andExpect(status().is5xxServerError()); - optionDTOModule = new MinderOptionDTO("TEST_MINDER_MODULE_ID_GYQ6", Translator.get("minder_extra_node.module"), 600L); - resourceList = new ArrayList<>(); - resourceList.add(optionDTOModule); - functionalCaseMinderRemoveRequest.setResourceList(resourceList); - this.requestPost(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest).andExpect(status().is5xxServerError()); - } - - @Test - @Order(5) public void testGetCaseReviewList() throws Exception { FunctionalCaseReviewMindRequest request = new FunctionalCaseReviewMindRequest(); request.setProjectId("project-case-minder-test"); diff --git a/backend/services/case-management/src/test/resources/dml/init_file_minder_test.sql b/backend/services/case-management/src/test/resources/dml/init_file_minder_test.sql index ba2950e4d2..c52fcbb495 100644 --- a/backend/services/case-management/src/test/resources/dml/init_file_minder_test.sql +++ b/backend/services/case-management/src/test/resources/dml/init_file_minder_test.sql @@ -15,7 +15,8 @@ VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_1', 1, 'TEST_MINDER_MODULE_ID_GYQ', 'pro ('TEST_FUNCTIONAL_MINDER_CASE_ID_6', 6, 'TEST_MINDER_MODULE_ID_GYQ5', 'project-case-minder-test', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'TEXT', 55000, 'v3.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_6', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL), ('TEST_FUNCTIONAL_MINDER_CASE_ID_8', 3, 'TEST_MINDER_MODULE_ID_GYQ2', 'project-case-minder-test', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 25000, 'v3.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_8', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL), - ('TEST_FUNCTIONAL_MINDER_CASE_ID_7', 7, 'TEST_MINDER_MODULE_ID_GYQ6', 'project-case-minder-test-xx', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'TEXT', 55000, 'v3.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_7', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL); + ('TEST_FUNCTIONAL_MINDER_CASE_ID_7', 7, 'TEST_MINDER_MODULE_ID_GYQ6', 'project-case-minder-test-xx', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'TEXT', 55000, 'v3.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_7', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL), + ('TEST_FUNCTIONAL_MINDER_CASE_ID_9', 8, 'TEST_MINDER_MODULE_ID_GYQ6', 'project-case-minder-test', '100001', 'copy_用来删除', 'UN_REVIEWED', NULL, 'TEXT', 55000, 'v3.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_7', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL); @@ -41,7 +42,9 @@ VALUES ('TEST_MINDER_MODULE_ID_GYQ5', 'project-case-minder-test', '测试所属模块5', 'TEST_MINDER_MODULE_ID_GYQ4', 0, 1669174143999, 1669174143999, 'admin', 'admin'), ('TEST_MINDER_MODULE_ID_GYQ7', 'project-case-minder-test', '测试所属模块7', 'TEST_MINDER_MODULE_ID_GYQ', 0, 1669174143999, 1669174143999, 'admin', 'admin'), ('TEST_MINDER_MODULE_ID_GYQ8', 'project-case-minder-test', '测试所属模块8', 'TEST_MINDER_MODULE_ID_GYQ', 0, 1669174143999, 1669174143999, 'admin', 'admin'), - ('TEST_MINDER_MODULE_ID_GYQ6', 'project-case-minder-test-xx', '测试所属模块1', 'NONE', 0, 1669174143999, 1669174143999, 'admin', 'admin'); + ('TEST_MINDER_MODULE_ID_GYQ6', 'project-case-minder-test-xx', '测试所属模块1', 'NONE', 0, 1669174143999, 1669174143999, 'admin', 'admin'), + ('TEST_MINDER_MODULE_ID_GYQ9', 'project-case-minder-test', '用来删除', 'NONE', 0, 1669174143999, 1669174143999, 'admin', 'admin'); +;