fix(接口测试): 场景接口模块导入逻辑重构

--user=郭雨琦
This commit is contained in:
guoyuqi 2022-06-29 17:15:57 +08:00 committed by xiaomeinvG
parent 9ca3c0ba75
commit f21a4a5c5d
10 changed files with 462 additions and 261 deletions

View File

@ -11,5 +11,6 @@ import java.util.List;
@Setter
public class UpdateScenarioModuleDTO {
private List<ApiScenarioModule> moduleList;
private List<ApiScenarioWithBLOBs> needUpdateList;
private List<ApiScenarioWithBLOBs> apiScenarioWithBLOBsList;
}

View File

@ -11,6 +11,7 @@ import java.util.List;
@Setter
public class UpdateApiModuleDTO {
private List<ApiModule> moduleList;
private List<ApiDefinitionWithBLOBs> apiDefinitionWithBLOBsList;
private List<ApiDefinitionWithBLOBs> needUpdateList;
private List<ApiDefinitionWithBLOBs> definitionWithBLOBs;
}

View File

@ -76,6 +76,8 @@ import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
@Service
@Transactional(rollbackFor = Exception.class)
public class ApiAutomationService {
@ -1336,17 +1338,21 @@ public class ApiAutomationService {
ApiDefinitionMapper apiDefinitionMapper = sqlSession.getMapper(ApiDefinitionMapper.class);
ApiScenarioModuleMapper apiScenarioModuleMapper = sqlSession.getMapper(ApiScenarioModuleMapper.class);
List<ApiScenarioWithBLOBs> data = apiImport.getData();
List<ApiScenarioWithBLOBs> initData = apiImport.getData();
currentScenarioOrder.remove();
UpdateScenarioModuleDTO updateScenarioModuleDTO = apiScenarioModuleService.checkScenarioModule(request.getModuleId(), request.getProjectId(), data, StringUtils.equals("fullCoverage", request.getModeId()), request.getCoverModule());
UpdateScenarioModuleDTO updateScenarioModuleDTO = apiScenarioModuleService.checkScenarioModule(request, initData, StringUtils.equals("fullCoverage", request.getModeId()), request.getCoverModule());
List<ApiScenarioModule> moduleList = updateScenarioModuleDTO.getModuleList();
List<ApiScenarioWithBLOBs> apiScenarioWithBLOBsList = updateScenarioModuleDTO.getApiScenarioWithBLOBsList();
List<ApiScenarioWithBLOBs> data = updateScenarioModuleDTO.getApiScenarioWithBLOBsList();
List<ApiScenarioWithBLOBs> needUpdateList = updateScenarioModuleDTO.getNeedUpdateList();
if (moduleList != null) {
for (ApiScenarioModule apiScenarioModule : moduleList) {
apiScenarioModuleMapper.insert(apiScenarioModule);
}
}
int num = 0;
Project project = new Project();
Project project;
if (!CollectionUtils.isEmpty(data) && data.get(0) != null && data.get(0).getProjectId() != null) {
project = projectMapper.selectByPrimaryKey(data.get(0).getProjectId());
ProjectConfig config = projectApplicationService.getSpecificTypeValue(project.getId(), ProjectApplicationType.SCENARIO_CUSTOM_NUM.name());
@ -1358,7 +1364,7 @@ public class ApiAutomationService {
for (int i = 0; i < data.size(); i++) {
ApiScenarioWithBLOBs item = data.get(i);
List<ApiScenarioWithBLOBs> sameList = apiScenarioWithBLOBsList.stream().filter(t -> t.getName().equals(item.getName())).collect(Collectors.toList());
List<ApiScenarioWithBLOBs> sameList = needUpdateList.stream().filter(t -> t.getId().equals(item.getId())).collect(toList());
if (StringUtils.isBlank(item.getCreateUser())) {
item.setCreateUser(SessionUtils.getUserId());
}

View File

@ -1376,25 +1376,29 @@ public class ApiDefinitionService {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
currentApiCaseOrder.remove();
currentApiOrder.remove();
List<ApiDefinitionWithBLOBs> data = apiImport.getData();
String defaultVersion = extProjectVersionMapper.getDefaultVersion(request.getProjectId());
request.setDefaultVersion(defaultVersion);
List<ApiDefinitionWithBLOBs> initData = apiImport.getData();
Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
ProjectConfig config = projectApplicationService.getSpecificTypeValue(project.getId(), ProjectApplicationType.URL_REPEATABLE.name());
boolean urlRepeat = config.getUrlRepeatable();
UpdateApiModuleDTO updateApiModuleDTO = apiModuleService.checkApiModule(request.getModuleId(), request.getProjectId(), apiImport.getProtocol(), data, StringUtils.equals("fullCoverage", request.getModeId()), request.getCoverModule(), urlRepeat);
List<ApiDefinitionWithBLOBs> updateList = updateApiModuleDTO.getApiDefinitionWithBLOBsList();
UpdateApiModuleDTO updateApiModuleDTO = apiModuleService.checkApiModule(request, apiImport, initData, StringUtils.equals("fullCoverage", request.getModeId()), urlRepeat);
List<ApiDefinitionWithBLOBs> updateList = updateApiModuleDTO.getNeedUpdateList();
List<ApiDefinitionWithBLOBs> data = updateApiModuleDTO.getDefinitionWithBLOBs();
List<ApiModule> moduleList = updateApiModuleDTO.getModuleList();
ApiDefinitionMapper batchMapper = sqlSession.getMapper(ApiDefinitionMapper.class);
ApiTestCaseMapper apiTestCaseMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
ExtApiDefinitionMapper extApiDefinitionMapper = sqlSession.getMapper(ExtApiDefinitionMapper.class);
ApiModuleMapper apiModuleMapper = sqlSession.getMapper(ApiModuleMapper.class);
int num = 0;
if (!CollectionUtils.isEmpty(data) && data.get(0) != null && data.get(0).getProjectId() != null) {
num = getNextNum(data.get(0).getProjectId());
}
String defaultVersion = extProjectVersionMapper.getDefaultVersion(request.getProjectId());
request.setDefaultVersion(defaultVersion);
for (int i = 0; i < data.size(); i++) {
ApiDefinitionWithBLOBs item = data.get(i);
this.setModule(item);
@ -1416,9 +1420,11 @@ public class ApiDefinitionService {
} else {
importCreate(item, batchMapper, apiTestCaseMapper, extApiDefinitionMapper, request, apiImport.getCases(), apiImport.getMocks(), updateList);
}
for (ApiModule apiModule : updateApiModuleDTO.getModuleList()) {
if (moduleList != null) {
for (ApiModule apiModule : moduleList) {
apiModuleMapper.insert(apiModule);
}
}
if (i % 300 == 0) {
sqlSession.flushStatements();
}

View File

@ -2,7 +2,9 @@ package io.metersphere.api.service;
import com.alibaba.fastjson.JSON;
import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.definition.*;
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiDefinitionMapper;
import io.metersphere.base.mapper.ApiModuleMapper;
@ -10,6 +12,7 @@ import io.metersphere.base.mapper.ext.ExtApiDefinitionMapper;
import io.metersphere.base.mapper.ext.ExtApiModuleMapper;
import io.metersphere.commons.constants.TestCaseConstants;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.i18n.Translator;
@ -600,137 +603,280 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
/**
* 上传文件时对文件的模块进行检测
*
* @param moduleId 上传文件时选的模块ID
* @param projectId
* @param protocol
* @param data
* @param fullCoverage 是否覆盖接口
* @param fullCoverageApi 是否更新当前接口所在模块 (如果开启url重复可重复的是某一模块下的接口只在这个模块下不包含其子模块)
* @return Return to the newly added module list and api list
*/
public UpdateApiModuleDTO checkApiModule(String moduleId, String projectId, String protocol, List<ApiDefinitionWithBLOBs> data, Boolean fullCoverage, Boolean fullCoverageApi, boolean urlRepeat) {
Map<String, ApiModule> map = new HashMap<>();
Map<String, ApiDefinitionWithBLOBs> updateApiMap = new HashMap<>();
public UpdateApiModuleDTO checkApiModule(ApiTestImportRequest request, ApiDefinitionImport apiImport, List<ApiDefinitionWithBLOBs> data, Boolean fullCoverage, boolean urlRepeat) {
Boolean fullCoverageApi = request.getCoverModule();
String projectId = request.getProjectId();
String protocol = request.getProtocol();
//上传文件时选的模块ID
String chooseModuleId = request.getModuleId();
//标准版ESB数据导入不区分是否覆盖默认都为覆盖
if (apiImport.getEsbApiParamsMap() != null) {
fullCoverage = true;
}
String updateVersionId = getUpdateVersionId(request, fullCoverage);
//需要新增的模块key 为模块路径
Map<String, ApiModule> moduleMap = new HashMap<>();
//系统原有的需要更新的list
List<ApiDefinitionWithBLOBs> toUpdateList = new ArrayList<>();
//获取当前项目的当前协议下的所有模块的Tree
List<ApiModuleDTO> apiModules = this.getApiModulesByProjectAndPro(projectId, protocol);
List<ApiModuleDTO> nodeTreeByProjectId = this.getNodeTrees(apiModules);
Map<String, List<ApiModule>> pidChildrenMap = new HashMap<>();
Map<String, String> idPathMap = new HashMap<>();
//所有模块的ID 及其自身 的map
Map<String, ApiModuleDTO> idModuleMap = apiModules.stream().collect(Collectors.toMap(ApiModuleDTO::getId, apiModuleDTO -> apiModuleDTO));
buildProcessData(nodeTreeByProjectId, pidChildrenMap, idPathMap);
Map<String, ApiDefinitionWithBLOBs> methodPathMap = data.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), apiDefinition -> apiDefinition));
//父级ID与其子模块集合的map
Map<String, List<ApiModule>> pidChildrenMap = new HashMap<>();
//所有模块的ID 及其全路径的map
Map<String, String> idPathMap = new HashMap<>();
String initParentModulePath = "/root";
Map<String, String> initParentModulePathMap = new HashMap<>();
initParentModulePathMap.put("root", initParentModulePath);
buildProcessData(nodeTreeByProjectId, pidChildrenMap, idPathMap, initParentModulePathMap);
//获取选中的模块
ApiModuleDTO chooseModule = null;
if (moduleId != null) {
chooseModule = idModuleMap.get(moduleId);
if (chooseModuleId != null) {
chooseModule = idModuleMap.get(chooseModuleId);
}
List<ApiDefinitionWithBLOBs> optionData = new ArrayList<>();
//去重 如果url可重复 则模块+名称+请求方式+路径 唯一否则 请求方式+路径唯一
//覆盖模式留重复的最后一个不覆盖留第一个
removeRepeat(data, fullCoverage, urlRepeat, optionData);
//处理模块
setModule(moduleMap, pidChildrenMap, idPathMap, idModuleMap, optionData, chooseModule);
//系统内重复的数据
List<ApiDefinitionWithBLOBs> repeatApiDefinitionWithBLOBs;
if (chooseModule != null) {
repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByBLOBsSameUrl(data, chooseModule.getId());
repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByBLOBsSameUrl(data, projectId, chooseModule.getId(), updateVersionId);
} else {
repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByBLOBs(data);
repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByBLOBs(data, projectId, updateVersionId);
}
//允许接口重复
//处理数据
if (urlRepeat) {
//允许覆盖接口
//按照原来的顺序
Map<String, ApiDefinitionWithBLOBs> methodPathMap = data.stream().collect(Collectors.toMap(t -> t.getName() + t.getMethod() + t.getPath() + (t.getModulePath() == null ? "" : t.getModulePath()), api -> api));
//覆盖接口
if (fullCoverage) {
//允许覆盖模块
//允许覆盖模块用导入的重复数据的最后一条覆盖查询的所有重复数据
if (fullCoverageApi) {
coverApiModule(map, updateApiMap, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule, repeatApiDefinitionWithBLOBs);
} else {
//覆盖但不覆盖模块
justCoverApi(map, updateApiMap, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule, repeatApiDefinitionWithBLOBs);
}
} else {
//不覆盖接口直接新增
setModule(map, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule);
}
} else {
//不允许接口重复
if (fullCoverage) {
if (fullCoverageApi) {
coverApiModule(map, updateApiMap, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule, repeatApiDefinitionWithBLOBs);
} else {
//覆盖但不覆盖模块
justCoverApi(map, updateApiMap, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule, repeatApiDefinitionWithBLOBs);
}
} else {
//不覆盖接口
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
Map<String, ApiDefinitionWithBLOBs> collect = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), apiDefinition -> apiDefinition));
collect.forEach((k, v) -> {
if (methodPathMap.get(k) != null) {
methodPathMap.remove(k);
Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath()));
startCoverModule(toUpdateList, optionData, methodPathMap, repeatDataMap);
}
});
} else {
//覆盖但不覆盖模块
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath()));
moduleMap = judgeModuleMap(moduleMap, methodPathMap, repeatDataMap);
startCover(toUpdateList, optionData, methodPathMap, repeatDataMap);
}
setModule(map, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule);
}
} else {
//不覆盖,同一接口不做更新
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath()));
removeSameData(repeatDataMap, methodPathMap, optionData);
}
}
} else {
Map<String, ApiDefinitionWithBLOBs> methodPathMap = optionData.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), api -> api));
if (fullCoverage) {
if (fullCoverageApi) {
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getMethod() + t.getPath()));
startCoverModule(toUpdateList, optionData, methodPathMap, repeatDataMap);
}
} else {
//不覆盖模块
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getMethod() + t.getPath()));
if (repeatDataMap.size() >= methodPathMap.size()) {
//导入文件没有新增接口无需创建接口模块
moduleMap = new HashMap<>();
}
startCover(toUpdateList, optionData, methodPathMap, repeatDataMap);
}
}
} else {
//不覆盖,同一接口不做更新
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getMethod() + t.getPath()));
removeSameData(repeatDataMap, methodPathMap, optionData);
}
}
}
UpdateApiModuleDTO updateApiModuleDTO = new UpdateApiModuleDTO();
updateApiModuleDTO.setModuleList((List<ApiModule>) map.values());
updateApiModuleDTO.setApiDefinitionWithBLOBsList((List<ApiDefinitionWithBLOBs>) updateApiMap.values());
updateApiModuleDTO.setModuleList(new ArrayList<>(moduleMap.values()));
updateApiModuleDTO.setNeedUpdateList(toUpdateList);
updateApiModuleDTO.setDefinitionWithBLOBs(optionData);
return updateApiModuleDTO;
}
private void coverApiModule(Map<String, ApiModule> map, Map<String, ApiDefinitionWithBLOBs> updateApiMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, Map<String, ApiDefinitionWithBLOBs> methodPathMap, ApiModuleDTO chooseModule, List<ApiDefinitionWithBLOBs> repeatApiDefinitionWithBLOBs) {
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
Map<String, ApiDefinitionWithBLOBs> collect = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), apiDefinition -> apiDefinition));
collect.forEach((k, v) -> {
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k);
if (apiDefinitionWithBLOBs != null) {
//Check whether the content has changed, if not, do not change the creatoCover
Boolean toCover = apiDefinitionService.checkIsSynchronize(v, apiDefinitionWithBLOBs);
//需要更新
if (toCover) {
if (updateApiMap.get(k) != null) {
apiDefinitionWithBLOBs.setId(v.getId());
updateApiMap.put(k, apiDefinitionWithBLOBs);
private void removeRepeat(List<ApiDefinitionWithBLOBs> data, Boolean fullCoverage, boolean urlRepeat, List<ApiDefinitionWithBLOBs> optionData) {
if (urlRepeat) {
LinkedHashMap<String, List<ApiDefinitionWithBLOBs>> methodPathMap = data.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + (t.getModulePath() == null ? "" : t.getModulePath()), LinkedHashMap::new, Collectors.toList()));
if (fullCoverage) {
methodPathMap.forEach((k, v) -> {
optionData.add(v.get(v.size() - 1));
});
} else {
methodPathMap.forEach((k, v) -> {
optionData.add(v.get(0));
});
}
} else {
methodPathMap.remove(k);
}
}
LinkedHashMap<String, List<ApiDefinitionWithBLOBs>> methodPathMap = data.stream().collect(Collectors.groupingBy(t -> t.getMethod() + t.getPath(), LinkedHashMap::new, Collectors.toList()));
if (fullCoverage) {
methodPathMap.forEach((k, v) -> {
optionData.add(v.get(v.size() - 1));
});
} else {
methodPathMap.forEach((k, v) -> {
optionData.add(v.get(0));
});
}
setModule(map, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule);
}
}
private void justCoverApi(Map<String, ApiModule> map, Map<String, ApiDefinitionWithBLOBs> updateApiMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, Map<String, ApiDefinitionWithBLOBs> methodPathMap, ApiModuleDTO chooseModule, List<ApiDefinitionWithBLOBs> repeatApiDefinitionWithBLOBs) {
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
Map<String, ApiDefinitionWithBLOBs> collect = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), apiDefinition -> apiDefinition));
collect.forEach((k, v) -> {
private String getUpdateVersionId(ApiTestImportRequest request, Boolean fullCoverage) {
String updateVersionId;
if (!fullCoverage) {
if (request.getVersionId() == null) {
updateVersionId = request.getDefaultVersion();
} else {
updateVersionId = request.getVersionId();
}
} else {
if (request.getUpdateVersionId() == null) {
updateVersionId = request.getDefaultVersion();
} else {
updateVersionId = request.getUpdateVersionId();
}
}
return updateVersionId;
}
private void removeSameData(Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap, Map<String, ApiDefinitionWithBLOBs> methodPathMap, List<ApiDefinitionWithBLOBs> optionData) {
repeatDataMap.forEach((k, v) -> {
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k);
if (apiDefinitionWithBLOBs != null) {
//Check whether the content has changed, if not, do not change the creatoCover
Boolean toCover = apiDefinitionService.checkIsSynchronize(v, apiDefinitionWithBLOBs);
//需要更新
if (toCover) {
if (updateApiMap.get(k) != null) {
apiDefinitionWithBLOBs.setId(v.getId());
updateApiMap.put(k, apiDefinitionWithBLOBs);
}
}
methodPathMap.remove(k);
optionData.remove(apiDefinitionWithBLOBs);
}
});
}
setModule(map, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule);
private void startCoverModule(List<ApiDefinitionWithBLOBs> toUpdateList, List<ApiDefinitionWithBLOBs> optionData, Map<String, ApiDefinitionWithBLOBs> methodPathMap, Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap) {
List<ApiDefinitionWithBLOBs> coverApiList = new ArrayList<>();
repeatDataMap.forEach((k, v) -> {
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k);
if (apiDefinitionWithBLOBs != null) {
for (ApiDefinitionWithBLOBs definitionWithBLOBs : v) {
ApiDefinitionWithBLOBs api = new ApiDefinitionWithBLOBs();
BeanUtils.copyBean(api, apiDefinitionWithBLOBs);
api.setId(definitionWithBLOBs.getId());
coverApiList.add(api);
}
optionData.remove(apiDefinitionWithBLOBs);
}
});
buildOtherParam(toUpdateList, optionData, coverApiList);
}
private void setModule(Map<String, ApiModule> map, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, Map<String, ApiDefinitionWithBLOBs> methodPathMap, ApiModuleDTO chooseModule) {
methodPathMap.forEach((methodPath, datum) -> {
String[] pathTree;
private void startCover(List<ApiDefinitionWithBLOBs> toUpdateList, List<ApiDefinitionWithBLOBs> optionData, Map<String, ApiDefinitionWithBLOBs> methodPathMap, Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap) {
List<ApiDefinitionWithBLOBs> coverApiList = new ArrayList<>();
repeatDataMap.forEach((k, v) -> {
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k);
if (apiDefinitionWithBLOBs != null) {
for (ApiDefinitionWithBLOBs definitionWithBLOBs : v) {
ApiDefinitionWithBLOBs api = new ApiDefinitionWithBLOBs();
BeanUtils.copyBean(api, apiDefinitionWithBLOBs);
api.setId(definitionWithBLOBs.getId());
api.setModuleId(definitionWithBLOBs.getModuleId());
api.setModulePath(definitionWithBLOBs.getModulePath());
coverApiList.add(api);
}
optionData.remove(apiDefinitionWithBLOBs);
}
});
buildOtherParam(toUpdateList, optionData, coverApiList);
}
private Map<String, ApiModule> judgeModuleMap(Map<String, ApiModule> moduleMap, Map<String, ApiDefinitionWithBLOBs> methodPathMap, Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap) {
Set<String> repeatKeys = repeatDataMap.keySet();
Set<String> importKeys = methodPathMap.keySet();
List<String> repeatKeyList = new ArrayList<>(repeatKeys);
List<String> importKeysList = new ArrayList<>(importKeys);
List<String> intersection = repeatKeyList.stream().filter(item -> importKeysList.contains(item)).collect(Collectors.toList());
if (intersection.size() == importKeysList.size()) {
//导入文件没有新增接口无需创建接口模块
moduleMap = new HashMap<>();
}
return moduleMap;
}
private void buildOtherParam(List<ApiDefinitionWithBLOBs> toUpdateList, List<ApiDefinitionWithBLOBs> optionData, List<ApiDefinitionWithBLOBs> coverApiList) {
optionData.addAll(coverApiList);
toUpdateList.addAll(coverApiList);
}
private List<ApiDefinitionWithBLOBs> setModule(Map<String, ApiModule> moduleMap, Map<String, List<ApiModule>> pidChildrenMap,
Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, List<ApiDefinitionWithBLOBs> data, ApiModuleDTO chooseModule) {
for (ApiDefinitionWithBLOBs datum : data) {
String modulePath = datum.getModulePath();
ApiModule apiModule = map.get(modulePath);
ApiModule apiModule = moduleMap.get(modulePath);
if (chooseModule != null) {
dealChooseModuleData(moduleMap, pidChildrenMap, idPathMap, idModuleMap, chooseModule, datum, modulePath);
} else {
dealNoModuleData(moduleMap, pidChildrenMap, idPathMap, idModuleMap, datum, modulePath, apiModule);
}
}
return data;
}
private void dealNoModuleData(Map<String, ApiModule> moduleMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, ApiDefinitionWithBLOBs datum, String modulePath, ApiModule apiModule) {
String[] pathTree;
if (StringUtils.isNotBlank(modulePath)) {
//导入时没选模块但接口有模块的根据modulePath和当前协议查询当前项目里是否有同名称模块如果有就在该模块下建立接口否则新建模块
pathTree = getPathTree(modulePath);
if (apiModule != null) {
datum.setModuleId(apiModule.getId());
datum.setModulePath(modulePath);
} else {
List<ApiModule> moduleList = pidChildrenMap.get("root");
ApiModule minModule = getMinModule(pathTree, moduleList, null, pidChildrenMap, moduleMap, idPathMap, idModuleMap);
String id = minModule.getId();
datum.setModuleId(id);
datum.setModulePath(idPathMap.get(id));
}
} else {
//导入时即没选中模块接口自身也没模块的直接返会当前项目当前协议下的默认模块
List<ApiModule> moduleList = pidChildrenMap.get("root");
for (ApiModule module : moduleList) {
if (module.getName().equals("未规划接口")) {
datum.setModuleId(module.getId());
datum.setModulePath("/" + module.getName());
}
}
}
}
private void dealChooseModuleData(Map<String, ApiModule> moduleMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, ApiModuleDTO chooseModule, ApiDefinitionWithBLOBs datum, String modulePath) {
String[] pathTree;
if (chooseModule.getParentId() == null) {
chooseModule.setParentId("root");
}
@ -747,7 +893,7 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
pathTree = getPathTree(s + modulePath);
ApiModule chooseModuleOne = JSON.parseObject(JSON.toJSONString(chooseModule), ApiModule.class);
ApiModule minModule = getMinModule(pathTree, moduleList, chooseModuleOne, pidChildrenMap, map, idPathMap, idModuleMap);
ApiModule minModule = getMinModule(pathTree, moduleList, chooseModuleOne, pidChildrenMap, moduleMap, idPathMap, idModuleMap);
String id = minModule.getId();
datum.setModuleId(id);
datum.setModulePath(idPathMap.get(id));
@ -756,32 +902,6 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
datum.setModuleId(chooseModule.getId());
datum.setModulePath(idPathMap.get(chooseModule.getId()));
}
} else {
if (StringUtils.isNotBlank(modulePath)) {
//导入时没选模块但接口有模块的根据modulePath和当前协议查询当前项目里是否有同名称模块如果有就在该模块下建立接口否则新建模块
pathTree = getPathTree(modulePath);
if (apiModule != null) {
datum.setModuleId(apiModule.getId());
datum.setModulePath(modulePath);
} else {
List<ApiModule> moduleList = pidChildrenMap.get("root");
ApiModule minModule = getMinModule(pathTree, moduleList, null, pidChildrenMap, map, idPathMap, idModuleMap);
String id = minModule.getId();
datum.setModuleId(id);
datum.setModulePath(idPathMap.get(id));
}
} else {
//导入时即没选中模块接口自身也没模块的直接返会当前项目当前协议下的默认模块
List<ApiModule> moduleList = pidChildrenMap.get("root");
for (ApiModule module : moduleList) {
if (module.getName().equals("未规划接口")) {
datum.setModuleId(module.getId());
datum.setModulePath("/" + module.getName());
}
}
}
}
});
}
private String[] getPathTree(String modulePath) {
@ -797,7 +917,8 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
}
}
private ApiModule getMinModule(String[] tagTree, List<ApiModule> moduleList, ApiModule parentModule, Map<String, List<ApiModule>> pidChildrenMap, Map<String, ApiModule> map, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap) {
private ApiModule getMinModule(String[] tagTree, List<ApiModule> moduleList, ApiModule parentModule, Map<String, List<ApiModule>> pidChildrenMap, Map<String, ApiModule> moduleMap
, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap) {
//如果parentModule==null 则证明需要创建根目录同级的模块
ApiModule returnModule = null;
for (int i = 0; i < tagTree.length; i++) {
@ -817,7 +938,7 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
parentModule = JSON.parseObject(JSON.toJSONString(apiModuleDTO), ApiModule.class);
}
}
return createModule(tagTree, i, parentModule, map, pidChildrenMap, idPathMap);
return createModule(tagTree, i, parentModule, moduleMap, pidChildrenMap, idPathMap);
} else {
returnModule = collect.get(0);
moduleList = pidChildrenMap.get(collect.get(0).getId());
@ -826,8 +947,7 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
return returnModule;
}
private ApiModule createModule(String[] tagTree, int i, ApiModule parentModule, Map<String, ApiModule> map, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap) {
private ApiModule createModule(String[] tagTree, int i, ApiModule parentModule, Map<String, ApiModule> moduleMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap) {
ApiModule returnModule = null;
for (int i1 = i; i1 < tagTree.length; i1++) {
String pathName = tagTree[i1];
@ -859,27 +979,30 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
path = "/" + pathName;
}
idPathMap.put(newModule.getId(), path);
map.putIfAbsent(path, newModule);
moduleMap.putIfAbsent(path, newModule);
parentModule = newModule;
returnModule = newModule;
}
return returnModule;
}
private void buildProcessData(List<ApiModuleDTO> nodeTreeByProjectId, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap) {
private void buildProcessData(List<ApiModuleDTO> nodeTreeByProjectId, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, String> parentModulePathMap) {
//当前层级的模块的所有子模块的集合
List<ApiModuleDTO> childrenList = new ArrayList<>();
int i = 0;
List<ApiModule> moduleList = new ArrayList<>();
for (ApiModuleDTO apiModuleDTO : nodeTreeByProjectId) {
if (apiModuleDTO.getPath() != null) {
apiModuleDTO.setPath(apiModuleDTO.getPath() + "/" + apiModuleDTO.getName());
if (StringUtils.isBlank(apiModuleDTO.getParentId())) {
apiModuleDTO.setParentId("root");
}
String parentModulePath = parentModulePathMap.get(apiModuleDTO.getParentId());
if (parentModulePath != null) {
apiModuleDTO.setPath(parentModulePath + "/" + apiModuleDTO.getName());
} else {
apiModuleDTO.setPath("/" + apiModuleDTO.getName());
}
idPathMap.put(apiModuleDTO.getId(), apiModuleDTO.getPath());
if (StringUtils.isBlank(apiModuleDTO.getParentId())) {
apiModuleDTO.setParentId("root");
}
ApiModule apiModule = buildModule(moduleList, apiModuleDTO);
if (pidChildrenMap.get(apiModuleDTO.getParentId()) != null) {
pidChildrenMap.get(apiModuleDTO.getParentId()).add(apiModule);
@ -895,9 +1018,10 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
pidChildrenMap.put(apiModuleDTO.getId(), new ArrayList<>());
}
}
parentModulePathMap.put(apiModuleDTO.getId(), apiModuleDTO.getPath());
}
if (i == nodeTreeByProjectId.size() && nodeTreeByProjectId.size() > 0) {
buildProcessData(childrenList, pidChildrenMap, idPathMap);
buildProcessData(childrenList, pidChildrenMap, idPathMap, parentModulePathMap);
}
}
@ -913,5 +1037,4 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
return apiModule;
}
}

