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 bfde235433..bbd7861248 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -1335,15 +1335,19 @@ public class ApiAutomationService { _importCreate(sameList, batchMapper, extApiScenarioMapper, scenarioWithBLOBs, apiTestImportRequest, apiTestCaseMapper, apiDefinitionMapper); } else if (StringUtils.equals("incrementalMerge", apiTestImportRequest.getModeId())) { if (CollectionUtils.isEmpty(sameList)) { - scenarioWithBLOBs.setOrder(getImportNextOrder(request.getProjectId())); + if (scenarioWithBLOBs.getVersionId() == null || scenarioWithBLOBs.getVersionId().equals("new")) { + scenarioWithBLOBs.setLatest(apiTestImportRequest.getVersionId().equals(apiTestImportRequest.getDefaultVersion())); + } else { + scenarioWithBLOBs.setOrder(getImportNextOrder(request.getProjectId())); + scenarioWithBLOBs.setRefId(scenarioWithBLOBs.getId()); + scenarioWithBLOBs.setLatest(true); + } scenarioWithBLOBs.setId(UUID.randomUUID().toString()); - scenarioWithBLOBs.setRefId(scenarioWithBLOBs.getId()); if (StringUtils.isNotEmpty(apiTestImportRequest.getVersionId())) { scenarioWithBLOBs.setVersionId(apiTestImportRequest.getVersionId()); } else { scenarioWithBLOBs.setVersionId(apiTestImportRequest.getDefaultVersion()); } - scenarioWithBLOBs.setLatest(true); checkReferenceCase(scenarioWithBLOBs, apiTestCaseMapper, apiDefinitionMapper); batchMapper.insert(scenarioWithBLOBs); // 存储依赖关系 @@ -1375,6 +1379,9 @@ public class ApiAutomationService { String defaultVersion = extProjectVersionMapper.getDefaultVersion(request.getProjectId()); request.setDefaultVersion(defaultVersion); + if (request.getVersionId() == null) { + request.setVersionId(defaultVersion); + } UpdateScenarioModuleDTO updateScenarioModuleDTO = apiScenarioModuleService.checkScenarioModule(request, initData, StringUtils.equals("fullCoverage", request.getModeId()), request.getCoverModule()); List moduleList = updateScenarioModuleDTO.getModuleList(); @@ -1404,7 +1411,9 @@ public class ApiAutomationService { if (item.getName().length() > 255) { item.setName(item.getName().substring(0, 255)); } - item.setNum(num); + if (item.getVersionId() == null || !item.getVersionId().equals("new")) { + item.setNum(num); + } if (BooleanUtils.isFalse(request.getOpenCustomNum())) { // 如果未开启,即使有自定值也直接覆盖 item.setCustomNum(String.valueOf(num)); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 71ef39eea8..522608e449 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -803,17 +803,21 @@ public class ApiDefinitionService { _importCreate(collect, batchMapper, apiTestCaseMapper, apiDefinition, extApiDefinitionMapper, apiTestImportRequest, cases, mocks); } else if (StringUtils.equals("incrementalMerge", apiTestImportRequest.getModeId())) { if (CollectionUtils.isEmpty(collect)) { - //postman 可能含有前置脚本,接口定义去掉脚本 - apiDefinition.setOrder(getImportNextOrder(apiTestImportRequest.getProjectId())); String originId = apiDefinition.getId(); + //postman 可能含有前置脚本,接口定义去掉脚本 + if (apiDefinition.getVersionId() == null || apiDefinition.getVersionId().equals("new")) { + apiDefinition.setLatest(apiTestImportRequest.getVersionId().equals(apiTestImportRequest.getDefaultVersion())); + } else { + apiDefinition.setOrder(getImportNextOrder(apiTestImportRequest.getProjectId())); + apiDefinition.setRefId(apiDefinition.getId()); + apiDefinition.setLatest(true); // 新增的接口 latest = true + } apiDefinition.setId(UUID.randomUUID().toString()); - apiDefinition.setRefId(apiDefinition.getId()); if (StringUtils.isNotEmpty(apiTestImportRequest.getVersionId())) { apiDefinition.setVersionId(apiTestImportRequest.getVersionId()); } else { apiDefinition.setVersionId(apiTestImportRequest.getDefaultVersion()); } - apiDefinition.setLatest(true); // 新增的接口 latest = true batchMapper.insert(apiDefinition); String requestStr = setImportHashTree(apiDefinition); @@ -917,7 +921,6 @@ public class ApiDefinitionService { apiDefinition.setOriginalState(existApi.getOriginalState()); apiDefinition.setCaseStatus(existApi.getCaseStatus()); apiDefinition.setNum(existApi.getNum()); //id 不变 - apiDefinition.setRefId(existApi.getRefId()); if (existApi.getRefId() != null) { apiDefinition.setRefId(existApi.getRefId()); } else { @@ -1416,6 +1419,9 @@ public class ApiDefinitionService { currentApiOrder.remove(); String defaultVersion = extProjectVersionMapper.getDefaultVersion(request.getProjectId()); request.setDefaultVersion(defaultVersion); + if (request.getVersionId() == null) { + request.setVersionId(defaultVersion); + } List initData = apiImport.getData(); Project project = projectMapper.selectByPrimaryKey(request.getProjectId()); @@ -1446,14 +1452,20 @@ public class ApiDefinitionService { apiModuleMapper.insert(apiModule); } } - + //如果需要导入的数据为空。此时清空mock信息 + if (data.isEmpty()) { + apiImport.getMocks().clear(); + } for (int i = 0; i < data.size(); i++) { ApiDefinitionWithBLOBs item = data.get(i); this.setModule(item); if (item.getName().length() > 255) { item.setName(item.getName().substring(0, 255)); } - item.setNum(num++); + //如果是创建版本数据,则num和其他版本数据一致 + if (item.getVersionId() == null || !item.getVersionId().equals("new")) { + item.setNum(num++); + } //如果EsbData需要存储,则需要进行接口是否更新的判断 if (apiImport.getEsbApiParamsMap() != null) { String apiId = item.getId(); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java b/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java index 3fd87d4824..438e124043 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java @@ -619,14 +619,9 @@ public class ApiModuleService extends NodeTreeService { if (apiImport.getEsbApiParamsMap() != null) { fullCoverage = true; } - Set versionSet = new HashSet<>(); - if (fullCoverage) { - setFullVersionSet(request, versionSet); - } else { - String updateVersionId = getUpdateVersionId(request); - versionSet.add(updateVersionId); - } + String updateVersionId = getUpdateVersionId(request); + String versionId = getVersionId(request); //需要新增的模块,key 为模块路径 Map moduleMap = new HashMap<>(); @@ -665,29 +660,87 @@ public class ApiModuleService extends NodeTreeService { //处理模块 setModule(moduleMap, pidChildrenMap, idPathMap, idModuleMap, optionData, chooseModule); //系统内重复的数据 - repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByBLOBs(optionData, projectId, versionSet); + repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByBLOBs(optionData, projectId); //处理数据 if (urlRepeat) { - moduleMap = getRepeatApiModuleMap(fullCoverage, fullCoverageApi, moduleMap, toUpdateList, idPathMap, chooseModule, optionData, repeatApiDefinitionWithBLOBs); - //最后在整个体统内检查一遍 + Map methodPathMap; + Map> repeatDataMap; + //按照原来的顺序 + if (chooseModule != null) { + String chooseModuleParentId = getChooseModuleParentId(chooseModule); + String chooseModulePath = getChooseModulePath(idPathMap, chooseModule, chooseModuleParentId); + methodPathMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + t.getMethod() + t.getPath() + chooseModulePath, api -> api)); + ApiModuleDTO finalChooseModule = chooseModule; + repeatDataMap = repeatApiDefinitionWithBLOBs.stream().filter(t -> t.getModuleId().equals(finalChooseModule.getId())).collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath())); + } else { + methodPathMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + t.getMethod() + t.getPath() + (t.getModulePath() == null ? "" : t.getModulePath()), api -> api)); + repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath())); + } + + //覆盖接口 + if (fullCoverage) { + //允许覆盖模块,用导入的重复数据的最后一条覆盖查询的所有重复数据 + if (fullCoverageApi) { + if (!repeatApiDefinitionWithBLOBs.isEmpty()) { + startCoverModule(toUpdateList, optionData, methodPathMap, repeatDataMap, updateVersionId); + } + } else { + //覆盖但不覆盖模块 + if (!repeatApiDefinitionWithBLOBs.isEmpty()) { + moduleMap = judgeModuleMap(moduleMap, methodPathMap, repeatDataMap); + startCover(toUpdateList, optionData, methodPathMap, repeatDataMap, updateVersionId); + } + } + } else { + //不覆盖,同一接口不做更新 + if (!repeatApiDefinitionWithBLOBs.isEmpty()) { + removeSameData(repeatDataMap, methodPathMap, optionData, moduleMap, versionId); + } + } //最后在整个体统内检查一遍 if (!repeatApiDefinitionWithBLOBs.isEmpty()) { Map> repeatMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath())); Map optionMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath(), api -> api)); if (fullCoverage) { - startCover(toUpdateList, optionData, optionMap, repeatMap); + startCover(toUpdateList, optionData, optionMap, repeatMap, updateVersionId); } else { //不覆盖,同一接口不做更新 if (!repeatApiDefinitionWithBLOBs.isEmpty()) { - removeSameData(repeatMap, optionMap, optionData, moduleMap); + removeSameData(repeatMap, optionMap, optionData, moduleMap, versionId); } } } } else { - moduleMap = getOnlyApiModuleMap(fullCoverage, fullCoverageApi, moduleMap, toUpdateList, optionData, repeatApiDefinitionWithBLOBs); + Map methodPathMap; + Map> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getMethod() + t.getPath())); + + //按照原来的顺序 + methodPathMap = optionData.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), api -> api)); + + if (fullCoverage) { + if (fullCoverageApi) { + if (!repeatApiDefinitionWithBLOBs.isEmpty()) { + startCoverModule(toUpdateList, optionData, methodPathMap, repeatDataMap, updateVersionId); + } + } else { + //不覆盖模块 + if (!repeatApiDefinitionWithBLOBs.isEmpty()) { + if (repeatDataMap.size() >= methodPathMap.size()) { + //导入文件没有新增接口无需创建接口模块 + moduleMap = new HashMap<>(); + } + startCover(toUpdateList, optionData, methodPathMap, repeatDataMap, updateVersionId); + } + } + } else { + //不覆盖,同一接口不做更新 + if (!repeatApiDefinitionWithBLOBs.isEmpty()) { + removeSameData(repeatDataMap, methodPathMap, optionData, moduleMap, versionId); + } + } } } else { //去重,TCP,SQL,DUBBO 模块下名称唯一 - removeRepeat(data, fullCoverage, optionData); + removeRepeatOrigin(data, fullCoverage, optionData); //处理模块 setModule(moduleMap, pidChildrenMap, idPathMap, idModuleMap, optionData, chooseModule); @@ -696,19 +749,43 @@ public class ApiModuleService extends NodeTreeService { List nameList = optionData.stream().map(ApiDefinitionWithBLOBs::getName).collect(Collectors.toList()); //获取系统内重复数据 - repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByProtocol(nameList, protocol, versionSet); + repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByProtocol(nameList, protocol); - moduleMap = getOtherApiModuleMap(fullCoverage, fullCoverageApi, chooseModuleId, moduleMap, toUpdateList, idPathMap, chooseModule, optionData, repeatApiDefinitionWithBLOBs); + Map repeatDataMap = null; + Map nameModuleMap = null; + if (chooseModule != null) { + if (!repeatApiDefinitionWithBLOBs.isEmpty()) { + String chooseModuleParentId = getChooseModuleParentId(chooseModule); + String chooseModulePath = getChooseModulePath(idPathMap, chooseModule, chooseModuleParentId); + nameModuleMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + chooseModulePath, api -> api)); + repeatDataMap = repeatApiDefinitionWithBLOBs.stream().filter(t -> t.getModuleId().equals(chooseModuleId)).collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), api -> api)); + } + } else { + nameModuleMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + (t.getModulePath() == null ? "" : t.getModulePath()), api -> api)); + repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), api -> api)); + } + + //处理数据 + if (fullCoverage) { + if (fullCoverageApi) { + coverModule(toUpdateList, nameModuleMap, repeatDataMap, updateVersionId); + } else { + moduleMap = cover(moduleMap, toUpdateList, nameModuleMap, repeatDataMap, updateVersionId); + } + } else { + //不覆盖 + removeRepeat(optionData, nameModuleMap, repeatDataMap, moduleMap, versionId); + } //系统内检查重复 if (!repeatApiDefinitionWithBLOBs.isEmpty()) { Map repeatMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), api -> api)); Map optionMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), api -> api)); if (fullCoverage) { - cover(moduleMap, toUpdateList, optionMap, repeatMap); + cover(moduleMap, toUpdateList, optionMap, repeatMap, updateVersionId); } else { //不覆盖,同一接口不做更新 - removeRepeat(optionData, optionMap, repeatMap, moduleMap); + removeRepeat(optionData, optionMap, repeatMap, moduleMap, versionId); } } } @@ -716,36 +793,6 @@ public class ApiModuleService extends NodeTreeService { return getUpdateApiModuleDTO(moduleMap, toUpdateList, optionData); } - private Map getOtherApiModuleMap(Boolean fullCoverage, Boolean fullCoverageApi, String chooseModuleId, Map moduleMap, List toUpdateList, Map idPathMap, ApiModuleDTO chooseModule, List optionData, List repeatApiDefinitionWithBLOBs) { - Map repeatDataMap = null; - - Map nameModuleMap = null; - if (chooseModule != null) { - if (!repeatApiDefinitionWithBLOBs.isEmpty()) { - String chooseModuleParentId = getChooseModuleParentId(chooseModule); - String chooseModulePath = getChooseModulePath(idPathMap, chooseModule, chooseModuleParentId); - nameModuleMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + chooseModulePath, api -> api)); - repeatDataMap = repeatApiDefinitionWithBLOBs.stream().filter(t -> t.getModuleId().equals(chooseModuleId)).collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), api -> api)); - } - } else { - nameModuleMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + (t.getModulePath() == null ? "" : t.getModulePath()), api -> api)); - repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), api -> api)); - } - - //处理数据 - if (fullCoverage) { - if (fullCoverageApi) { - coverModule(toUpdateList, nameModuleMap, repeatDataMap); - } else { - moduleMap = cover(moduleMap, toUpdateList, nameModuleMap, repeatDataMap); - } - } else { - //不覆盖 - removeRepeat(optionData, nameModuleMap, repeatDataMap, moduleMap); - } - return moduleMap; - } - private UpdateApiModuleDTO getUpdateApiModuleDTO(Map moduleMap, List toUpdateList, List optionData) { UpdateApiModuleDTO updateApiModuleDTO = new UpdateApiModuleDTO(); @@ -755,7 +802,9 @@ public class ApiModuleService extends NodeTreeService { return updateApiModuleDTO; } - private void removeRepeat(List optionData, Map nameModuleMap, Map repeatDataMap, Map moduleMap) { + private void removeRepeat(List optionData, Map nameModuleMap, + Map repeatDataMap, Map moduleMap, + String versionId) { if (nameModuleMap != null) { Map> moduleOptionData = optionData.stream().collect(Collectors.groupingBy(ApiDefinition::getModulePath)); Map finalNameModuleMap = nameModuleMap; @@ -769,13 +818,25 @@ public class ApiModuleService extends NodeTreeService { removeModulePath(moduleMap, moduleOptionData, modulePath); moduleDatas.remove(apiDefinitionWithBLOBs); } - optionData.remove(apiDefinitionWithBLOBs); + //不覆盖选择版本,如果被选版本有同接口,不导入,否则创建新版本接口 + if (v.getVersionId().equals(versionId)) { + optionData.remove(apiDefinitionWithBLOBs); + } else { + //这里是为了标识当前数据是需要创建版本的,不是全新增的数据 + apiDefinitionWithBLOBs.setVersionId("new"); + apiDefinitionWithBLOBs.setNum(v.getNum()); + apiDefinitionWithBLOBs.setStatus(v.getStatus()); + apiDefinitionWithBLOBs.setOrder(v.getOrder()); + apiDefinitionWithBLOBs.setRefId(v.getRefId()); + apiDefinitionWithBLOBs.setLatest(v.getLatest()); + } } }); } } - private Map cover(Map moduleMap, List toUpdateList, Map nameModuleMap, Map repeatDataMap) { + private Map cover(Map moduleMap, List toUpdateList, + Map nameModuleMap, Map repeatDataMap, String updateVersionId) { //覆盖但不覆盖模块 if (nameModuleMap != null) { //导入文件没有新增接口无需创建接口模块 @@ -785,7 +846,7 @@ public class ApiModuleService extends NodeTreeService { ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = finalNameModuleMap.get(k); if (apiDefinitionWithBLOBs != null) { apiDefinitionWithBLOBs.setId(v.getId()); - apiDefinitionWithBLOBs.setVersionId(v.getVersionId()); + apiDefinitionWithBLOBs.setVersionId(updateVersionId); apiDefinitionWithBLOBs.setModuleId(v.getModuleId()); apiDefinitionWithBLOBs.setModulePath(v.getModulePath()); apiDefinitionWithBLOBs.setNum(v.getNum()); @@ -793,6 +854,7 @@ public class ApiModuleService extends NodeTreeService { apiDefinitionWithBLOBs.setOrder(v.getOrder()); apiDefinitionWithBLOBs.setRefId(v.getRefId()); apiDefinitionWithBLOBs.setLatest(v.getLatest()); + apiDefinitionWithBLOBs.setCreateTime(v.getCreateTime()); toUpdateList.add(apiDefinitionWithBLOBs); } }); @@ -817,26 +879,21 @@ public class ApiModuleService extends NodeTreeService { return moduleMap; } - private void coverModule(List toUpdateList, Map nameModuleMap, Map repeatDataMap) { + private void coverModule(List toUpdateList, Map nameModuleMap, Map repeatDataMap, String updateVersionId) { if (nameModuleMap != null) { Map finalNameModuleMap = nameModuleMap; repeatDataMap.forEach((k, v) -> { ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = finalNameModuleMap.get(k); if (apiDefinitionWithBLOBs != null) { apiDefinitionWithBLOBs.setId(v.getId()); - apiDefinitionWithBLOBs.setVersionId(v.getVersionId()); - apiDefinitionWithBLOBs.setNum(v.getNum()); - apiDefinitionWithBLOBs.setStatus(v.getStatus()); - apiDefinitionWithBLOBs.setOrder(v.getOrder()); - apiDefinitionWithBLOBs.setRefId(v.getRefId()); - apiDefinitionWithBLOBs.setLatest(v.getLatest()); + setApiParam(apiDefinitionWithBLOBs, updateVersionId, v); toUpdateList.add(apiDefinitionWithBLOBs); } }); } } - private void removeRepeat(List data, Boolean fullCoverage, List optionData) { + private void removeRepeatOrigin(List data, Boolean fullCoverage, List optionData) { LinkedHashMap> methodPathMap = data.stream().collect(Collectors.groupingBy(t -> t.getName() + (t.getModulePath() == null ? "" : t.getModulePath()), LinkedHashMap::new, Collectors.toList())); if (fullCoverage) { methodPathMap.forEach((k, v) -> { @@ -849,75 +906,6 @@ public class ApiModuleService extends NodeTreeService { } } - private Map getOnlyApiModuleMap(Boolean fullCoverage, Boolean fullCoverageApi, Map moduleMap, List toUpdateList, List optionData, List repeatApiDefinitionWithBLOBs) { - Map methodPathMap; - Map> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getMethod() + t.getPath())); - - //按照原来的顺序 - methodPathMap = optionData.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), api -> api)); - - if (fullCoverage) { - if (fullCoverageApi) { - if (!repeatApiDefinitionWithBLOBs.isEmpty()) { - startCoverModule(toUpdateList, optionData, methodPathMap, repeatDataMap); - } - } else { - //不覆盖模块 - if (!repeatApiDefinitionWithBLOBs.isEmpty()) { - if (repeatDataMap.size() >= methodPathMap.size()) { - //导入文件没有新增接口无需创建接口模块 - moduleMap = new HashMap<>(); - } - startCover(toUpdateList, optionData, methodPathMap, repeatDataMap); - } - } - } else { - //不覆盖,同一接口不做更新 - if (!repeatApiDefinitionWithBLOBs.isEmpty()) { - removeSameData(repeatDataMap, methodPathMap, optionData, moduleMap); - } - } - return moduleMap; - } - - private Map getRepeatApiModuleMap(Boolean fullCoverage, Boolean fullCoverageApi, Map moduleMap, List toUpdateList, Map idPathMap, ApiModuleDTO chooseModule, List optionData, List repeatApiDefinitionWithBLOBs) { - Map methodPathMap; - Map> repeatDataMap; - //按照原来的顺序 - if (chooseModule != null) { - String chooseModuleParentId = getChooseModuleParentId(chooseModule); - String chooseModulePath = getChooseModulePath(idPathMap, chooseModule, chooseModuleParentId); - methodPathMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + t.getMethod() + t.getPath() + chooseModulePath, api -> api)); - repeatDataMap = repeatApiDefinitionWithBLOBs.stream().filter(t -> t.getModuleId().equals(chooseModule.getId())).collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath())); - } else { - methodPathMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + t.getMethod() + t.getPath() + (t.getModulePath() == null ? "" : t.getModulePath()), api -> api)); - repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath())); - } - - - //覆盖接口 - if (fullCoverage) { - //允许覆盖模块,用导入的重复数据的最后一条覆盖查询的所有重复数据 - if (fullCoverageApi) { - if (!repeatApiDefinitionWithBLOBs.isEmpty()) { - startCoverModule(toUpdateList, optionData, methodPathMap, repeatDataMap); - } - } else { - //覆盖但不覆盖模块 - if (!repeatApiDefinitionWithBLOBs.isEmpty()) { - moduleMap = judgeModuleMap(moduleMap, methodPathMap, repeatDataMap); - startCover(toUpdateList, optionData, methodPathMap, repeatDataMap); - } - } - } else { - //不覆盖,同一接口不做更新 - if (!repeatApiDefinitionWithBLOBs.isEmpty()) { - removeSameData(repeatDataMap, methodPathMap, optionData, moduleMap); - } - } - return moduleMap; - } - private void removeHTTPRepeat(List data, Boolean fullCoverage, boolean urlRepeat, List optionData) { if (urlRepeat) { LinkedHashMap> methodPathMap = data.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + (t.getModulePath() == null ? "" : t.getModulePath()), LinkedHashMap::new, Collectors.toList())); @@ -944,34 +932,29 @@ public class ApiModuleService extends NodeTreeService { } } - private void setFullVersionSet(ApiTestImportRequest request, Set versionSet) { - String creatVersionId; - if (request.getVersionId() != null) { - creatVersionId = request.getVersionId(); + private String getVersionId(ApiTestImportRequest request) { + String versionId; + if (request.getVersionId() == null) { + versionId = request.getDefaultVersion(); } else { - creatVersionId = request.getDefaultVersion(); + versionId = request.getVersionId(); } - versionSet.add(creatVersionId); + return versionId; + } + + private String getUpdateVersionId(ApiTestImportRequest request) { String updateVersionId; if (request.getUpdateVersionId() != null) { updateVersionId = request.getUpdateVersionId(); } else { updateVersionId = request.getDefaultVersion(); } - versionSet.add(updateVersionId); - } - - private String getUpdateVersionId(ApiTestImportRequest request) { - String updateVersionId; - if (request.getVersionId() == null) { - updateVersionId = request.getDefaultVersion(); - } else { - updateVersionId = request.getVersionId(); - } return updateVersionId; } - private void removeSameData(Map> repeatDataMap, Map methodPathMap, List optionData, Map moduleMap) { + private void removeSameData(Map> repeatDataMap, Map methodPathMap, + List optionData, Map moduleMap, String versionId) { + Map> moduleOptionData = optionData.stream().collect(Collectors.groupingBy(ApiDefinition::getModulePath)); BiConsumer> stringListBiConsumer = (k, v) -> { ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k); @@ -983,13 +966,35 @@ public class ApiModuleService extends NodeTreeService { removeModulePath(moduleMap, moduleOptionData, modulePath); moduleDatas.remove(apiDefinitionWithBLOBs); } - - optionData.remove(apiDefinitionWithBLOBs); + //不覆盖选择版本,如果被选版本有同接口,不导入,否则创建新版本接口 + List sameVersionList = v.stream().filter(t -> t.getVersionId().equals(versionId)).collect(Collectors.toList()); + if (!sameVersionList.isEmpty()) { + optionData.remove(apiDefinitionWithBLOBs); + } else { + for (ApiDefinitionWithBLOBs definitionWithBLOBs : v) { + apiDefinitionWithBLOBs.setVersionId("new"); + apiDefinitionWithBLOBs.setNum(definitionWithBLOBs.getNum()); + apiDefinitionWithBLOBs.setStatus(definitionWithBLOBs.getStatus()); + apiDefinitionWithBLOBs.setOrder(definitionWithBLOBs.getOrder()); + apiDefinitionWithBLOBs.setRefId(definitionWithBLOBs.getRefId()); + apiDefinitionWithBLOBs.setLatest(definitionWithBLOBs.getLatest()); + } + } } }; repeatDataMap.forEach(stringListBiConsumer); } + private void setApiParam(ApiDefinitionWithBLOBs apiDefinitionWithBLOBs, String versionId, ApiDefinitionWithBLOBs definitionWithBLOBs) { + apiDefinitionWithBLOBs.setVersionId(versionId); + apiDefinitionWithBLOBs.setNum(definitionWithBLOBs.getNum()); + apiDefinitionWithBLOBs.setStatus(definitionWithBLOBs.getStatus()); + apiDefinitionWithBLOBs.setOrder(definitionWithBLOBs.getOrder()); + apiDefinitionWithBLOBs.setRefId(definitionWithBLOBs.getRefId()); + apiDefinitionWithBLOBs.setLatest(definitionWithBLOBs.getLatest()); + apiDefinitionWithBLOBs.setCreateTime(definitionWithBLOBs.getCreateTime()); + } + private void removeModulePath(Map moduleMap, Map> moduleOptionData, String modulePath) { if (StringUtils.isBlank(modulePath)) { return; @@ -1004,7 +1009,9 @@ public class ApiModuleService extends NodeTreeService { } - private void startCoverModule(List toUpdateList, List optionData, Map methodPathMap, Map> repeatDataMap) { + private void startCoverModule(List toUpdateList, List optionData, + Map methodPathMap, Map> repeatDataMap, + String updateVersionId) { List coverApiList = new ArrayList<>(); repeatDataMap.forEach((k, v) -> { ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k); @@ -1013,12 +1020,13 @@ public class ApiModuleService extends NodeTreeService { ApiDefinitionWithBLOBs api = new ApiDefinitionWithBLOBs(); BeanUtils.copyBean(api, apiDefinitionWithBLOBs); api.setId(definitionWithBLOBs.getId()); - api.setVersionId(definitionWithBLOBs.getVersionId()); + api.setVersionId(updateVersionId); api.setOrder(definitionWithBLOBs.getOrder()); api.setRefId(apiDefinitionWithBLOBs.getRefId()); api.setLatest(apiDefinitionWithBLOBs.getLatest()); api.setNum(definitionWithBLOBs.getNum()); api.setStatus(definitionWithBLOBs.getStatus()); + api.setCreateTime(definitionWithBLOBs.getCreateTime()); coverApiList.add(api); } optionData.remove(apiDefinitionWithBLOBs); @@ -1027,7 +1035,9 @@ public class ApiModuleService extends NodeTreeService { buildOtherParam(toUpdateList, optionData, coverApiList); } - private void startCover(List toUpdateList, List optionData, Map methodPathMap, Map> repeatDataMap) { + private void startCover(List toUpdateList, List optionData, + Map methodPathMap, Map> repeatDataMap, + String updateVersionId) { List coverApiList = new ArrayList<>(); repeatDataMap.forEach((k, v) -> { ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k); @@ -1038,12 +1048,13 @@ public class ApiModuleService extends NodeTreeService { api.setId(definitionWithBLOBs.getId()); api.setNum(definitionWithBLOBs.getNum()); api.setStatus(definitionWithBLOBs.getStatus()); - api.setVersionId(definitionWithBLOBs.getVersionId()); + api.setVersionId(updateVersionId); api.setModuleId(definitionWithBLOBs.getModuleId()); api.setModulePath(definitionWithBLOBs.getModulePath()); api.setOrder(definitionWithBLOBs.getOrder()); api.setRefId(apiDefinitionWithBLOBs.getRefId()); api.setLatest(apiDefinitionWithBLOBs.getLatest()); + api.setCreateTime(definitionWithBLOBs.getCreateTime()); coverApiList.add(api); } optionData.remove(apiDefinitionWithBLOBs); @@ -1068,6 +1079,7 @@ public class ApiModuleService extends NodeTreeService { private void buildOtherParam(List toUpdateList, List optionData, List coverApiList) { optionData.addAll(coverApiList); toUpdateList.addAll(coverApiList); + } private List setModule(Map moduleMap, Map> pidChildrenMap, @@ -1116,7 +1128,6 @@ public class ApiModuleService extends NodeTreeService { String chooseModuleParentId = getChooseModuleParentId(chooseModule); //导入时选了模块,且接口有模块的 if (StringUtils.isNotBlank(modulePath)) { - List moduleList = pidChildrenMap.get(chooseModuleParentId); pathTree = getPathTree(modulePath); ApiModule chooseModuleOne = JSON.parseObject(JSON.toJSONString(chooseModule), ApiModule.class); ApiModule minModule = getChooseMinModule(pathTree, chooseModuleOne, pidChildrenMap, moduleMap, idPathMap); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java index 9b15059be1..57bc362f0b 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java @@ -503,49 +503,21 @@ public class ApiScenarioModuleService extends NodeTreeService versionSet = new HashSet<>(); - - if (fullCoverage) { - setFullVersionSet(request, versionSet); - } else { - String updateVersionId = getUpdateVersionId(request); - versionSet.add(updateVersionId); - } - + String updateVersionId = getUpdateVersionId(request); + String versionId = getVersionId(request); List optionData = new ArrayList<>(); //覆盖模式留重复的最后一个,不覆盖留第一个 LinkedHashMap> nameModuleMapList = data.stream().collect(Collectors.groupingBy(t -> t.getName() + (t.getModulePath() == null ? "" : t.getModulePath()), LinkedHashMap::new, Collectors.toList())); - removeRepeat(fullCoverage, optionData, nameModuleMapList); + removeRepeatOrigin(fullCoverage, optionData, nameModuleMapList); //处理模块 setModule(optionData, moduleMap, pidChildrenMap, idPathMap, idModuleMap, chooseModule); List names = optionData.stream().map(ApiScenario::getName).collect(Collectors.toList()); //系统内重复的数据 - List repeatApiScenarioWithBLOBs = extApiScenarioMapper.selectRepeatByBLOBs(names, projectId, versionSet); + List repeatApiScenarioWithBLOBs = extApiScenarioMapper.selectRepeatByBLOBs(names, projectId); - moduleMap = getApiScenarioModuleMap(fullCoverage, fullCoverageScenario, moduleMap, toUpdateList, chooseModuleId, idPathMap, chooseModule, optionData, repeatApiScenarioWithBLOBs); - - if (!repeatApiScenarioWithBLOBs.isEmpty()) { - Map repeatMap = repeatApiScenarioWithBLOBs.stream().collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), scenario -> scenario)); - Map optionMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), scenario -> scenario)); - if (fullCoverage) { - startCover(toUpdateList, optionMap, repeatMap); - } else { - //不覆盖,同一接口不做更新 - removeRepeat(optionData, optionMap, repeatMap, moduleMap); - } - } - - UpdateScenarioModuleDTO updateScenarioModuleDTO = new UpdateScenarioModuleDTO(); - updateScenarioModuleDTO.setModuleList(new ArrayList<>(moduleMap.values())); - updateScenarioModuleDTO.setNeedUpdateList(toUpdateList); - updateScenarioModuleDTO.setApiScenarioWithBLOBsList(optionData); - return updateScenarioModuleDTO; - } - - private Map getApiScenarioModuleMap(Boolean fullCoverage, Boolean fullCoverageScenario, Map moduleMap, List toUpdateList, String chooseModuleId, Map idPathMap, ApiScenarioModuleDTO chooseModule, List optionData, List repeatApiScenarioWithBLOBs) { Map nameModuleMap = null; Map repeatDataMap = null; if (chooseModule != null) { @@ -562,40 +534,41 @@ public class ApiScenarioModuleService extends NodeTreeService repeatMap = repeatApiScenarioWithBLOBs.stream().collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), scenario -> scenario)); + Map optionMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), scenario -> scenario)); + if (fullCoverage) { + startCover(toUpdateList, optionMap, repeatMap, updateVersionId); + } else { + //不覆盖,同一接口不做更新 + removeRepeat(optionData, optionMap, repeatMap, moduleMap, versionId); + } + } + + UpdateScenarioModuleDTO updateScenarioModuleDTO = new UpdateScenarioModuleDTO(); + updateScenarioModuleDTO.setModuleList(new ArrayList<>(moduleMap.values())); + updateScenarioModuleDTO.setNeedUpdateList(toUpdateList); + updateScenarioModuleDTO.setApiScenarioWithBLOBsList(optionData); + return updateScenarioModuleDTO; } - private void setFullVersionSet(ApiTestImportRequest request, Set versionSet) { - String creatVersionId; - if (request.getVersionId() != null) { - creatVersionId = request.getVersionId(); - } else { - creatVersionId = request.getDefaultVersion(); - } - versionSet.add(creatVersionId); - String updateVersionId; - if (request.getUpdateVersionId() != null) { - updateVersionId = request.getUpdateVersionId(); - } else { - updateVersionId = request.getDefaultVersion(); - } - versionSet.add(updateVersionId); - } - - private void removeRepeat(List optionData, Map nameModuleMap, Map repeatDataMap, Map moduleMap) { + private void removeRepeat(List optionData, Map nameModuleMap, + Map repeatDataMap, Map moduleMap, + String versionId) { if (repeatDataMap != null) { Map> moduleOptionData = optionData.stream().collect(Collectors.groupingBy(ApiScenario::getModulePath)); repeatDataMap.forEach((k, v) -> { @@ -608,7 +581,18 @@ public class ApiScenarioModuleService extends NodeTreeService toUpdateList, Map nameModuleMap, Map repeatDataMap) { + private void startCover(List toUpdateList, Map nameModuleMap, Map repeatDataMap, String updateVersionId) { repeatDataMap.forEach((k, v) -> { ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameModuleMap.get(k); if (apiScenarioWithBLOBs != null) { apiScenarioWithBLOBs.setId(v.getId()); - apiScenarioWithBLOBs.setVersionId(v.getVersionId()); + apiScenarioWithBLOBs.setVersionId(updateVersionId); apiScenarioWithBLOBs.setApiScenarioModuleId(v.getApiScenarioModuleId()); apiScenarioWithBLOBs.setModulePath(v.getModulePath()); apiScenarioWithBLOBs.setNum(v.getNum()); apiScenarioWithBLOBs.setStatus(v.getStatus()); + apiScenarioWithBLOBs.setCreateTime(v.getCreateTime()); + apiScenarioWithBLOBs.setRefId(v.getRefId()); + apiScenarioWithBLOBs.setOrder(v.getOrder()); + apiScenarioWithBLOBs.setLatest(v.getLatest()); toUpdateList.add(apiScenarioWithBLOBs); } }); @@ -660,22 +648,27 @@ public class ApiScenarioModuleService extends NodeTreeService toUpdateList, Map nameModuleMap, Map repeatDataMap) { + private void startCoverModule(List toUpdateList, Map nameModuleMap, + Map repeatDataMap, String updateVersionId) { if (repeatDataMap != null) { repeatDataMap.forEach((k, v) -> { ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameModuleMap.get(k); if (apiScenarioWithBLOBs != null) { apiScenarioWithBLOBs.setId(v.getId()); - apiScenarioWithBLOBs.setVersionId(v.getVersionId()); + apiScenarioWithBLOBs.setVersionId(updateVersionId); apiScenarioWithBLOBs.setNum(v.getNum()); apiScenarioWithBLOBs.setStatus(v.getStatus()); + apiScenarioWithBLOBs.setCreateTime(v.getCreateTime()); + apiScenarioWithBLOBs.setRefId(v.getRefId()); + apiScenarioWithBLOBs.setOrder(v.getOrder()); + apiScenarioWithBLOBs.setLatest(v.getLatest()); toUpdateList.add(apiScenarioWithBLOBs); } }); } } - private void removeRepeat(Boolean fullCoverage, List optionData, LinkedHashMap> nameModuleMapList) { + private void removeRepeatOrigin(Boolean fullCoverage, List optionData, LinkedHashMap> nameModuleMapList) { if (fullCoverage) { nameModuleMapList.forEach((k, v) -> { optionData.add(v.get(v.size() - 1)); @@ -687,12 +680,22 @@ public class ApiScenarioModuleService extends NodeTreeService parentModuleList = pidChildrenMap.get(chooseModuleParentId); //场景的全部路径的集合 - tagTree = getTagTree(chooseModulePath + modulePath); - + tagTree = getTagTree(modulePath); ApiScenarioModule chooseModuleOne = JSON.parseObject(JSON.toJSONString(chooseModule), ApiScenarioModule.class); ApiScenarioModule minModule = getChooseMinModule(tagTree, chooseModuleOne, pidChildrenMap, map, idPathMap); String id = minModule.getId(); diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java index e25496ca6f..b4df6ccbf0 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java @@ -93,11 +93,11 @@ public interface ExtApiDefinitionMapper { int toBeUpdateApi(@Param("ids") List ids, @Param("toBeUpdate") Boolean toBeUpdate); - List selectRepeatByBLOBs(@Param("blobs") List blobs, @Param("projectId") String projectId, @Param("versionIds") Set versionIds); + List selectRepeatByBLOBs(@Param("blobs") List blobs, @Param("projectId") String projectId); - List selectRepeatByBLOBsSameUrl(@Param("blobs") List blobs, @Param("projectId") String projectId, @Param("moduleId") String moduleId, @Param("versionIds") Set versionIds); + List selectRepeatByBLOBsSameUrl(@Param("blobs") List blobs, @Param("projectId") String projectId, @Param("moduleId") String moduleId); - List selectRepeatByProtocol(@Param("names") List names, @Param("protocol") String protocol, @Param("versionIds") Set versionIds); + List selectRepeatByProtocol(@Param("names") List names, @Param("protocol") String protocol); int countById(String id); } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml index 61d46712a4..91ce128429 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml @@ -1087,10 +1087,6 @@ and status != 'Trash' and project_id = #{projectId} - and version_id in - - #{versionId} - diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java index 84c6b219a3..7986378334 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java @@ -91,7 +91,7 @@ public interface ExtApiScenarioMapper { List selectByStatusIsNotTrash(); - List selectRepeatByBLOBs(@Param("names") List names, @Param("projectId") String projectId, @Param("versionIds") Set versionIds); + List selectRepeatByBLOBs(@Param("names") List names, @Param("projectId") String projectId); } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml index 8bf3066280..e02e3d6ec1 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml @@ -828,10 +828,6 @@ and status != 'Trash' and project_id = #{projectId} - and version_id in - - #{versionId} -