From 8e1f189ce95e012810d01f2578092e1c183006c9 Mon Sep 17 00:00:00 2001 From: wenyann <64353056+wenyann@users.noreply.github.com> Date: Fri, 22 Jan 2021 17:01:41 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20swagger=E5=AE=9A=E6=97=B6=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ApiDefinitionController.java | 4 + .../api/service/ApiDefinitionService.java | 4 + .../commons/utils/UrlTestUtils.java | 4 +- .../job/sechedule/ScheduleManager.java | 3 +- .../job/sechedule/SwaggerUrlImportJob.java | 2 + .../engine/docker/DockerTestEngine.java | 4 +- .../metersphere/service/ScheduleService.java | 5 +- .../automation/scenario/EditApiScenario.vue | 4 +- .../complete/EditCompleteHTTPApi.vue | 14 ++- .../components/import/ApiImport.vue | 115 ++++++++++++------ .../components/module/ApiModule.vue | 2 +- .../components/module/ApiModuleHeader.vue | 18 ++- .../settings/system/Organization.vue | 3 + frontend/src/common/js/regex.js | 2 +- frontend/src/i18n/en-US.js | 2 + frontend/src/i18n/zh-CN.js | 2 + frontend/src/i18n/zh-TW.js | 2 + 17 files changed, 132 insertions(+), 58 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java index 548efbfca9..b5eb53ac4c 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java @@ -144,6 +144,10 @@ public class ApiDefinitionController { public void createSchedule(@RequestBody Schedule request) { apiDefinitionService.createSchedule(request); } + @PostMapping(value = "/schedule/update") + public void updateSchedule(@RequestBody Schedule request){ + apiDefinitionService.updateSchedule(request); + } @PostMapping("/getReference") public ReferenceDTO getReference(@RequestBody ApiScenarioRequest request) { diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index e5f2d6bdb4..54b810a949 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -604,6 +604,10 @@ public class ApiDefinitionService { this.addOrUpdateSwaggerImportCronJob(request); } + public void updateSchedule(Schedule request){ + scheduleService.editSchedule(request); + this.addOrUpdateSwaggerImportCronJob(request); + } private void addOrUpdateSwaggerImportCronJob(Schedule request) { scheduleService.addOrUpdateCronJob(request, SwaggerUrlImportJob.getJobKey(request.getResourceId()), SwaggerUrlImportJob.getTriggerKey(request.getResourceId()), SwaggerUrlImportJob.class); diff --git a/backend/src/main/java/io/metersphere/commons/utils/UrlTestUtils.java b/backend/src/main/java/io/metersphere/commons/utils/UrlTestUtils.java index d536cf484d..d891194623 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/UrlTestUtils.java +++ b/backend/src/main/java/io/metersphere/commons/utils/UrlTestUtils.java @@ -5,7 +5,7 @@ import java.net.URLConnection; public class UrlTestUtils { - public static boolean testUrlWithTimeOut(String urlString, int timeOutMillSeconds) { + /* public static boolean testUrlWithTimeOut(String urlString, int timeOutMillSeconds) { try { URL url = new URL(urlString); URLConnection co = url.openConnection(); @@ -16,5 +16,5 @@ public class UrlTestUtils { LogUtil.error(e); return false; } - } + }*/ } diff --git a/backend/src/main/java/io/metersphere/job/sechedule/ScheduleManager.java b/backend/src/main/java/io/metersphere/job/sechedule/ScheduleManager.java index 7c64968203..d0575bb36a 100644 --- a/backend/src/main/java/io/metersphere/job/sechedule/ScheduleManager.java +++ b/backend/src/main/java/io/metersphere/job/sechedule/ScheduleManager.java @@ -290,11 +290,12 @@ public class ScheduleManager { addOrUpdateCronJob(jobKey, triggerKey, jobClass, cron, null); } - public JobDataMap getDefaultJobDataMap(String resourceId, String expression, String userId) { + public JobDataMap getDefaultJobDataMap(String resourceId, String expression, String userId,String swaggerUrl) { JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put("resourceId", resourceId); jobDataMap.put("expression", expression); jobDataMap.put("userId", userId); + jobDataMap.put("swaggerUrl",swaggerUrl); return jobDataMap; } diff --git a/backend/src/main/java/io/metersphere/job/sechedule/SwaggerUrlImportJob.java b/backend/src/main/java/io/metersphere/job/sechedule/SwaggerUrlImportJob.java index 4cf4fd7479..0e517e8843 100644 --- a/backend/src/main/java/io/metersphere/job/sechedule/SwaggerUrlImportJob.java +++ b/backend/src/main/java/io/metersphere/job/sechedule/SwaggerUrlImportJob.java @@ -24,6 +24,8 @@ public class SwaggerUrlImportJob extends MsScheduleJob { ApiTestImportRequest request = new ApiTestImportRequest(); request.setProjectId(resourceId); request.setSwaggerUrl(swaggerUrl); + request.setPlatform("Swagger2"); + request.setSaved(true); apiDefinitionService.apiTestImport(null, request); } diff --git a/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java b/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java index abcfa543c8..da06425f46 100644 --- a/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java +++ b/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java @@ -80,10 +80,10 @@ public class DockerTestEngine extends AbstractEngine { } // docker 不能从 localhost 中下载文件 - if (StringUtils.contains(metersphereUrl, "http://localhost") + /* if (StringUtils.contains(metersphereUrl, "http://localhost") || !UrlTestUtils.testUrlWithTimeOut(metersphereUrl, 1000)) { MSException.throwException(Translator.get("run_load_test_file_init_error")); - } + }*/ Map env = new HashMap<>(); env.put("RATIO", "" + ratio); diff --git a/backend/src/main/java/io/metersphere/service/ScheduleService.java b/backend/src/main/java/io/metersphere/service/ScheduleService.java index 12820f9114..2da372b26f 100644 --- a/backend/src/main/java/io/metersphere/service/ScheduleService.java +++ b/backend/src/main/java/io/metersphere/service/ScheduleService.java @@ -111,7 +111,7 @@ public class ScheduleService { LogUtil.error("初始化任务:" + JSON.toJSONString(schedule)); scheduleManager.addOrUpdateCronJob(new JobKey(schedule.getKey(), schedule.getGroup()), new TriggerKey(schedule.getKey(), schedule.getGroup()), Class.forName(schedule.getJob()), schedule.getValue(), - scheduleManager.getDefaultJobDataMap(schedule.getResourceId(), schedule.getValue(), schedule.getUserId())); + scheduleManager.getDefaultJobDataMap(schedule.getResourceId(), schedule.getValue(), schedule.getUserId(),schedule.getSwaggerUrl())); } } catch (Exception e) { LogUtil.error("初始化任务失败", e); @@ -139,7 +139,8 @@ public class ScheduleService { String cronExpression = request.getValue(); if (enable != null && enable && StringUtils.isNotBlank(cronExpression)) { try { - scheduleManager.addOrUpdateCronJob(jobKey, triggerKey, clazz, cronExpression, scheduleManager.getDefaultJobDataMap(request.getResourceId(), cronExpression, SessionUtils.getUser().getId())); + scheduleManager.addOrUpdateCronJob(jobKey, triggerKey, clazz, cronExpression, + scheduleManager.getDefaultJobDataMap(request.getResourceId(), cronExpression, SessionUtils.getUser().getId(),request.getSwaggerUrl())); } catch (SchedulerException e) { LogUtil.error(e.getMessage(), e); MSException.throwException("定时任务开启异常"); diff --git a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue index 7f67e9d0e3..17692a0f33 100644 --- a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue @@ -66,7 +66,6 @@ :value="item.id"> - @@ -92,7 +91,7 @@
-

{{$t('api_test.automation.scenario_step')}}

+

{{ $t('api_test.automation.scenario_stepscenario_step') }}

@@ -854,7 +853,6 @@ this.result = this.$get("/api/automation/getApiScenario/" + this.currentScenario.id, response => { if (response.data) { this.path = "/api/automation/update"; - this.currentScenario.description = response.data.description; if (response.data.scenarioDefinition != null) { let obj = JSON.parse(response.data.scenarioDefinition); if (obj) { diff --git a/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue b/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue index 4530217333..a4298a747c 100644 --- a/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue +++ b/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue @@ -42,9 +42,14 @@
- {{ $t('api_test.definition.select_comp.no_data') }}, + {{ + $t('api_test.definition.select_comp.no_data') + }}, - {{ $t('api_test.definition.select_comp.add_data') }} + {{ + $t('api_test.definition.select_comp.add_data') + }} +
@@ -95,7 +100,8 @@

{{ $t('api_test.definition.request.req_param') }}

- +
@@ -202,7 +208,7 @@ export default { if (!this.httpForm.path || this.httpForm.path.indexOf('?') === -1) return; let url = this.getURL(this.addProtocol(this.httpForm.path)); if (url) { - this.httpForm.path = decodeURIComponent(this.httpForm.path.substr(0,this.httpForm.path.indexOf("?"))); + this.httpForm.path = decodeURIComponent(this.httpForm.path.substr(0, this.httpForm.path.indexOf("?"))); } }, addProtocol(url) { diff --git a/frontend/src/business/components/api/definition/components/import/ApiImport.vue b/frontend/src/business/components/api/definition/components/import/ApiImport.vue index b119b49ad2..0c264eecfa 100644 --- a/frontend/src/business/components/api/definition/components/import/ApiImport.vue +++ b/frontend/src/business/components/api/definition/components/import/ApiImport.vue @@ -19,43 +19,60 @@
+ + + + + + + + + + + + + + + + +
+
{{ $t('api_test.api_import.file_size_limit') }}
+
+
- - -
-
{{ $t('api_test.api_import.file_size_limit') }}
-
+ + + + + + + - - - + + + + + +
- - - - - - - - - -
@@ -76,6 +93,8 @@ import MsDialogFooter from "../../../../common/components/MsDialogFooter"; import {listenGoBack, removeGoBackListener} from "@/common/js/utils"; import {getCurrentProjectID} from "../../../../../../common/js/utils"; import ScheduleImport from "@/business/components/api/definition/components/import/ImportScheduleEdit"; +import {buildNodePath} from "@/business/components/api/definition/model/NodeTree"; + export default { name: "ApiImport", components: {ScheduleImport, MsDialogFooter}, @@ -83,14 +102,24 @@ export default { saved: { type: Boolean, default: true, - } + }, + moduleOptions: {} }, data() { return { visible: false, swaggerUrlEable: false, - swaggerSynchronization:false, + swaggerSynchronization: false, showEnvironmentSelect: true, + modeOptions: [{ + id: 'fullCoverage', + name: '全量覆盖' + }, + { + id: 'incrementalMerge', + name: '增量合并' + }], + protocol: "", platforms: [ { name: 'Metersphere', @@ -122,7 +151,9 @@ export default { useEnvironment: false, formData: { file: undefined, - swaggerUrl: '' + swaggerUrl: '', + modeId: '', + moduleId: '' }, rules: {}, currentModule: {}, @@ -148,15 +179,19 @@ export default { } }, methods: { - scheduleEdit(){ - if(this.swaggerSynchronization){ - this.$refs.scheduleEdit.open(this.buildParam()); + scheduleEdit() { + if (this.swaggerSynchronization) { + this.$refs.scheduleEdit.open(this.buildParam()); + } else { + this.result = this.$post("/api/definition/schedule/update", this.schedule, response => { + }); } }, open(module) { this.currentModule = module; this.visible = true; listenGoBack(this.close); + }, upload(file) { this.formData.file = file.file; diff --git a/frontend/src/business/components/api/definition/components/module/ApiModule.vue b/frontend/src/business/components/api/definition/components/module/ApiModule.vue index 73e221ba19..5e6a17da7d 100644 --- a/frontend/src/business/components/api/definition/components/module/ApiModule.vue +++ b/frontend/src/business/components/api/definition/components/module/ApiModule.vue @@ -72,7 +72,7 @@ } }, planId: String, - relevanceProjectId: String + relevanceProjectId: String, }, computed: { isPlanModel() { diff --git a/frontend/src/business/components/api/definition/components/module/ApiModuleHeader.vue b/frontend/src/business/components/api/definition/components/module/ApiModuleHeader.vue index b6c49762be..be32a14310 100644 --- a/frontend/src/business/components/api/definition/components/module/ApiModuleHeader.vue +++ b/frontend/src/business/components/api/definition/components/module/ApiModuleHeader.vue @@ -33,7 +33,7 @@ @saveAsEdit="saveAsEdit" @refresh="refresh" ref="basisApi"/> - + @@ -43,6 +43,7 @@ import MsAddBasisApi from "../basis/AddBasisApi"; import ApiImport from "../import/ApiImport"; import ModuleTrashButton from "./ModuleTrashButton"; import {getCurrentProjectID} from "../../../../../../common/js/utils"; +import {buildNodePath} from "@/business/components/api/definition/model/NodeTree"; export default { name: "ApiModuleHeader", @@ -50,6 +51,7 @@ export default { data() { return { options: OPTIONS, + moduleOptions: {} } }, props: { @@ -70,9 +72,10 @@ export default { default() { return false } - } + }, }, methods: { + handleCommand(e) { switch (e) { case "debug": @@ -88,6 +91,17 @@ export default { this.$warning(this.$t('commons.check_project_tip')); return; } + this.protocol = "HTTP"; + this.result = this.$get("/api/module/list/" + getCurrentProjectID() + "/" + this.protocol, response => { + if (response.data != undefined && response.data != null) { + this.data = response.data; + let moduleOptions = []; + this.data.forEach(node => { + buildNodePath(node, {path: ''}, moduleOptions); + }); + this.moduleOptions = moduleOptions + } + }); this.$refs.apiImport.open(this.currentModule); break; default: diff --git a/frontend/src/business/components/settings/system/Organization.vue b/frontend/src/business/components/settings/system/Organization.vue index 888236af0f..8fc66f3284 100644 --- a/frontend/src/business/components/settings/system/Organization.vue +++ b/frontend/src/business/components/settings/system/Organization.vue @@ -252,6 +252,9 @@ export default { activated() { this.initTableData(); }, + created() { + this.list() + }, methods: { create() { this.dialogOrgAddVisible = true; diff --git a/frontend/src/common/js/regex.js b/frontend/src/common/js/regex.js index 9320e4d0c0..3896d86635 100644 --- a/frontend/src/common/js/regex.js +++ b/frontend/src/common/js/regex.js @@ -1 +1 @@ -export const PHONE_REGEX = '^1(3|4|5|7|8|9)\\d{9}$'; +export const PHONE_REGEX = '^1(3|4|5|6|7|8|9)\\d{9}$'; diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 7ab5af8958..0b5bb806e2 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -1,5 +1,7 @@ export default { commons: { + import_mode: 'Import mode', + import_module: 'Import module', please_fill_in_the_template: 'Please fill in the template', cut_back_old_version: 'Cut back to old version', cut_back_new_version: 'Switch back to new version', diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index c1bfaf44ac..c6d885c7d2 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -1,5 +1,7 @@ export default { commons: { + import_mode: '导入模式', + import_module: '导入模块', please_fill_in_the_template: '请填写模版内容', cut_back_old_version: '切回旧版', cut_back_new_version: '切回新版', diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index 2087fad310..90c0057fa4 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -1,5 +1,7 @@ export default { commons: { + import_mode: '導入模式', + import_module: '導入模塊', please_fill_in_the_template: '請填寫模版內容', cut_back_old_version: '切回舊版', cut_back_new_version: '切回新版', From 3048d8b52d5a50997dfb6b25015883b438e5e871 Mon Sep 17 00:00:00 2001 From: wenyann <64353056+wenyann@users.noreply.github.com> Date: Fri, 22 Jan 2021 17:06:03 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20swagger=E5=AE=9A=E6=97=B6=E5=90=8C?= =?UTF-8?q?=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/metersphere/commons/utils/UrlTestUtils.java | 4 ++-- .../performance/engine/docker/DockerTestEngine.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/io/metersphere/commons/utils/UrlTestUtils.java b/backend/src/main/java/io/metersphere/commons/utils/UrlTestUtils.java index d891194623..d536cf484d 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/UrlTestUtils.java +++ b/backend/src/main/java/io/metersphere/commons/utils/UrlTestUtils.java @@ -5,7 +5,7 @@ import java.net.URLConnection; public class UrlTestUtils { - /* public static boolean testUrlWithTimeOut(String urlString, int timeOutMillSeconds) { + public static boolean testUrlWithTimeOut(String urlString, int timeOutMillSeconds) { try { URL url = new URL(urlString); URLConnection co = url.openConnection(); @@ -16,5 +16,5 @@ public class UrlTestUtils { LogUtil.error(e); return false; } - }*/ + } } diff --git a/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java b/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java index da06425f46..abcfa543c8 100644 --- a/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java +++ b/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java @@ -80,10 +80,10 @@ public class DockerTestEngine extends AbstractEngine { } // docker 不能从 localhost 中下载文件 - /* if (StringUtils.contains(metersphereUrl, "http://localhost") + if (StringUtils.contains(metersphereUrl, "http://localhost") || !UrlTestUtils.testUrlWithTimeOut(metersphereUrl, 1000)) { MSException.throwException(Translator.get("run_load_test_file_init_error")); - }*/ + } Map env = new HashMap<>(); env.put("RATIO", "" + ratio); From 4b41e9df0c8f26ff6fa154a62dc4ab4fc63782f1 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Fri, 22 Jan 2021 17:14:12 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix(=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92):?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=E6=8A=A5=E5=91=8A=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TestResultAdvanceChartComponent.vue | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TestResultAdvanceChartComponent.vue b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TestResultAdvanceChartComponent.vue index f587d05600..35ebb9a58e 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TestResultAdvanceChartComponent.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TestResultAdvanceChartComponent.vue @@ -119,7 +119,7 @@ this.functionalCharData = []; if (this.executeResult.functionalResult) { this.executeResult.functionalResult.forEach(item => { - let data = this.dataMap.get(item.status); + let data = this.copyData(item.status); data.value = item.count; this.functionalCharData.push(data); }); @@ -129,7 +129,7 @@ this.apiCharData = []; if (this.executeResult.apiResult) { this.executeResult.apiResult.forEach(item => { - let data = this.dataMap.get(item.status); + let data = this.copyData(item.status); data.value = item.count; this.apiCharData.push(data); }); @@ -139,7 +139,7 @@ this.scenarioCharData = []; if (this.executeResult.apiResult) { this.executeResult.scenarioResult.forEach(item => { - let data = this.dataMap.get(item.status); + let data = this.copyData(item.status); data.value = item.count; this.scenarioCharData.push(data); }); @@ -149,12 +149,15 @@ this.loadCharData = []; if (this.executeResult.loadResult) { this.executeResult.loadResult.forEach(item => { - let data = this.dataMap.get(item.status); + let data = this.copyData(item.status); data.value = item.count; this.loadCharData.push(data); }); } }, + copyData(status) { + return JSON.parse(JSON.stringify(this.dataMap.get(status))) + }, reload() { this.isShow = false; this.$nextTick(function () {