refactor: 导入接口支持选择版本

--story=1004981 --user=刘瑞斌 版本对比(X-Pack)-导入数据关于版本的改动 https://www.tapd.cn/55049933/s/1090837
This commit is contained in:
CaptainB 2022-01-12 13:50:29 +08:00 committed by 刘瑞斌
parent 76d4f5dcb3
commit 3d3dd075bf
8 changed files with 205 additions and 35 deletions

View File

@ -23,6 +23,8 @@ public class ApiTestImportRequest {
//导入策略 //导入策略
private String modeId; private String modeId;
private String userId; private String userId;
private String versionId; // 新导入选择的版本
private String updateVersionId; // 覆盖导入已存在的接口选择的版本
//调用类型 //调用类型
private String type; private String type;
// 是否开启自定义ID // 是否开启自定义ID

View File

@ -1069,20 +1069,47 @@ public class ApiAutomationService {
} }
private void _importCreate(List<ApiScenarioWithBLOBs> sameRequest, ApiScenarioMapper batchMapper, ApiScenarioWithBLOBs scenarioWithBLOBs, ApiTestImportRequest apiTestImportRequest) { private void _importCreate(List<ApiScenarioWithBLOBs> sameRequest, ApiScenarioMapper batchMapper, ApiScenarioWithBLOBs scenarioWithBLOBs, ApiTestImportRequest apiTestImportRequest) {
String defaultVersion = extProjectVersionMapper.getDefaultVersion(apiTestImportRequest.getProjectId());
if (CollectionUtils.isEmpty(sameRequest)) { if (CollectionUtils.isEmpty(sameRequest)) {
scenarioWithBLOBs.setId(UUID.randomUUID().toString()); scenarioWithBLOBs.setId(UUID.randomUUID().toString());
List<ApiMethodUrlDTO> useUrl = this.parseUrl(scenarioWithBLOBs); List<ApiMethodUrlDTO> useUrl = this.parseUrl(scenarioWithBLOBs);
scenarioWithBLOBs.setUseUrl(JSONArray.toJSONString(useUrl)); scenarioWithBLOBs.setUseUrl(JSONArray.toJSONString(useUrl));
scenarioWithBLOBs.setOrder(getImportNextOrder(apiTestImportRequest.getProjectId())); scenarioWithBLOBs.setOrder(getImportNextOrder(apiTestImportRequest.getProjectId()));
// 导入时设置版本
scenarioWithBLOBs.setRefId(scenarioWithBLOBs.getId());
if (StringUtils.isNotEmpty(apiTestImportRequest.getVersionId())) {
scenarioWithBLOBs.setVersionId(apiTestImportRequest.getVersionId());
} else {
scenarioWithBLOBs.setVersionId(defaultVersion);
}
batchMapper.insert(scenarioWithBLOBs); batchMapper.insert(scenarioWithBLOBs);
apiScenarioReferenceIdService.saveByApiScenario(scenarioWithBLOBs); apiScenarioReferenceIdService.saveByApiScenario(scenarioWithBLOBs);
} else { } else {
//如果存在则修改 //如果存在则修改
scenarioWithBLOBs.setId(sameRequest.get(0).getId()); if (StringUtils.isEmpty(apiTestImportRequest.getUpdateVersionId())) {
scenarioWithBLOBs.setNum(sameRequest.get(0).getNum()); apiTestImportRequest.setUpdateVersionId(defaultVersion);
}
Optional<ApiScenarioWithBLOBs> scenarioOp = sameRequest.stream()
.filter(api -> StringUtils.equals(api.getVersionId(), apiTestImportRequest.getUpdateVersionId()))
.findFirst();
// 新增对应的版本
if (!scenarioOp.isPresent()) {
scenarioWithBLOBs.setId(UUID.randomUUID().toString());
scenarioWithBLOBs.setRefId(sameRequest.get(0).getRefId());
scenarioWithBLOBs.setVersionId(apiTestImportRequest.getUpdateVersionId());
scenarioWithBLOBs.setNum(sameRequest.get(0).getNum()); // 使用第一个num当作本次的num
batchMapper.insert(scenarioWithBLOBs);
} else {
ApiScenarioWithBLOBs existScenario = scenarioOp.get();
scenarioWithBLOBs.setId(existScenario.getId());
scenarioWithBLOBs.setRefId(existScenario.getRefId());
scenarioWithBLOBs.setVersionId(apiTestImportRequest.getUpdateVersionId());
scenarioWithBLOBs.setNum(existScenario.getNum());
List<ApiMethodUrlDTO> useUrl = this.parseUrl(scenarioWithBLOBs); List<ApiMethodUrlDTO> useUrl = this.parseUrl(scenarioWithBLOBs);
scenarioWithBLOBs.setUseUrl(JSONArray.toJSONString(useUrl)); scenarioWithBLOBs.setUseUrl(JSONArray.toJSONString(useUrl));
batchMapper.updateByPrimaryKeyWithBLOBs(scenarioWithBLOBs); batchMapper.updateByPrimaryKeyWithBLOBs(scenarioWithBLOBs);
}
apiScenarioReferenceIdService.saveByApiScenario(scenarioWithBLOBs); apiScenarioReferenceIdService.saveByApiScenario(scenarioWithBLOBs);
} }
} }
@ -1143,6 +1170,13 @@ public class ApiAutomationService {
scenarioWithBLOBs.setUseUrl(JSONArray.toJSONString(useUrl)); scenarioWithBLOBs.setUseUrl(JSONArray.toJSONString(useUrl));
scenarioWithBLOBs.setOrder(getImportNextOrder(request.getProjectId())); scenarioWithBLOBs.setOrder(getImportNextOrder(request.getProjectId()));
scenarioWithBLOBs.setId(UUID.randomUUID().toString()); scenarioWithBLOBs.setId(UUID.randomUUID().toString());
scenarioWithBLOBs.setRefId(scenarioWithBLOBs.getId());
if (StringUtils.isNotEmpty(apiTestImportRequest.getVersionId())) {
scenarioWithBLOBs.setVersionId(apiTestImportRequest.getVersionId());
} else {
String defaultVersion = extProjectVersionMapper.getDefaultVersion(apiTestImportRequest.getProjectId());
scenarioWithBLOBs.setVersionId(defaultVersion);
}
batchMapper.insert(scenarioWithBLOBs); batchMapper.insert(scenarioWithBLOBs);
// 存储依赖关系 // 存储依赖关系
@ -1189,9 +1223,6 @@ public class ApiAutomationService {
if (StringUtils.isBlank(item.getId())) { if (StringUtils.isBlank(item.getId())) {
item.setId(UUID.randomUUID().toString()); item.setId(UUID.randomUUID().toString());
} }
// 导入时设置版本
item.setVersionId(extProjectVersionMapper.getDefaultVersion(project.getId()));
item.setRefId(item.getId());
importCreate(item, batchMapper, request); importCreate(item, batchMapper, request);
if (i % 300 == 0) { if (i % 300 == 0) {
sqlSession.flushStatements(); sqlSession.flushStatements();

View File

@ -680,7 +680,12 @@ public class ApiDefinitionService {
String originId = apiDefinition.getId(); String originId = apiDefinition.getId();
apiDefinition.setId(UUID.randomUUID().toString()); apiDefinition.setId(UUID.randomUUID().toString());
apiDefinition.setRefId(apiDefinition.getId()); apiDefinition.setRefId(apiDefinition.getId());
apiDefinition.setVersionId(extProjectVersionMapper.getDefaultVersion(apiTestImportRequest.getProjectId())); if (StringUtils.isNotEmpty(apiTestImportRequest.getVersionId())) {
apiDefinition.setVersionId(apiTestImportRequest.getVersionId());
} else {
String defaultVersion = extProjectVersionMapper.getDefaultVersion(apiTestImportRequest.getProjectId());
apiDefinition.setVersionId(defaultVersion);
}
batchMapper.insert(apiDefinition); batchMapper.insert(apiDefinition);
String requestStr = setImportHashTree(apiDefinition); String requestStr = setImportHashTree(apiDefinition);
reSetImportCasesApiId(cases, originId, apiDefinition.getId()); reSetImportCasesApiId(cases, originId, apiDefinition.getId());
@ -718,10 +723,15 @@ public class ApiDefinitionService {
private void _importCreate(List<ApiDefinition> sameRequest, ApiDefinitionMapper batchMapper, ApiDefinitionWithBLOBs apiDefinition, private void _importCreate(List<ApiDefinition> sameRequest, ApiDefinitionMapper batchMapper, ApiDefinitionWithBLOBs apiDefinition,
ApiTestCaseMapper apiTestCaseMapper, ApiTestImportRequest apiTestImportRequest, List<ApiTestCaseWithBLOBs> cases, List<MockConfigImportDTO> mocks) { ApiTestCaseMapper apiTestCaseMapper, ApiTestImportRequest apiTestImportRequest, List<ApiTestCaseWithBLOBs> cases, List<MockConfigImportDTO> mocks) {
String originId = apiDefinition.getId(); String originId = apiDefinition.getId();
String defaultVersion = extProjectVersionMapper.getDefaultVersion(apiTestImportRequest.getProjectId());
if (CollectionUtils.isEmpty(sameRequest)) { if (CollectionUtils.isEmpty(sameRequest)) {
apiDefinition.setId(UUID.randomUUID().toString()); apiDefinition.setId(UUID.randomUUID().toString());
apiDefinition.setRefId(apiDefinition.getId()); apiDefinition.setRefId(apiDefinition.getId());
apiDefinition.setVersionId(extProjectVersionMapper.getDefaultVersion(apiTestImportRequest.getProjectId())); if (StringUtils.isNotEmpty(apiTestImportRequest.getVersionId())) {
apiDefinition.setVersionId(apiTestImportRequest.getVersionId());
} else {
apiDefinition.setVersionId(defaultVersion);
}
apiDefinition.setOrder(getImportNextOrder(apiTestImportRequest.getProjectId())); apiDefinition.setOrder(getImportNextOrder(apiTestImportRequest.getProjectId()));
reSetImportCasesApiId(cases, originId, apiDefinition.getId()); reSetImportCasesApiId(cases, originId, apiDefinition.getId());
reSetImportMocksApiId(mocks, originId, apiDefinition.getId(), apiDefinition.getNum()); reSetImportMocksApiId(mocks, originId, apiDefinition.getId(), apiDefinition.getNum());
@ -738,33 +748,54 @@ public class ApiDefinitionService {
} }
} else { } else {
apiDefinition.setStatus(sameRequest.get(0).getStatus()); //如果存在则修改
apiDefinition.setOriginalState(sameRequest.get(0).getOriginalState()); if (StringUtils.isEmpty(apiTestImportRequest.getUpdateVersionId())) {
apiDefinition.setCaseStatus(sameRequest.get(0).getCaseStatus()); apiTestImportRequest.setUpdateVersionId(defaultVersion);
apiDefinition.setNum(sameRequest.get(0).getNum()); //id 不变 }
Optional<ApiDefinition> apiOp = sameRequest.stream()
.filter(api -> StringUtils.equals(api.getVersionId(), apiTestImportRequest.getUpdateVersionId()))
.findFirst();
if (!apiOp.isPresent()) {
apiDefinition.setId(UUID.randomUUID().toString());
apiDefinition.setRefId(sameRequest.get(0).getRefId());
apiDefinition.setVersionId(apiTestImportRequest.getUpdateVersionId());
apiDefinition.setNum(sameRequest.get(0).getNum()); // 使用第一个num当作本次的num
batchMapper.insert(apiDefinition);
} else {
ApiDefinition existApi = apiOp.get();
apiDefinition.setStatus(existApi.getStatus());
apiDefinition.setOriginalState(existApi.getOriginalState());
apiDefinition.setCaseStatus(existApi.getCaseStatus());
apiDefinition.setNum(existApi.getNum()); //id 不变
apiDefinition.setRefId(existApi.getRefId());
apiDefinition.setVersionId(apiTestImportRequest.getUpdateVersionId());
if (!StringUtils.equalsIgnoreCase(apiTestImportRequest.getPlatform(), ApiImportPlatform.Metersphere.name())) { if (!StringUtils.equalsIgnoreCase(apiTestImportRequest.getPlatform(), ApiImportPlatform.Metersphere.name())) {
apiDefinition.setTags(sameRequest.get(0).getTags()); // 其他格式 tag 不变MS 格式替换 apiDefinition.setTags(existApi.getTags()); // 其他格式 tag 不变MS 格式替换
} }
if (StringUtils.equalsIgnoreCase(apiDefinition.getProtocol(), RequestType.HTTP)) { if (StringUtils.equalsIgnoreCase(apiDefinition.getProtocol(), RequestType.HTTP)) {
//如果存在则修改 //如果存在则修改
apiDefinition.setId(sameRequest.get(0).getId()); apiDefinition.setId(existApi.getId());
String request = setImportHashTree(apiDefinition); String request = setImportHashTree(apiDefinition);
apiDefinition.setModuleId(sameRequest.get(0).getModuleId()); apiDefinition.setModuleId(existApi.getModuleId());
apiDefinition.setModulePath(sameRequest.get(0).getModulePath()); apiDefinition.setModulePath(existApi.getModulePath());
apiDefinition.setOrder(sameRequest.get(0).getOrder()); apiDefinition.setOrder(existApi.getOrder());
apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition); apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition);
apiDefinition.setRequest(request); apiDefinition.setRequest(request);
reSetImportCasesApiId(cases, originId, apiDefinition.getId()); reSetImportCasesApiId(cases, originId, apiDefinition.getId());
importApiCase(apiDefinition, apiTestImportRequest); importApiCase(apiDefinition, apiTestImportRequest);
} else { } else {
apiDefinition.setId(sameRequest.get(0).getId()); apiDefinition.setId(existApi.getId());
if (StringUtils.equalsAnyIgnoreCase(apiDefinition.getProtocol(), RequestType.TCP)) { if (StringUtils.equalsAnyIgnoreCase(apiDefinition.getProtocol(), RequestType.TCP)) {
setImportTCPHashTree(apiDefinition); setImportTCPHashTree(apiDefinition);
} }
apiDefinition.setOrder(sameRequest.get(0).getOrder()); apiDefinition.setOrder(existApi.getOrder());
reSetImportCasesApiId(cases, originId, apiDefinition.getId()); reSetImportCasesApiId(cases, originId, apiDefinition.getId());
apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition); apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition);
} }
}
} }
} }

View File

@ -29,6 +29,24 @@
<el-option v-for="item in modeOptions" :key="item.id" :label="item.name" :value="item.id"/> <el-option v-for="item in modeOptions" :key="item.id" :label="item.name" :value="item.id"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item v-xpack v-if="projectVersionEnable && formData.modeId === 'incrementalMerge'"
:label="$t('api_test.api_import.import_version')" prop="versionId">
<el-select size="small" v-model="formData.versionId" clearable style="width: 100%">
<el-option v-for="item in versionOptions" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
</el-form-item>
<el-form-item v-xpack v-if="projectVersionEnable && formData.modeId === 'fullCoverage'"
:label="$t('api_test.api_import.data_update_version')" prop="versionId">
<el-select size="small" v-model="formData.updateVersionId" clearable style="width: 100%">
<el-option v-for="item in versionOptions" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
</el-form-item>
<el-form-item v-xpack v-if="projectVersionEnable && formData.modeId === 'fullCoverage'"
:label="$t('api_test.api_import.data_new_version')" prop="versionId">
<el-select size="small" v-model="formData.versionId" clearable style="width: 100%">
<el-option v-for="item in versionOptions" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
</el-form-item>
</el-col> </el-col>
<el-col :span="1"> <el-col :span="1">
<el-divider direction="vertical"/> <el-divider direction="vertical"/>
@ -75,7 +93,7 @@
<script> <script>
import MsDialogFooter from "../../../../common/components/MsDialogFooter"; import MsDialogFooter from "../../../../common/components/MsDialogFooter";
import {getCurrentProjectID, listenGoBack, removeGoBackListener} from "@/common/js/utils"; import {getCurrentProjectID, hasLicense, listenGoBack, removeGoBackListener} from "@/common/js/utils";
import MsSelectTree from "../../../../common/select-tree/SelectTree"; import MsSelectTree from "../../../../common/select-tree/SelectTree";
export default { export default {
@ -152,11 +170,17 @@
id: 'id', id: 'id',
label: 'name', label: 'name',
}, },
versionOptions: [],
projectVersionEnable: false,
} }
}, },
activated() { activated() {
this.selectedPlatform = this.platforms[0]; this.selectedPlatform = this.platforms[0];
}, },
created() {
this.getVersionOptions();
this.checkVersionEnable();
},
watch: { watch: {
selectedPlatformValue() { selectedPlatformValue() {
for (let i in this.platforms) { for (let i in this.platforms) {
@ -273,6 +297,28 @@
this.formData.moduleId = id; this.formData.moduleId = id;
this.formData.modulePath = data.path; this.formData.modulePath = data.path;
}, },
getVersionOptions() {
if (hasLicense()) {
this.$get('/project/version/get-project-versions/' + getCurrentProjectID(), response => {
this.versionOptions = response.data.filter(v => v.status === 'open');
this.versionOptions.forEach(v => {
if (v.latest) {
v.name = v.name + ' ' + this.$t('api_test.api_import.current_version');
}
});
});
}
},
checkVersionEnable() {
if (!this.projectId) {
return;
}
if (hasLicense()) {
this.$get('/project/version/enable/' + this.projectId, response => {
this.projectVersionEnable = response.data;
});
}
}
} }
} }
</script> </script>