View File

@ -2,6 +2,7 @@ package io.metersphere.api.service;
import com.alibaba.fastjson.JSON;
import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.automation.*;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiScenarioMapper;
@ -472,111 +473,161 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
/**
* 上传文件时对文件的模块进行检测
*
* @param moduleId 上传文件时选的模块ID
* @param projectId
* @param data
* @param fullCoverage 是否覆盖接口
* @param fullCoverageApi 是否更新当前接口所在模块
* @return Return to the newly added module map
*/
public UpdateScenarioModuleDTO checkScenarioModule(String moduleId, String projectId, List<ApiScenarioWithBLOBs> data, Boolean fullCoverage, Boolean fullCoverageApi) {
Map<String, ApiScenarioModule> map = new HashMap<>();
Map<String, ApiScenarioWithBLOBs> updateMap = new HashMap<>();
public UpdateScenarioModuleDTO checkScenarioModule(ApiTestImportRequest request, List<ApiScenarioWithBLOBs> data, Boolean fullCoverage, Boolean fullCoverageApi) {
//需要新增的模块key 为模块路径
Map<String, ApiScenarioModule> moduleMap = new HashMap<>();
List<ApiScenarioWithBLOBs> toUpdateList = new ArrayList<>();
//上传文件时选的模块ID
String chooseModuleId = request.getModuleId();
String projectId = request.getProjectId();
//获取当前项目的当前协议下的所有模块的Tree
List<ApiScenarioModuleDTO> scenarioModules = extApiScenarioModuleMapper.getNodeTreeByProjectId(projectId);
List<ApiScenarioModuleDTO> nodeTreeByProjectId = this.getNodeTrees(scenarioModules);
Map<String, ApiScenarioModuleDTO> idModuleMap = scenarioModules.stream().collect(Collectors.toMap(ApiScenarioModuleDTO::getId, scenarioModuleDTO -> scenarioModuleDTO));
Map<String, List<ApiScenarioModule>> pidChildrenMap = new HashMap<>();
Map<String, String> idPathMap = new HashMap<>();
Map<String, ApiScenarioModuleDTO> idModuleMap = scenarioModules.stream().collect(Collectors.toMap(ApiScenarioModuleDTO::getId, scenarioModuleDTO -> scenarioModuleDTO));
buildProcessData(nodeTreeByProjectId, pidChildrenMap, idPathMap);
Map<String, ApiScenarioWithBLOBs> nameMap = data.stream().collect(Collectors.toMap(ApiScenario::getName, apiScenario -> apiScenario));
//构建以上两种数据
String initParentModulePath = "/root";
Map<String, String> initParentModulePathMap = new HashMap<>();
initParentModulePathMap.put("root", initParentModulePath);
buildProcessData(nodeTreeByProjectId, pidChildrenMap, idPathMap, initParentModulePathMap);
ApiScenarioModuleDTO chooseModule = null;
if (moduleId != null) {
chooseModule = idModuleMap.get(moduleId);
if (chooseModuleId != null) {
chooseModule = idModuleMap.get(chooseModuleId);
}
String updateVersionId = getUpdateVersionId(request, fullCoverage);
List<ApiScenarioWithBLOBs> optionData = new ArrayList<>();
//覆盖模式留重复的最后一个不覆盖留第一个
LinkedHashMap<String, List<ApiScenarioWithBLOBs>> nameModuleMapList = data.stream().collect(Collectors.groupingBy(t -> t.getName() + (t.getModulePath() == null ? "" : t.getModulePath()), LinkedHashMap::new, Collectors.toList()));
removeRepeat(fullCoverage, optionData, nameModuleMapList);
//处理模块
setModule(optionData, moduleMap, pidChildrenMap, idPathMap, idModuleMap, chooseModule);
//系统内重复的数据
List<ApiScenarioWithBLOBs> repeatApiScenarioWithBLOBs;
if (chooseModule != null) {
repeatApiScenarioWithBLOBs = extApiScenarioMapper.selectRepeatByBLOBsSameUrl(data, chooseModule.getId());
repeatApiScenarioWithBLOBs = extApiScenarioMapper.selectRepeatByBLOBsSameUrl(data, projectId, chooseModule.getId(), updateVersionId);
} else {
repeatApiScenarioWithBLOBs = extApiScenarioMapper.selectRepeatByBLOBs(data);
repeatApiScenarioWithBLOBs = extApiScenarioMapper.selectRepeatByBLOBs(data, projectId, updateVersionId);
}
Map<String, ApiScenarioWithBLOBs> nameModuleMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + (t.getModulePath() == null ? "" : t.getModulePath()), scenario -> scenario));
Map<String, ApiScenarioWithBLOBs> repeatDataMap = null;
if (!repeatApiScenarioWithBLOBs.isEmpty()) {
repeatDataMap = repeatApiScenarioWithBLOBs.stream().collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), scenario -> scenario));
}
//处理数据
if (fullCoverage) {
if (fullCoverageApi) {
coverScenarioModule(updateMap, nameMap, repeatApiScenarioWithBLOBs);
startCoverModule(toUpdateList, nameModuleMap, repeatDataMap);
} else {
//只覆盖场景
justCoverScenario(updateMap, nameMap, repeatApiScenarioWithBLOBs);
//覆盖但不覆盖模块
if (repeatDataMap != null) {
//导入文件没有新增场景无需创建接口模块
moduleMap = judgeModuleMap(moduleMap, nameModuleMap, repeatDataMap);
startCover(toUpdateList, nameModuleMap, repeatDataMap);
}
}
} else {
//不覆盖
if (!repeatApiScenarioWithBLOBs.isEmpty()) {
Map<String, ApiScenarioWithBLOBs> collect = repeatApiScenarioWithBLOBs.stream().collect(Collectors.toMap(ApiScenario::getName, scenario -> scenario));
collect.forEach((k, v) -> {
if (nameMap.get(k) != null) {
nameMap.remove(k);
}
});
}
setModule(nameMap, map, pidChildrenMap, idPathMap, idModuleMap, chooseModule);
removeRepeat(optionData, nameModuleMap, repeatDataMap);
}
UpdateScenarioModuleDTO updateScenarioModuleDTO = new UpdateScenarioModuleDTO();
updateScenarioModuleDTO.setModuleList((List<ApiScenarioModule>) map.values());
updateScenarioModuleDTO.setApiScenarioWithBLOBsList((List<ApiScenarioWithBLOBs>) nameMap.values());
updateScenarioModuleDTO.setModuleList(new ArrayList<>(moduleMap.values()));
updateScenarioModuleDTO.setNeedUpdateList(toUpdateList);
updateScenarioModuleDTO.setApiScenarioWithBLOBsList(optionData);
return updateScenarioModuleDTO;
}
private void coverScenarioModule(Map<String, ApiScenarioWithBLOBs> updateMap, Map<String, ApiScenarioWithBLOBs> nameMap, List<ApiScenarioWithBLOBs> repeatApiScenarioWithBLOBs) {
if (!repeatApiScenarioWithBLOBs.isEmpty()) {
Map<String, ApiScenarioWithBLOBs> collect = repeatApiScenarioWithBLOBs.stream().collect(Collectors.toMap(ApiScenario::getName, apiScenario -> apiScenario));
collect.forEach((name, scenario) -> {
ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameMap.get(name);
private void removeRepeat(List<ApiScenarioWithBLOBs> optionData, Map<String, ApiScenarioWithBLOBs> nameModuleMap, Map<String, ApiScenarioWithBLOBs> repeatDataMap) {
if (repeatDataMap != null) {
repeatDataMap.forEach((k, v) -> {
ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameModuleMap.get(k);
if (apiScenarioWithBLOBs != null) {
//Check whether the content has changed, if not, do not change the creatoCover
Boolean toCover = apiAutomationService.checkIsSynchronize(scenario, apiScenarioWithBLOBs);
//需要更新
if (toCover) {
if (updateMap.get(name) != null) {
apiScenarioWithBLOBs.setId(scenario.getId());
updateMap.put(name, apiScenarioWithBLOBs);
optionData.remove(apiScenarioWithBLOBs);
}
});
}
}
private void startCover(List<ApiScenarioWithBLOBs> toUpdateList, Map<String, ApiScenarioWithBLOBs> nameModuleMap, Map<String, ApiScenarioWithBLOBs> repeatDataMap) {
repeatDataMap.forEach((k, v) -> {
ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameModuleMap.get(k);
if (apiScenarioWithBLOBs != null) {
apiScenarioWithBLOBs.setId(v.getId());
apiScenarioWithBLOBs.setApiScenarioModuleId(v.getApiScenarioModuleId());
apiScenarioWithBLOBs.setModulePath(v.getModulePath());
toUpdateList.add(apiScenarioWithBLOBs);
}
});
}
private Map<String, ApiScenarioModule> judgeModuleMap(Map<String, ApiScenarioModule> moduleMap, Map<String, ApiScenarioWithBLOBs> nameModuleMap, Map<String, ApiScenarioWithBLOBs> repeatDataMap) {
if (repeatDataMap.size() >= nameModuleMap.size()) {
moduleMap = new HashMap<>();
}
return moduleMap;
}
private void startCoverModule(List<ApiScenarioWithBLOBs> toUpdateList, Map<String, ApiScenarioWithBLOBs> nameModuleMap, Map<String, ApiScenarioWithBLOBs> repeatDataMap) {
if (repeatDataMap != null) {
repeatDataMap.forEach((k, v) -> {
ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameModuleMap.get(k);
if (apiScenarioWithBLOBs != null) {
apiScenarioWithBLOBs.setId(v.getId());
toUpdateList.add(apiScenarioWithBLOBs);
}
});
}
}
private void removeRepeat(Boolean fullCoverage, List<ApiScenarioWithBLOBs> optionData, LinkedHashMap<String, List<ApiScenarioWithBLOBs>> nameModuleMapList) {
if (fullCoverage) {
nameModuleMapList.forEach((k, v) -> {
optionData.add(v.get(v.size() - 1));
});
} else {
nameModuleMapList.forEach((k, v) -> {
optionData.add(v.get(0));
});
}
}
private String getUpdateVersionId(ApiTestImportRequest request, Boolean fullCoverage) {
String updateVersionId;
if (!fullCoverage) {
if (request.getVersionId() == null) {
updateVersionId = request.getDefaultVersion();
} else {
updateVersionId = request.getVersionId();
}
} else {
nameMap.remove(name);
if (request.getUpdateVersionId() == null) {
updateVersionId = request.getDefaultVersion();
} else {
updateVersionId = request.getUpdateVersionId();
}
}
});
}
return updateVersionId;
}
private void justCoverScenario(Map<String, ApiScenarioWithBLOBs> updateMap, Map<String, ApiScenarioWithBLOBs> nameMap, List<ApiScenarioWithBLOBs> repeatApiScenarioWithBLOBs) {
if (!repeatApiScenarioWithBLOBs.isEmpty()) {
Map<String, ApiScenarioWithBLOBs> collect = repeatApiScenarioWithBLOBs.stream().collect(Collectors.toMap(ApiScenario::getName, apiScenario -> apiScenario));
collect.forEach((name, scenario) -> {
ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameMap.get(name);
if (apiScenarioWithBLOBs != null) {
//Check whether the content has changed, if not, do not change the creatoCover
Boolean toCover = apiAutomationService.checkIsSynchronize(scenario, apiScenarioWithBLOBs);
//需要更新
if (toCover) {
if (updateMap.get(name) != null) {
apiScenarioWithBLOBs.setId(scenario.getId());
updateMap.put(name, apiScenarioWithBLOBs);
}
}
nameMap.remove(name);
}
});
}
}
private void setModule(Map<String, ApiScenarioWithBLOBs> nameMap, Map<String, ApiScenarioModule> map, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiScenarioModuleDTO> idModuleMap, ApiScenarioModuleDTO chooseModule) {
nameMap.forEach((k, datum) -> {
private void setModule(List<ApiScenarioWithBLOBs> data, Map<String, ApiScenarioModule> map, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiScenarioModuleDTO> idModuleMap, ApiScenarioModuleDTO chooseModule) {
for (ApiScenarioWithBLOBs datum : data) {
StringBuilder path = new StringBuilder();
path.append("/");
String[] tagTree;
@ -589,17 +640,19 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
String chooseModuleParentId = chooseModule.getParentId();
//导入时选了模块且接口有模块的
if (StringUtils.isNotBlank(modulePath)) {
List<ApiScenarioModule> moduleList = pidChildrenMap.get(chooseModuleParentId);
//选中模块的同级模块集合用于和场景的全路径做对比
List<ApiScenarioModule> parentModuleList = pidChildrenMap.get(chooseModuleParentId);
String s;
if (chooseModuleParentId.equals("root")) {
s = "/" + chooseModule.getName();
} else {
s = idPathMap.get(chooseModuleParentId);
}
//场景的全部路径的集合
tagTree = getTagTree(s + modulePath);
ApiScenarioModule chooseModuleOne = JSON.parseObject(JSON.toJSONString(chooseModule), ApiScenarioModule.class);
ApiScenarioModule minModule = getMinModule(tagTree, moduleList, chooseModuleOne, pidChildrenMap, map, idPathMap, idModuleMap);
ApiScenarioModule minModule = getMinModule(tagTree, parentModuleList, chooseModuleOne, pidChildrenMap, map, idPathMap, idModuleMap);
String id = minModule.getId();
datum.setApiScenarioModuleId(id);
datum.setModulePath(idPathMap.get(id));
@ -616,8 +669,9 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
datum.setApiScenarioModuleId(scenarioModule.getId());
datum.setModulePath(modulePath);
} else {
List<ApiScenarioModule> moduleList = pidChildrenMap.get("root");
ApiScenarioModule minModule = getMinModule(tagTree, moduleList, null, pidChildrenMap, map, idPathMap, idModuleMap);
//父级同级的模块list
List<ApiScenarioModule> parentModuleList = pidChildrenMap.get("root");
ApiScenarioModule minModule = getMinModule(tagTree, parentModuleList, null, pidChildrenMap, map, idPathMap, idModuleMap);
String id = minModule.getId();
datum.setApiScenarioModuleId(id);
datum.setModulePath(idPathMap.get(id));
@ -633,7 +687,7 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
}
}
}
});
}
}
private String[] getTagTree(String modulePath) {
@ -649,13 +703,15 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
}
}
private ApiScenarioModule getMinModule(String[] tagTree, List<ApiScenarioModule> moduleList, ApiScenarioModule parentModule, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, ApiScenarioModule> map, Map<String, String> idPathMap, Map<String, ApiScenarioModuleDTO> idModuleMap) {
private ApiScenarioModule getMinModule(String[] tagTree, List<ApiScenarioModule> parentModuleList, ApiScenarioModule parentModule, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, ApiScenarioModule> map, Map<String, String> idPathMap, Map<String, ApiScenarioModuleDTO> idModuleMap) {
//如果parentModule==null 则证明需要创建根目录同级的模块
ApiScenarioModule returnModule = null;
for (int i = 0; i < tagTree.length; i++) {
int finalI = i;
List<ApiScenarioModule> collect = moduleList.stream().filter(t -> t.getName().equals(tagTree[finalI])).collect(Collectors.toList());
//查找上一级里面是否有当前全路径的第一级没有则需要创建
List<ApiScenarioModule> collect = parentModuleList.stream().filter(t -> t.getName().equals(tagTree[finalI])).collect(Collectors.toList());
if (collect.isEmpty()) {
//如果找不到而且父级模块也为空证明当前的父级模块应为root
if (parentModule == null) {
List<ApiScenarioModule> moduleList1 = pidChildrenMap.get("root");
ApiScenarioModule apiModule = moduleList1.get(0);
@ -663,16 +719,18 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
apiModule.setLevel(0);
parentModule = apiModule;
} else if (i > 0) {
if (!moduleList.isEmpty()) {
String parentId = moduleList.get(0).getParentId();
//如果已经循环第二次级以上如果父模块不为空 parentModuleList不为空tagTree[finalI] 找不到那就从上一级开始创建
if (!parentModuleList.isEmpty()) {
String parentId = parentModuleList.get(0).getParentId();
ApiScenarioModuleDTO apiScenarioModuleDTO = idModuleMap.get(parentId);
parentModule = JSON.parseObject(JSON.toJSONString(apiScenarioModuleDTO), ApiScenarioModule.class);
}
}
//开始创建tagTree[finalI]这个模块
return createModule(tagTree, i, parentModule, map, pidChildrenMap, idPathMap);
} else {
returnModule = collect.get(0);
moduleList = pidChildrenMap.get(collect.get(0).getId());
parentModuleList = pidChildrenMap.get(collect.get(0).getId());
}
}
return returnModule;
@ -684,6 +742,8 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
ApiScenarioModule returnModule = null;
for (int i1 = i; i1 < tagTree.length; i1++) {
String pathName = tagTree[i1];
//创建模块
ApiScenarioModule newModule = this.getNewModule(pathName, parentModule.getProjectId(), parentModule.getLevel() + 1);
String parentId;
if (parentModule.getId().equals("root")) {
@ -718,20 +778,22 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
return returnModule;
}
private void buildProcessData(List<ApiScenarioModuleDTO> nodeTreeByProjectId, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, String> idPathMap) {
private void buildProcessData(List<ApiScenarioModuleDTO> nodeTreeByProjectId, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, String> parentModulePathMap) {
List<ApiScenarioModuleDTO> childrenList = new ArrayList<>();
int i = 0;
List<ApiScenarioModule> moduleList = new ArrayList<>();
for (ApiScenarioModuleDTO scenarioModuleDTO : nodeTreeByProjectId) {
if (scenarioModuleDTO.getPath() != null) {
scenarioModuleDTO.setPath(scenarioModuleDTO.getPath() + "/" + scenarioModuleDTO.getName());
if (StringUtils.isBlank(scenarioModuleDTO.getParentId())) {
scenarioModuleDTO.setParentId("root");
}
String parentModulePath = parentModulePathMap.get(scenarioModuleDTO.getParentId());
if (parentModulePath != null) {
scenarioModuleDTO.setPath(parentModulePath + "/" + scenarioModuleDTO.getName());
} else {
scenarioModuleDTO.setPath("/" + scenarioModuleDTO.getName());
}
idPathMap.put(scenarioModuleDTO.getId(), scenarioModuleDTO.getPath());
if (StringUtils.isBlank(scenarioModuleDTO.getParentId())) {
scenarioModuleDTO.setParentId("root");
}
ApiScenarioModule scenarioModule = buildModule(moduleList, scenarioModuleDTO);
if (pidChildrenMap.get(scenarioModuleDTO.getParentId()) != null) {
pidChildrenMap.get(scenarioModuleDTO.getParentId()).add(scenarioModule);
@ -747,9 +809,10 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
pidChildrenMap.put(scenarioModuleDTO.getId(), new ArrayList<>());
}
}
parentModulePathMap.put(scenarioModuleDTO.getId(), scenarioModuleDTO.getPath());
}
if (i == nodeTreeByProjectId.size() && nodeTreeByProjectId.size() > 0) {
buildProcessData(childrenList, pidChildrenMap, idPathMap);
buildProcessData(childrenList, pidChildrenMap, idPathMap, parentModulePathMap);
}
}

View File

@ -93,9 +93,9 @@ public interface ExtApiDefinitionMapper {
int toBeUpdateApi(@Param("ids") List<String> ids, @Param("toBeUpdate") Boolean toBeUpdate);
List<ApiDefinitionWithBLOBs> selectRepeatByBLOBs(@Param("blobs") List<ApiDefinitionWithBLOBs> blobs);
List<ApiDefinitionWithBLOBs> selectRepeatByBLOBs(@Param("blobs") List<ApiDefinitionWithBLOBs> blobs, @Param("projectId") String projectId, @Param("versionId") String versionId);
List<ApiDefinitionWithBLOBs> selectRepeatByBLOBsSameUrl(@Param("blobs") List<ApiDefinitionWithBLOBs> blobs, @Param("moduleId") String moduleId);
List<ApiDefinitionWithBLOBs> selectRepeatByBLOBsSameUrl(@Param("blobs") List<ApiDefinitionWithBLOBs> blobs, @Param("projectId") String projectId, @Param("moduleId") String moduleId, @Param("versionId") String versionId);
}

View File

@ -1010,13 +1010,17 @@
<select id="selectRepeatByBLOBs" resultType="io.metersphere.base.domain.ApiDefinitionWithBLOBs">
SELECT * from api_definition
<include refid="Same_Where_Clause"/>
and status != 'TRASH'
and status != 'Trash'
and project_id = #{projectId}
and version_id = #{versionId}
</select>
<select id="selectRepeatByBLOBsSameUrl" resultType="io.metersphere.base.domain.ApiDefinitionWithBLOBs">
SELECT * from api_definition
<include refid="Same_Where_Clause"/>
and status != 'TRASH'
and project_id = #{projectId}
and module_id = #{moduleId}
and version_id = #{versionId}
</select>
<sql id="Same_Where_Clause">
<where>
@ -1030,11 +1034,7 @@
<if test="blob.path">
and api_definition.path = #{blob.path}
</if>
<if test="blob.projectId">
and api_definition.project_id = #{blob.projectId}
</if>
</trim>
</foreach>
</trim>
</if>

View File

@ -91,9 +91,9 @@ public interface ExtApiScenarioMapper {
List<ApiScenarioWithBLOBs> selectByStatusIsNotTrash();
List<ApiScenarioWithBLOBs> selectRepeatByBLOBs(@Param("blobs") List<ApiScenarioWithBLOBs> blobs);
List<ApiScenarioWithBLOBs> selectRepeatByBLOBs(@Param("blobs") List<ApiScenarioWithBLOBs> blobs, @Param("projectId") String projectId, @Param("versionId") String versionId);
List<ApiScenarioWithBLOBs> selectRepeatByBLOBsSameUrl(@Param("blobs") List<ApiScenarioWithBLOBs> blobs, @Param("moduleId") String moduleId);
List<ApiScenarioWithBLOBs> selectRepeatByBLOBsSameUrl(@Param("blobs") List<ApiScenarioWithBLOBs> blobs, @Param("projectId") String projectId, @Param("moduleId") String moduleId, @Param("versionId") String versionId);
}

View File

@ -774,7 +774,9 @@
<select id="selectRepeatByBLOBs" resultType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
SELECT * from api_scenario
<include refid="Same_Where_Clause"/>
and status != 'TRASH'
and status != 'Trash'
and project_id = #{projectId}
and version_id = #{versionId}
</select>
<select id="selectRepeatByBLOBsSameUrl" resultType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
@ -782,6 +784,8 @@
<include refid="Same_Where_Clause"/>
and status != 'TRASH'
and api_scenario_module_id = #{moduleId}
and project_id = #{projectId}
and version_id = #{versionId}
</select>
<sql id="Same_Where_Clause">
@ -793,9 +797,6 @@
<if test="blob.name">
and api_scenario.name = #{blob.name}
</if>
<if test="blob.projectId">
and api_scenario.project_id = #{blob.projectId}
</if>
</trim>
</foreach>