fix(测试跟踪): 测试计划报告分享支持访问其他模块报告

--bug=1018368 --user=陈建星 【测试跟踪】测试计划-查看测试报告-导出/分享-报告打开是空白 https://www.tapd.cn/55049933/s/1267815
This commit is contained in:
chenjianxing 2022-10-19 16:13:13 +08:00 committed by jianxing
parent 71b690831b
commit fa8dfcee06
17 changed files with 237 additions and 167 deletions

View File

@ -136,9 +136,9 @@ public class TestPlanApiCaseController {
return testPlanApiCaseService.selectStatusForPlanReport(planId); return testPlanApiCaseService.selectStatusForPlanReport(planId);
} }
@PostMapping("/get/plan/env/map/{resourceType}") @PostMapping("/get/plan/env/map")
public Map<String, List<String>> getPlanProjectEnvMap(@RequestBody List<String> resourceIds, @PathVariable("resourceType") String resourceType) { public Map<String, List<String>> getPlanProjectEnvMap(@RequestBody List<String> resourceIds) {
return testPlanApiCaseService.getPlanProjectEnvMap(resourceIds, resourceType); return testPlanApiCaseService.getPlanProjectEnvMap(resourceIds);
} }
@PostMapping("/set/env/{planId}") @PostMapping("/set/env/{planId}")

View File

@ -225,4 +225,9 @@ public class TestPlanScenarioCaseController {
testPlanScenarioCaseService.buildScenarioResponse(cases); testPlanScenarioCaseService.buildScenarioResponse(cases);
return cases; return cases;
} }
@PostMapping("/get/plan/env/map")
public Map<String, List<String>> getPlanProjectEnvMap(@RequestBody List<String> resourceIds) {
return testPlanScenarioCaseService.getPlanProjectEnvMap(resourceIds);
}
} }

View File