View File

@ -32,6 +32,24 @@
<el-option v-for="item in modeOptions" :key="item.id" :label="item.name" :value="item.id"/> <el-option v-for="item in modeOptions" :key="item.id" :label="item.name" :value="item.id"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item v-xpack v-if="projectVersionEnable && formData.modeId === 'incrementalMerge'"
:label="$t('api_test.api_import.import_version')" prop="versionId">
<el-select size="small" v-model="formData.versionId" clearable style="width: 100%">
<el-option v-for="item in versionOptions" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
</el-form-item>
<el-form-item v-xpack v-if="projectVersionEnable && formData.modeId === 'fullCoverage'"
:label="$t('api_test.api_import.data_update_version')" prop="versionId">
<el-select size="small" v-model="formData.updateVersionId" clearable style="width: 100%">
<el-option v-for="item in versionOptions" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
</el-form-item>
<el-form-item v-xpack v-if="projectVersionEnable && formData.modeId === 'fullCoverage'"
:label="$t('api_test.api_import.data_new_version')" prop="versionId">
<el-select size="small" v-model="formData.versionId" clearable style="width: 100%">
<el-option v-for="item in versionOptions" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
</el-form-item>
<el-form-item v-if="showTemplate"> <el-form-item v-if="showTemplate">
<el-link type="primary" class="download-template" <el-link type="primary" class="download-template"
@click="downloadTemplate" @click="downloadTemplate"
@ -237,7 +255,9 @@
queryArguments: [], queryArguments: [],
authConfig: { authConfig: {
hashTree: [] hashTree: []
} },
versionOptions: [],
projectVersionEnable: false,
} }
}, },
created() { created() {
@ -246,6 +266,9 @@
this.platforms.push(this.harPlanform); this.platforms.push(this.harPlanform);
this.platforms.push(this.jmeterPlatform); this.platforms.push(this.jmeterPlatform);
this.selectedPlatform = this.platforms[0]; this.selectedPlatform = this.platforms[0];
//
this.getVersionOptions();
this.checkVersionEnable();
}, },
watch: { watch: {
moduleOptions() { moduleOptions() {
@ -260,6 +283,9 @@
break; break;
} }
} }
if (this.selectedPlatformValue === 'Har' || this.selectedPlatformValue === 'ESB') {
this.formData.modeId = 'fullCoverage';
}
}, },
propotal() { propotal() {
let postmanIndex = this.platforms.indexOf(this.postmanPlanform); let postmanIndex = this.platforms.indexOf(this.postmanPlanform);
@ -403,6 +429,28 @@
this.fileList = []; this.fileList = [];
removeGoBackListener(this.close); removeGoBackListener(this.close);
this.visible = false; this.visible = false;
},
getVersionOptions() {
if (hasLicense()) {
this.$get('/project/version/get-project-versions/' + getCurrentProjectID(), response => {
this.versionOptions = response.data.filter(v => v.status === 'open');
this.versionOptions.forEach(v => {
if (v.latest) {
v.name = v.name + ' ' + this.$t('api_test.api_import.current_version');
}
});
});
}
},
checkVersionEnable() {
if (!this.projectId) {
return;
}
if (hasLicense()) {
this.$get('/project/version/enable/' + this.projectId, response => {
this.projectVersionEnable = response.data;
});
}
} }
} }
} }

