refactor(功能用例): 用例变更历史保存

This commit is contained in:
WangXu10 2023-12-04 10:58:27 +08:00 committed by Craftsman
parent cdd8db044c
commit e79f47611e
5 changed files with 110 additions and 17 deletions

View File

@ -0,0 +1,36 @@
package io.metersphere.functional.dto;
import io.metersphere.functional.domain.FunctionalCase;
import io.metersphere.functional.domain.FunctionalCaseAttachment;
import io.metersphere.functional.domain.FunctionalCaseBlob;
import io.metersphere.functional.domain.FunctionalCaseCustomField;
import io.metersphere.project.domain.FileAssociation;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
@Data
public class FunctionalCaseHistoryLogDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private FunctionalCase functionalCase;
private FunctionalCaseBlob functionalCaseBlob;
private List<FunctionalCaseCustomField> customFields;
private List<FunctionalCaseAttachment> caseAttachments;
private List<FileAssociation> fileAssociationList;
public FunctionalCaseHistoryLogDTO(FunctionalCase functionalCase, FunctionalCaseBlob functionalCaseBlob, List<FunctionalCaseCustomField> customFields, List<FunctionalCaseAttachment> caseAttachments, List<FileAssociation> fileAssociationList) {
this.functionalCase = functionalCase;
this.functionalCaseBlob = functionalCaseBlob;
this.customFields = customFields;
this.caseAttachments = caseAttachments;
this.fileAssociationList = fileAssociationList;
}
}

View File

