refactor(测试计划): 优化生成报告逻辑

This commit is contained in:
song-cc-rock 2024-08-08 11:28:41 +08:00 committed by Craftsman
parent 495f4c9463
commit 37ae81423c
3 changed files with 180 additions and 123 deletions

View File

@ -22,114 +22,118 @@ import java.util.List;
@Service @Service
public class TestPlanReportLogService { public class TestPlanReportLogService {
@Resource @Resource
private ProjectMapper projectMapper; private ProjectMapper projectMapper;
@Resource @Resource
private OperationLogService operationLogService; private OperationLogService operationLogService;
@Resource @Resource
private ExtTestPlanReportMapper extTestPlanReportMapper; private ExtTestPlanReportMapper extTestPlanReportMapper;
@Resource @Resource
private TestPlanReportMapper testPlanReportMapper; private TestPlanReportMapper testPlanReportMapper;
@SuppressWarnings("unused")
public LogDTO deleteLog(String id) {
TestPlanReport report = testPlanReportMapper.selectByPrimaryKey(id);
Project project = projectMapper.selectByPrimaryKey(report.getProjectId());
LogDTO dto = new LogDTO(
report.getProjectId(),
project.getOrganizationId(),
report.getId(),
null,
OperationLogType.DELETE.name(),
OperationLogModule.TEST_PLAN_REPORT,
report.getName());
public LogDTO deleteLog(String id) { dto.setPath(OperationLogAspect.getPath());
TestPlanReport report = testPlanReportMapper.selectByPrimaryKey(id); dto.setMethod(HttpMethodConstants.GET.name());
Project project = projectMapper.selectByPrimaryKey(report.getProjectId()); dto.setOriginalValue(JSON.toJSONBytes(report));
LogDTO dto = new LogDTO( return dto;
report.getProjectId(), }
project.getOrganizationId(),
report.getId(),
null,
OperationLogType.DELETE.name(),
OperationLogModule.TEST_PLAN_REPORT,
report.getName());
dto.setPath(OperationLogAspect.getPath()); @SuppressWarnings("unused")
dto.setMethod(HttpMethodConstants.GET.name()); public LogDTO updateLog(String id) {
dto.setOriginalValue(JSON.toJSONBytes(report)); TestPlanReport report = testPlanReportMapper.selectByPrimaryKey(id);
return dto; Project project = projectMapper.selectByPrimaryKey(report.getProjectId());
} LogDTO dto = new LogDTO(
report.getProjectId(),
project.getOrganizationId(),
report.getId(),
null,
OperationLogType.UPDATE.name(),
OperationLogModule.TEST_PLAN_REPORT,
report.getName());
public LogDTO updateLog(String id) { dto.setPath(OperationLogAspect.getPath());
TestPlanReport report = testPlanReportMapper.selectByPrimaryKey(id); dto.setMethod(HttpMethodConstants.GET.name());
Project project = projectMapper.selectByPrimaryKey(report.getProjectId()); dto.setOriginalValue(JSON.toJSONBytes(report));
LogDTO dto = new LogDTO( return dto;
report.getProjectId(), }
project.getOrganizationId(),
report.getId(),
null,
OperationLogType.UPDATE.name(),
OperationLogModule.TEST_PLAN_REPORT,
report.getName());
dto.setPath(OperationLogAspect.getPath()); @SuppressWarnings("unused")
dto.setMethod(HttpMethodConstants.GET.name()); public LogDTO renameLog(String id, Object name) {
dto.setOriginalValue(JSON.toJSONBytes(report)); TestPlanReport report = testPlanReportMapper.selectByPrimaryKey(id);
return dto; Project project = projectMapper.selectByPrimaryKey(report.getProjectId());
} LogDTO dto = new LogDTO(
report.getProjectId(),
project.getOrganizationId(),
report.getId(),
null,
OperationLogType.UPDATE.name(),
OperationLogModule.TEST_PLAN_REPORT,
name.toString());
public LogDTO renameLog(String id, Object name) { dto.setPath(OperationLogAspect.getPath());
TestPlanReport report = testPlanReportMapper.selectByPrimaryKey(id); dto.setMethod(HttpMethodConstants.GET.name());
Project project = projectMapper.selectByPrimaryKey(report.getProjectId()); dto.setOriginalValue(JSON.toJSONBytes(report));
LogDTO dto = new LogDTO( return dto;
report.getProjectId(), }
project.getOrganizationId(),
report.getId(),
null,
OperationLogType.UPDATE.name(),
OperationLogModule.TEST_PLAN_REPORT,
name.toString());
dto.setPath(OperationLogAspect.getPath()); @SuppressWarnings("unused")
dto.setMethod(HttpMethodConstants.GET.name()); public LogDTO updateDetailLog(TestPlanReportDetailEditRequest request) {
dto.setOriginalValue(JSON.toJSONBytes(report)); return updateLog(request.getId());
return dto; }
}
public LogDTO updateDetailLog(TestPlanReportDetailEditRequest request) { public void batchDeleteLog(List<String> ids, String userId, String projectId) {
return updateLog(request.getId()); Project project = projectMapper.selectByPrimaryKey(projectId);
} List<TestPlanReport> reports = extTestPlanReportMapper.selectReportByIds(ids);
List<LogDTO> logs = new ArrayList<>();
reports.forEach(report -> {
LogDTO dto = new LogDTO(
projectId,
project.getOrganizationId(),
report.getId(),
userId,
OperationLogType.DELETE.name(),
OperationLogModule.TEST_PLAN_REPORT,
report.getName());
public void batchDeleteLog(List<String> ids, String userId, String projectId) { dto.setPath(OperationLogAspect.getPath());
Project project = projectMapper.selectByPrimaryKey(projectId); dto.setMethod(HttpMethodConstants.POST.name());
List<TestPlanReport> reports = extTestPlanReportMapper.selectReportByIds(ids); dto.setOriginalValue(JSON.toJSONBytes(report));
List<LogDTO> logs = new ArrayList<>(); logs.add(dto);
reports.forEach(report -> { });
LogDTO dto = new LogDTO( operationLogService.batchAdd(logs);
projectId, }
project.getOrganizationId(),
report.getId(),
userId,
OperationLogType.DELETE.name(),
OperationLogModule.TEST_PLAN_REPORT,
report.getName());
dto.setPath(OperationLogAspect.getPath()); /**
dto.setMethod(HttpMethodConstants.POST.name()); * 生成报告日志
dto.setOriginalValue(JSON.toJSONBytes(report)); *
logs.add(dto); * @param report 报告
}); * @param userId 用户ID
operationLogService.batchAdd(logs); * @param projectId 项目ID
} */
public void addLog(TestPlanReport report, String userId, String projectId) {
/** Project project = projectMapper.selectByPrimaryKey(projectId);
* 生成报告日志 LogDTO log = new LogDTO(
* @param report 报告 projectId,
* @param userId 用户ID project.getOrganizationId(),
* @param projectId 项目ID report.getId(),
*/ userId,
public void addLog(TestPlanReport report, String userId, String projectId) { OperationLogType.ADD.name(),
Project project = projectMapper.selectByPrimaryKey(projectId); report.getIntegrated() ? OperationLogModule.TEST_PLAN_GROUP_REPORT : OperationLogModule.TEST_PLAN_REPORT,
LogDTO log = new LogDTO( report.getName());
projectId, log.setMethod(HttpMethodConstants.POST.name());
project.getOrganizationId(), log.setOriginalValue(JSON.toJSONBytes(report));
report.getId(), operationLogService.add(log);
userId, }
OperationLogType.ADD.name(),
report.getIntegrated() ? OperationLogModule.TEST_PLAN_GROUP_REPORT : OperationLogModule.TEST_PLAN_REPORT,
report.getName());
log.setMethod(HttpMethodConstants.POST.name());
log.setOriginalValue(JSON.toJSONBytes(report));
operationLogService.add(log);
}
} }

View File

@ -1,5 +1,6 @@
package io.metersphere.plan.service; package io.metersphere.plan.service;
import com.google.common.collect.Maps;
import io.metersphere.bug.dto.response.BugDTO; import io.metersphere.bug.dto.response.BugDTO;
import io.metersphere.bug.service.BugCommonService; import io.metersphere.bug.service.BugCommonService;
import io.metersphere.plan.constants.AssociateCaseType; import io.metersphere.plan.constants.AssociateCaseType;
@ -107,6 +108,8 @@ public class TestPlanReportService {
@Resource @Resource
private CommonFileService commonFileService; private CommonFileService commonFileService;
private static final int MAX_REPORT_NAME_LENGTH = 300;
/** /**
* 分页查询报告列表 * 分页查询报告列表
* *
@ -128,7 +131,7 @@ public class TestPlanReportService {
* 报告重命名 * 报告重命名
*/ */
public void rename(String id, String name) { public void rename(String id, String name) {
if (name.length() > 300) { if (name.length() > MAX_REPORT_NAME_LENGTH) {
throw new MSException(Translator.get("test_plan_report_name_length_range")); throw new MSException(Translator.get("test_plan_report_name_length_range"));
} }
TestPlanReport report = checkReport(id); TestPlanReport report = checkReport(id);
@ -197,7 +200,7 @@ public class TestPlanReportService {
Map<String, TestPlanReport> reportMap = testPlanReports.stream().collect(Collectors.toMap(TestPlanReport::getId, r -> r)); Map<String, TestPlanReport> reportMap = testPlanReports.stream().collect(Collectors.toMap(TestPlanReport::getId, r -> r));
List<String> reportIdList = testPlanReports.stream().map(TestPlanReport::getId).toList(); List<String> reportIdList = testPlanReports.stream().map(TestPlanReport::getId).toList();
reportIdList.forEach(reportId -> { reportIdList.forEach(reportId -> {
/** /*
* 独立计划直接删除; 子计划的报告删除时, 保留报告记录 * 独立计划直接删除; 子计划的报告删除时, 保留报告记录
*/ */
TestPlanReport report = reportMap.get(reportId); TestPlanReport report = reportMap.get(reportId);
@ -216,6 +219,11 @@ public class TestPlanReportService {
} }
} }
/**
* 删除报告内容
*
* @param reportIdList 报告ID集合
*/
private void deleteTestPlanReportBlobs(List<String> reportIdList) { private void deleteTestPlanReportBlobs(List<String> reportIdList) {
TestPlanReportSummaryExample summaryExample = new TestPlanReportSummaryExample(); TestPlanReportSummaryExample summaryExample = new TestPlanReportSummaryExample();
summaryExample.createCriteria().andTestPlanReportIdIn(reportIdList); summaryExample.createCriteria().andTestPlanReportIdIn(reportIdList);
@ -301,8 +309,17 @@ public class TestPlanReportService {
return genReport(prepareReportId, request, false, currentUser, null); return genReport(prepareReportId, request, false, currentUser, null);
} }
/**
* 生成报告
*
* @param prepareReportId 预生成报告ID
* @param request 请求参数
* @param manual 是否手动生成
* @param currentUser 当前用户
* @param manualReportName 手动生成报告名称
*/
public Map<String, String> genReport(String prepareReportId, TestPlanReportGenRequest request, boolean manual, String currentUser, String manualReportName) { public Map<String, String> genReport(String prepareReportId, TestPlanReportGenRequest request, boolean manual, String currentUser, String manualReportName) {
Map<String, String> preReportMap = new HashMap<>(); Map<String, String> preReportMap = Maps.newHashMapWithExpectedSize(8);
TestPlanReportManualParam reportManualParam = TestPlanReportManualParam.builder().manualName(manualReportName).targetId(request.getTestPlanId()).build(); TestPlanReportManualParam reportManualParam = TestPlanReportManualParam.builder().manualName(manualReportName).targetId(request.getTestPlanId()).build();
try { try {
// 所有计划 // 所有计划
@ -422,11 +439,7 @@ public class TestPlanReportService {
Map<String, String> casePriorityMap = options.stream().collect(Collectors.toMap(SelectOption::getValue, SelectOption::getText)); Map<String, String> casePriorityMap = options.stream().collect(Collectors.toMap(SelectOption::getValue, SelectOption::getText));
// 用例模块 // 用例模块
List<String> moduleIds = reportFunctionCases.stream().map(TestPlanReportFunctionCase::getFunctionCaseModule).filter(Objects::nonNull).toList(); List<String> moduleIds = reportFunctionCases.stream().map(TestPlanReportFunctionCase::getFunctionCaseModule).filter(Objects::nonNull).toList();
Map<String, String> moduleMap = new HashMap<>(); Map<String, String> moduleMap = getModuleMapByIds(moduleIds, CaseType.FUNCTIONAL_CASE.getKey());
if (CollectionUtils.isNotEmpty(moduleIds)) {
List<TestPlanBaseModule> modules = extTestPlanReportFunctionalCaseMapper.getPlanExecuteCaseModules(moduleIds);
moduleMap = modules.stream().collect(Collectors.toMap(TestPlanBaseModule::getId, TestPlanBaseModule::getName));
}
// 关联的功能用例最新一次执行历史 // 关联的功能用例最新一次执行历史
List<String> relateIds = reportFunctionCases.stream().map(TestPlanReportFunctionCase::getTestPlanFunctionCaseId).toList(); List<String> relateIds = reportFunctionCases.stream().map(TestPlanReportFunctionCase::getTestPlanFunctionCaseId).toList();
TestPlanCaseExecuteHistoryExample example = new TestPlanCaseExecuteHistoryExample(); TestPlanCaseExecuteHistoryExample example = new TestPlanCaseExecuteHistoryExample();
@ -438,7 +451,9 @@ public class TestPlanReportService {
reportFunctionalCase.setId(IDGenerator.nextStr()); reportFunctionalCase.setId(IDGenerator.nextStr());
reportFunctionalCase.setTestPlanReportId(report.getId()); reportFunctionalCase.setTestPlanReportId(report.getId());
reportFunctionalCase.setTestPlanName(genParam.getTestPlanName()); reportFunctionalCase.setTestPlanName(genParam.getTestPlanName());
reportFunctionalCase.setFunctionCaseModule(moduleMap.getOrDefault(reportFunctionalCase.getFunctionCaseModule(), reportFunctionalCase.getFunctionCaseModule())); if (reportFunctionalCase.getFunctionCaseModule() != null) {
reportFunctionalCase.setFunctionCaseModule(moduleMap.getOrDefault(reportFunctionalCase.getFunctionCaseModule(), reportFunctionalCase.getFunctionCaseModule()));
}
reportFunctionalCase.setFunctionCasePriority(casePriorityMap.get(reportFunctionalCase.getFunctionCaseId())); reportFunctionalCase.setFunctionCasePriority(casePriorityMap.get(reportFunctionalCase.getFunctionCaseId()));
List<TestPlanCaseExecuteHistory> hisList = functionalExecMap.get(reportFunctionalCase.getTestPlanFunctionCaseId()); List<TestPlanCaseExecuteHistory> hisList = functionalExecMap.get(reportFunctionalCase.getTestPlanFunctionCaseId());
if (CollectionUtils.isNotEmpty(hisList)) { if (CollectionUtils.isNotEmpty(hisList)) {
@ -459,17 +474,15 @@ public class TestPlanReportService {
if (CollectionUtils.isNotEmpty(reportApiCases)) { if (CollectionUtils.isNotEmpty(reportApiCases)) {
// 用例模块 // 用例模块
List<String> moduleIds = reportApiCases.stream().map(TestPlanReportApiCase::getApiCaseModule).filter(Objects::nonNull).toList(); List<String> moduleIds = reportApiCases.stream().map(TestPlanReportApiCase::getApiCaseModule).filter(Objects::nonNull).toList();
Map<String, String> moduleMap = new HashMap<>(); Map<String, String> moduleMap = getModuleMapByIds(moduleIds, CaseType.API_CASE.getKey());
if (CollectionUtils.isNotEmpty(moduleIds)) {
List<TestPlanBaseModule> modules = extTestPlanReportApiCaseMapper.getPlanExecuteCaseModules(moduleIds);
moduleMap = modules.stream().collect(Collectors.toMap(TestPlanBaseModule::getId, TestPlanBaseModule::getName));
}
for (TestPlanReportApiCase reportApiCase : reportApiCases) { for (TestPlanReportApiCase reportApiCase : reportApiCases) {
reportApiCase.setId(IDGenerator.nextStr()); reportApiCase.setId(IDGenerator.nextStr());
reportApiCase.setTestPlanReportId(report.getId()); reportApiCase.setTestPlanReportId(report.getId());
reportApiCase.setTestPlanName(genParam.getTestPlanName()); reportApiCase.setTestPlanName(genParam.getTestPlanName());
reportApiCase.setApiCaseModule(moduleMap.getOrDefault(reportApiCase.getApiCaseModule(), reportApiCase.getApiCaseModule())); if (reportApiCase.getApiCaseModule() != null) {
reportApiCase.setApiCaseModule(moduleMap.getOrDefault(reportApiCase.getApiCaseModule(), reportApiCase.getApiCaseModule()));
}
// 根据不超过数据库字段最大长度压缩模块名 // 根据不超过数据库字段最大长度压缩模块名
reportApiCase.setApiCaseModule(ServiceUtils.compressName(reportApiCase.getApiCaseModule(), 450)); reportApiCase.setApiCaseModule(ServiceUtils.compressName(reportApiCase.getApiCaseModule(), 450));
if (!genParam.getUseManual()) { if (!genParam.getUseManual()) {
@ -489,17 +502,15 @@ public class TestPlanReportService {
if (CollectionUtils.isNotEmpty(reportApiScenarios)) { if (CollectionUtils.isNotEmpty(reportApiScenarios)) {
// 用例模块 // 用例模块
List<String> moduleIds = reportApiScenarios.stream().map(TestPlanReportApiScenario::getApiScenarioModule).filter(Objects::nonNull).toList(); List<String> moduleIds = reportApiScenarios.stream().map(TestPlanReportApiScenario::getApiScenarioModule).filter(Objects::nonNull).toList();
Map<String, String> moduleMap = new HashMap<>(); Map<String, String> moduleMap = getModuleMapByIds(moduleIds, CaseType.SCENARIO_CASE.getKey());
if (CollectionUtils.isNotEmpty(moduleIds)) {
List<TestPlanBaseModule> modules = extTestPlanReportApiScenarioMapper.getPlanExecuteCaseModules(moduleIds);
moduleMap = modules.stream().collect(Collectors.toMap(TestPlanBaseModule::getId, TestPlanBaseModule::getName));
}
for (TestPlanReportApiScenario reportApiScenario : reportApiScenarios) { for (TestPlanReportApiScenario reportApiScenario : reportApiScenarios) {
reportApiScenario.setId(IDGenerator.nextStr()); reportApiScenario.setId(IDGenerator.nextStr());
reportApiScenario.setTestPlanReportId(report.getId()); reportApiScenario.setTestPlanReportId(report.getId());
reportApiScenario.setTestPlanName(genParam.getTestPlanName()); reportApiScenario.setTestPlanName(genParam.getTestPlanName());
reportApiScenario.setApiScenarioModule(moduleMap.getOrDefault(reportApiScenario.getApiScenarioModule(), reportApiScenario.getApiScenarioModule())); if (reportApiScenario.getApiScenarioModule() != null) {
reportApiScenario.setApiScenarioModule(moduleMap.getOrDefault(reportApiScenario.getApiScenarioModule(), reportApiScenario.getApiScenarioModule()));
}
// 根据不超过数据库字段最大长度压缩模块名 // 根据不超过数据库字段最大长度压缩模块名
reportApiScenario.setApiScenarioModule(ServiceUtils.compressName(reportApiScenario.getApiScenarioModule(), 450)); reportApiScenario.setApiScenarioModule(ServiceUtils.compressName(reportApiScenario.getApiScenarioModule(), 450));
if (!genParam.getUseManual()) { if (!genParam.getUseManual()) {
@ -1097,10 +1108,24 @@ public class TestPlanReportService {
return userOptions.stream().collect(Collectors.toMap(OptionDTO::getId, OptionDTO::getName)); return userOptions.stream().collect(Collectors.toMap(OptionDTO::getId, OptionDTO::getName));
} }
/**
* 计划报告列表
*
* @param request 请求参数
* @return 报告列表
*/
public List<TestPlanReportDetailResponse> planReportList(TestPlanReportDetailPageRequest request) { public List<TestPlanReportDetailResponse> planReportList(TestPlanReportDetailPageRequest request) {
return extTestPlanReportMapper.getPlanReportListById(request); return extTestPlanReportMapper.getPlanReportListById(request);
} }
/**
* 预览富文本文件
*
* @param projectId 项目ID
* @param fileId 文件ID
* @param compressed 是否压缩
* @return 富文本内容
*/
public ResponseEntity<byte[]> previewMd(String projectId, String fileId, boolean compressed) { public ResponseEntity<byte[]> previewMd(String projectId, String fileId, boolean compressed) {
byte[] bytes; byte[] bytes;
String fileName; String fileName;
@ -1128,6 +1153,11 @@ public class TestPlanReportService {
.body(bytes); .body(bytes);
} }
/**
* 更新执行时间和状态
*
* @param prepareReportId 预生成报告ID
*/
public void updateExecuteTimeAndStatus(String prepareReportId) { public void updateExecuteTimeAndStatus(String prepareReportId) {
extTestPlanReportMapper.batchUpdateExecuteTimeAndStatus(System.currentTimeMillis(), Collections.singletonList(prepareReportId)); extTestPlanReportMapper.batchUpdateExecuteTimeAndStatus(System.currentTimeMillis(), Collections.singletonList(prepareReportId));
} }
@ -1148,4 +1178,26 @@ public class TestPlanReportService {
fileRequest.setStorage(StorageType.MINIO.name()); fileRequest.setStorage(StorageType.MINIO.name());
return fileRequest; return fileRequest;
} }
/**
* 获取模块集合
*
* @param moduleIds 模块ID集合
* @param caseType 用例类型
* @return 模块集合
*/
private Map<String, String> getModuleMapByIds(List<String> moduleIds, String caseType) {
if (CollectionUtils.isEmpty(moduleIds)) {
return Map.of();
}
List<TestPlanBaseModule> modules = new ArrayList<>();
if (StringUtils.equals(caseType, CaseType.FUNCTIONAL_CASE.getKey())) {
modules = extTestPlanReportFunctionalCaseMapper.getPlanExecuteCaseModules(moduleIds);
} else if (StringUtils.equals(caseType, CaseType.API_CASE.getKey())) {
modules = extTestPlanReportApiCaseMapper.getPlanExecuteCaseModules(moduleIds);
} else if (StringUtils.equals(caseType, CaseType.SCENARIO_CASE.getKey())) {
modules = extTestPlanReportApiScenarioMapper.getPlanExecuteCaseModules(moduleIds);
}
return modules.stream().collect(Collectors.toMap(TestPlanBaseModule::getId, TestPlanBaseModule::getName));
}
} }

View File

@ -420,7 +420,8 @@ public class TestPlanReportControllerTests extends BaseTest {
//测试清除方法 //测试清除方法
CleanupTestPlanReportServiceImpl cleanupTestPlanReportService = CommonBeanFactory.getBean(CleanupTestPlanReportServiceImpl.class); CleanupTestPlanReportServiceImpl cleanupTestPlanReportService = CommonBeanFactory.getBean(CleanupTestPlanReportServiceImpl.class);
cleanupTestPlanReportService.cleanReport(new HashMap<>() {{ assert cleanupTestPlanReportService != null;
cleanupTestPlanReportService.cleanReport(new HashMap<>() {{
this.put(ProjectApplicationType.TEST_PLAN.TEST_PLAN_CLEAN_REPORT.name(), "3M"); this.put(ProjectApplicationType.TEST_PLAN.TEST_PLAN_CLEAN_REPORT.name(), "3M");
}}, DEFAULT_PROJECT_ID); }}, DEFAULT_PROJECT_ID);
//清除所有数据 //清除所有数据
@ -470,6 +471,6 @@ public class TestPlanReportControllerTests extends BaseTest {
private String getManualGenPlanReportId() { private String getManualGenPlanReportId() {
TestPlanReportExample example = new TestPlanReportExample(); TestPlanReportExample example = new TestPlanReportExample();
example.createCriteria().andTestPlanIdEqualTo("plan_id_for_gen_report").andDefaultLayoutEqualTo(false); example.createCriteria().andTestPlanIdEqualTo("plan_id_for_gen_report").andDefaultLayoutEqualTo(false);
return testPlanReportMapper.selectByExample(example).get(0).getId(); return testPlanReportMapper.selectByExample(example).getFirst().getId();
} }
} }