View File

@ -1671,6 +1671,10 @@ export default {
cover_tip_1: "1. Add if the interface path does not exist", cover_tip_1: "1. Add if the interface path does not exist",
cover_tip_2: "2. The interface path is consistent with the original interface, if the content is inconsistent, the original interface will be overwritten", cover_tip_2: "2. The interface path is consistent with the original interface, if the content is inconsistent, the original interface will be overwritten",
cover_tip_3: "3. If the interface path and content are consistent with the original interface, no change will be made", cover_tip_3: "3. If the interface path and content are consistent with the original interface, no change will be made",
import_version: 'Import version',
data_update_version: 'Api update version',
data_new_version: 'Api creation version',
current_version: 'Current version',
}, },
home_page: { home_page: {
unit_of_measurement: "", unit_of_measurement: "",

View File

@ -1676,6 +1676,10 @@ export default {
cover_tip_1: "1. 接口路径不存在则新增", cover_tip_1: "1. 接口路径不存在则新增",
cover_tip_2: "2. 接口路径与原接口一致,内容不一致则覆盖原接口", cover_tip_2: "2. 接口路径与原接口一致,内容不一致则覆盖原接口",
cover_tip_3: "3. 接口路径、内容与原接口一致则不做变更", cover_tip_3: "3. 接口路径、内容与原接口一致则不做变更",
import_version: '导入版本',
data_update_version: '数据更新版本',
data_new_version: '数据创建版本',
current_version: '当前版本',
}, },
home_page: { home_page: {
unit_of_measurement: "个", unit_of_measurement: "个",

View File

@ -1676,6 +1676,10 @@ export default {
cover_tip_1: "1. 接口路徑不存在則新增", cover_tip_1: "1. 接口路徑不存在則新增",
cover_tip_2: "2. 接口路徑與原接口一致,內容不一致則覆蓋原接口", cover_tip_2: "2. 接口路徑與原接口一致,內容不一致則覆蓋原接口",
cover_tip_3: "3. 接口路徑、內容與原接口一致則不做變更", cover_tip_3: "3. 接口路徑、內容與原接口一致則不做變更",
import_version: '導入版本',
data_update_version: '數據更新版本',
data_new_version: '數據創建版本',
current_version: '當前版本',
}, },
home_page: { home_page: {
unit_of_measurement: "個", unit_of_measurement: "個",