refactor(接口测试): 优化导入逻辑

--task=1008278 --user=王孝刚 接口测试导入逻辑优化(1.20同步上)
https://www.tapd.cn/55049933/s/1187315
This commit is contained in:
wxg0103 2022-06-21 10:33:46 +08:00 committed by f2c-ci-robot[bot]
parent e0b7f5d621
commit 9e42c8ae83
10 changed files with 735 additions and 654 deletions

View File

@ -35,5 +35,9 @@ public class ApiTestImportRequest {
private List<KeyValue> headers;
private List<KeyValue> arguments;
private MsAuthManager authManager;
// 是否覆盖模块
private Boolean coverModule;
// 当前协议
private String protocol;
}

View File

@ -76,6 +76,8 @@ public class MsDefinitionParser extends MsAbstractParser<ApiDefinitionImport> {
private ApiDefinitionImport parseMsFormat(String testStr, ApiTestImportRequest importRequest) {
ApiDefinitionImport apiDefinitionImport = JSON.parseObject(testStr, ApiDefinitionImport.class, Feature.DisableSpecialKeyDetect);
List<ApiDefinitionWithBLOBs> protocol = apiDefinitionImport.getData().stream().filter(item -> StringUtils.equals(importRequest.getProtocol(), item.getProtocol())).collect(Collectors.toList());
apiDefinitionImport.setData(protocol);
Map<String, List<ApiTestCaseWithBLOBs>> caseMap = new HashMap<>();
if (apiDefinitionImport.getCases() != null) {
apiDefinitionImport.getCases().forEach(item -> {

View File

@ -679,7 +679,8 @@ public class ApiAutomationService {
.andProjectIdEqualTo(request.getProjectId())
.andStatusNotEqualTo("Trash")
.andIdNotEqualTo(request.getId())
.andVersionIdEqualTo(request.getVersionId());
.andVersionIdEqualTo(request.getVersionId())
.andApiScenarioModuleIdEqualTo(request.getApiScenarioModuleId());
if (apiScenarioMapper.countByExample(example) > 0) {
MSException.throwException(Translator.get("automation_name_already_exists"));
}

View File

@ -520,7 +520,7 @@ public class ApiDefinitionService {
criteria.andMethodEqualTo(request.getMethod()).andStatusNotEqualTo("Trash")
.andProtocolEqualTo(request.getProtocol()).andPathEqualTo(request.getPath())
.andProjectIdEqualTo(request.getProjectId()).andIdNotEqualTo(request.getId())
.andVersionIdEqualTo(request.getVersionId());
.andVersionIdEqualTo(request.getVersionId()).andModuleIdEqualTo(request.getModuleId());
Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
ProjectConfig config = projectApplicationService.getSpecificTypeValue(project.getId(), ProjectApplicationType.URL_REPEATABLE.name());
boolean urlRepeat = config.getUrlRepeatable();
@ -537,7 +537,7 @@ public class ApiDefinitionService {
} else {
example.createCriteria().andProtocolEqualTo(request.getProtocol()).andStatusNotEqualTo("Trash")
.andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId())
.andIdNotEqualTo(request.getId()).andVersionIdEqualTo(request.getVersionId());
.andIdNotEqualTo(request.getId()).andVersionIdEqualTo(request.getVersionId()).andModuleIdEqualTo(request.getModuleId());
if (apiDefinitionMapper.countByExample(example) > 0) {
MSException.throwException(Translator.get("load_test_already_exists"));
}

View File

@ -22,12 +22,17 @@
<el-row>
<el-col :span="11">
<el-form-item :label="$t('commons.import_module')">
<ms-select-tree size="small" :data="moduleOptions" :defaultKey="formData.moduleId" @getValue="setModule" :obj="moduleObj" clearable checkStrictly/>
<ms-select-tree size="small" :data="moduleOptions" :defaultKey="formData.moduleId" @getValue="setModule"
:obj="moduleObj" clearable checkStrictly/>
</el-form-item>
<el-form-item v-if="!isHar" :label="$t('commons.import_mode')">
<el-select size="small" v-model="formData.modeId" class="project-select" clearable>
<el-option v-for="item in modeOptions" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
<el-checkbox size="mini" v-if="formData.modeId === 'fullCoverage'"
v-model="formData.coverModule">
{{ this.$t('commons.cover_scenario') }}
</el-checkbox>
</el-form-item>
<el-form-item v-xpack v-if="projectVersionEnable && formData.modeId === 'incrementalMerge'"
:label="$t('api_test.api_import.import_version')" prop="versionId">
@ -80,11 +85,15 @@
<span>{{ $t('api_test.api_import.export_tip') }}{{ selectedPlatform.exportTip }}</span>
</div>
<div>
<span>
{{ $t('api_test.api_import.import_cover_tip') }}<br/>
{{ $t('api_test.api_import.cover_tip_1') }}<br/>
{{ $t('api_test.api_import.cover_tip_2') }}<br/>
{{ $t('api_test.api_import.cover_tip_3') }}
<span>
{{ $t('api_test.api_import.cover_tip') }} :<br/>
{{ $t('api_test.api_import.cover_tip_scenario_1') }}<br/>
{{ $t('api_test.api_import.cover_tip_scenario_2') }}<br/>
{{ $t('api_test.api_import.cover_tip_scenario_3') }}<br/>
{{ $t('api_test.api_import.cover_tip_scenario_4') }}<br/>
{{ $t('api_test.api_import.no_cover_tip') }} :<br/>
{{ $t('api_test.api_import.no_cover_tip_scenario_1') }}<br/>
{{ $t('api_test.api_import.no_cover_tip_scenario_2') }}
</span>
</div>
</div>
@ -107,293 +116,293 @@ export default {
moduleOptions: Array,
},
data() {
return {
visible: false,
swaggerUrlEable: false,
swaggerSynchronization: false,
showEnvironmentSelect: true,
modeOptions: [{
id: 'fullCoverage',
name: this.$t('commons.cover')
return {
visible: false,
swaggerUrlEable: false,
swaggerSynchronization: false,
showEnvironmentSelect: true,
modeOptions: [{
id: 'fullCoverage',
name: this.$t('commons.cover')
},
{
id: 'incrementalMerge',
name: this.$t('commons.not_cover')
}],
protocol: "",
platforms: [
{
name: 'MeterSphere',
value: 'Metersphere',
tip: this.$t('api_test.api_import.ms_tip'),
exportTip: this.$t('api_test.api_import.ms_export_tip'),
suffixes: new Set(['json'])
},
{
id: 'incrementalMerge',
name: this.$t('commons.not_cover')
}],
protocol: "",
platforms: [
{
name: 'MeterSphere',
value: 'Metersphere',
tip: this.$t('api_test.api_import.ms_tip'),
exportTip: this.$t('api_test.api_import.ms_export_tip'),
suffixes: new Set(['json'])
},
{
name: 'Postman',
value: 'Postman',
tip: this.$t('api_test.api_import.postman_tip'),
exportTip: this.$t('api_test.api_import.post_export_tip'),
suffixes: new Set(['json'])
},
{
name: 'JMeter',
value: 'Jmeter',
tip: this.$t('api_test.api_import.jmeter_tip'),
exportTip: this.$t('api_test.api_import.jmeter_export_tip'),
suffixes: new Set(['jmx'])
},
{
name: 'HAR',
value: 'Har',
tip: this.$t('api_test.api_import.har_tip'),
exportTip: this.$t('api_test.api_import.har_export_tip'),
suffixes: new Set(['har'])
}
],
selectedPlatform: {},
selectedPlatformValue: 'Metersphere',
result: {},
projects: [],
environments: [],
useEnvironment: false,
formData: {
file: undefined,
swaggerUrl: '',
modeId: 'incrementalMerge',
moduleId: '',
{
name: 'Postman',
value: 'Postman',
tip: this.$t('api_test.api_import.postman_tip'),
exportTip: this.$t('api_test.api_import.post_export_tip'),
suffixes: new Set(['json'])
},
rules: {},
currentModule: {},
fileList: [],
moduleObj: {
id: 'id',
label: 'name',
{
name: 'JMeter',
value: 'Jmeter',
tip: this.$t('api_test.api_import.jmeter_tip'),
exportTip: this.$t('api_test.api_import.jmeter_export_tip'),
suffixes: new Set(['jmx'])
},
versionOptions: [],
projectVersionEnable: false,
}
},
activated() {
this.selectedPlatform = this.platforms[0];
},
created() {
this.getVersionOptions();
this.checkVersionEnable();
},
watch: {
selectedPlatformValue() {
for (let i in this.platforms) {
if (this.platforms[i].value === this.selectedPlatformValue) {
this.selectedPlatform = this.platforms[i];
break;
}
{
name: 'HAR',
value: 'Har',
tip: this.$t('api_test.api_import.har_tip'),
exportTip: this.$t('api_test.api_import.har_export_tip'),
suffixes: new Set(['har'])
}
if (this.selectedPlatformValue === 'Har') {
this.formData.modeId = 'fullCoverage';
],
selectedPlatform: {},
selectedPlatformValue: 'Metersphere',
result: {},
projects: [],
environments: [],
useEnvironment: false,
formData: {
file: undefined,
swaggerUrl: '',
modeId: 'incrementalMerge',
moduleId: '',
coverModule: false
},
rules: {},
currentModule: {},
fileList: [],
moduleObj: {
id: 'id',
label: 'name',
},
versionOptions: [],
projectVersionEnable: false,
}
},
created() {
this.getVersionOptions();
this.checkVersionEnable();
this.selectedPlatform = this.platforms[0];
},
watch: {
selectedPlatformValue() {
for (let i in this.platforms) {
if (this.platforms[i].value === this.selectedPlatformValue) {
this.selectedPlatform = this.platforms[i];
break;
}
}
if (this.selectedPlatformValue === 'Har') {
this.formData.modeId = 'fullCoverage';
}
}
},
computed: {
isHar() {
return this.selectedPlatformValue === 'Har';
},
projectId() {
return getCurrentProjectID();
},
},
methods: {
scheduleEdit() {
if (!this.formData.swaggerUrl) {
this.$warning(this.$t('commons.please_fill_path'));
this.swaggerSynchronization = !this.swaggerSynchronization
} else {
if (this.swaggerSynchronization) {
this.$refs.scheduleEdit.open(this.buildParam());
}
}
},
computed: {
isHar() {
return this.selectedPlatformValue === 'Har';
},
projectId() {
return getCurrentProjectID();
},
scheduleEditByText() {
this.$refs.scheduleEdit.open(this.buildParam());
},
methods: {
scheduleEdit() {
if (!this.formData.swaggerUrl) {
this.$warning(this.$t('commons.please_fill_path'));
this.swaggerSynchronization = !this.swaggerSynchronization
open(module) {
this.currentModule = module;
this.visible = true;
listenGoBack(this.close);
},
upload(file) {
this.formData.file = file.file;
},
handleExceed(files, fileList) {
this.$warning(this.$t('test_track.case.import.upload_limit_count'));
},
handleRemove(file, fileList) {
this.formData.file = undefined;
},
uploadValidate(file, fileList) {
let suffix = file.name.substring(file.name.lastIndexOf('.') + 1);
if (this.selectedPlatform.suffixes && !this.selectedPlatform.suffixes.has(suffix)) {
this.$warning(this.$t('api_test.api_import.suffixFormatErr'));
return false;
}
if (file.size / 1024 / 1024 > 100) {
this.$warning(this.$t('test_track.case.import.upload_limit_size'));
return false;
}
return true;
},
save() {
if (!this.formData.file) {
this.$warning("请添加一个文件");
return;
}
let suffix = this.formData.file.name.substring(this.formData.file.name.lastIndexOf('.') + 1);
if (this.selectedPlatform.suffixes && !this.selectedPlatform.suffixes.has(suffix)) {
this.$warning(this.$t('api_test.api_import.suffixFormatErr'));
return false;
}
this.$refs.form.validate(valid => {
if (valid) {
let param = this.buildParam();
this.result = this.$fileUpload('/api/automation/import', param.file, null, this.buildParam(), response => {
let res = response.data;
this.$success(this.$t('test_track.case.import.success'));
this.visible = false;
this.$emit('refreshAll', res);
});
} else {
if (this.swaggerSynchronization) {
this.$refs.scheduleEdit.open(this.buildParam());
return false;
}
});
},
buildParam() {
let param = {};
Object.assign(param, this.formData);
param.platform = this.selectedPlatformValue;
param.saved = this.saved;
if (this.currentModule) {
param.moduleId = this.formData.moduleId
this.moduleOptions.filter(item => {
if (item.id === this.formData.moduleId) {
param.modulePath = item.path
}
}
},
scheduleEditByText() {
this.$refs.scheduleEdit.open(this.buildParam());
},
open(module) {
this.currentModule = module;
this.visible = true;
listenGoBack(this.close);
},
upload(file) {
this.formData.file = file.file;
},
handleExceed(files, fileList) {
this.$warning(this.$t('test_track.case.import.upload_limit_count'));
},
handleRemove(file, fileList) {
this.formData.file = undefined;
},
uploadValidate(file, fileList) {
let suffix = file.name.substring(file.name.lastIndexOf('.') + 1);
if (this.selectedPlatform.suffixes && !this.selectedPlatform.suffixes.has(suffix)) {
this.$warning(this.$t('api_test.api_import.suffixFormatErr'));
return false;
}
if (file.size / 1024 / 1024 > 100) {
this.$warning(this.$t('test_track.case.import.upload_limit_size'));
return false;
}
return true;
},
save() {
if (!this.formData.file) {
this.$warning("请添加一个文件");
return;
}
let suffix = this.formData.file.name.substring(this.formData.file.name.lastIndexOf('.') + 1);
if (this.selectedPlatform.suffixes && !this.selectedPlatform.suffixes.has(suffix)) {
this.$warning(this.$t('api_test.api_import.suffixFormatErr'));
return false;
}
this.$refs.form.validate(valid => {
if (valid) {
let param = this.buildParam();
this.result = this.$fileUpload('/api/automation/import', param.file, null, this.buildParam(), response => {
let res = response.data;
this.$success(this.$t('test_track.case.import.success'));
this.visible = false;
this.$emit('refreshAll', res);
});
} else {
return false;
}
});
},
buildParam() {
let param = {};
Object.assign(param, this.formData);
param.platform = this.selectedPlatformValue;
param.saved = this.saved;
if (this.currentModule) {
param.moduleId = this.formData.moduleId
this.moduleOptions.filter(item => {
if (item.id === this.formData.moduleId) {
param.modulePath = item.path
})
param.modeId = this.formData.modeId
}
param.projectId = this.projectId;
if (!this.swaggerUrlEable) {
param.swaggerUrl = undefined;
}
return param;
},
close() {
this.formData = {
file: undefined,
swaggerUrl: '',
modeId: this.formData.modeId,
moduleId: '',
};
this.fileList = [];
removeGoBackListener(this.close);
this.visible = false;
},
setModule(id, data) {
this.formData.moduleId = id;
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.latest_version');
}
})
param.modeId = this.formData.modeId
}
param.projectId = this.projectId;
if (!this.swaggerUrlEable) {
param.swaggerUrl = undefined;
}
return param;
},
close() {
this.formData = {
file: undefined,
swaggerUrl: '',
modeId: this.formData.modeId,
moduleId: '',
};
this.fileList = [];
removeGoBackListener(this.close);
this.visible = false;
},
setModule(id, data) {
this.formData.moduleId = id;
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.latest_version');
}
});
});
}
},
checkVersionEnable() {
if (!this.projectId) {
return;
}
if (hasLicense()) {
this.$get('/project/version/enable/' + this.projectId, response => {
this.projectVersionEnable = response.data;
});
}
});
}
},
checkVersionEnable() {
if (!this.projectId) {
return;
}
if (hasLicense()) {
this.$get('/project/version/enable/' + this.projectId, response => {
this.projectVersionEnable = response.data;
});
}
}
}
}
</script>
<style scoped>
.api-import >>> .el-dialog {
min-width: 700px;
}
.api-import >>> .el-dialog {
min-width: 700px;
}
.format-tip {
background: #EDEDED;
}
.format-tip {
background: #EDEDED;
}
.api-upload {
text-align: center;
margin: auto 0;
}
.api-upload {
text-align: center;
margin: auto 0;
}
.api-upload >>> .el-upload {
width: 100%;
max-width: 350px;
}
.api-upload >>> .el-upload {
width: 100%;
max-width: 350px;
}
.api-upload >>> .el-upload-dragger {
width: 100%;
}
.api-upload >>> .el-upload-dragger {
width: 100%;
}
.el-radio-group {
margin: 10px 0;
}
.el-radio-group {
margin: 10px 0;
}
.header-bar, .format-tip, .el-form {
border: solid #E1E1E1 1px;
margin: 10px 0;
padding: 10px;
border-radius: 3px;
}
.header-bar, .format-tip, .el-form {
border: solid #E1E1E1 1px;
margin: 10px 0;
padding: 10px;
border-radius: 3px;
}
.header-bar {
padding: 10px 30px;
}
.header-bar {
padding: 10px 30px;
}
.api-import >>> .el-dialog__body {
padding: 15px 25px;
}
.api-import >>> .el-dialog__body {
padding: 15px 25px;
}
.operate-button {
float: right;
}
.operate-button {
float: right;
}
.save-button {
margin-left: 10px;
}
.save-button {
margin-left: 10px;
}
.el-form {
padding: 30px 10px;
}
.el-form {
padding: 30px 10px;
}
.dialog-footer {
float: right;
}
.dialog-footer {
float: right;
}
.swagger-url-disable {
margin-top: 10px;
.swagger-url-disable {
margin-top: 10px;
margin-left: 80px;
}
margin-left: 80px;
}
.el-divider {
height: 200px;
}
.el-divider {
height: 200px;
}
</style>

View File

@ -32,6 +32,10 @@
<el-select size="small" v-model="formData.modeId" clearable style="width: 100%">
<el-option v-for="item in modeOptions" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
<el-checkbox size="mini" v-if="formData.modeId === 'fullCoverage'" v-model="formData.coverModule"
style="display:block;">
{{ this.$t('commons.cover_api') }}
</el-checkbox>
</el-form-item>
<el-form-item v-xpack v-if="projectVersionEnable && formData.modeId === 'incrementalMerge'"
:label="$t('api_test.api_import.import_version')" prop="versionId">
@ -54,7 +58,7 @@
<el-form-item v-if="showTemplate">
<el-link type="primary" class="download-template"
@click="downloadTemplate"
>{{$t('test_track.case.import.download_template')}}
>{{ $t('test_track.case.import.download_template') }}
</el-link>
</el-form-item>
<el-form-item v-if="isSwagger2">
@ -78,21 +82,23 @@
</el-col>
<el-col :span="14" v-show="isSwagger2 && authEnable && swaggerUrlEnable">
<!--请求头 -->
<div style="margin-top: 15px;">
<span>{{$t('api_test.request.headers')}}{{$t('api_test.api_import.optional')}}</span>
</div>
<ms-api-key-value :show-desc="true" :isShowEnable="isShowEnable" :suggestions="headerSuggestions" :items="headers"/>
<!--query 参数-->
<div style="margin-top: 10px">
<span>{{$t('api_test.definition.request.query_param')}}{{$t('api_test.api_import.optional')}}</span>
</div>
<ms-api-variable :with-mor-setting="true" :is-read-only="isReadOnly" :isShowEnable="isShowEnable" :parameters="queryArguments"/>
<!--认证配置-->
<div style="margin-top: 10px">
<span>{{$t('api_test.definition.request.auth_config')}}{{$t('api_test.api_import.optional')}}</span>
</div>
<ms-api-auth-config :is-read-only="isReadOnly" :request="authConfig" :encryptShow="false" ref="importAuth"/>
<!--请求头 -->
<div style="margin-top: 15px;">
<span>{{ $t('api_test.request.headers') }}{{ $t('api_test.api_import.optional') }}</span>
</div>
<ms-api-key-value :show-desc="true" :isShowEnable="isShowEnable" :suggestions="headerSuggestions"
:items="headers"/>
<!--query 参数-->
<div style="margin-top: 10px">
<span>{{ $t('api_test.definition.request.query_param') }}{{ $t('api_test.api_import.optional') }}</span>
</div>
<ms-api-variable :with-mor-setting="true" :is-read-only="isReadOnly" :isShowEnable="isShowEnable"
:parameters="queryArguments"/>
<!--认证配置-->
<div style="margin-top: 10px">
<span>{{ $t('api_test.definition.request.auth_config') }}{{ $t('api_test.api_import.optional') }}</span>
</div>
<ms-api-auth-config :is-read-only="isReadOnly" :request="authConfig" :encryptShow="false" ref="importAuth"/>
</el-col>
<el-col :span="12"
@ -125,10 +131,18 @@
</div>
<div>
<span>
{{ $t('api_test.api_import.import_cover_tip') }}<br/>
{{ $t('api_test.api_import.import_tip') }} : <br/>
{{ $t('api_test.api_import.import_tip1') }} <br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ $t('api_test.api_import.import_tip2') }} <br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ $t('api_test.api_import.import_tip3') }} <br/>
{{ $t('api_test.api_import.cover_tip') }} :<br/>
{{ $t('api_test.api_import.cover_tip_1') }}<br/>
{{ $t('api_test.api_import.cover_tip_2') }}<br/>
{{ $t('api_test.api_import.cover_tip_3') }}
{{ $t('api_test.api_import.cover_tip_3') }}<br/>
{{ $t('api_test.api_import.cover_tip_4') }}<br/>
{{ $t('api_test.api_import.no_cover_tip') }} :<br/>
{{ $t('api_test.api_import.no_cover_tip_1') }}<br/>
{{ $t('api_test.api_import.no_cover_tip_2') }}
</span>
</div>
</div>
@ -158,403 +172,405 @@ export default {
props: {
saved: {
type: Boolean,
default: true,
},
moduleOptions: Array,
propotal: String,
model: {
type: String,
default: 'definition'
}
default: true,
},
data() {
return {
visible: false,
swaggerUrlEnable: false,
authEnable: false,
showEnvironmentSelect: true,
showXpackCompnent:false,
headerSuggestions: REQUEST_HEADERS,
moduleObj: {
id: 'id',
label: 'name',
moduleOptions: Array,
protocol: String,
model: {
type: String,
default: 'definition'
}
},
data() {
return {
visible: false,
swaggerUrlEnable: false,
authEnable: false,
showEnvironmentSelect: true,
showXpackCompnent: false,
headerSuggestions: REQUEST_HEADERS,
moduleObj: {
id: 'id',
label: 'name',
},
modeOptions: [
{
id: 'fullCoverage',
name: this.$t('commons.cover')
},
modeOptions: [
{
id: 'fullCoverage',
name: this.$t('commons.cover')
},
{
id: 'incrementalMerge',
name: this.$t('commons.not_cover')
}
],
protocol: "",
platforms: [
{
name: 'MeterSphere',
value: 'Metersphere',
tip: this.$t('api_test.api_import.ms_tip'),
exportTip: this.$t('api_test.api_import.ms_export_tip'),
suffixes: new Set(['json'])
},
],
postmanPlanform: {
name: 'Postman',
value: 'Postman',
tip: this.$t('api_test.api_import.postman_tip'),
exportTip: this.$t('api_test.api_import.post_export_tip'),
{
id: 'incrementalMerge',
name: this.$t('commons.not_cover')
}
],
platforms: [
{
name: 'MeterSphere',
value: 'Metersphere',
tip: this.$t('api_test.api_import.ms_tip'),
exportTip: this.$t('api_test.api_import.ms_export_tip'),
suffixes: new Set(['json'])
},
swaggerPlanform: {
name: 'Swagger',
value: 'Swagger2',
tip: this.$t('api_test.api_import.swagger_tip'),
exportTip: this.$t('api_test.api_import.swagger_export_tip'),
suffixes: new Set(['json'])
},
harPlanform: {
name: 'HAR',
value: 'Har',
tip: this.$t('api_test.api_import.har_tip'),
exportTip: this.$t('api_test.api_import.har_export_tip'),
suffixes: new Set(['har'])
},
esbPlanform: {
name: 'ESB',
value: 'ESB',
tip: this.$t('api_test.api_import.esb_tip'),
exportTip: this.$t('api_test.api_import.esb_export_tip'),
suffixes: new Set(['xlsx', 'xls'])
},
jmeterPlatform: {
name: 'JMeter',
value: 'Jmeter',
tip: this.$t('api_test.api_import.jmeter_tip'),
exportTip: this.$t('api_test.api_import.jmeter_export_tip'),
suffixes: new Set(['jmx'])
},
selectedPlatform: {},
selectedPlatformValue: 'Metersphere',
result: {},
projects: [],
environments: [],
useEnvironment: false,
formData: {
file: undefined,
swaggerUrl: '',
modeId: 'incrementalMerge',
moduleId: ''
},
rules: {
modeId: [
{required: true, message: this.$t('commons.please_select_import_mode'), trigger: 'change'},
],
},
currentModule: {},
fileList: [],
isShowEnable: true,
isReadOnly: false,
headers: [],
queryArguments: [],
authConfig: {
hashTree: []
},
versionOptions: [],
projectVersionEnable: false,
],
postmanPlanform: {
name: 'Postman',
value: 'Postman',
tip: this.$t('api_test.api_import.postman_tip'),
exportTip: this.$t('api_test.api_import.post_export_tip'),
suffixes: new Set(['json'])
},
swaggerPlanform: {
name: 'Swagger',
value: 'Swagger2',
tip: this.$t('api_test.api_import.swagger_tip'),
exportTip: this.$t('api_test.api_import.swagger_export_tip'),
suffixes: new Set(['json'])
},
harPlanform: {
name: 'HAR',
value: 'Har',
tip: this.$t('api_test.api_import.har_tip'),
exportTip: this.$t('api_test.api_import.har_export_tip'),
suffixes: new Set(['har'])
},
esbPlanform: {
name: 'ESB',
value: 'ESB',
tip: this.$t('api_test.api_import.esb_tip'),
exportTip: this.$t('api_test.api_import.esb_export_tip'),
suffixes: new Set(['xlsx', 'xls'])
},
jmeterPlatform: {
name: 'JMeter',
value: 'Jmeter',
tip: this.$t('api_test.api_import.jmeter_tip'),
exportTip: this.$t('api_test.api_import.jmeter_export_tip'),
suffixes: new Set(['jmx'])
},
selectedPlatform: {},
selectedPlatformValue: 'Metersphere',
result: {},
projects: [],
environments: [],
useEnvironment: false,
formData: {
file: undefined,
swaggerUrl: '',
modeId: 'incrementalMerge',
moduleId: '',
coverModule: false
},
rules: {
modeId: [
{required: true, message: this.$t('commons.please_select_import_mode'), trigger: 'change'},
],
},
currentModule: {},
fileList: [],
isShowEnable: true,
isReadOnly: false,
headers: [],
queryArguments: [],
authConfig: {
hashTree: []
},
versionOptions: [],
projectVersionEnable: false,
}
},
created() {
this.platforms.push(this.postmanPlanform);
this.platforms.push(this.swaggerPlanform);
this.platforms.push(this.harPlanform);
this.platforms.push(this.jmeterPlatform);
this.selectedPlatform = this.platforms[0];
//
this.getVersionOptions();
this.checkVersionEnable();
},
watch: {
moduleOptions() {
if (this.moduleOptions.length > 0) {
this.formData.moduleId = this.moduleOptions[0].id;
}
},
created() {
this.platforms.push(this.postmanPlanform);
this.platforms.push(this.swaggerPlanform);
this.platforms.push(this.harPlanform);
this.platforms.push(this.jmeterPlatform);
this.selectedPlatform = this.platforms[0];
//
this.getVersionOptions();
this.checkVersionEnable();
},
watch: {
moduleOptions() {
if (this.moduleOptions.length > 0) {
this.formData.moduleId = this.moduleOptions[0].id;
}
},
selectedPlatformValue() {
for (let i in this.platforms) {
if (this.platforms[i].value === this.selectedPlatformValue) {
this.selectedPlatform = this.platforms[i];
break;
}
}
if (this.selectedPlatformValue === 'Har' || this.selectedPlatformValue === 'ESB') {
this.formData.modeId = 'fullCoverage';
}
},
propotal() {
let postmanIndex = this.platforms.indexOf(this.postmanPlanform);
let swaggerPlanformIndex = this.platforms.indexOf(this.swaggerPlanform);
let harPlanformIndex = this.platforms.indexOf(this.harPlanform);
let esbPlanformIndex = this.platforms.indexOf(this.esbPlanform);
if (postmanIndex >= 0) {
this.platforms.splice(this.platforms.indexOf(this.postmanPlanform), 1);
}
if (swaggerPlanformIndex >= 0) {
this.platforms.splice(this.platforms.indexOf(this.swaggerPlanform), 1);
}
if (harPlanformIndex >= 0) {
this.platforms.splice(this.platforms.indexOf(this.harPlanform), 1);
}
if (esbPlanformIndex >= 0) {
this.platforms.splice(this.platforms.indexOf(this.esbPlanform), 1);
}
if (this.propotal === 'TCP') {
if(hasLicense()){
this.platforms.push(this.esbPlanform);
}
return true;
} else if (this.propotal === 'HTTP') {
this.platforms.push(this.postmanPlanform);
this.platforms.push(this.swaggerPlanform);
this.platforms.push(this.harPlanform);
return false;
selectedPlatformValue() {
for (let i in this.platforms) {
if (this.platforms[i].value === this.selectedPlatformValue) {
this.selectedPlatform = this.platforms[i];
break;
}
}
},
computed: {
isSwagger2() {
return this.selectedPlatformValue === 'Swagger2';
},
showImportModel() {
return this.selectedPlatformValue != 'Har' && this.selectedPlatformValue != 'ESB';
},
showTemplate() {
return this.selectedPlatformValue === 'ESB';
},
isScenarioModel() {
return this.model === 'scenario';
},
projectId() {
return getCurrentProjectID();
},
dialogWidth() {
if (this.isSwagger2 && this.authEnable && this.swaggerUrlEnable) {
return '80%';
}
return '30%';
if (this.selectedPlatformValue === 'Har' || this.selectedPlatformValue === 'ESB') {
this.formData.modeId = 'fullCoverage';
}
},
methods: {
open(module) {
this.currentModule = module;
this.visible = true;
listenGoBack(this.close);
},
upload(file) {
this.formData.file = file.file;
},
handleExceed(files, fileList) {
this.$warning(this.$t('test_track.case.import.upload_limit_count'));
},
handleRemove(file, fileList) {
this.formData.file = undefined;
},
downloadTemplate() {
if (this.selectedPlatformValue == "ESB") {
this.$fileDownload('/api/definition/export/esbExcelTemplate');
}
},
uploadValidate(file, fileList) {
let suffix = file.name.substring(file.name.lastIndexOf('.') + 1);
if (this.selectedPlatform.suffixes && !this.selectedPlatform.suffixes.has(suffix)) {
this.$warning(this.$t('api_test.api_import.suffixFormatErr'));
return false;
}
if (file.size / 1024 / 1024 > 100) {
this.$warning(this.$t('test_track.case.import.upload_limit_size'));
return false;
protocol() {
let postmanIndex = this.platforms.indexOf(this.postmanPlanform);
let swaggerPlanformIndex = this.platforms.indexOf(this.swaggerPlanform);
let harPlanformIndex = this.platforms.indexOf(this.harPlanform);
let esbPlanformIndex = this.platforms.indexOf(this.esbPlanform);
if (postmanIndex >= 0) {
this.platforms.splice(this.platforms.indexOf(this.postmanPlanform), 1);
}
if (swaggerPlanformIndex >= 0) {
this.platforms.splice(this.platforms.indexOf(this.swaggerPlanform), 1);
}
if (harPlanformIndex >= 0) {
this.platforms.splice(this.platforms.indexOf(this.harPlanform), 1);
}
if (esbPlanformIndex >= 0) {
this.platforms.splice(this.platforms.indexOf(this.esbPlanform), 1);
}
if (this.protocol === 'TCP') {
if (hasLicense()) {
this.platforms.push(this.esbPlanform);
}
return true;
},
save() {
this.$refs.form.validate(valid => {
if (valid) {
if ((this.selectedPlatformValue != 'Swagger2' || (this.selectedPlatformValue == 'Swagger2' && !this.swaggerUrlEnable)) && !this.formData.file) {
this.$warning(this.$t('commons.please_upload'));
return;
}
let url = '/api/definition/import';
if (this.isScenarioModel) {
url = '/api/automation/import';
}
let param = this.buildParam();
this.result = this.$fileUpload(url, param.file, null, this.buildParam(), response => {
let res = response.data;
this.$success(this.$t('test_track.case.import.success'));
this.visible = false;
this.$emit('refresh', res);
});
} else {
return false;
} else if (this.protocol === 'HTTP') {
this.platforms.push(this.postmanPlanform);
this.platforms.push(this.swaggerPlanform);
this.platforms.push(this.harPlanform);
return false;
}
}
},
computed: {
isSwagger2() {
return this.selectedPlatformValue === 'Swagger2';
},
showImportModel() {
return this.selectedPlatformValue != 'Har' && this.selectedPlatformValue != 'ESB';
},
showTemplate() {
return this.selectedPlatformValue === 'ESB';
},
isScenarioModel() {
return this.model === 'scenario';
},
projectId() {
return getCurrentProjectID();
},
dialogWidth() {
if (this.isSwagger2 && this.authEnable && this.swaggerUrlEnable) {
return '80%';
}
return '30%';
}
},
methods: {
open(module) {
this.currentModule = module;
this.visible = true;
listenGoBack(this.close);
},
upload(file) {
this.formData.file = file.file;
},
handleExceed(files, fileList) {
this.$warning(this.$t('test_track.case.import.upload_limit_count'));
},
handleRemove(file, fileList) {
this.formData.file = undefined;
},
downloadTemplate() {
if (this.selectedPlatformValue == "ESB") {
this.$fileDownload('/api/definition/export/esbExcelTemplate');
}
},
uploadValidate(file, fileList) {
let suffix = file.name.substring(file.name.lastIndexOf('.') + 1);
if (this.selectedPlatform.suffixes && !this.selectedPlatform.suffixes.has(suffix)) {
this.$warning(this.$t('api_test.api_import.suffixFormatErr'));
return false;
}
if (file.size / 1024 / 1024 > 100) {
this.$warning(this.$t('test_track.case.import.upload_limit_size'));
return false;
}
return true;
},
save() {
this.$refs.form.validate(valid => {
if (valid) {
if ((this.selectedPlatformValue != 'Swagger2' || (this.selectedPlatformValue == 'Swagger2' && !this.swaggerUrlEnable)) && !this.formData.file) {
this.$warning(this.$t('commons.please_upload'));
return;
}
let url = '/api/definition/import';
if (this.isScenarioModel) {
url = '/api/automation/import';
}
let param = this.buildParam();
this.result = this.$fileUpload(url, param.file, null, this.buildParam(), response => {
let res = response.data;
this.$success(this.$t('test_track.case.import.success'));
this.visible = false;
this.$emit('refresh', res);
});
} else {
return false;
}
});
},
setModule(id, data) {
this.formData.moduleId = id;
this.formData.modulePath = data.path;
},
clearAuthInfo() {
this.headers = [];
this.queryArguments = [];
this.headers.push(new KeyValue({enable: true}));
this.queryArguments.push(new KeyValue({enable: true}));
this.authConfig = {hashTree: [], authManager: {}};
this.$refs.importAuth.initData();
},
changeAuthEnable() {
if (!this.authEnable) {
this.clearAuthInfo();
}
},
buildParam() {
let param = {};
Object.assign(param, this.formData);
param.platform = this.selectedPlatformValue;
param.saved = this.saved;
param.model = this.model;
if (this.currentModule) {
if (!this.formData.moduleId || this.formData.moduleId.length === 0) {
param.moduleId = this.currentModule[0].id;
} else {
param.moduleId = this.formData.moduleId
}
param.modeId = this.formData.modeId
}
param.projectId = this.projectId;
param.protocol = this.protocol;
if (!this.swaggerUrlEnable) {
param.swaggerUrl = undefined;
}
if (this.authEnable) {
//
param.headers = this.headers;
// query
param.arguments = this.queryArguments;
// BaseAuth
if (this.authConfig.authManager != undefined) {
this.authConfig.authManager.clazzName = TYPE_TO_C.get("AuthManager");
param.authManager = this.authConfig.authManager;
}
}
return param;
},
close() {
this.formData = {
file: undefined,
swaggerUrl: '',
modeId: this.formData.modeId,
};
this.fileList = [];
removeGoBackListener(this.close);
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.latest_version');
}
});
});
}
},
checkVersionEnable() {
if (!this.projectId) {
return;
}
if (hasLicense()) {
this.$get('/project/version/enable/' + this.projectId, response => {
this.projectVersionEnable = response.data;
});
},
setModule(id, data) {
this.formData.moduleId = id;
this.formData.modulePath = data.path;
},
clearAuthInfo(){
this.headers = [];
this.queryArguments = [];
this.headers.push(new KeyValue({enable: true}));
this.queryArguments.push(new KeyValue({enable: true}));
this.authConfig = {hashTree: [], authManager: {}};
this.$refs.importAuth.initData();
},
changeAuthEnable() {
if(!this.authEnable){
this.clearAuthInfo();
}
},
buildParam() {
let param = {};
Object.assign(param, this.formData);
param.platform = this.selectedPlatformValue;
param.saved = this.saved;
param.model = this.model;
if (this.currentModule) {
if (!this.formData.moduleId || this.formData.moduleId.length === 0) {
param.moduleId = this.currentModule[0].id;
} else {
param.moduleId= this.formData.moduleId
}
param.modeId = this.formData.modeId
}
param.projectId = this.projectId;
if (!this.swaggerUrlEnable) {
param.swaggerUrl = undefined;
}
if(this.authEnable){
//
param.headers = this.headers;
// query
param.arguments = this.queryArguments;
// BaseAuth
if(this.authConfig.authManager != undefined){
this.authConfig.authManager.clazzName = TYPE_TO_C.get("AuthManager");
param.authManager = this.authConfig.authManager;
}
}
return param;
},
close() {
this.formData = {
file: undefined,
swaggerUrl: '',
modeId: this.formData.modeId,
};
this.fileList = [];
removeGoBackListener(this.close);
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.latest_version');
}
});
});
}
},
checkVersionEnable() {
if (!this.projectId) {
return;
}
if (hasLicense()) {
this.$get('/project/version/enable/' + this.projectId, response => {
this.projectVersionEnable = response.data;
});
}
}
}
}
}
</script>
<style scoped>
.api-import >>> .el-dialog {
min-width: 750px;
}
.api-import >>> .el-dialog {
min-width: 750px;
}
.format-tip {
background: #EDEDED;
}
.format-tip {
background: #EDEDED;
}
.api-upload {
text-align: center;
margin: auto 0;
}
.api-upload {
text-align: center;
margin: auto 0;
}
.api-upload >>> .el-upload {
width: 100%;
max-width: 350px;
}
.api-upload >>> .el-upload {
width: 100%;
max-width: 350px;
}
.api-upload >>> .el-upload-dragger {
width: 100%;
}
.api-upload >>> .el-upload-dragger {
width: 100%;
}
.el-radio-group {
margin: 10px 0;
}
.el-radio-group {
margin: 10px 0;
}
.el-radio {
margin-right: 20px;
}
.el-radio {
margin-right: 20px;
}
.header-bar, .format-tip, .el-form {
border: solid #E1E1E1 1px;
margin: 10px 0;
padding: 10px;
border-radius: 3px;
}
.header-bar, .format-tip, .el-form {
border: solid #E1E1E1 1px;
margin: 10px 0;
padding: 10px;
border-radius: 3px;
}
.header-bar {
padding: 10px 15px;
}
.header-bar {
padding: 10px 15px;
}
.api-import >>> .el-dialog__body {
padding: 15px 25px;
}
.api-import >>> .el-dialog__body {
padding: 15px 25px;
}
.operate-button {
float: right;
}
.operate-button {
float: right;
}
.save-button {
margin-left: 10px;
}
.save-button {
margin-left: 10px;
}
.el-form {
padding: 30px 10px;
}
.el-form {
padding: 30px 10px;
}
.dialog-footer {
float: right;
}
.dialog-footer {
float: right;
}
.swagger-url-disable {
margin-top: 10px;
.swagger-url-disable {
margin-top: 10px;
margin-left: 80px;
}
margin-left: 80px;
}
.el-divider {
height: 200px;
}
.el-divider {
height: 200px;
}
</style>

View File

@ -27,7 +27,7 @@
@saveAsEdit="saveAsEdit"
@refresh="refresh"
ref="basisApi"/>
<api-import :propotal="condition.protocol" ref="apiImport" :moduleOptions="moduleOptions"
<api-import :protocol="condition.protocol" ref="apiImport" :moduleOptions="moduleOptions"
@refresh="$emit('refresh')"/>
</div>
</template>

View File

@ -18,6 +18,8 @@ export default {
pass_rate: 'Pass Rate',
execution_times: 'Execution Times',
cover: 'Cover',
cover_api: 'Synchronously override API modules',
cover_scenario: 'Synchronous overlay scene module',
module_title: 'Default module',
save_data_when_page_change: 'Save when page change',
not_cover: 'Not Cover',
@ -1766,9 +1768,24 @@ export default {
file_exceed_limit: "The number of files exceeds the limit",
import_cover_tip: "Import mode: Overwrite mode description",
file_name_to_long: "File name is too long",
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_3: "3. If the interface path and content are consistent with the original interface, no change will be made",
import_tip: "Import Instructions",
import_tip1: "Note: The import file contains a variety of protocols, you need to switch the protocol to import multiple times",
import_tip2: "If the URL can be repeated, if the interface name + request type + request path are consistent, it is judged to be the same interface",
import_tip3: "If the URL is not enabled, it can be repeated. If the request type + request path are consistent, it is judged to be the same interface",
cover_tip: "Override mode",
cover_tip_1: "1. If the \"Synchronously overwrite API module\" option is checked, the API module is the module specified in the import file",
cover_tip_2: "2. The same interface already exists in the system, if the content is inconsistent, the original interface of the system will be overwritten",
cover_tip_3: "3. The same interface that already exists in the system will not be changed if the content is the same",
cover_tip_4: "4. Add interfaces that do not exist in the system",
cover_tip_scenario_1: "1. If the \"Synchronously overwrite Scenario module\" option is checked, the Scenario module is the module specified in the import file",
cover_tip_scenario_2: "2. The same Scenario already exists in the system, if the content is inconsistent, the original Scenario of the system will be overwritten",
cover_tip_scenario_3: "3. The same Scenario that already exists in the system will not be changed if the content is the same",
cover_tip_scenario_4: "4. Add Scenario that do not exist in the system",
no_cover_tip: "No overlay mode",
no_cover_tip_1: "1. The same interface that already exists in the system will not be changed",
no_cover_tip_2: "2. Add interfaces that do not exist in the system",
no_cover_tip_scenario_1: "1. The same Scenario that already exists in the system will not be changed",
no_cover_tip_scenario_2: "2. Add Scenario that do not exist in the system",
import_version: 'Import version',
data_update_version: 'Api update version',
data_new_version: 'Api creation version',

View File

@ -18,6 +18,8 @@ export default {
pass_rate: '通过率',
execution_times: '执行次数',
cover: '覆盖',
cover_api: '同步覆盖API模块',
cover_scenario: '同步覆盖场景模块',
module_title: '默认模块',
save_data_when_page_change: '翻页保存勾选项',
not_cover: '不覆盖',
@ -1770,10 +1772,24 @@ export default {
next_synchronization_time: "下次同步时间",
ms_env_import_file_limit: "仅支持通过MeterSphere导出的json格式文件",
file_exceed_limit: "文件数量超出限制",
import_cover_tip: "导入模式: 覆盖模式说明",
cover_tip_1: "1. 接口路径不存在则新增",
cover_tip_2: "2. 接口路径与原接口一致,内容不一致则覆盖原接口",
cover_tip_3: "3. 接口路径、内容与原接口一致则不做变更",
import_tip: "导入说明",
import_tip1: "注:导入文件包含多种协议,需切换协议多次导入",
import_tip2: "开启URL可重复接口名称+请求类型+请求路径一致则判断为同一接口",
import_tip3: "未开启URL可重复请求类型+请求路径一致则判断为同一接口",
cover_tip: "覆盖模式",
cover_tip_1: "1. 如勾选“同步覆盖API模块”选项则API模块为导入文件中指定的模块",
cover_tip_2: "2. 系统已存在的同一接口,内容不一致则覆盖系统原接口",
cover_tip_3: "3. 系统已存在的同一接口,内容一致则不做变更",
cover_tip_4: "4. 系统不存在的接口则新增",
cover_tip_scenario_1: "1. 如勾选“同步覆盖场景模块”选项,则场景模块为导入文件中指定的模块",
cover_tip_scenario_2: "2. 系统已存在的同一场景,内容不一致则覆盖系统原场景",
cover_tip_scenario_3: "3. 系统已存在的同一场景,内容一致则不做变更",
cover_tip_scenario_4: "4. 系统不存在的场景则新增",
no_cover_tip: "不覆盖模式",
no_cover_tip_1: "1. 系统已存在的同一接口,则不做变更",
no_cover_tip_2: "2. 系统不存在的接口则新增",
no_cover_tip_scenario_1: "1. 系统已存在的同一场景,则不做变更",
no_cover_tip_scenario_2: "2. 系统不存在的场景则新增",
import_version: '导入版本',
data_update_version: '数据更新版本',
data_new_version: '数据创建版本',

View File

@ -18,6 +18,8 @@ export default {
pass_rate: '通過率',
execution_times: '執行次數',
cover: '覆蓋',
cover_api: '同步覆蓋API模塊',
cover_scenario: '同步覆蓋場景模塊',
module_title: '默認模塊',
save_data_when_page_change: '翻頁保存勾選項',
not_cover: '不覆蓋',
@ -1770,10 +1772,24 @@ export default {
next_synchronization_time: "下次同步時間",
ms_env_import_file_limit: "僅支持通過MeterSphere導出的json格式文件",
file_exceed_limit: "文件數量超出限製",
import_cover_tip: "導入模式: 覆蓋模式說明",
cover_tip_1: "1. 接口路徑不存在則新增",
cover_tip_2: "2. 接口路徑與原接口一致,內容不一致則覆蓋原接口",
cover_tip_3: "3. 接口路徑、內容與原接口一致則不做變更",
import_tip: "導入說明",
import_tip1: "注:導入檔案包含多種協定,需切換協定多次導入",
import_tip2: "開啟URL可重複介面名稱+請求類型+請求路徑一致則判斷為同一介面",
import_tip3: "未開啟URL可重複請求類型+請求路徑一致則判斷為同一介面",
cover_tip: "覆蓋模式",
cover_tip_1: "1. 如勾選“同步覆蓋API模塊”選項則API模塊為導入檔案中指定的模塊",
cover_tip_2: "2. 系統已存在的同一介面,內容不一致則覆蓋系統原介面",
cover_tip_3: "3. 系統已存在的同一介面,內容一致則不做變更",
cover_tip_4: "4. 系統不存在的介面則新增",
cover_tip_scenario_1: "1. 如勾選“同步覆蓋場景模塊”選項,則場景模塊為導入檔案中指定的模塊",
cover_tip_scenario_2: "2. 系統已存在的同一場景,內容不一致則覆蓋系統原場景",
cover_tip_scenario_3: "3. 系統已存在的同一場景,內容一致則不做變更",
cover_tip_scenario_4: "4. 系統不存在的場景則新增",
no_cover_tip_scenario_1: "1. 系统已存在的同一場景,则不做變更",
no_cover_tip_scenario_2: "2. 系统不存在的場景则新增",
no_cover_tip: "不覆蓋模式",
no_cover_tip_1: "1. 系統已存在的同一介面,則不做變更",
no_cover_tip_2: "2. 系統不存在的介面則新增",
import_version: '導入版本',
data_update_version: '數據更新版本',
data_new_version: '數據創建版本',