@ -25,7 +25,6 @@ import io.metersphere.base.mapper.plan.TestPlanApiCaseMapper;
import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiCaseMapper; import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiCaseMapper;
import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.CommonConstants; import io.metersphere.commons.constants.CommonConstants;
import io.metersphere.commons.constants.ElementConstants;
import io.metersphere.commons.constants.TriggerMode; import io.metersphere.commons.constants.TriggerMode;
import io.metersphere.commons.enums.ApiReportStatus; import io.metersphere.commons.enums.ApiReportStatus;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
@ -521,10 +520,9 @@ public class TestPlanApiCaseService {
return extTestPlanApiCaseMapper.selectForPlanReport(planId); return extTestPlanApiCaseMapper.selectForPlanReport(planId);
} }
public Map<String, List<String>> getPlanProjectEnvMap(List<String> resourceIds, String resourceType) { public Map<String, List<String>> getPlanProjectEnvMap(List<String> resourceIds) {
Map<String, List<String>> result = new LinkedHashMap<>(); Map<String, List<String>> result = new LinkedHashMap<>();
if (!CollectionUtils.isEmpty(resourceIds)) { if (!CollectionUtils.isEmpty(resourceIds)) {
if (StringUtils.equalsIgnoreCase("ApiCase", resourceType)) {
List<ApiDefinitionExecResultWithBLOBs> execResults = apiDefinitionExecResultService.selectByResourceIdsAndMaxCreateTime(resourceIds); List<ApiDefinitionExecResultWithBLOBs> execResults = apiDefinitionExecResultService.selectByResourceIdsAndMaxCreateTime(resourceIds);
execResults.forEach(item -> { execResults.forEach(item -> {
String envConf = item.getEnvConfig(); String envConf = item.getEnvConfig();
@ -532,15 +530,11 @@ public class TestPlanApiCaseService {
Map<String, List<String>> projectEnvMap = apiDefinitionService.getProjectEnvNameByEnvConfig(projectId, envConf); Map<String, List<String>> projectEnvMap = apiDefinitionService.getProjectEnvNameByEnvConfig(projectId, envConf);
this.setProjectEnvMap(result, projectEnvMap); this.setProjectEnvMap(result, projectEnvMap);
}); });
} else if (StringUtils.equalsIgnoreCase(ElementConstants.SCENARIO, resourceType)) {
Map<String, List<String>> projectEnvMap = apiScenarioEnvService.selectProjectEnvMapByTestPlanScenarioIds(resourceIds);
this.setProjectEnvMap(result, projectEnvMap);
}
} }
return result; return result;
} }
private void setProjectEnvMap(Map<String, List<String>> result, Map<String, List<String>> projectEnvMap) { public void setProjectEnvMap(Map<String, List<String>> result, Map<String, List<String>> projectEnvMap) {
if (MapUtils.isNotEmpty(projectEnvMap)) { if (MapUtils.isNotEmpty(projectEnvMap)) {
for (Map.Entry<String, List<String>> entry : projectEnvMap.entrySet()) { for (Map.Entry<String, List<String>> entry : projectEnvMap.entrySet()) {
String projectName = entry.getKey(); String projectName = entry.getKey();

View File

@ -6,51 +6,17 @@ import io.metersphere.api.dto.ApiCaseRelevanceRequest;
import io.metersphere.api.dto.EnvironmentType; import io.metersphere.api.dto.EnvironmentType;
import io.metersphere.api.dto.RelevanceScenarioRequest; import io.metersphere.api.dto.RelevanceScenarioRequest;
import io.metersphere.api.dto.ScenarioEnv; import io.metersphere.api.dto.ScenarioEnv;
import io.metersphere.api.dto.automation.ApiScenarioDTO;
import io.metersphere.api.dto.automation.ApiScenarioModuleDTO;
import io.metersphere.api.dto.automation.ApiScenarioReportResult; import io.metersphere.api.dto.automation.ApiScenarioReportResult;
import io.metersphere.api.dto.automation.ApiScenarioRequest; import io.metersphere.api.dto.automation.*;
import io.metersphere.api.dto.automation.ExecuteType; import io.metersphere.api.dto.plan.*;
import io.metersphere.api.dto.automation.RunScenarioRequest; import io.metersphere.api.exec.scenario.ApiScenarioEnvService;
import io.metersphere.api.dto.automation.RunTestPlanScenarioRequest; import io.metersphere.base.domain.*;
import io.metersphere.api.dto.automation.TestPlanFailureApiDTO;
import io.metersphere.api.dto.automation.TestPlanFailureScenarioDTO;
import io.metersphere.api.dto.automation.TestPlanScenarioRequest;
import io.metersphere.api.dto.plan.ApiPlanReportDTO;
import io.metersphere.api.dto.plan.ApiPlanReportRequest;
import io.metersphere.api.dto.plan.TestPlanApiCaseInfoDTO;
import io.metersphere.api.dto.plan.TestPlanApiReportInfoDTO;
import io.metersphere.api.dto.plan.TestPlanApiScenarioInfoDTO;
import io.metersphere.api.dto.plan.TestPlanEnvInfoDTO;
import io.metersphere.api.dto.plan.TestPlanExecuteReportDTO;
import io.metersphere.api.dto.plan.TestPlanReportRunInfoDTO;
import io.metersphere.api.dto.plan.TestPlanScenarioCaseBatchRequest;
import io.metersphere.api.dto.plan.TestPlanScenarioStepCountDTO;
import io.metersphere.api.dto.plan.TestPlanScenarioStepCountSimpleDTO;
import io.metersphere.service.scenario.ApiScenarioService;
import io.metersphere.service.definition.ApiDefinitionExecResultService;
import io.metersphere.service.definition.ApiDefinitionService;
import io.metersphere.service.scenario.ApiScenarioModuleService;
import io.metersphere.service.scenario.ApiScenarioReportService;
import io.metersphere.base.domain.ApiDefinitionExecResult;
import io.metersphere.base.domain.ApiDefinitionExecResultExample;
import io.metersphere.base.domain.ApiDefinitionExecResultWithBLOBs;
import io.metersphere.base.domain.ApiScenario;
import io.metersphere.base.domain.ApiScenarioExample;
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
import io.metersphere.base.domain.EnvironmentGroup;
import io.metersphere.base.domain.Project;
import io.metersphere.base.domain.TestPlanApiScenario;
import io.metersphere.base.domain.TestPlanApiScenarioExample;
import io.metersphere.base.domain.TestPlanReport;
import io.metersphere.base.domain.User;
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper; import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
import io.metersphere.base.mapper.ApiScenarioMapper; import io.metersphere.base.mapper.ApiScenarioMapper;
import io.metersphere.base.mapper.ApiTestEnvironmentMapper; import io.metersphere.base.mapper.ApiTestEnvironmentMapper;
import io.metersphere.base.mapper.plan.TestPlanApiScenarioMapper;
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper; import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
import io.metersphere.base.mapper.ext.ExtApiScenarioModuleMapper; import io.metersphere.base.mapper.ext.ExtApiScenarioModuleMapper;
import io.metersphere.base.mapper.plan.TestPlanApiScenarioMapper;
import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiCaseMapper; import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiCaseMapper;
import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiScenarioMapper; import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiScenarioMapper;
import io.metersphere.base.mapper.plan.ext.ExtTestPlanScenarioCaseMapper; import io.metersphere.base.mapper.plan.ext.ExtTestPlanScenarioCaseMapper;
@ -59,11 +25,7 @@ import io.metersphere.commons.constants.CommonConstants;
import io.metersphere.commons.constants.ProjectApplicationType; import io.metersphere.commons.constants.ProjectApplicationType;
import io.metersphere.commons.enums.ApiReportStatus; import io.metersphere.commons.enums.ApiReportStatus;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.JSON; import io.metersphere.commons.utils.*;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.dto.MsExecResponseDTO; import io.metersphere.dto.MsExecResponseDTO;
import io.metersphere.dto.PlanReportCaseDTO; import io.metersphere.dto.PlanReportCaseDTO;
import io.metersphere.dto.ProjectConfig; import io.metersphere.dto.ProjectConfig;
@ -77,6 +39,10 @@ import io.metersphere.service.BaseProjectApplicationService;
import io.metersphere.service.BaseProjectService; import io.metersphere.service.BaseProjectService;
import io.metersphere.service.BaseUserService; import io.metersphere.service.BaseUserService;
import io.metersphere.service.ServiceUtils; import io.metersphere.service.ServiceUtils;
import io.metersphere.service.definition.ApiDefinitionExecResultService;
import io.metersphere.service.scenario.ApiScenarioModuleService;
import io.metersphere.service.scenario.ApiScenarioReportService;
import io.metersphere.service.scenario.ApiScenarioService;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils; import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -89,19 +55,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@ -139,7 +93,7 @@ public class TestPlanScenarioCaseService {
@Resource @Resource
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper; private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
@Resource @Resource
private ApiDefinitionService apiDefinitionService; private ApiScenarioEnvService apiScenarioEnvService;
@Resource @Resource
private ApiDefinitionExecResultService apiDefinitionExecResultService; private ApiDefinitionExecResultService apiDefinitionExecResultService;
@Resource @Resource
@ -1199,6 +1153,14 @@ public class TestPlanScenarioCaseService {
return extTestPlanScenarioCaseMapper.selectForPlanReport(planId); return extTestPlanScenarioCaseMapper.selectForPlanReport(planId);
} }
public Map<String, List<String>> getPlanProjectEnvMap(List<String> resourceIds) {
Map<String, List<String>> result = new LinkedHashMap<>();
if (!com.alibaba.nacos.common.utils.CollectionUtils.isEmpty(resourceIds)) {
Map<String, List<String>> projectEnvMap = apiScenarioEnvService.selectProjectEnvMapByTestPlanScenarioIds(resourceIds);
testPlanApiCaseService.setProjectEnvMap(result, projectEnvMap);
}
return result;
}
public List<ApiScenarioModuleDTO> getNodeByPlanId(List<String> projectIds, String planId) { public List<ApiScenarioModuleDTO> getNodeByPlanId(List<String> projectIds, String planId) {
List<ApiScenarioModuleDTO> list = new ArrayList<>(); List<ApiScenarioModuleDTO> list = new ArrayList<>();

View File

@ -5,6 +5,7 @@ import io.metersphere.base.domain.UserKey;
import io.metersphere.commons.constants.ApiKeyConstants; import io.metersphere.commons.constants.ApiKeyConstants;
import io.metersphere.commons.constants.SessionConstants; import io.metersphere.commons.constants.SessionConstants;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.service.BaseUserService;
import io.metersphere.service.UserKeyService; import io.metersphere.service.UserKeyService;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -93,6 +94,11 @@ public class HttpHeaderUtils {
} }
} }
public static void runAsUser(String userId) {
BaseUserService baseUserService = CommonBeanFactory.getBean(BaseUserService.class);
runAsUser(baseUserService.getUserDTO(userId));
}
public static void clearUser() { public static void clearUser() {
sessionUserThreadLocal.remove(); sessionUserThreadLocal.remove();
} }

View File

@ -65,7 +65,7 @@ public class ShiroUtils {
filterChainDefinitionMap.put("/document/**", "anon"); filterChainDefinitionMap.put("/document/**", "anon");
filterChainDefinitionMap.put("/chart-pic/**", "anon"); filterChainDefinitionMap.put("/chart-pic/**", "anon");
filterChainDefinitionMap.put("/share/**", "anon"); filterChainDefinitionMap.put("/share/**", "anon");
filterChainDefinitionMap.put("/sharePlanReport", "anon"); filterChainDefinitionMap.put("/share-plan-report", "anon");
filterChainDefinitionMap.put("/share-report", "anon"); filterChainDefinitionMap.put("/share-report", "anon");
filterChainDefinitionMap.put("/share-document", "anon"); filterChainDefinitionMap.put("/share-document", "anon");
filterChainDefinitionMap.put("/share-api-report", "anon"); filterChainDefinitionMap.put("/share-api-report", "anon");

View File

@ -39,7 +39,7 @@ public class ShareController {
@GetMapping("/test/plan/report/{shareId}/{planId}") @GetMapping("/test/plan/report/{shareId}/{planId}")
public TestPlanSimpleReportDTO getReport(@PathVariable String shareId, @PathVariable String planId) { public TestPlanSimpleReportDTO getReport(@PathVariable String shareId, @PathVariable String planId) {
baseShareInfoService.validate(shareId, planId); baseShareInfoService.validate(shareId, planId);
return testPlanService.getReport(planId, null); return testPlanService.getShareReport(baseShareInfoService.get(shareId), planId);
} }
@GetMapping("/report/export/{shareId}/{planId}/{lang}") @GetMapping("/report/export/{shareId}/{planId}/{lang}")
@ -59,6 +59,6 @@ public class ShareController {
@GetMapping("/test/plan/report/db/{shareId}/{reportId}") @GetMapping("/test/plan/report/db/{shareId}/{reportId}")
public TestPlanSimpleReportDTO getTestPlanDbReport(@PathVariable String shareId, @PathVariable String reportId) { public TestPlanSimpleReportDTO getTestPlanDbReport(@PathVariable String shareId, @PathVariable String reportId) {
baseShareInfoService.validate(shareId, reportId); baseShareInfoService.validate(shareId, reportId);
return testPlanReportService.getReport(reportId); return testPlanReportService.getShareDbReport(baseShareInfoService.get(shareId), reportId);
} }
} }

View File

@ -1,13 +1,22 @@
package io.metersphere.controller; package io.metersphere.controller;
import org.springframework.stereotype.Controller; import io.metersphere.controller.handler.annotation.NoResultHolder;
import io.metersphere.plan.service.TestPlanService;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@Controller import javax.annotation.Resource;
@RestController
public class ShareReportController { public class ShareReportController {
@GetMapping(value = "/sharePlanReport") @Resource
TestPlanService testPlanService;
@NoResultHolder
@GetMapping(value = "/share-plan-report")
public String shareRedirect() { public String shareRedirect() {
return "share-plan-report.html"; return testPlanService.getShareReport();
} }
} }

View File

@ -166,7 +166,7 @@ public class TestPlanMessageService {
paramMap.putAll(new BeanMap(testPlanDTOWithMetric)); paramMap.putAll(new BeanMap(testPlanDTOWithMetric));
String testPlanShareUrl = getTestPlanShareUrl(testPlanReport.getId(), creator); String testPlanShareUrl = getTestPlanShareUrl(testPlanReport.getId(), creator);
paramMap.put("planShareUrl", baseSystemConfigDTO.getUrl() + "/sharePlanReport" + testPlanShareUrl); paramMap.put("planShareUrl", baseSystemConfigDTO.getUrl() + "/share-plan-report" + testPlanShareUrl);
/** /**
* 测试计划的消息通知配置包括 完成成功失败 * 测试计划的消息通知配置包括 完成成功失败

View File

@ -939,6 +939,15 @@ public class TestPlanReportService {
this.delete(testPlanReportIdList); this.delete(testPlanReportIdList);
} }
public TestPlanSimpleReportDTO getShareDbReport(ShareInfo shareInfo, String reportId) {
HttpHeaderUtils.runAsUser(shareInfo.getCreateUserId());
try {
return getReport(reportId);
} finally {
HttpHeaderUtils.clearUser();
}
}
public TestPlanSimpleReportDTO getReport(String reportId) { public TestPlanSimpleReportDTO getReport(String reportId) {
TestPlanReportContentExample example = new TestPlanReportContentExample(); TestPlanReportContentExample example = new TestPlanReportContentExample();
example.createCriteria().andTestPlanReportIdEqualTo(reportId); example.createCriteria().andTestPlanReportIdEqualTo(reportId);
@ -956,66 +965,101 @@ public class TestPlanReportService {
TestPlanSimpleReportDTO testPlanReportDTO = new TestPlanSimpleReportDTO(); TestPlanSimpleReportDTO testPlanReportDTO = new TestPlanSimpleReportDTO();
BeanUtils.copyBean(testPlanReportDTO, testPlanReportContent); BeanUtils.copyBean(testPlanReportDTO, testPlanReportContent);
this.generateEnvironmentInfo(testPlanReportDTO, reportId); this.generateEnvironmentInfo(testPlanReportDTO, reportId);
if (StringUtils.isNotBlank(testPlanReportContent.getFunctionResult())) {
testPlanReportDTO.setFunctionResult(JSON.parseObject(testPlanReportContent.getFunctionResult(), TestPlanFunctionResultReportDTO.class)); testPlanReportDTO.setFunctionResult(
} getReportContentResultObject(testPlanReportContent.getFunctionResult(), TestPlanFunctionResultReportDTO.class)
if (StringUtils.isNotBlank(testPlanReportContent.getApiResult())) { );
testPlanReportDTO.setApiResult(JSON.parseObject(testPlanReportContent.getApiResult(), TestPlanApiResultReportDTO.class));
} testPlanReportDTO.setApiResult(
if (StringUtils.isNotBlank(testPlanReportContent.getLoadResult())) { getReportContentResultObject(testPlanReportContent.getApiResult(), TestPlanApiResultReportDTO.class)
testPlanReportDTO.setLoadResult(JSON.parseObject(testPlanReportContent.getLoadResult(), TestPlanLoadResultReportDTO.class)); );
}
if (StringUtils.isNotBlank(testPlanReportContent.getFunctionAllCases())) { testPlanReportDTO.setLoadResult(
testPlanReportDTO.setFunctionAllCases(JSON.parseArray(testPlanReportContent.getFunctionAllCases(), TestPlanCaseDTO.class)); getReportContentResultObject(testPlanReportContent.getLoadResult(), TestPlanLoadResultReportDTO.class)
} );
if (StringUtils.isNotBlank(testPlanReportContent.getIssueList())) {
testPlanReportDTO.setIssueList(JSON.parseArray(testPlanReportContent.getIssueList(), IssuesDao.class)); testPlanReportDTO.setFunctionAllCases(
} getReportContentResultArray(testPlanReportContent.getFunctionAllCases(), TestPlanCaseDTO.class)
if (StringUtils.isNotBlank(testPlanReportContent.getApiAllCases())) { );
testPlanReportDTO.setApiAllCases(JSON.parseArray(testPlanReportContent.getApiAllCases(), TestPlanFailureApiDTO.class));
} testPlanReportDTO.setIssueList(
if (StringUtils.isNotBlank(testPlanReportContent.getApiFailureCases())) { getReportContentResultArray(testPlanReportContent.getIssueList(), IssuesDao.class)
testPlanReportDTO.setApiFailureCases(JSON.parseArray(testPlanReportContent.getApiFailureCases(), TestPlanFailureApiDTO.class)); );
}
if (StringUtils.isNotBlank(testPlanReportContent.getScenarioAllCases())) { testPlanReportDTO.setApiAllCases(
testPlanReportDTO.setScenarioAllCases(JSON.parseArray(testPlanReportContent.getScenarioAllCases(), TestPlanFailureScenarioDTO.class)); getReportContentResultArray(testPlanReportContent.getApiAllCases(), TestPlanFailureApiDTO.class)
} );
if (StringUtils.isNotBlank(testPlanReportContent.getScenarioFailureCases())) {
testPlanReportDTO.setScenarioFailureCases(JSON.parseArray(testPlanReportContent.getScenarioFailureCases(), TestPlanFailureScenarioDTO.class)); testPlanReportDTO.setApiFailureCases(
} getReportContentResultArray(testPlanReportContent.getApiFailureCases(), TestPlanFailureApiDTO.class)
if (StringUtils.isNotBlank(testPlanReportContent.getLoadAllCases())) { );
testPlanReportDTO.setLoadAllCases(JSON.parseArray(testPlanReportContent.getLoadAllCases(), TestPlanLoadCaseDTO.class));
} testPlanReportDTO.setScenarioAllCases(
if (StringUtils.isNotBlank(testPlanReportContent.getLoadFailureCases())) { getReportContentResultArray(testPlanReportContent.getScenarioAllCases(), TestPlanFailureScenarioDTO.class)
testPlanReportDTO.setLoadFailureCases(JSON.parseArray(testPlanReportContent.getLoadFailureCases(), TestPlanLoadCaseDTO.class)); );
}
if (StringUtils.isNotBlank(testPlanReportContent.getErrorReportCases())) { testPlanReportDTO.setScenarioFailureCases(
testPlanReportDTO.setErrorReportCases(JSON.parseArray(testPlanReportContent.getErrorReportCases(), TestPlanFailureApiDTO.class)); getReportContentResultArray(testPlanReportContent.getScenarioFailureCases(), TestPlanFailureScenarioDTO.class)
} );
if (StringUtils.isNotBlank(testPlanReportContent.getErrorReportScenarios())) {
testPlanReportDTO.setErrorReportScenarios(JSON.parseArray(testPlanReportContent.getErrorReportScenarios(), TestPlanFailureScenarioDTO.class)); testPlanReportDTO.setLoadAllCases(
} getReportContentResultArray(testPlanReportContent.getLoadAllCases(), TestPlanLoadCaseDTO.class)
if (StringUtils.isNotBlank(testPlanReportContent.getUnExecuteCases())) { );
testPlanReportDTO.setUnExecuteCases(JSON.parseArray(testPlanReportContent.getUnExecuteCases(), TestPlanFailureApiDTO.class));
} testPlanReportDTO.setLoadFailureCases(
if (StringUtils.isNotBlank(testPlanReportContent.getUnExecuteScenarios())) { getReportContentResultArray(testPlanReportContent.getLoadFailureCases(), TestPlanLoadCaseDTO.class)
testPlanReportDTO.setUnExecuteScenarios(JSON.parseArray(testPlanReportContent.getUnExecuteScenarios(), TestPlanFailureScenarioDTO.class)); );
}
if (StringUtils.isNotBlank(testPlanReportContent.getUiResult())) { testPlanReportDTO.setErrorReportCases(
testPlanReportDTO.setUiResult(JSON.parseObject(testPlanReportContent.getUiResult(), TestPlanUiResultReportDTO.class)); getReportContentResultArray(testPlanReportContent.getErrorReportCases(), TestPlanFailureApiDTO.class)
} );
if (StringUtils.isNotBlank(testPlanReportContent.getUiAllCases())) {
testPlanReportDTO.setUiAllCases(JSON.parseArray(testPlanReportContent.getUiAllCases(), TestPlanUiScenarioDTO.class)); testPlanReportDTO.setErrorReportScenarios(
} getReportContentResultArray(testPlanReportContent.getErrorReportScenarios(), TestPlanFailureScenarioDTO.class)
if (StringUtils.isNotBlank(testPlanReportContent.getUiFailureCases())) { );
testPlanReportDTO.setUiFailureCases(JSON.parseArray(testPlanReportContent.getUiFailureCases(), TestPlanUiScenarioDTO.class));
} testPlanReportDTO.setUnExecuteCases(
getReportContentResultArray(testPlanReportContent.getUnExecuteCases(), TestPlanFailureApiDTO.class)
);
testPlanReportDTO.setUnExecuteScenarios(
getReportContentResultArray(testPlanReportContent.getUnExecuteScenarios(), TestPlanFailureScenarioDTO.class)
);
testPlanReportDTO.setUiResult(
getReportContentResultObject(testPlanReportContent.getUiResult(), TestPlanUiResultReportDTO.class)
);
testPlanReportDTO.setUiAllCases(
getReportContentResultArray(testPlanReportContent.getUiAllCases(), TestPlanUiScenarioDTO.class)
);
testPlanReportDTO.setUiFailureCases(
getReportContentResultArray(testPlanReportContent.getUiFailureCases(), TestPlanUiScenarioDTO.class)
);
testPlanReportDTO.setId(reportId); testPlanReportDTO.setId(reportId);
TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(testPlanReportContent.getTestPlanReportId()); TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(testPlanReportContent.getTestPlanReportId());
testPlanReportDTO.setName(testPlanReport.getName()); testPlanReportDTO.setName(testPlanReport.getName());
return testPlanReportDTO; return testPlanReportDTO;
} }
private <T> T getReportContentResultObject(String contentStr, Class<T> clazz) {
if (StringUtils.isNotBlank(contentStr)) {
return JSON.parseObject(contentStr, clazz);
}
return null;
}
private <T> List<T> getReportContentResultArray(String contentStr, Class<T> clazz) {
if (StringUtils.isNotBlank(contentStr)) {
return JSON.parseArray(contentStr, clazz);
}
return null;
}
private void generateEnvironmentInfo(TestPlanSimpleReportDTO testPlanReportDTO, String reportId) { private void generateEnvironmentInfo(TestPlanSimpleReportDTO testPlanReportDTO, String reportId) {
TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(reportId); TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(reportId);
try { try {

View File

@ -33,6 +33,7 @@ import io.metersphere.plan.reuest.ui.RunUiScenarioRequest;
import io.metersphere.plan.service.remote.api.PlanApiAutomationService; import io.metersphere.plan.service.remote.api.PlanApiAutomationService;
import io.metersphere.plan.service.remote.api.PlanTestPlanApiCaseService; import io.metersphere.plan.service.remote.api.PlanTestPlanApiCaseService;
import io.metersphere.plan.service.remote.api.PlanTestPlanScenarioCaseService; import io.metersphere.plan.service.remote.api.PlanTestPlanScenarioCaseService;
import io.metersphere.plan.service.remote.gateway.GatewayService;
import io.metersphere.plan.service.remote.performance.PerfExecService; import io.metersphere.plan.service.remote.performance.PerfExecService;
import io.metersphere.plan.service.remote.performance.PlanTestPlanLoadCaseService; import io.metersphere.plan.service.remote.performance.PlanTestPlanLoadCaseService;
import io.metersphere.plan.service.remote.ui.PlanTestPlanUiScenarioCaseService; import io.metersphere.plan.service.remote.ui.PlanTestPlanUiScenarioCaseService;
@ -139,6 +140,8 @@ public class TestPlanService {
private TestPlanExecutionQueueService testPlanExecutionQueueService; private TestPlanExecutionQueueService testPlanExecutionQueueService;
@Resource @Resource
private KafkaTemplate<String, String> kafkaTemplate; private KafkaTemplate<String, String> kafkaTemplate;
@Resource
private GatewayService gatewayService;
public synchronized TestPlan addTestPlan(AddTestPlanRequest testPlan) { public synchronized TestPlan addTestPlan(AddTestPlanRequest testPlan) {
if (getTestPlanByName(testPlan.getName()).size() > 0) { if (getTestPlanByName(testPlan.getName()).size() > 0) {
@ -1072,6 +1075,36 @@ public class TestPlanService {
} }
} }
public String getShareReport() {
Object microServices = gatewayService.getMicroServices();
return replaceSharReport(microServices);
}
/**
* 获取微服务信息替换前端变量
* 实现跨服务访问报告
*/
public String replaceSharReport(Object microServices) {
try (InputStreamReader isr = new InputStreamReader(getClass().getResourceAsStream("/public/share-plan-report.html"), StandardCharsets.UTF_8);) {
BufferedReader bufferedReader = new BufferedReader(isr);
StringBuilder reportStr = new StringBuilder();
String line;
while (null != (line = bufferedReader.readLine())) {
if (line.contains("\"#microService\"")) {
line = line.replace("\"#microService\"", new Gson().toJson(microServices));
}
line += StringUtils.LF;
reportStr.append(line);
}
return reportStr.toString();
} catch (Throwable e) {
LogUtil.error(e);
MSException.throwException(e);
}
return null;
}
public Map<String, List<String>> getApiCaseEnv(List<String> planApiCaseIds) { public Map<String, List<String>> getApiCaseEnv(List<String> planApiCaseIds) {
return planTestPlanApiCaseService.getApiCaseEnv(planApiCaseIds); return planTestPlanApiCaseService.getApiCaseEnv(planApiCaseIds);
} }
@ -1330,6 +1363,15 @@ public class TestPlanService {
} }
} }
public TestPlanSimpleReportDTO getShareReport(ShareInfo shareInfo, String planId) {
HttpHeaderUtils.runAsUser(shareInfo.getCreateUserId());
try {
return getReport(planId, null);
} finally {
HttpHeaderUtils.clearUser();
}
}
/** /**
* 生成测试计划报告并进行统计 * 生成测试计划报告并进行统计
* *

View File

@ -36,7 +36,7 @@ public class PlanTestPlanApiCaseService extends ApiTestService {
calculatePlanReport(report, planReportCaseDTOS); calculatePlanReport(report, planReportCaseDTOS);
//记录接口用例的运行环境信息 //记录接口用例的运行环境信息
List<String> idList = planReportCaseDTOS.stream().map(PlanReportCaseDTO::getId).collect(Collectors.toList()); List<String> idList = planReportCaseDTOS.stream().map(PlanReportCaseDTO::getId).collect(Collectors.toList());
report.setProjectEnvMap(getPlanProjectEnvMap(idList, "ApiCase")); report.setProjectEnvMap(getPlanProjectEnvMap(idList));
} catch (MSException e) { } catch (MSException e) {
LogUtil.error(e); LogUtil.error(e);
} }
@ -76,8 +76,8 @@ public class PlanTestPlanApiCaseService extends ApiTestService {
return microService.getForDataArray(serviceName, BASE_UEL + "/get/report/status/" + planId, PlanReportCaseDTO.class); return microService.getForDataArray(serviceName, BASE_UEL + "/get/report/status/" + planId, PlanReportCaseDTO.class);
} }
public Map<String, List<String>> getPlanProjectEnvMap(List<String> resourceIds, String resourceType) { public Map<String, List<String>> getPlanProjectEnvMap(List<String> resourceIds) {
return (Map<String, List<String>>) microService.postForData(serviceName, BASE_UEL + "/get/plan/env/map/" + resourceType, resourceIds); return (Map<String, List<String>>) microService.postForData(serviceName, BASE_UEL + "/get/plan/env/map", resourceIds);
} }
public List<MsExecResponseDTO> run(BatchRunDefinitionRequest request) { public List<MsExecResponseDTO> run(BatchRunDefinitionRequest request) {

View File

@ -29,7 +29,7 @@ public class PlanTestPlanScenarioCaseService extends ApiTestService {
calculatePlanReport(report, planReportCaseDTOS); calculatePlanReport(report, planReportCaseDTOS);
//记录接口用例的运行环境信息 //记录接口用例的运行环境信息
List<String> idList = planReportCaseDTOS.stream().map(PlanReportCaseDTO::getId).collect(Collectors.toList()); List<String> idList = planReportCaseDTOS.stream().map(PlanReportCaseDTO::getId).collect(Collectors.toList());
report.setProjectEnvMap(getPlanProjectEnvMap(idList, "Scenario")); report.setProjectEnvMap(getPlanProjectEnvMap(idList));
} catch (MSException e) { } catch (MSException e) {
LogUtil.error(e); LogUtil.error(e);
} }
@ -90,8 +90,8 @@ public class PlanTestPlanScenarioCaseService extends ApiTestService {
return microService.getForDataArray(serviceName, BASE_UEL + "/get/report/status/" + planId, PlanReportCaseDTO.class); return microService.getForDataArray(serviceName, BASE_UEL + "/get/report/status/" + planId, PlanReportCaseDTO.class);
} }
public Map<String, List<String>> getPlanProjectEnvMap(List<String> resourceIds, String resourceType) { public Map<String, List<String>> getPlanProjectEnvMap(List<String> resourceIds) {
return (Map<String, List<String>>) microService.postForData(serviceName, BASE_UEL + "/get/plan/env/map/" + resourceType, resourceIds); return (Map<String, List<String>>) microService.postForData(serviceName, BASE_UEL + "/get/plan/env/map", resourceIds);
} }
public List<String> getExecResultByPlanId(String planId) { public List<String> getExecResultByPlanId(String planId) {

View File

@ -0,0 +1,16 @@
package io.metersphere.plan.service.remote.gateway;
import io.metersphere.commons.constants.MicroServiceName;
import io.metersphere.service.RemoteService;
import org.springframework.stereotype.Service;
@Service
public class GatewayService extends RemoteService {
public GatewayService() {
super(MicroServiceName.GATEWAY);
}
public Object getMicroServices() {
return microService.getForData(serviceName, "/services");
}
}

View File

@ -52,6 +52,6 @@ export function getShareId() {
} }
export function getShareRedirectUrl(data) { export function getShareRedirectUrl(data) {
let name = '/sharePlanReport'; let name = '/share-plan-report';
return generateShareUrl(name, data.shareUrl); return generateShareUrl(name, data.shareUrl);
} }

View File

@ -12,30 +12,8 @@ import plugins from "metersphere-frontend/src/plugins";
import mavonEditor from "mavon-editor"; import mavonEditor from "mavon-editor";
import {createPinia, PiniaVuePlugin} from 'pinia' import {createPinia, PiniaVuePlugin} from 'pinia'
import PersistedState from "pinia-plugin-persistedstate"; import PersistedState from "pinia-plugin-persistedstate";
import {TokenKey} from "metersphere-frontend/src/utils/constants";
import axios from 'axios';
function planReportUse(id, template) { function planReportUse(id, template) {
// 获取gateway路由
let user = JSON.parse(localStorage.getItem(TokenKey));
axios({
method: 'get',
url: '/services',
headers: {
'CSRF-TOKEN': user.csrfToken,
'X-AUTH-TOKEN': user.sessionId
},
}).then((res)=>{
let modules = {}, microPorts = {};
res.data.data.forEach(svc => {
let name = svc.serviceId;
modules[name] = true;
microPorts[name] = svc.port;
})
sessionStorage.setItem("micro_apps", JSON.stringify(modules));
sessionStorage.setItem("micro_ports", JSON.stringify(microPorts));
})
const pinia = createPinia() const pinia = createPinia()
pinia.use(PersistedState)//开启缓存存储在localstorage pinia.use(PersistedState)//开启缓存存储在localstorage

View File

@ -10,4 +10,18 @@
<body> <body>
<div id="sharePlanReport"></div> <div id="sharePlanReport"></div>
</body> </body>
<script type="text/javascript">
// 后端获取服务列表替换
let microService = "#microService";
let modules = {}, microPorts = {};
microService.forEach(svc => {
let name = svc.serviceId;
modules[name] = true;
microPorts[name] = svc.port;
});
sessionStorage.setItem("micro_apps", JSON.stringify(modules));
sessionStorage.setItem("micro_ports", JSON.stringify(microPorts));
</script>
</html> </html>