feat(用例管理): 脑图字段统一保存接口

This commit is contained in:
guoyuqi 2024-05-16 12:34:52 +08:00 committed by 刘瑞斌
parent 7db01bf024
commit 5784ac55a0
11 changed files with 808 additions and 731 deletions

View File

@ -2,28 +2,23 @@ package io.metersphere.functional.controller;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import io.metersphere.functional.dto.FunctionalMinderTreeDTO; import io.metersphere.functional.dto.FunctionalMinderTreeDTO;
import io.metersphere.functional.dto.MinderOptionDTO;
import io.metersphere.functional.request.FunctionalCaseMindRequest; import io.metersphere.functional.request.FunctionalCaseMindRequest;
import io.metersphere.functional.request.FunctionalCaseMinderEditRequest; import io.metersphere.functional.request.FunctionalCaseMinderEditRequest;
import io.metersphere.functional.request.FunctionalCaseMinderRemoveRequest;
import io.metersphere.functional.request.FunctionalCaseReviewMindRequest; import io.metersphere.functional.request.FunctionalCaseReviewMindRequest;
import io.metersphere.functional.service.FunctionalCaseLogService;
import io.metersphere.functional.service.FunctionalCaseMinderService; import io.metersphere.functional.service.FunctionalCaseMinderService;
import io.metersphere.functional.service.FunctionalCaseNoticeService;
import io.metersphere.sdk.constants.PermissionConstants; 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.security.CheckOwner;
import io.metersphere.system.utils.SessionUtils; import io.metersphere.system.utils.SessionUtils;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated; 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; import java.util.List;
@ -46,46 +41,18 @@ public class FunctionalCaseMinderController {
return functionalCaseMinderService.getMindFunctionalCase(request, false); return functionalCaseMinderService.getMindFunctionalCase(request, false);
} }
@PostMapping("/update/source/name") @PostMapping("/edit")
@Operation(summary = "脑图更新资源名称") @Operation(summary = "脑图保存")
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE) @RequiresPermissions(value = {
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateMinderFunctionalCaseLog(#request)", msClass = FunctionalCaseLogService.class) PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE,
@SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.UPDATE, target = "#targetClass.getMainFunctionalCaseMinderDTO(#request)", targetClass = FunctionalCaseNoticeService.class) PermissionConstants.FUNCTIONAL_CASE_READ_DELETE,
@CheckOwner(resourceId = "#request.getId()", resourceType = "functional_case") PermissionConstants.FUNCTIONAL_CASE_READ_ADD,
public void updateFunctionalCaseName(@Validated @RequestBody FunctionalCaseMinderEditRequest request) { }, logical = Logical.OR)
public void editFunctionalCaseBatch(@Validated @RequestBody FunctionalCaseMinderEditRequest request) {
String userId = SessionUtils.getUserId(); 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<MinderOptionDTO> resourceList) {
String userId = SessionUtils.getUserId();
functionalCaseMinderService.deleteFunctionalCaseBatch(projectId, resourceList, userId);
}
@PostMapping("/review/list") @PostMapping("/review/list")
@Operation(summary = "用例管理-功能用例-脑图用例跟根据模块ID查询列表") @Operation(summary = "用例管理-功能用例-脑图用例跟根据模块ID查询列表")
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_MINDER) @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_MINDER)

View File

@ -14,7 +14,7 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor @NoArgsConstructor
public class MinderOptionDTO { public class MinderOptionDTO {
@Schema(description = "节点ID,如果是用例的子节点,比如 前置条件步骤描述等传其父节点ID") @Schema(description = "节点ID(用例/模块的id)")
@NotBlank(message = "{functional_case.id.not_blank}") @NotBlank(message = "{functional_case.id.not_blank}")
private String id; private String id;
@ -22,7 +22,4 @@ public class MinderOptionDTO {
@NotBlank(message = "{functional_case_test.test_type.not_blank}") @NotBlank(message = "{functional_case_test.test_type.not_blank}")
private String type; private String type;
@Schema(description = "节点顺序")
@NotBlank(message = "{functional_case.pos.not_blank}")
private Long pos;
} }

View File

@ -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<String> tags;
@Schema(description = "自定义字段集合")
private List<CaseCustomFieldDTO> customFields;
}

View File

@ -1,33 +1,32 @@
package io.metersphere.functional.request; package io.metersphere.functional.request;
import io.metersphere.functional.dto.MinderOptionDTO;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
import java.util.List;
/** /**
* @author wx * @author guoyuqi
*/ */
@Data @Data
public class FunctionalCaseMinderEditRequest{ 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) @Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{functional_case.project_id.not_blank}") @NotBlank(message = "{functional_case.project_id.not_blank}")
private String projectId; private String projectId;
@Schema(description = "资源名称(更新节点的名称包括前置的编辑)") @Schema(description = "版本id")
private String name; private String versionId;
@Schema(description = "步骤描述及其预期结果的排序(更新步骤描述时必填)") @Schema(description = "新增/修改的用例对象集合", requiredMode = Schema.RequiredMode.REQUIRED)
private Long pos; private List<FunctionalCaseChangeRequest> updateCaseList;
@Schema(description = "资源类型") @Schema(description = "新增/修改的模块集合(只记录操作的节点,节点下的子节点不需要记录)", requiredMode = Schema.RequiredMode.REQUIRED)
private String type; private List<FunctionalCaseModuleEditRequest> updateModuleList;
@Schema(description = "用例等级(只更新用例的等级时传)") @Schema(description = "删除的模块/用例的集合", requiredMode = Schema.RequiredMode.REQUIRED)
private String priority; private List<MinderOptionDTO> deleteResourceList;
} }

View File

@ -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;
}

View File

