diff --git a/backend/src/main/java/io/metersphere/api/controller/APIScenarioReportController.java b/backend/src/main/java/io/metersphere/api/controller/APIScenarioReportController.java index b5f0109caa..09114930f9 100644 --- a/backend/src/main/java/io/metersphere/api/controller/APIScenarioReportController.java +++ b/backend/src/main/java/io/metersphere/api/controller/APIScenarioReportController.java @@ -7,7 +7,6 @@ import io.metersphere.api.dto.QueryAPIReportRequest; import io.metersphere.api.dto.automation.APIScenarioReportResult; import io.metersphere.api.dto.automation.ExecuteType; import io.metersphere.api.service.ApiScenarioReportService; -import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.RoleConstants; import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; @@ -27,12 +26,9 @@ public class APIScenarioReportController { @Resource private ApiScenarioReportService apiReportService; - @GetMapping("/get/{reportId}/{infoDb}") - public APIScenarioReportResult get(@PathVariable String reportId, @PathVariable Boolean infoDb) { - if (infoDb) { - return apiReportService.get(reportId); - } - return apiReportService.getCacheResult(reportId); + @GetMapping("/get/{reportId}") + public APIScenarioReportResult get(@PathVariable String reportId) { + return apiReportService.get(reportId); } @PostMapping("/list/{goPage}/{pageSize}") @@ -42,13 +38,6 @@ public class APIScenarioReportController { return PageUtils.setPageInfo(page, apiReportService.list(request)); } - @PostMapping("/add") - @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) - public void add(@RequestBody APIScenarioReportResult node) { - node.setExecuteType(ExecuteType.Saved.name()); - apiReportService.save(node, ApiRunMode.SCENARIO.name()); - } - @PostMapping("/update") @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) public String update(@RequestBody APIScenarioReportResult node) { diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java index fd7e1e3b1b..fb49ac9127 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java @@ -81,7 +81,7 @@ public class ApiAutomationController { @PostMapping(value = "/run/debug") public void runDebug(@RequestPart("request") RunDefinitionRequest request, @RequestPart(value = "files") List bodyFiles) { request.setExecuteType(ExecuteType.Debug.name()); - apiAutomationService.run(request, bodyFiles); + apiAutomationService.debugRun(request, bodyFiles); } @PostMapping(value = "/run") @@ -90,6 +90,13 @@ public class ApiAutomationController { apiAutomationService.run(request); } + @PostMapping(value = "/run/batch") + public void runBatch(@RequestBody RunScenarioRequest request) { + request.setExecuteType(ExecuteType.Saved.name()); + apiAutomationService.run(request); + } + + @PostMapping("/getReference") public ReferenceDTO getReference(@RequestBody ApiScenarioRequest request) { return apiAutomationService.getReference(request); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java index b329cfcffa..34e4655a21 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java @@ -21,6 +21,10 @@ public class RunDefinitionRequest { private String projectId; + private String scenarioId; + + private String scenarioName; + private String environmentId; private MsTestElement testElement; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java index db3cbf8834..b70b2f703a 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java @@ -84,7 +84,7 @@ public class MsScenario extends MsTestElement { } // 场景变量 if (CollectionUtils.isNotEmpty(this.getVariables())) { - tree.add(arguments()); + tree.add(arguments(config)); } if (CollectionUtils.isNotEmpty(hashTree)) { @@ -95,7 +95,7 @@ public class MsScenario extends MsTestElement { } - private Arguments arguments() { + private Arguments arguments(ParameterConfig config) { Arguments arguments = new Arguments(); arguments.setEnabled(true); arguments.setName(name + "Variables"); @@ -104,7 +104,12 @@ public class MsScenario extends MsTestElement { variables.stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue -> arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=") ); + if (config != null && config.getConfig() != null && config.getConfig().getCommonConfig() != null + && CollectionUtils.isNotEmpty(config.getConfig().getCommonConfig().getVariables())) { + config.getConfig().getCommonConfig().getVariables().stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue -> + arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=") + ); + } return arguments; } - } diff --git a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java index b4abea3e3d..a5e259cf01 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -189,27 +189,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl BaseSystemConfigDTO baseSystemConfigDTO = systemParameterService.getBaseInfo(); reportUrl = baseSystemConfigDTO.getUrl() + "/#/api/automation/report"; - String scenaName = scenarioReport.getName(); - if (scenaName == null) { - scenaName = ""; - } else { - String[] sceneNameArr = scenaName.split("-"); - if (sceneNameArr.length >= 4) { - //如果以yyyy-MM-dd 时间类型结尾 - String endStr = "-" + sceneNameArr[sceneNameArr.length - 3] + "-" + sceneNameArr[sceneNameArr.length - 2] + "-" + sceneNameArr[sceneNameArr.length - 1]; - scenaName = scenaName.split(endStr)[0]; - } else { - //如果以时间戳结尾 - scenaName = scenaName.split("-")[0]; - } - } - ApiScenarioReport savedReport = apiScenarioReportService.get(testId); - String scenarioID = ""; - if(savedReport!=null){ - scenarioID = savedReport.getScenarioId(); - } - - testResult.setTestId(scenarioID); + testResult.setTestId(scenarioReport.getScenarioId()); } else { apiTestService.changeStatus(testId, APITestStatus.Completed); report = apiReportService.getRunningReport(testResult.getTestId()); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java index b027338cef..2f620e1825 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -260,10 +260,15 @@ public class ApiAutomationService { return new ArrayList<>(); } - private void createAPIScenarioReportResult(String id, String triggerMode, String execType, String projectId, String userID) { + private void createAPIScenarioReportResult(String id, String scenarioId, String scenarioName, String triggerMode, String execType, String projectId, String userID) { APIScenarioReportResult report = new APIScenarioReportResult(); report.setId(id); - report.setName("测试执行结果"); + report.setTestId(id); + if (StringUtils.isNotEmpty(scenarioName)) { + report.setName(scenarioName); + } else { + report.setName("零时调试名称"); + } report.setCreateTime(System.currentTimeMillis()); report.setUpdateTime(System.currentTimeMillis()); report.setStatus(APITestStatus.Running.name()); @@ -272,12 +277,12 @@ public class ApiAutomationService { } else { report.setUserId(SessionUtils.getUserId()); } - report.setTriggerMode(triggerMode); report.setExecuteType(execType); report.setProjectId(projectId); - apiReportService.addResult(report); - + report.setScenarioName(scenarioName); + report.setScenarioId(scenarioId); + apiScenarioReportMapper.insert(report); } /** @@ -292,10 +297,17 @@ public class ApiAutomationService { testPlan.setHashTree(new LinkedList<>()); HashTree jmeterTestPlanHashTree = new ListedHashTree(); String projectID = request.getProjectId(); + boolean isOne = true; for (ApiScenarioWithBLOBs item : apiScenarios) { MsThreadGroup group = new MsThreadGroup(); group.setLabel(item.getName()); - group.setName(item.getName()); + // 批量执行的结果直接存储为报告 + if (isOne) { + group.setName(request.getId()); + isOne = false; + } else { + group.setName(UUID.randomUUID().toString()); + } projectID = item.getProjectId(); try { ObjectMapper mapper = new ObjectMapper(); @@ -318,6 +330,9 @@ public class ApiAutomationService { group.setEnableCookieShare(scenario.isEnableCookieShare()); LinkedList scenarios = new LinkedList<>(); scenarios.add(scenario); + // 创建场景报告 + createAPIScenarioReportResult(group.getName(), item.getId(), item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(), + request.getExecuteType(), projectID, request.getReportUserID()); group.setHashTree(scenarios); testPlan.getHashTree().add(group); } catch (Exception ex) { @@ -332,9 +347,6 @@ public class ApiAutomationService { } // 调用执行方法 jMeterService.runDefinition(request.getId(), jmeterTestPlanHashTree, request.getReportId(), runMode); - - createAPIScenarioReportResult(request.getId(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(), - request.getExecuteType(), projectID, request.getReportUserID()); return request.getId(); } @@ -346,7 +358,7 @@ public class ApiAutomationService { * @param bodyFiles * @return */ - public String run(RunDefinitionRequest request, List bodyFiles) { + public String debugRun(RunDefinitionRequest request, List bodyFiles) { List bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()); apiDefinitionService.createBodyFiles(bodyUploadIds, bodyFiles); EnvironmentConfig envConfig = null; @@ -359,7 +371,7 @@ public class ApiAutomationService { HashTree hashTree = request.getTestElement().generateHashTree(config); // 调用执行方法 jMeterService.runDefinition(request.getId(), hashTree, request.getReportId(), ApiRunMode.SCENARIO.name()); - createAPIScenarioReportResult(request.getId(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(), + createAPIScenarioReportResult(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(), SessionUtils.getUserId()); return request.getId(); } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java index 9e6aef5552..3c306f6453 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -1,7 +1,6 @@ package io.metersphere.api.service; import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; import io.metersphere.api.dto.DeleteAPIReportRequest; import io.metersphere.api.dto.QueryAPIReportRequest; import io.metersphere.api.dto.automation.APIScenarioReportResult; @@ -15,30 +14,26 @@ import io.metersphere.base.mapper.ApiScenarioReportDetailMapper; import io.metersphere.base.mapper.ApiScenarioReportMapper; import io.metersphere.base.mapper.TestPlanApiScenarioMapper; import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper; -import io.metersphere.commons.constants.APITestStatus; import io.metersphere.commons.constants.ApiRunMode; -import io.metersphere.commons.constants.ReportTriggerMode; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.DateUtils; -import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.ServiceUtils; import io.metersphere.i18n.Translator; -import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import sun.security.util.Cache; import javax.annotation.Resource; import java.nio.charset.StandardCharsets; import java.text.DecimalFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; @Service @Transactional(rollbackFor = Exception.class) public class ApiScenarioReportService { - - private static Cache cache = Cache.newHardMemoryCache(0, 3600 * 24); @Resource private ExtApiScenarioReportMapper extApiScenarioReportMapper; @Resource @@ -50,77 +45,18 @@ public class ApiScenarioReportService { @Resource private TestPlanApiScenarioMapper testPlanApiScenarioMapper; - public String getApiScenarioId(String name, String projectID) { - ApiScenarioExample example = new ApiScenarioExample(); - example.createCriteria().andNameEqualTo(name).andProjectIdEqualTo(projectID).andStatusNotEqualTo("Trash"); - List list = apiScenarioMapper.selectByExample(example); - if (list.isEmpty()) { - return null; - } else { - return list.get(0).getId(); - } - } - public ApiScenarioReport complete(TestResult result, String runMode) { - Object obj = cache.get(result.getTestId()); - if (obj == null) { - MSException.throwException(Translator.get("api_report_is_null")); - } - APIScenarioReportResult report = (APIScenarioReportResult) obj; - report.setTestId(result.getTestId()); - if (CollectionUtils.isNotEmpty(result.getScenarios())) { - try { - report.setName(result.getScenarios().get(0).getName() + "-" + DateUtils.getTimeString(System.currentTimeMillis())); - } catch (Exception e) { - LogUtil.error(e.getMessage()); - } - } - // report detail - ApiScenarioReportDetail detail = new ApiScenarioReportDetail(); - detail.setReportId(result.getTestId()); - detail.setProjectId(report.getProjectId()); - report.setTestId(result.getTestId()); - detail.setContent(JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8)); - // report - report.setUpdateTime(System.currentTimeMillis()); - if (!StringUtils.equals(report.getStatus(), APITestStatus.Debug.name())) { - if (result.getError() > 0) { - report.setStatus(APITestStatus.Error.name()); + // 更新场景 + if (result != null) { + if (StringUtils.equals(runMode, ApiRunMode.SCENARIO_PLAN.name())) { + return updatePlanCase(result); } else { - report.setStatus(APITestStatus.Success.name()); + return updateScenario(result); } } - report.setContent(new String(detail.getContent(), StandardCharsets.UTF_8)); - this.save(report, runMode); - // 此方法适用于前端发起 - if (!report.getTriggerMode().equals(ReportTriggerMode.SCHEDULE.name())) { - cache.put(report.getId(), report); - } - return report; - } - - /** - * 获取零时执行报告 - * - * @param testId - */ - public APIScenarioReportResult getCacheResult(String testId) { - Object res = cache.get(testId); - if (res != null) { - APIScenarioReportResult reportResult = (APIScenarioReportResult) res; - if (!reportResult.getStatus().equals(APITestStatus.Running.name())) { - cache.remove(testId); - } - return reportResult; - } return null; } - - public void addResult(APIScenarioReportResult res) { - cache.put(res.getId(), res); - } - public APIScenarioReportResult get(String reportId) { APIScenarioReportResult reportResult = extApiScenarioReportMapper.get(reportId); ApiScenarioReportDetail detail = apiScenarioReportDetailMapper.selectByPrimaryKey(reportId); @@ -143,26 +79,14 @@ public class ApiScenarioReportService { } } - public ApiScenarioReport createReport(APIScenarioReportResult test, String scenarioName, String scenarioId, String result, String testId) { - checkNameExist(test); - ApiScenarioReport report = new ApiScenarioReport(); - if (StringUtils.isNotEmpty(testId)) { - report.setId(testId); - } else { - report.setId(UUID.randomUUID().toString()); - } - report.setProjectId(test.getProjectId()); - report.setName(scenarioName + "-" + DateUtils.getTimeStr(System.currentTimeMillis())); - report.setTriggerMode(test.getTriggerMode()); - report.setDescription(test.getDescription()); - report.setCreateTime(System.currentTimeMillis()); + public ApiScenarioReport editReport(ScenarioResult test) { + ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(test.getName()); + report.setId(report.getId()); + report.setName(report.getScenarioName() + "-" + DateUtils.getTimeStr(System.currentTimeMillis())); report.setUpdateTime(System.currentTimeMillis()); - report.setStatus(result); - report.setUserId(test.getUserId()); - report.setExecuteType(test.getExecuteType()); - report.setScenarioId(scenarioId); - report.setScenarioName(scenarioName); - apiScenarioReportMapper.insert(report); + String status = test.getError() == 0 ? "Success" : "Error"; + report.setStatus(status); + apiScenarioReportMapper.updateByPrimaryKeySelective(report); return report; } @@ -194,20 +118,8 @@ public class ApiScenarioReportService { return testResult; } - public void save(APIScenarioReportResult test, String runModel) { - TestResult result = JSON.parseObject(test.getContent(), TestResult.class); - // 更新场景 - if (result != null) { - if (StringUtils.equals(runModel, ApiRunMode.SCENARIO_PLAN.name())) { - updatePlanCase(result, test); - } else { - updateScenario(result, test); - } - } - } - - public void updatePlanCase(TestResult result, APIScenarioReportResult scenarioReportResult) { - TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(scenarioReportResult.getId()); + public ApiScenarioReport updatePlanCase(TestResult result) { + TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(result.getTestId()); ScenarioResult scenarioResult = result.getScenarios().get(0); if (scenarioResult.getError() > 0) { testPlanApiScenario.setLastResult("Fail"); @@ -217,33 +129,44 @@ public class ApiScenarioReportService { String passRate = new DecimalFormat("0%").format((float) scenarioResult.getSuccess() / (scenarioResult.getSuccess() + scenarioResult.getError())); testPlanApiScenario.setPassRate(passRate); // 存储场景报告 - String testId = null; - if (CollectionUtils.isNotEmpty(result.getScenarios()) && result.getScenarios().size() == 1) { - testId = scenarioReportResult.getTestId(); - } - ApiScenarioReport report = createReport(scenarioReportResult, scenarioResult.getName(), testPlanApiScenario.getApiScenarioId(), scenarioResult.getError() == 0 ? "Success" : "Error", testId); + ApiScenarioReport report = editReport(scenarioResult); // 报告详情内容 ApiScenarioReportDetail detail = new ApiScenarioReportDetail(); TestResult newResult = createTestResult(result); List scenarioResults = new ArrayList(); + scenarioResult.setName(report.getScenarioName()); scenarioResults.add(scenarioResult); newResult.setScenarios(scenarioResults); detail.setContent(JSON.toJSONString(newResult).getBytes(StandardCharsets.UTF_8)); detail.setReportId(report.getId()); - detail.setProjectId(scenarioReportResult.getProjectId()); + detail.setProjectId(report.getProjectId()); apiScenarioReportDetailMapper.insert(detail); testPlanApiScenario.setReportId(report.getId()); testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario); + return report; } - public void updateScenario(TestResult result, APIScenarioReportResult scenarioReportResult) { - result.getScenarios().forEach(item -> { - ApiScenarioExample example = new ApiScenarioExample(); - example.createCriteria().andNameEqualTo(item.getName()).andProjectIdEqualTo(scenarioReportResult.getProjectId()); - List list = apiScenarioMapper.selectByExample(example); - if (list.size() > 0) { - ApiScenario scenario = list.get(0); + public ApiScenarioReport updateScenario(TestResult result) { + ApiScenarioReport lastReport = null; + for (ScenarioResult item : result.getScenarios()) { + // 更新报告状态 + ApiScenarioReport report = editReport(item); + + // 报告详情内容 + ApiScenarioReportDetail detail = new ApiScenarioReportDetail(); + TestResult newResult = createTestResult(result); + List scenarioResults = new ArrayList(); + item.setName(report.getScenarioName()); + scenarioResults.add(item); + newResult.setScenarios(scenarioResults); + detail.setContent(JSON.toJSONString(newResult).getBytes(StandardCharsets.UTF_8)); + detail.setReportId(report.getId()); + detail.setProjectId(report.getProjectId()); + apiScenarioReportDetailMapper.insert(detail); + // 更新场景状态 + ApiScenario scenario = apiScenarioMapper.selectByPrimaryKey(report.getScenarioId()); + if (scenario != null) { if (item.getError() > 0) { scenario.setLastResult("Fail"); } else { @@ -251,28 +174,12 @@ public class ApiScenarioReportService { } String passRate = new DecimalFormat("0%").format((float) item.getSuccess() / (item.getSuccess() + item.getError())); scenario.setPassRate(passRate); - - // 存储场景报告 - String testId = null; - if (CollectionUtils.isNotEmpty(result.getScenarios()) && result.getScenarios().size() == 1) { - testId = scenarioReportResult.getTestId(); - } - ApiScenarioReport report = createReport(scenarioReportResult, scenario.getName(), scenario.getId(), scenario.getLastResult(), testId); - // 报告详情内容 - ApiScenarioReportDetail detail = new ApiScenarioReportDetail(); - TestResult newResult = createTestResult(result); - List scenarioResults = new ArrayList(); - scenarioResults.add(item); - newResult.setScenarios(scenarioResults); - detail.setContent(JSON.toJSONString(newResult).getBytes(StandardCharsets.UTF_8)); - detail.setReportId(report.getId()); - detail.setProjectId(scenario.getProjectId()); - apiScenarioReportDetailMapper.insert(detail); - // 更新场景状态 scenario.setReportId(report.getId()); apiScenarioMapper.updateByPrimaryKey(scenario); } - }); + lastReport = report; + } + return lastReport; } public String update(APIScenarioReportResult test) { diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionExecResultMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionExecResultMapper.xml index 0fa037c30c..82cdf50340 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionExecResultMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionExecResultMapper.xml @@ -37,8 +37,8 @@ SELECT testCase.testCaseName AS caseName,testCase.testPlanName AS testPlan ,caseErrorCountData.dataCountNumber AS failureTimes,'apiCase' AS caseType FROM ( SELECT apiCase.id AS testCaseID,apiCase.`name` AS testCaseName,group_concat(testPlan.`name`) AS testPlanName FROM api_test_case apiCase - LEFT JOIN test_plan_api_case testPlanCase ON testPlanCase.api_case_id = apiCase.id - LEFT JOIN test_plan testPlan ON testPlan.id = testPlanCase.test_plan_id + INNER JOIN test_plan_api_case testPlanCase ON testPlanCase.api_case_id = apiCase.id + INNER JOIN test_plan testPlan ON testPlan.id = testPlanCase.test_plan_id GROUP BY apiCase.id ORDER BY apiCase.create_time DESC )testCase @@ -54,7 +54,7 @@ FROM api_scenario_report report INNER JOIN api_scenario_report_detail reportDetail ON report.id = reportDetail.report_id INNER JOIN api_scenario scene ON report.scenario_id = scene.id - LEFT JOIN + INNER JOIN ( SELECT apiScene.api_scenario_id, diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml index 5ad0ad5a92..0048ae51c0 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml @@ -192,5 +192,6 @@ SELECT acitem.`name`,acitem.id FROM api_scenario acitem INNER JOIN `schedule` sc ON acitem.id = sc.resource_id ) ac on ar.scenario_id = ac.id WHERE acr.project_id = #{projectId} + GROUP BY groupField; \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestCaseMapper.xml index 234bf0d40d..fcf28b8024 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestCaseMapper.xml @@ -279,14 +279,14 @@ diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestReportMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestReportMapper.xml index 536eb80268..fec8a3e2c8 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestReportMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestReportMapper.xml @@ -160,6 +160,7 @@ WHERE sch.resource_id IN ( SELECT id FROM api_test WHERE project_id = #{projectId,jdbcType=VARCHAR} ) + GROUP BY groupField;