@ -1,18 +1,18 @@
package io.metersphere.functional.service; package io.metersphere.functional.service;
import io.metersphere.functional.domain.FunctionalCase; import io.metersphere.functional.domain.*;
import io.metersphere.functional.domain.FunctionalCaseDemand;
import io.metersphere.functional.dto.BaseFunctionalCaseBatchDTO; import io.metersphere.functional.dto.BaseFunctionalCaseBatchDTO;
import io.metersphere.functional.mapper.ExtFunctionalCaseMapper; import io.metersphere.functional.dto.FunctionalCaseHistoryLogDTO;
import io.metersphere.functional.mapper.FunctionalCaseDemandMapper; import io.metersphere.functional.mapper.*;
import io.metersphere.functional.mapper.FunctionalCaseMapper;
import io.metersphere.functional.request.*; import io.metersphere.functional.request.*;
import io.metersphere.project.domain.FileAssociation;
import io.metersphere.project.domain.FileAssociationExample;
import io.metersphere.project.mapper.FileAssociationMapper;
import io.metersphere.sdk.constants.HttpMethodConstants; import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
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.log.service.OperationLogService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -31,15 +31,20 @@ public class FunctionalCaseLogService {
@Resource @Resource
private FunctionalCaseMapper functionalCaseMapper; private FunctionalCaseMapper functionalCaseMapper;
@Resource
private OperationLogService operationLogService;
@Resource @Resource
private FunctionalCaseService functionalCaseService; private FunctionalCaseService functionalCaseService;
@Resource @Resource
private ExtFunctionalCaseMapper extFunctionalCaseMapper; private ExtFunctionalCaseMapper extFunctionalCaseMapper;
@Resource @Resource
private FunctionalCaseDemandMapper functionalCaseDemandMapper; private FunctionalCaseDemandMapper functionalCaseDemandMapper;
@Resource
private FunctionalCaseBlobMapper functionalCaseBlobMapper;
@Resource
private FunctionalCaseCustomFieldMapper functionalCaseCustomFieldMapper;
@Resource
private FunctionalCaseAttachmentMapper functionalCaseAttachmentMapper;
@Resource
private FileAssociationMapper fileAssociationMapper;
//TODO 日志(需要修改) //TODO 日志(需要修改)
@ -60,10 +65,10 @@ public class FunctionalCaseLogService {
OperationLogType.ADD.name(), OperationLogType.ADD.name(),
OperationLogModule.FUNCTIONAL_CASE, OperationLogModule.FUNCTIONAL_CASE,
requests.getName()); requests.getName());
dto.setHistory(true);
dto.setPath("/functional/case/add"); dto.setPath("/functional/case/add");
dto.setMethod(HttpMethodConstants.POST.name()); dto.setMethod(HttpMethodConstants.POST.name());
dto.setOriginalValue(JSON.toJSONBytes(requests)); dto.setModifiedValue(JSON.toJSONBytes(requests));
return dto; return dto;
} }
@ -76,7 +81,7 @@ public class FunctionalCaseLogService {
* @return * @return
*/ */
public LogDTO updateFunctionalCaseLog(FunctionalCaseEditRequest requests, List<MultipartFile> files) { public LogDTO updateFunctionalCaseLog(FunctionalCaseEditRequest requests, List<MultipartFile> files) {
//TODO 获取原值 FunctionalCaseHistoryLogDTO historyLogDTO = getOriginalValue(requests.getId());
LogDTO dto = new LogDTO( LogDTO dto = new LogDTO(
requests.getProjectId(), requests.getProjectId(),
null, null,
@ -85,13 +90,37 @@ public class FunctionalCaseLogService {
OperationLogType.UPDATE.name(), OperationLogType.UPDATE.name(),
OperationLogModule.FUNCTIONAL_CASE, OperationLogModule.FUNCTIONAL_CASE,
requests.getName()); requests.getName());
dto.setHistory(true);
dto.setPath("/functional/case/update"); dto.setPath("/functional/case/update");
dto.setMethod(HttpMethodConstants.POST.name()); dto.setMethod(HttpMethodConstants.POST.name());
dto.setModifiedValue(JSON.toJSONBytes(requests)); dto.setModifiedValue(JSON.toJSONBytes(requests));
dto.setOriginalValue(JSON.toJSONBytes(historyLogDTO));
return dto; return dto;
} }
private FunctionalCaseHistoryLogDTO getOriginalValue(String id) {
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(id);
FunctionalCaseBlob functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey(id);
//自定义字段
FunctionalCaseCustomFieldExample fieldExample = new FunctionalCaseCustomFieldExample();
fieldExample.createCriteria().andCaseIdEqualTo(id);
List<FunctionalCaseCustomField> customFields = functionalCaseCustomFieldMapper.selectByExample(fieldExample);
//附件 本地 + 文件库
FunctionalCaseAttachmentExample attachmentExample = new FunctionalCaseAttachmentExample();
attachmentExample.createCriteria().andCaseIdEqualTo(id);
List<FunctionalCaseAttachment> caseAttachments = functionalCaseAttachmentMapper.selectByExample(attachmentExample);
FileAssociationExample example = new FileAssociationExample();
example.createCriteria().andSourceIdEqualTo(id);
List<FileAssociation> fileAssociationList = fileAssociationMapper.selectByExample(example);
FunctionalCaseHistoryLogDTO historyLogDTO = new FunctionalCaseHistoryLogDTO(functionalCase, functionalCaseBlob, customFields, caseAttachments, fileAssociationList);
return historyLogDTO;
}
/** /**
* 删除用例 日志 * 删除用例 日志
@ -260,6 +289,7 @@ public class FunctionalCaseLogService {
if (CollectionUtils.isNotEmpty(ids)) { if (CollectionUtils.isNotEmpty(ids)) {
List<FunctionalCase> functionalCases = extFunctionalCaseMapper.getLogInfo(ids, false); List<FunctionalCase> functionalCases = extFunctionalCaseMapper.getLogInfo(ids, false);
functionalCases.forEach(functionalCase -> { functionalCases.forEach(functionalCase -> {
FunctionalCaseHistoryLogDTO historyLogDTO = getOriginalValue(functionalCase.getId());
LogDTO dto = new LogDTO( LogDTO dto = new LogDTO(
functionalCase.getProjectId(), functionalCase.getProjectId(),
null, null,
@ -268,10 +298,10 @@ public class FunctionalCaseLogService {
OperationLogType.DELETE.name(), OperationLogType.DELETE.name(),
OperationLogModule.FUNCTIONAL_CASE, OperationLogModule.FUNCTIONAL_CASE,
functionalCase.getName()); functionalCase.getName());
dto.setHistory(true);
dto.setPath("/functional/case/batch/edit"); dto.setPath("/functional/case/batch/edit");
dto.setMethod(HttpMethodConstants.POST.name()); dto.setMethod(HttpMethodConstants.POST.name());
dto.setOriginalValue(JSON.toJSONBytes(functionalCase)); dto.setOriginalValue(JSON.toJSONBytes(historyLogDTO));
dtoList.add(dto); dtoList.add(dto);
}); });
} }

View File

@ -14,6 +14,9 @@ public class LogDTO extends OperationLog {
@Schema(description = "变更后内容") @Schema(description = "变更后内容")
private byte[] modifiedValue; private byte[] modifiedValue;
@Schema(description = "是否需要历史记录")
private Boolean history = false;
public LogDTO() { public LogDTO() {
} }
public LogDTO(String projectId, String organizationId, String sourceId, String createUser, String type, String module, String content) { public LogDTO(String projectId, String organizationId, String sourceId, String createUser, String type, String module, String content) {

View File

@ -82,7 +82,9 @@ public class OperationLogService {
} }
log.setContent(subStrContent(log.getContent())); log.setContent(subStrContent(log.getContent()));
operationLogMapper.insert(log); operationLogMapper.insert(log);
if (log.getHistory()) {
operationHistoryMapper.insert(getHistory(log)); operationHistoryMapper.insert(getHistory(log));
}
operationLogBlobMapper.insert(getBlob(log)); operationLogBlobMapper.insert(getBlob(log));
} }
@ -127,7 +129,9 @@ public class OperationLogService {
item.setCreateTime(currentTimeMillis); item.setCreateTime(currentTimeMillis);
// 限制长度 // 限制长度
operationLogMapper.insert(item); operationLogMapper.insert(item);
if (item.getHistory()) {
operationHistoryMapper.insert(getHistory(item)); operationHistoryMapper.insert(getHistory(item));
}
logBlobMapper.insert(getBlob(item)); logBlobMapper.insert(getBlob(item));
}); });
} }

View File

@ -2,8 +2,11 @@ package io.metersphere.system.controller;
import io.metersphere.system.base.BaseTest; import io.metersphere.system.base.BaseTest;
import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.system.log.dto.LogDTO;
import io.metersphere.system.log.service.OperationLogService;
import io.metersphere.system.log.vo.OperationLogRequest; import io.metersphere.system.log.vo.OperationLogRequest;
import io.metersphere.system.controller.param.OperationLogRequestDefinition; import io.metersphere.system.controller.param.OperationLogRequestDefinition;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -14,7 +17,9 @@ import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultActions;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -34,6 +39,8 @@ public class OperationLogControllerTests extends BaseTest {
public static final String ORGANIZATION = "ORGANIZATION"; public static final String ORGANIZATION = "ORGANIZATION";
public static final String PROJECT = "PROJECT"; public static final String PROJECT = "PROJECT";
@Resource
private OperationLogService opreationLogService;
/** /**
* 系统级别 查询 用例 * 系统级别 查询 用例
@ -167,4 +174,17 @@ public class OperationLogControllerTests extends BaseTest {
} }
@Test
@Order(4)
public void testLog() throws Exception {
//增加覆蓋率
LogDTO logDTO = new LogDTO(DEFAULT_PROJECT_ID,DEFAULT_ORGANIZATION_ID,"test_source_id","admin",DEFAULT_ADD,"SYSTEM","測試");
logDTO.setHistory(true);
logDTO.setMethod("test");
opreationLogService.add(logDTO);
List<LogDTO> logDTOList = new ArrayList<>();
logDTOList.add(logDTO);
opreationLogService.batchAdd(logDTOList);
}
} }