@ -7,25 +7,19 @@ import io.metersphere.bug.mapper.BugRelationCaseMapper;
import io.metersphere.functional.domain.*; import io.metersphere.functional.domain.*;
import io.metersphere.functional.dto.BaseFunctionalCaseBatchDTO; import io.metersphere.functional.dto.BaseFunctionalCaseBatchDTO;
import io.metersphere.functional.dto.FunctionalCaseHistoryLogDTO; import io.metersphere.functional.dto.FunctionalCaseHistoryLogDTO;
import io.metersphere.functional.dto.MinderOptionDTO;
import io.metersphere.functional.mapper.*; import io.metersphere.functional.mapper.*;
import io.metersphere.functional.request.*; import io.metersphere.functional.request.*;
import io.metersphere.project.domain.FileAssociation; import io.metersphere.project.domain.FileAssociation;
import io.metersphere.project.domain.FileAssociationExample; import io.metersphere.project.domain.FileAssociationExample;
import io.metersphere.project.mapper.FileAssociationMapper; import io.metersphere.project.mapper.FileAssociationMapper;
import io.metersphere.sdk.constants.HttpMethodConstants; import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.JSON; 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.OperationLogModule;
import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.log.dto.LogDTO; import io.metersphere.system.log.dto.LogDTO;
import io.metersphere.system.mapper.CustomFieldMapper; import io.metersphere.system.mapper.CustomFieldMapper;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -33,9 +27,6 @@ import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/** /**
* @author wx * @author wx
@ -196,86 +187,7 @@ public class FunctionalCaseLogService {
} }
return dtoList; return dtoList;
} }
public List<LogDTO> batchUpdateFunctionalCaseLogByIds(List<String> ids, String path) {
List<LogDTO> dtoList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(ids)) {
List<FunctionalCase> 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<LogDTO> deleteBatchMinderFunctionalCaseLog(List<MinderOptionDTO> resourceList) {
if (CollectionUtils.isEmpty(resourceList)) {
return new ArrayList<>();
}
String path = "/functional/mind/case/batch/delete/";
List<String> caseAllIds = new ArrayList<>();
Map<String, List<MinderOptionDTO>> resourceMap = resourceList.stream().collect(Collectors.groupingBy(MinderOptionDTO::getType));
List<MinderOptionDTO> caseOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.case"));
if (CollectionUtils.isNotEmpty(caseOptionDTOS)) {
List<String> caseIds = caseOptionDTOS.stream().map(MinderOptionDTO::getId).toList();
caseAllIds.addAll(caseIds);
}
List<MinderOptionDTO> moduleOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.module"));
if (CollectionUtils.isNotEmpty(moduleOptionDTOS)) {
List<String> moduleIds = moduleOptionDTOS.stream().map(MinderOptionDTO::getId).toList();
List<FunctionalCase> functionalCaseByModuleIds = getFunctionalCaseByModuleIds(moduleIds, new ArrayList<>());
List<String> list = functionalCaseByModuleIds.stream().map(FunctionalCase::getId).toList();
caseAllIds.addAll(list);
}
Set<String> strings = resourceMap.keySet();
List<LogDTO>logDTOS = new ArrayList<>();
List<String>ids = 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<LogDTO> logDTOS1 = batchDeleteFunctionalCaseLogByIds(caseAllIds, path);
logDTOS.addAll(logDTOS1);
} else {
//更新
List<MinderOptionDTO> keyOptionDTOS = resourceMap.get(key);
if (CollectionUtils.isNotEmpty(keyOptionDTOS)) {
List<String> list = keyOptionDTOS.stream().map(MinderOptionDTO::getId).toList();
ids.addAll(list);
}
}
}
List<LogDTO> logDTOS1 = batchUpdateFunctionalCaseLogByIds(ids, path);
logDTOS.addAll(logDTOS1);
return logDTOS;
}
public List<FunctionalCase> getFunctionalCaseByModuleIds(List<String> deleteIds, List<FunctionalCase> functionalCases) {
if (CollectionUtils.isEmpty(deleteIds)) {
return functionalCases;
}
List<FunctionalCase> functionalCaseList = extFunctionalCaseMapper.checkCaseByModuleIds(deleteIds);
if (CollectionUtils.isNotEmpty(functionalCaseList)) {
functionalCases.addAll(functionalCaseList);
}
List<String> childrenIds = extFunctionalCaseModuleMapper.selectChildrenIdsByParentIds(deleteIds);
if (CollectionUtils.isNotEmpty(childrenIds)) {
getFunctionalCaseByModuleIds(childrenIds, functionalCases);
}
return functionalCases;
}
/** /**
* 恢复项目 * 恢复项目
* *
@ -507,35 +419,6 @@ public class FunctionalCaseLogService {
return null; 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<FunctionalCaseCustomField> functionalCaseCustomFields = newDto.getCustomFields();
CustomFieldExample example = new CustomFieldExample();
example.createCriteria().andNameEqualTo("functional_priority").andSceneEqualTo("FUNCTIONAL").andScopeIdEqualTo(request.getProjectId());
List<CustomField> 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 @NotNull
private static LogDTO getUpdateLogDTO(String projectId, String sourceId, String content, String path) { private static LogDTO getUpdateLogDTO(String projectId, String sourceId, String content, String path) {
LogDTO dto = new LogDTO( LogDTO dto = new LogDTO(

View File

@ -1,21 +1,36 @@
package io.metersphere.functional.service; package io.metersphere.functional.service;
import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
import io.metersphere.functional.constants.FunctionalCaseTypeConstants; import io.metersphere.functional.constants.FunctionalCaseTypeConstants;
import io.metersphere.functional.domain.*; import io.metersphere.functional.domain.*;
import io.metersphere.functional.dto.*; import io.metersphere.functional.dto.*;
import io.metersphere.functional.mapper.*; import io.metersphere.functional.mapper.*;
import io.metersphere.functional.request.*; 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.exception.MSException;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Translator; import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.CustomField; import io.metersphere.system.domain.CustomField;
import io.metersphere.system.domain.CustomFieldExample; import io.metersphere.system.domain.CustomFieldExample;
import io.metersphere.system.domain.User; 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.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.CustomFieldMapper;
import io.metersphere.system.mapper.ExtCheckOwnerMapper; import io.metersphere.system.mapper.ExtCheckOwnerMapper;
import io.metersphere.system.mapper.UserMapper; import io.metersphere.system.mapper.UserMapper;
import io.metersphere.system.notice.constants.NoticeConstants; import io.metersphere.system.notice.constants.NoticeConstants;
import io.metersphere.system.service.CommonNoticeSendService;
import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -28,9 +43,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -42,6 +55,9 @@ import java.util.stream.Collectors;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public class FunctionalCaseMinderService { public class FunctionalCaseMinderService {
protected static final long LIMIT_POS = NodeSortUtils.DEFAULT_NODE_INTERVAL_POS;
@Resource @Resource
private FunctionalCaseMapper functionalCaseMapper; private FunctionalCaseMapper functionalCaseMapper;
@ -52,15 +68,9 @@ public class FunctionalCaseMinderService {
@Resource @Resource
private FunctionalCaseBlobMapper functionalCaseBlobMapper; private FunctionalCaseBlobMapper functionalCaseBlobMapper;
@Resource
private ExtFunctionalCaseBlobMapper extFunctionalCaseBlobMapper;
@Resource @Resource
private FunctionalCaseModuleMapper functionalCaseModuleMapper; private FunctionalCaseModuleMapper functionalCaseModuleMapper;
@Resource
private ExtFunctionalCaseModuleMapper extFunctionalCaseModuleMapper;
@Resource @Resource
private CustomFieldMapper customFieldMapper; private CustomFieldMapper customFieldMapper;
@ -77,17 +87,36 @@ public class FunctionalCaseMinderService {
private FunctionalCaseModuleService functionalCaseModuleService; private FunctionalCaseModuleService functionalCaseModuleService;
@Resource @Resource
private FunctionalCaseNoticeService functionalCaseNoticeService; private ExtBaseProjectVersionMapper extBaseProjectVersionMapper;
@Resource
private CommonNoticeSendService commonNoticeSendService;
@Resource
private OperationLogService operationLogService;
@Resource @Resource
private UserMapper userMapper; private UserMapper userMapper;
@Resource
private ProjectMapper projectMapper;
@Resource @Resource
SqlSessionFactory sqlSessionFactory; 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 = "functional_case";
private static final String FUNCTIONAL_CASE_MODULE = "functional_case_module"; 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; return list;
} }
private void buildList(List<FunctionalCaseMindDTO> functionalCaseMindDTOList, List<FunctionalMinderTreeDTO> 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<FunctionalMinderTreeDTO> children = buildChildren(functionalCaseMindDTO);
root.setChildren(children);
root.setData(rootData);
list.add(root);
}
}
private List<FunctionalMinderTreeDTO> buildChildren(FunctionalCaseMindDTO functionalCaseMindDTO) { private List<FunctionalMinderTreeDTO> buildChildren(FunctionalCaseMindDTO functionalCaseMindDTO) {
List<FunctionalMinderTreeDTO> children = new ArrayList<>(); List<FunctionalMinderTreeDTO> children = new ArrayList<>();
if (functionalCaseMindDTO.getPrerequisite() != null) { if (functionalCaseMindDTO.getPrerequisite() != null) {
@ -144,7 +191,6 @@ public class FunctionalCaseMinderService {
} }
} }
if (functionalCaseMindDTO.getDescription() != null) { if (functionalCaseMindDTO.getDescription() != null) {
String descriptionText = new String(functionalCaseMindDTO.getDescription(), StandardCharsets.UTF_8); String descriptionText = new String(functionalCaseMindDTO.getDescription(), StandardCharsets.UTF_8);
FunctionalMinderTreeDTO descriptionFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(descriptionText, Translator.get("minder_extra_node.description"), (long) (i + 1)); FunctionalMinderTreeDTO descriptionFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(descriptionText, Translator.get("minder_extra_node.description"), (long) (i + 1));
@ -165,301 +211,546 @@ public class FunctionalCaseMinderService {
return functionalMinderTreeDTO; return functionalMinderTreeDTO;
} }
public void updateFunctionalCase(FunctionalCaseMinderEditRequest request, String userId) { private void checkPermission(List<String> sourceIds, String tableName, String userId) {
if (StringUtils.isNotBlank(request.getName())) { if (CollectionUtils.isNotEmpty(sourceIds)) {
if (StringUtils.equalsIgnoreCase(request.getType(), Translator.get("minder_extra_node.case"))) { if (!extCheckOwnerMapper.checkoutOwner(tableName, userId, sourceIds)) {
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<CustomField> 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<FunctionalCaseStepDTO> 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<FunctionalCaseStepDTO> 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<MinderOptionDTO> resourceList = request.getResourceList();
if (CollectionUtils.isEmpty(resourceList)) {
throw new MSException(Translator.get("node.not_blank"));
}
Map<String, List<MinderOptionDTO>> resourceMap = resourceList.stream().collect(Collectors.groupingBy(MinderOptionDTO::getType));
MinderTargetDTO caseMinderTargetDTO = request.getCaseMinderTargetDTO();
MinderTargetDTO moduleMinderTargetDTO = request.getModuleMinderTargetDTO();
List<MinderOptionDTO> caseOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.case"));
List<String> caseIds = new ArrayList<>();
caseIds = checkPermission(caseOptionDTOS, caseIds, FUNCTIONAL_CASE, userId);
List<String> moduleIds = new ArrayList<>();
List<MinderOptionDTO> 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<String> checkPermission(List<MinderOptionDTO> caseOptionDTOS, List<String> caseIds, String functionalCase, String userId) {
if (CollectionUtils.isNotEmpty(caseOptionDTOS)) {
caseIds = caseOptionDTOS.stream().map(MinderOptionDTO::getId).toList();
if (!extCheckOwnerMapper.checkoutOwner(functionalCase, userId, caseIds)) {
throw new MSException(Translator.get(CHECK_OWNER_CASE)); throw new MSException(Translator.get(CHECK_OWNER_CASE));
} }
} }
return caseIds;
} }
private void moveSortModule(String projectId, String userId, MinderTargetDTO moduleMinderTargetDTO, List<String> moduleIds) { public void editFunctionalCaseBatch(FunctionalCaseMinderEditRequest request, String userId) {
if (moduleMinderTargetDTO != null && StringUtils.isNotBlank(moduleMinderTargetDTO.getTargetId())) { //处理删除的模块和用例
//排序 deleteResource(request, userId);
String targetId = moduleMinderTargetDTO.getTargetId();
FunctionalCaseModule functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey(targetId); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
if (functionalCaseModule != null){ FunctionalCaseMapper caseMapper = sqlSession.getMapper(FunctionalCaseMapper.class);
FunctionalCaseModuleExample functionalCaseModuleExample = new FunctionalCaseModuleExample(); FunctionalCaseBlobMapper caseBlobMapper = sqlSession.getMapper(FunctionalCaseBlobMapper.class);
functionalCaseModuleExample.createCriteria().andProjectIdEqualTo(projectId); FunctionalCaseCustomFieldMapper caseCustomFieldMapper = sqlSession.getMapper(FunctionalCaseCustomFieldMapper.class);
List<FunctionalCaseModule> functionalCaseModules = functionalCaseModuleMapper.selectByExample(functionalCaseModuleExample); FunctionalCaseModuleMapper moduleMapper = sqlSession.getMapper(FunctionalCaseModuleMapper.class);
List<String> ids = new ArrayList<>(functionalCaseModules.stream().map(FunctionalCaseModule::getId).toList());
List<String> finalIds = getFinalIds(moduleMinderTargetDTO, moduleIds, ids, targetId); List<LogDTO> addLogDTOS = new ArrayList<>();
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); List<FunctionalCaseDTO> noticeList = new ArrayList<>();
FunctionalCaseModuleMapper moduleMapper = sqlSession.getMapper(FunctionalCaseModuleMapper.class); List<FunctionalCaseDTO> updateNoticeList = new ArrayList<>();
for (int i = 0; i < finalIds.size(); i++) { List<LogDTO> updateLogDTOS = new ArrayList<>();
FunctionalCaseModule updateModule = new FunctionalCaseModule(); //处理用例
updateModule.setId(finalIds.get(i)); if (CollectionUtils.isNotEmpty(request.getUpdateCaseList())) {
updateModule.setPos(5000L * i); Map<String, List<FunctionalCaseChangeRequest>> resourceMap = request.getUpdateCaseList().stream().collect(Collectors.groupingBy(FunctionalCaseChangeRequest::getType));
updateModule.setUpdateUser(userId); //处理新增
updateModule.setUpdateTime(System.currentTimeMillis()); Map<String, String> customFieldNameMap = getCustomFieldNameMap(request);
moduleMapper.updateByPrimaryKeySelective(updateModule); List<FunctionalCaseChangeRequest> addList = resourceMap.get(OperationLogType.ADD.toString());
List<FunctionalCase> updatePosList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(addList)) {
Map<String, List<FunctionalCase>> 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<FunctionalCaseCustomField> 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(); moduleCaseMap.forEach((k, v) -> {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); updatePosList.addAll(v);
});
} }
} //处理更新
} List<FunctionalCaseChangeRequest> updateList = resourceMap.get(OperationLogType.UPDATE.toString());
if (CollectionUtils.isNotEmpty(updateList)) {
private void moveSortCase(String userId, MinderTargetDTO caseMinderTargetDTO, List<String> caseIds) { List<String> caseIds = updateList.stream().map(FunctionalCaseChangeRequest::getId).toList();
if (caseMinderTargetDTO != null && StringUtils.isNotBlank(caseMinderTargetDTO.getTargetId())) { FunctionalCaseCustomFieldExample example = new FunctionalCaseCustomFieldExample();
String targetId = caseMinderTargetDTO.getTargetId(); example.createCriteria().andCaseIdIn(caseIds);
//排序 List<FunctionalCaseCustomField> allFields = functionalCaseCustomFieldMapper.selectByExample(example);
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(targetId); Map<String, List<FunctionalCaseCustomField>> caseCustomFieldMap = allFields.stream().collect(Collectors.groupingBy(FunctionalCaseCustomField::getCaseId));
if (functionalCase != null && !functionalCase.getDeleted()) { Map<String, List<FunctionalCase>> moduleCaseMap = getModuleCaseMap(updateList);
FunctionalCaseExample functionalCaseExample = new FunctionalCaseExample(); FunctionalCaseExample functionalCaseExample = new FunctionalCaseExample();
functionalCaseExample.createCriteria().andDeletedEqualTo(false).andModuleIdEqualTo(functionalCase.getModuleId()).andProjectIdEqualTo(functionalCase.getProjectId()); functionalCaseExample.createCriteria().andIdIn(caseIds);
List<FunctionalCase> functionalCases = functionalCaseMapper.selectByExample(functionalCaseExample); List<FunctionalCase> oldCase = functionalCaseMapper.selectByExample(functionalCaseExample);
List<String> ids = new ArrayList<>(functionalCases.stream().map(FunctionalCase::getId).toList()); Map<String, FunctionalCase> oldCaseMap = oldCase.stream().collect(Collectors.toMap(FunctionalCase::getId, t -> t));
List<String> finalIds = getFinalIds(caseMinderTargetDTO, caseIds, ids, targetId); FunctionalCaseBlobExample functionalCaseBlobExample = new FunctionalCaseBlobExample();
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); List<FunctionalCaseBlob> functionalCaseBlobs = functionalCaseBlobMapper.selectByExample(functionalCaseBlobExample);
FunctionalCaseMapper caseMapper = sqlSession.getMapper(FunctionalCaseMapper.class); Map<String, FunctionalCaseBlob> oldBlobMap = functionalCaseBlobs.stream().collect(Collectors.toMap(FunctionalCaseBlob::getId, t -> t));
for (int i = 0; i < finalIds.size(); i++) {
FunctionalCase updateCase = new FunctionalCase(); for (FunctionalCaseChangeRequest functionalCaseChangeRequest : updateList) {
updateCase.setId(finalIds.get(i)); //基本信息
updateCase.setPos(5000L * i); String caseId = functionalCaseChangeRequest.getId();
updateCase.setUpdateUser(userId); FunctionalCase functionalCase = updateCase(request, userId, caseMapper);
updateCase.setUpdateTime(System.currentTimeMillis()); //更新附属表信息
caseMapper.updateByPrimaryKeySelective(updateCase); FunctionalCaseBlob functionalCaseBlob = updateBlob(functionalCaseChangeRequest, caseId, caseBlobMapper);
//更新自定义字段
List<FunctionalCaseCustomField> 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(); moduleCaseMap.forEach((k, v) -> {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); updatePosList.addAll(v);
});
}
//批量排序
batchSort(updatePosList, caseMapper);
}
//处理模块
if (CollectionUtils.isNotEmpty(request.getUpdateModuleList())) {
List<FunctionalCaseModule> updatePosList = new ArrayList<>();
//处理新增
Map<String, List<FunctionalCaseModuleEditRequest>> resourceMap = request.getUpdateModuleList().stream().collect(Collectors.groupingBy(FunctionalCaseModuleEditRequest::getType));
List<FunctionalCaseModuleEditRequest> addList = resourceMap.get(OperationLogType.ADD.toString());
if (CollectionUtils.isNotEmpty(addList)) {
Map<String, List<FunctionalCaseModule>> 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<FunctionalCaseModuleEditRequest> updateList = resourceMap.get(OperationLogType.UPDATE.toString());
if (CollectionUtils.isNotEmpty(updateList)) {
Map<String, List<FunctionalCaseModule>> 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<Map> 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<FunctionalCaseModule> 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<FunctionalCase> 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<String, List<FunctionalCaseModule>> parentModuleMap) {
List<FunctionalCaseModule> functionalCaseModules = parentModuleMap.get(functionalCaseModuleEditRequest.getParentId());
List<FunctionalCaseModule> 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<String, String> getCustomFieldNameMap(FunctionalCaseMinderEditRequest request) {
List<CaseCustomFieldDTO> 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<String> caseCustomFields = caseCustomFieldDTOS.stream().map(CaseCustomFieldDTO::getFieldId).toList();
CustomFieldExample customFieldExample = new CustomFieldExample();
customFieldExample.createCriteria().andIdIn(caseCustomFields);
List<CustomField> customFields = customFieldMapper.selectByExample(customFieldExample);
return customFields.stream().collect(Collectors.toMap(CustomField::getId, CustomField::getName));
} }
@NotNull @NotNull
private static List<String> getFinalIds(MinderTargetDTO minderTargetDTO, List<String> paramIds, List<String> selectIds, String targetId) { private static FunctionalCaseDTO getFunctionalCaseDTO(FunctionalCase functionalCase, List<FunctionalCaseCustomField> functionalCaseCustomFields, Map<String, String> customFieldNameMap) {
List<String> finalIds = new ArrayList<>(); FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
int i1 = selectIds.indexOf(targetId); BeanUtils.copyBean(functionalCaseDTO, functionalCase);
List<String> beforeIds; functionalCaseDTO.setTriggerMode(NoticeConstants.TriggerMode.MANUAL_EXECUTION);
List<String> afterIds; List<OptionDTO> fields = new ArrayList<>();
if (StringUtils.equals(minderTargetDTO.getMoveMode(), MoveTypeEnum.AFTER.name())) { if (CollectionUtils.isNotEmpty(functionalCaseCustomFields)) {
beforeIds = selectIds.subList(0, i1 + 1); for (FunctionalCaseCustomField customFieldDTO : functionalCaseCustomFields) {
afterIds = selectIds.subList(i1 + 1, selectIds.size()); 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<LogDTO> 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<String, List<FunctionalCaseModule>> getParentModuleMap(List<FunctionalCaseModuleEditRequest> addList) {
List<String> targetIds = addList.stream().map(FunctionalCaseModuleEditRequest::getTargetId).distinct().toList();
FunctionalCaseModuleExample functionalCaseModuleExample = new FunctionalCaseModuleExample();
functionalCaseModuleExample.createCriteria().andIdIn(targetIds);
List<FunctionalCaseModule> functionalCaseModules = functionalCaseModuleMapper.selectByExample(functionalCaseModuleExample);
List<String> 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 { } else {
beforeIds = selectIds.subList(0, i1); return maxPos + LIMIT_POS;
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<MinderOptionDTO> resourceList) {
if (StringUtils.isNotBlank(request.getSteps())) {
List<FunctionalCaseStepDTO> 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);
} }
} }
private void reSetModuleMap(FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest, Map<String, List<FunctionalCaseModule>> parentModuleMap, FunctionalCaseModule functionalCaseModule) {
public void deleteFunctionalCaseBatch(String projectId, List<MinderOptionDTO> resourceList, String userId) { List<FunctionalCaseModule> functionalCaseModuleInDbList = parentModuleMap.get(functionalCaseModule.getParentId());
if (CollectionUtils.isEmpty(resourceList)) { if (CollectionUtils.isEmpty(functionalCaseModuleInDbList)) {
throw new MSException(Translator.get("node.not_blank")); return;
} }
Map<String, List<MinderOptionDTO>> resourceMap = resourceList.stream().collect(Collectors.groupingBy(MinderOptionDTO::getType)); List<FunctionalCaseModule> sortList = functionalCaseModuleInDbList.stream().sorted(Comparator.comparing(FunctionalCaseModule::getPos)).toList();
User user = userMapper.selectByPrimaryKey(userId); int j = getModuleIndex(functionalCaseModuleEditRequest, sortList);
List<FunctionalCaseModule> functionalCaseModules = getFunctionalCaseModules(functionalCaseModuleEditRequest, functionalCaseModule, sortList, j);
List<MinderOptionDTO> caseOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.case")); for (int i = 0; i < functionalCaseModules.size(); i++) {
if (CollectionUtils.isNotEmpty(caseOptionDTOS)) { functionalCaseModules.get(i).setPos(5000L * i);
List<String> 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<MinderOptionDTO> caseModuleOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.module")); parentModuleMap.put(functionalCaseModule.getParentId(), functionalCaseModules);
if (CollectionUtils.isNotEmpty(caseModuleOptionDTOS)) {
List<String> moduleIds = caseModuleOptionDTOS.stream().map(MinderOptionDTO::getId).toList();
if (!extCheckOwnerMapper.checkoutOwner(FUNCTIONAL_CASE_MODULE, userId, moduleIds)) {
throw new MSException(Translator.get(CHECK_OWNER_CASE));
}
List<FunctionalCase> functionalCases = functionalCaseModuleService.deleteModuleByIds(moduleIds, new ArrayList<>(), userId);
functionalCaseModuleService.batchDelLog(functionalCases, projectId);
}
List<MinderOptionDTO> prerequisiteOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.prerequisite"));
updateBlob(userId, "prerequisite", prerequisiteOptionDTOS, projectId, user);
List<MinderOptionDTO> descriptionOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.description"));
updateBlob(userId, "description", descriptionOptionDTOS, projectId, user);
List<MinderOptionDTO> stepOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.steps"));
if (CollectionUtils.isNotEmpty(stepOptionDTOS)) {
List<MinderOptionDTO> stepResultOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.steps_expected_result"));
stepOptionDTOS.addAll(stepResultOptionDTOS);
updateBlob(userId, "steps", stepOptionDTOS, projectId, user);
}
List<MinderOptionDTO> textOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.text_description"));
updateBlob(userId, "text_description", textOptionDTOS, projectId, user);
List<MinderOptionDTO> resultOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.text_expected_result"));
updateBlob(userId, "expected_result", resultOptionDTOS, projectId, user);
} }
private void updateBlob(String userId, String column, List<MinderOptionDTO> preRequisiteOptionDTOS, String projectId, User user) { @NotNull
if (CollectionUtils.isNotEmpty(preRequisiteOptionDTOS)) { private static List<FunctionalCaseModule> getFunctionalCaseModules(FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest, FunctionalCaseModule functionalCaseModule, List<FunctionalCaseModule> sortList, int j) {
List<String> caseIds = preRequisiteOptionDTOS.stream().map(MinderOptionDTO::getId).distinct().toList(); List<FunctionalCaseModule> finallyModules = new ArrayList<>();
if (!extCheckOwnerMapper.checkoutOwner(FUNCTIONAL_CASE, userId, caseIds)) { List<FunctionalCaseModule> beforeModules;
throw new MSException(Translator.get(CHECK_OWNER_CASE)); List<FunctionalCaseModule> 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<FunctionalCaseModule> 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<String, List<FunctionalCase>> moduleCaseMap, FunctionalCase functionalCase) {
List<FunctionalCase> functionalCaseInDbList = moduleCaseMap.get(functionalCase.getModuleId());
if (CollectionUtils.isEmpty(functionalCaseInDbList)) {
return;
}
List<FunctionalCase> sortList = functionalCaseInDbList.stream().sorted(Comparator.comparing(FunctionalCase::getPos)).toList();
int j = 0;
j = getIndex(functionalCaseChangeRequest, sortList, j);
List<FunctionalCase> 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<String, List<FunctionalCase>> getModuleCaseMap(List<FunctionalCaseChangeRequest> addList) {
List<String> list = addList.stream().map(FunctionalCaseChangeRequest::getTargetId).distinct().toList();
FunctionalCaseExample functionalCaseExample = new FunctionalCaseExample();
functionalCaseExample.createCriteria().andIdIn(list);
List<FunctionalCase> functionalCases = functionalCaseMapper.selectByExample(functionalCaseExample);
List<String> targetModuleIds = functionalCases.stream().map(FunctionalCase::getModuleId).distinct().toList();
if (CollectionUtils.isEmpty(targetModuleIds)) {
return new HashMap<>();
}
functionalCaseExample = new FunctionalCaseExample();
functionalCaseExample.createCriteria().andModuleIdIn(targetModuleIds);
List<FunctionalCase> 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<FunctionalCaseCustomField> updateCustomFields(FunctionalCaseChangeRequest functionalCaseChangeRequest, Map<String, List<FunctionalCaseCustomField>> caseCustomFieldMap, String caseId, FunctionalCaseCustomFieldMapper caseCustomFieldMapper) {
List<FunctionalCaseCustomField> total = new ArrayList<>();
List<FunctionalCaseCustomField> functionalCaseCustomFields = caseCustomFieldMap.get(caseId);
List<CaseCustomFieldDTO> customFields = functionalCaseChangeRequest.getCustomFields();
if (CollectionUtils.isNotEmpty(customFields)) {
customFields = customFields.stream().distinct().collect(Collectors.toList());
List<String> fieldIds = customFields.stream().map(CaseCustomFieldDTO::getFieldId).collect(Collectors.toList());
Map<String, FunctionalCaseCustomField> collect = functionalCaseCustomFields.stream().filter(t -> fieldIds.contains(t.getFieldId())).collect(Collectors.toMap(FunctionalCaseCustomField::getFieldId, (item) -> item));
List<CaseCustomFieldDTO> addFields = new ArrayList<>();
List<CaseCustomFieldDTO> updateFields = new ArrayList<>();
customFields.forEach(customField -> {
if (collect.containsKey(customField.getFieldId())) {
updateFields.add(customField);
} else {
addFields.add(customField);
}
});
if (CollectionUtils.isNotEmpty(addFields)) {
List<FunctionalCaseCustomField> functionalCaseCustomFields1 = saveCustomField(caseId, caseCustomFieldMapper, addFields);
total.addAll(functionalCaseCustomFields1);
}
;
if (CollectionUtils.isNotEmpty(updateFields)) {
List<FunctionalCaseCustomField> functionalCaseCustomFields1 = updateField(updateFields, caseId, caseCustomFieldMapper);
total.addAll(functionalCaseCustomFields1);
}
}
return total;
}
@NotNull
private static List<FunctionalCase> getFunctionalCases(FunctionalCaseChangeRequest functionalCaseChangeRequest, List<FunctionalCase> sortList, int j, FunctionalCase functionalCase) {
List<FunctionalCase> finallyCases = new ArrayList<>();
List<FunctionalCase> beforeCases;
List<FunctionalCase> 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<FunctionalCase> 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<FunctionalCaseCustomField> updateField(List<CaseCustomFieldDTO> updateFields, String caseId, FunctionalCaseCustomFieldMapper caseCustomFieldMapper) {
List<FunctionalCaseCustomField> 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<FunctionalCaseCustomField> addCustomFields(FunctionalCaseChangeRequest functionalCaseChangeRequest, String caseId, FunctionalCaseCustomFieldMapper caseCustomFieldMapper) {
List<CaseCustomFieldDTO> customFields = functionalCaseChangeRequest.getCustomFields();
List<FunctionalCaseCustomField> caseCustomFields = new ArrayList<>();
if (CollectionUtils.isNotEmpty(customFields)) {
customFields = customFields.stream().distinct().collect(Collectors.toList());
caseCustomFields = saveCustomField(caseId, caseCustomFieldMapper, customFields);
}
return caseCustomFields;
}
private List<FunctionalCaseCustomField> saveCustomField(String caseId, FunctionalCaseCustomFieldMapper caseCustomFieldMapper, List<CaseCustomFieldDTO> customFields) {
List<FunctionalCaseCustomField> 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<String, List<MinderOptionDTO>> resourceMap = request.getDeleteResourceList().stream().collect(Collectors.groupingBy(MinderOptionDTO::getType));
List<MinderOptionDTO> caseOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.case"));
if (CollectionUtils.isNotEmpty(caseOptionDTOS)) {
List<String> 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<MinderOptionDTO> caseModuleOptionDTOS = resourceMap.get(Translator.get("minder_extra_node.module"));
if (CollectionUtils.isNotEmpty(caseModuleOptionDTOS)) {
List<String> moduleIds = caseModuleOptionDTOS.stream().map(MinderOptionDTO::getId).toList();
checkPermission(moduleIds, FUNCTIONAL_CASE_MODULE, userId);
List<FunctionalCase> 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<FunctionalCaseMindDTO> functionalCaseMindDTOList, List<FunctionalMinderTreeDTO> 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<FunctionalMinderTreeDTO> children = buildChildren(functionalCaseMindDTO);
root.setChildren(children);
root.setData(rootData);
list.add(root);
}
}
} }

View File

@ -132,7 +132,7 @@ public class FunctionalCaseModuleService extends ModuleTreeService {
batchDelLog(functionalCases, deleteModule.getProjectId()); batchDelLog(functionalCases, deleteModule.getProjectId());
List<String> ids = functionalCases.stream().map(FunctionalCase::getId).toList(); List<String> ids = functionalCases.stream().map(FunctionalCase::getId).toList();
User user = userMapper.selectByPrimaryKey(userId); User user = userMapper.selectByPrimaryKey(userId);
functionalCaseNoticeService.batchSendNotice(deleteModule.getProjectId(), ids, user, NoticeConstants.Event.UPDATE); functionalCaseNoticeService.batchSendNotice(deleteModule.getProjectId(), ids, user, NoticeConstants.Event.DELETE);
} }
} }

View File

@ -10,7 +10,6 @@ import io.metersphere.functional.mapper.FunctionalCaseMapper;
import io.metersphere.functional.request.FunctionalCaseAddRequest; import io.metersphere.functional.request.FunctionalCaseAddRequest;
import io.metersphere.functional.request.FunctionalCaseCommentRequest; import io.metersphere.functional.request.FunctionalCaseCommentRequest;
import io.metersphere.functional.request.FunctionalCaseEditRequest; import io.metersphere.functional.request.FunctionalCaseEditRequest;
import io.metersphere.functional.request.FunctionalCaseMinderEditRequest;
import io.metersphere.plan.domain.TestPlan; import io.metersphere.plan.domain.TestPlan;
import io.metersphere.plan.domain.TestPlanExample; import io.metersphere.plan.domain.TestPlanExample;
import io.metersphere.plan.domain.TestPlanFunctionalCase; 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.plan.mapper.TestPlanMapper;
import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.CustomField; import io.metersphere.system.domain.CustomField;
import io.metersphere.system.domain.CustomFieldExample; import io.metersphere.system.domain.CustomFieldExample;
import io.metersphere.system.domain.User; import io.metersphere.system.domain.User;
@ -309,45 +307,6 @@ public class FunctionalCaseNoticeService {
return dtoList; 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<OptionDTO> fields = new ArrayList<>();
FunctionalCaseCustomFieldExample fieldExample = new FunctionalCaseCustomFieldExample();
fieldExample.createCriteria().andCaseIdEqualTo(request.getId());
List<FunctionalCaseCustomField> functionalCaseCustomFields = functionalCaseCustomFieldMapper.selectByExample(fieldExample);
CustomFieldExample example = new CustomFieldExample();
example.createCriteria().andNameEqualTo("functional_priority").andSceneEqualTo("FUNCTIONAL").andScopeIdEqualTo(request.getProjectId());
List<CustomField> 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<String> ids, User user, String event) { public void batchSendNotice(String projectId, List<String> ids, User user, String event) {
int amount = 100;//每次读取的条数 int amount = 100;//每次读取的条数

View File

@ -1,24 +1,21 @@
package io.metersphere.functional.controller; package io.metersphere.functional.controller;
import io.metersphere.functional.domain.*; import io.metersphere.functional.domain.*;
import io.metersphere.functional.dto.CaseCustomFieldDTO;
import io.metersphere.functional.dto.FunctionalCaseStepDTO; import io.metersphere.functional.dto.FunctionalCaseStepDTO;
import io.metersphere.functional.dto.FunctionalMinderTreeDTO; import io.metersphere.functional.dto.FunctionalMinderTreeDTO;
import io.metersphere.functional.dto.MinderOptionDTO; import io.metersphere.functional.dto.MinderOptionDTO;
import io.metersphere.functional.dto.MinderTargetDTO;
import io.metersphere.functional.mapper.FunctionalCaseBlobMapper; import io.metersphere.functional.mapper.FunctionalCaseBlobMapper;
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper; import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
import io.metersphere.functional.mapper.FunctionalCaseMapper; import io.metersphere.functional.mapper.FunctionalCaseMapper;
import io.metersphere.functional.mapper.FunctionalCaseModuleMapper; import io.metersphere.functional.mapper.FunctionalCaseModuleMapper;
import io.metersphere.functional.request.FunctionalCaseMindRequest; import io.metersphere.functional.request.*;
import io.metersphere.functional.request.FunctionalCaseMinderEditRequest;
import io.metersphere.functional.request.FunctionalCaseMinderRemoveRequest;
import io.metersphere.functional.request.FunctionalCaseReviewMindRequest;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Translator; import io.metersphere.sdk.util.Translator;
import io.metersphere.system.base.BaseTest; import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder; import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.dto.sdk.enums.MoveTypeEnum;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
@ -30,29 +27,21 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc @AutoConfigureMockMvc
public class FunctionalCaseMinderControllerTest extends BaseTest { public class FunctionalCaseMinderControllerTest extends BaseTest {
//用例
public static final String FUNCTIONAL_CASE_LIST_URL = "/functional/mind/case/list"; 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"; public static final String FUNCTIONAL_CASE_REVIEW_LIST_URL = "/functional/mind/case/review/list";
@Resource @Resource
private FunctionalCaseBlobMapper functionalCaseBlobMapper; private FunctionalCaseBlobMapper functionalCaseBlobMapper;
@Resource @Resource
@ -117,200 +106,96 @@ public class FunctionalCaseMinderControllerTest extends BaseTest {
@Test @Test
@Order(2) @Order(2)
public void testUpdateCase() throws Exception { public void testEditList() throws Exception {
FunctionalCaseMinderEditRequest request = new FunctionalCaseMinderEditRequest(); FunctionalCaseMinderEditRequest request = new FunctionalCaseMinderEditRequest();
request.setProjectId("project-case-minder-test"); request.setProjectId("project-case-minder-test");
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); request.setVersionId("ffff");
request.setName("TEST_FUNCTIONAL_MINDER_CASE_ID_Change_Name"); List<FunctionalCaseChangeRequest> caseChangeRequests = new ArrayList<>();
request.setType(Translator.get("minder_extra_node.case")); FunctionalCaseChangeRequest caseChangeRequest = new FunctionalCaseChangeRequest();
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); caseChangeRequest.setId("12344");
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); caseChangeRequest.setName("新增用例");
Assertions.assertEquals(functionalCase.getName(), "TEST_FUNCTIONAL_MINDER_CASE_ID_Change_Name"); caseChangeRequest.setModuleId("TEST_MINDER_MODULE_ID_GYQ2");
request.setName("TEST_MINDER_MODULE_ID_GYQ5_Change_Name"); caseChangeRequest.setMoveMode("AFTER");
request.setId("TEST_MINDER_MODULE_ID_GYQ5"); caseChangeRequest.setTargetId("TEST_FUNCTIONAL_MINDER_CASE_ID_3");
request.setType(Translator.get("minder_extra_node.module")); caseChangeRequest.setTemplateId("100001");
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); caseChangeRequest.setType("ADD");
FunctionalCaseModule functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey("TEST_MINDER_MODULE_ID_GYQ5"); caseChangeRequest.setPrerequisite("前置条件");
Assertions.assertEquals(functionalCaseModule.getName(), "TEST_MINDER_MODULE_ID_GYQ5_Change_Name"); caseChangeRequest.setCaseEditType("TEXT");
List<CaseCustomFieldDTO> customFields = new ArrayList<>();
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); CaseCustomFieldDTO customFieldDTO = new CaseCustomFieldDTO();
request.setName("前置哈哈哈"); customFieldDTO.setFieldId("custom_field_minder_gyq_id_3");
request.setType(Translator.get("minder_extra_node.prerequisite")); customFieldDTO.setValue("P0");
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); customFields.add(customFieldDTO);
FunctionalCaseBlob functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); caseChangeRequest.setCustomFields(customFields);
Assertions.assertEquals(new String(functionalCaseBlob.getPrerequisite(), StandardCharsets.UTF_8), "前置哈哈哈"); caseChangeRequests.add(caseChangeRequest);
caseChangeRequest = new FunctionalCaseChangeRequest();
FunctionalCaseBlob functionalCaseBlobInDB = new FunctionalCaseBlob(); caseChangeRequest.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_1");
functionalCaseBlobInDB.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); caseChangeRequest.setName("TEST_MINDER_MODULE_ID_GYQ_更新");
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\":\" 得到的\"}]"; caseChangeRequest.setModuleId("TEST_MINDER_MODULE_ID_GYQ");
functionalCaseBlobInDB.setSteps(steps.getBytes(StandardCharsets.UTF_8)); caseChangeRequest.setTemplateId("100001");
functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlobInDB); caseChangeRequest.setMoveMode("BEFORE");
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); caseChangeRequest.setTargetId("TEST_FUNCTIONAL_MINDER_CASE_ID_2");
request.setName("步骤哈哈哈"); caseChangeRequest.setType("UPDATE");
request.setType(Translator.get("minder_extra_node.steps")); caseChangeRequest.setPrerequisite("前置条件");
request.setPos(1L); caseChangeRequest.setCaseEditType("TEXT");
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); customFields = new ArrayList<>();
functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); customFieldDTO = new CaseCustomFieldDTO();
customFieldDTO.setFieldId("custom_field_minder_gyq_id_3");
List<FunctionalCaseStepDTO> functionalCaseStepDTOS = JSON.parseArray(new String(functionalCaseBlob.getSteps(), StandardCharsets.UTF_8), FunctionalCaseStepDTO.class); customFieldDTO.setValue("P3");
functionalCaseStepDTOS.forEach(t->{ customFields.add(customFieldDTO);
if (t.getNum()==1) { caseChangeRequest.setCustomFields(customFields);
Assertions.assertEquals(t.getDesc(), "步骤哈哈哈"); caseChangeRequests.add(caseChangeRequest);
} request.setUpdateCaseList(caseChangeRequests);
}); List<FunctionalCaseModuleEditRequest> functionalCaseModuleEditRequests = new ArrayList<>();
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest = new FunctionalCaseModuleEditRequest();
request.setName("步骤结果哈哈哈"); functionalCaseModuleEditRequest.setId("uuuId");
request.setType(Translator.get("minder_extra_node.steps_expected_result")); functionalCaseModuleEditRequest.setType("ADD");
request.setPos(1L); functionalCaseModuleEditRequest.setMoveMode("AFTER");
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); functionalCaseModuleEditRequest.setTargetId("TEST_MINDER_MODULE_ID_GYQ8");
functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); functionalCaseModuleEditRequest.setName("新增9");
functionalCaseModuleEditRequest.setParentId("TEST_MINDER_MODULE_ID_GYQ");
functionalCaseStepDTOS = JSON.parseArray(new String(functionalCaseBlob.getSteps(), StandardCharsets.UTF_8), FunctionalCaseStepDTO.class); functionalCaseModuleEditRequests.add(functionalCaseModuleEditRequest);
functionalCaseStepDTOS.forEach(t->{ functionalCaseModuleEditRequest = new FunctionalCaseModuleEditRequest();
if (t.getNum()==1) { functionalCaseModuleEditRequest.setId("TEST_MINDER_MODULE_ID_GYQ7");
Assertions.assertEquals(t.getResult(), "步骤结果哈哈哈"); functionalCaseModuleEditRequest.setType("UPDATE");
} functionalCaseModuleEditRequest.setMoveMode("BEFORE");
}); functionalCaseModuleEditRequest.setTargetId("TEST_MINDER_MODULE_ID_GYQ8");
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); functionalCaseModuleEditRequest.setName("移动7");
request.setName("文本哈哈哈"); functionalCaseModuleEditRequest.setParentId("TEST_MINDER_MODULE_ID_GYQ");
request.setType(Translator.get("minder_extra_node.text_description")); functionalCaseModuleEditRequests.add(functionalCaseModuleEditRequest);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); request.setUpdateModuleList(functionalCaseModuleEditRequests);
functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); List<MinderOptionDTO> deleteResourceList = new ArrayList<>();
Assertions.assertEquals(new String(functionalCaseBlob.getTextDescription(), StandardCharsets.UTF_8), "文本哈哈哈");request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); MinderOptionDTO minderOptionDTO = new MinderOptionDTO();
request.setName("预期哈哈哈"); minderOptionDTO.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_9");
request.setType(Translator.get("minder_extra_node.text_expected_result")); minderOptionDTO.setType(Translator.get("minder_extra_node.case"));
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); deleteResourceList.add(minderOptionDTO);
functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); minderOptionDTO = new MinderOptionDTO();
Assertions.assertEquals(new String(functionalCaseBlob.getExpectedResult(), StandardCharsets.UTF_8), "预期哈哈哈"); minderOptionDTO.setId("TEST_MINDER_MODULE_ID_GYQ9");
request.setName("备注哈哈哈"); minderOptionDTO.setType(Translator.get("minder_extra_node.module"));
request.setType(Translator.get("minder_extra_node.description")); deleteResourceList.add(minderOptionDTO);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request); request.setDeleteResourceList(deleteResourceList);
functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_EDIT_URL, request);
Assertions.assertEquals(new String(functionalCaseBlob.getDescription(), StandardCharsets.UTF_8), "备注哈哈哈"); FunctionalCaseExample functionalCaseExample = new FunctionalCaseExample();
functionalCaseExample.createCriteria().andNameEqualTo("新增用例");
List<FunctionalCase> 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<FunctionalCaseModule> functionalCaseModules = functionalCaseModuleMapper.selectByExample(functionalCaseModuleExample);
Assertions.assertTrue(CollectionUtils.isNotEmpty(functionalCaseModules));
Assertions.assertTrue(functionalCaseModules.get(0).getPos()>0L);
request = new FunctionalCaseMinderEditRequest(); request = new FunctionalCaseMinderEditRequest();
request.setProjectId("project-case-minder-test"); request.setProjectId("project-case-minder-test");
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6"); request.setVersionId("ffff");
request.setPriority("P0"); this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_EDIT_URL, request);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_PRIORITY_URL, request); functionalCases = functionalCaseMapper.selectByExample(functionalCaseExample);
FunctionalCaseCustomFieldExample customField = new FunctionalCaseCustomFieldExample(); Assertions.assertTrue(CollectionUtils.isNotEmpty(functionalCases));
customField.createCriteria().andCaseIdEqualTo(request.getId()).andFieldIdEqualTo("custom_field_minder_gyq_id_3");
List<FunctionalCaseCustomField> 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);
} }
@Test @Test
@Order(3) @Order(3)
public void testDeleteCase() throws Exception{
List<MinderOptionDTO> 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<MinderOptionDTO> 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 { public void testGetCaseReviewList() throws Exception {
FunctionalCaseReviewMindRequest request = new FunctionalCaseReviewMindRequest(); FunctionalCaseReviewMindRequest request = new FunctionalCaseReviewMindRequest();
request.setProjectId("project-case-minder-test"); request.setProjectId("project-case-minder-test");

View File

@ -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_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_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_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_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_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');
;