From fcf879d06fc6a819b16b5fa4939a76d01164cf6b Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Fri, 6 Nov 2020 09:39:22 +0800 Subject: [PATCH 01/56] =?UTF-8?q?fix(=E6=B5=8B=E8=AF=95=E8=B7=9F=E8=B8=AA)?= =?UTF-8?q?:=20=E7=94=A8=E4=BE=8B=E5=AF=BC=E5=87=BA=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../track/service/TestCaseService.java | 17 ++++++++++++----- frontend/src/business/components/xpack | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java index 82c99bff35..ca463ab9b0 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java @@ -457,12 +457,19 @@ public class TestCaseService { if (t.getMethod().equals("manual")) { String steps = t.getSteps(); String setp = ""; - if (steps.contains("null") && !steps.contains("\"null\"")) { - setp = steps.replace("null", "\"\""); - } else { - setp = steps; + setp = steps; + JSONArray jsonArray = null; + + //解决旧版本保存用例导出报错 + try { + jsonArray = JSON.parseArray(setp); + } catch (Exception e) { + if (steps.contains("null") && !steps.contains("\"null\"")) { + setp = steps.replace("null", "\"\""); + jsonArray = JSON.parseArray(setp); + } } - JSONArray jsonArray = JSON.parseArray(setp); + for (int j = 0; j < jsonArray.size(); j++) { int num = j + 1; step.append(num + "." + jsonArray.getJSONObject(j).getString("desc") + "\n"); diff --git a/frontend/src/business/components/xpack b/frontend/src/business/components/xpack index b9091a47b1..eb237fb6bf 160000 --- a/frontend/src/business/components/xpack +++ b/frontend/src/business/components/xpack @@ -1 +1 @@ -Subproject commit b9091a47b197faef77c72b134b7cf604fe3209f0 +Subproject commit eb237fb6bfeba8d99e4db52450ae92f3cdd4ea33 From 437630eb8104150a9ec16a5870809499ca891370 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Wed, 11 Nov 2020 17:02:26 +0800 Subject: [PATCH 02/56] =?UTF-8?q?feat:=20zentao=E7=BB=84=E4=BB=B6=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=9C=B0=E5=9D=80=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../organization/components/ZentaoSetting.vue | 40 ++++++++++++++----- frontend/src/i18n/en-US.js | 2 + frontend/src/i18n/zh-CN.js | 2 + frontend/src/i18n/zh-TW.js | 2 + 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/frontend/src/business/components/settings/organization/components/ZentaoSetting.vue b/frontend/src/business/components/settings/organization/components/ZentaoSetting.vue index 64f9b5205f..512ac51e8f 100644 --- a/frontend/src/business/components/settings/organization/components/ZentaoSetting.vue +++ b/frontend/src/business/components/settings/organization/components/ZentaoSetting.vue @@ -10,6 +10,9 @@ + + + @@ -63,7 +66,12 @@ export default { required: true, message: this.$t('organization.integration.input_app_key'), trigger: ['change', 'blur'] - } + }, + url: { + required: true, + message: this.$t('organization.integration.input_zentao_url'), + trigger: ['change', 'blur'] + }, }, } }, @@ -71,12 +79,16 @@ export default { save() { this.$refs['form'].validate(valid => { if (valid) { - + let formatUrl = this.form.url.trim(); + if (!formatUrl.endsWith('/')) { + formatUrl = formatUrl + '/'; + } const {lastOrganizationId} = getCurrentUser(); let param = {}; let auth = { account: this.form.account, password: this.form.password, + url: formatUrl, }; param.organizationId = lastOrganizationId; param.platform = ZEN_TAO; @@ -106,6 +118,7 @@ export default { let config = JSON.parse(data.configuration); this.$set(this.form, 'account', config.account); this.$set(this.form, 'password', config.password); + this.$set(this.form, 'url', config.url); } else { this.clear(); } @@ -114,19 +127,26 @@ export default { clear() { this.$set(this.form, 'account', ''); this.$set(this.form, 'password', ''); + this.$set(this.form, 'url', ''); this.$nextTick(() => { this.$refs.form.clearValidate(); }); }, testConnection() { - if (this.form.account && this.form.password) { - this.$parent.result = this.$get("issues/auth/" + ZEN_TAO, () => { - this.$success(this.$t('organization.integration.verified')); - }); - } else { - this.$warning(this.$t('organization.integration.not_integrated')); - return false; - } + this.$refs['form'].validate(valid => { + if (valid) { + if (this.form.account && this.form.password) { + this.$parent.result = this.$get("issues/auth/" + ZEN_TAO, () => { + this.$success(this.$t('organization.integration.verified')); + }); + } else { + this.$warning(this.$t('organization.integration.not_integrated')); + return false; + } + } else { + return false; + } + }) }, cancelIntegration() { if (this.form.account && this.form.password) { diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 2fbdc80cc1..55284b52e2 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -262,6 +262,8 @@ export default { input_app_key: 'Please enter the key', input_jira_url: 'Please enter Jira address, for example: https://metersphere.atlassian.net/', input_jira_issuetype: 'Please enter the question type', + zentao_url: 'Zentao url', + input_zentao_url: 'Please enter Zentao address, for example: http://xx.xx.xx.xx/zentao/', use_tip: 'Usage guidelines:', use_tip_tapd: 'Basic Auth account information is queried in "Company Management-Security and Integration-Open Platform"', use_tip_jira: 'Jira software server authentication information is account password, Jira software cloud authentication information is account + token (account settings-security-create API token)', diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index b77911f571..bb7f14c105 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -262,6 +262,8 @@ export default { input_app_key: '请输入密钥', input_jira_url: '请输入Jira地址,例:https://metersphere.atlassian.net/', input_jira_issuetype: '请输入问题类型', + zentao_url: 'Zentao 地址', + input_zentao_url: '请输入Zentao地址,例:http://xx.xx.xx.xx/zentao/', use_tip: '使用指引:', use_tip_tapd: 'Tapd Basic Auth 账号信息在"公司管理-安全与集成-开放平台"中查询', use_tip_jira: 'Jira software server 认证信息为 账号密码,Jira software cloud 认证信息为 账号+令牌(账户设置-安全-创建API令牌)', diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index 43cc46c469..847aed50d8 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -264,6 +264,8 @@ export default { input_app_key: '請輸入密鑰', input_jira_url: '請輸入Jira地址,例:https://metersphere.atlassian.net/', input_jira_issuetype: '請輸入問題類型', + zentao_url: 'Zentao 地址', + input_zentao_url: '請輸入Zentao地址,例:http://xx.xx.xx.xx/zentao/', use_tip: '使用指引:', use_tip_tapd: 'Tapd Basic Auth 賬號信息在"公司管理-安全與集成-開放平臺"中查詢', use_tip_jira: 'Jira software server 認證信息為 賬號密碼,Jira software cloud 認證信息為 賬號+令牌(賬戶設置-安全-創建API令牌)', From a94453b51821b73486157faa62db645c2dcad0dd Mon Sep 17 00:00:00 2001 From: wenyann <64353056+wenyann@users.noreply.github.com> Date: Fri, 13 Nov 2020 14:15:54 +0800 Subject: [PATCH 03/56] =?UTF-8?q?fix:=20=E7=99=BB=E9=99=86=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E9=95=BF=E5=BA=A6=EF=BC=8C=E9=82=AE=E7=AE=B1=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notice/service/MailService.java | 6 +-- .../notice/PerformanceNoticeTask.java | 46 ++++++++++--------- .../service/PerformanceTestService.java | 1 + .../performance/service/ReportService.java | 5 +- frontend/src/login/Login.vue | 4 +- 5 files changed, 34 insertions(+), 28 deletions(-) diff --git a/backend/src/main/java/io/metersphere/notice/service/MailService.java b/backend/src/main/java/io/metersphere/notice/service/MailService.java index 3efeca32ae..14479ce941 100644 --- a/backend/src/main/java/io/metersphere/notice/service/MailService.java +++ b/backend/src/main/java/io/metersphere/notice/service/MailService.java @@ -341,7 +341,7 @@ public class MailService { JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); List paramList = systemParameterService.getParamList(ParamConstants.Classify.MAIL.getValue()); javaMailSender.setDefaultEncoding("UTF-8"); - javaMailSender.setProtocol("smtps"); + javaMailSender.setProtocol("smtp"); for (SystemParameter p : paramList) { switch (p.getParamKey()) { case "smtp.host": @@ -362,8 +362,8 @@ public class MailService { } Properties props = new Properties(); props.put("mail.smtp.auth", "true"); - props.put("mail.smtp.starttls.enable", "true"); - props.put("mail.smtp.starttls.required", "true"); + props.put("mail.smtp.starttls.enable", "false"); + props.put("mail.smtp.starttls.required", "false"); props.put("mail.smtp.timeout", "30000"); props.put("mail.smtp.connectiontimeout", "5000"); javaMailSender.setJavaMailProperties(props); diff --git a/backend/src/main/java/io/metersphere/performance/notice/PerformanceNoticeTask.java b/backend/src/main/java/io/metersphere/performance/notice/PerformanceNoticeTask.java index 5b041a02b4..db8cbbd74a 100644 --- a/backend/src/main/java/io/metersphere/performance/notice/PerformanceNoticeTask.java +++ b/backend/src/main/java/io/metersphere/performance/notice/PerformanceNoticeTask.java @@ -39,34 +39,36 @@ public class PerformanceNoticeTask { private LoadTestReportMapper loadTestReportMapper; private final ExecutorService executorService = Executors.newFixedThreadPool(20); - private boolean isRunning = true; - @PreDestroy + private boolean isRunning=false; + + /*@PreDestroy public void preDestroy() { isRunning = false; - } + }*/ public void registerNoticeTask(LoadTestReportWithBLOBs loadTestReport) { - int count = 20; - while (count-- > 0) { - LoadTestReportWithBLOBs loadTestReportFromDatabase = loadTestReportMapper.selectByPrimaryKey(loadTestReport.getId()); - if (StringUtils.equals(loadTestReportFromDatabase.getStatus(), PerformanceTestStatus.Completed.name())) { - isRunning = false; - sendSuccessNotice(loadTestReportFromDatabase); - return; + isRunning=true; + executorService.submit(() -> { + LogUtil.info("性能测试定时任务"); + while (isRunning) { + LoadTestReportWithBLOBs loadTestReportFromDatabase = loadTestReportMapper.selectByPrimaryKey(loadTestReport.getId()); + if (StringUtils.equals(loadTestReportFromDatabase.getStatus(), PerformanceTestStatus.Completed.name())) { + sendSuccessNotice(loadTestReportFromDatabase); + isRunning=false; + } + if (StringUtils.equals(loadTestReportFromDatabase.getStatus(), PerformanceTestStatus.Error.name())) { + sendFailNotice(loadTestReportFromDatabase); + isRunning=false; + } + try { + //查询定时任务是否关闭 + Thread.sleep(1000 * 30);// 每分钟检查 loadtest 的状态 + } catch (InterruptedException e) { + LogUtil.error(e); + } } - if (StringUtils.equals(loadTestReportFromDatabase.getStatus(), PerformanceTestStatus.Error.name())) { - isRunning = false; - sendFailNotice(loadTestReportFromDatabase); - return; - } - count--; - try { - Thread.sleep(1000 * 4L);// 每分钟检查 loadtest 的状态 - } catch (InterruptedException e) { - LogUtil.error(e); - } - } + }); } public void sendSuccessNotice(LoadTestReportWithBLOBs loadTestReport) { diff --git a/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java b/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java index 1dc40dfe1d..fe338d2858 100644 --- a/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java +++ b/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java @@ -207,6 +207,7 @@ public class PerformanceTestService { @Transactional(noRollbackFor = MSException.class)// 保存失败的信息 public String run(RunTestPlanRequest request) { + LogUtil.info("性能测试run测试"); final LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(request.getId()); if (request.getUserId() != null) { loadTest.setUserId(request.getUserId()); diff --git a/backend/src/main/java/io/metersphere/performance/service/ReportService.java b/backend/src/main/java/io/metersphere/performance/service/ReportService.java index b50f6d4c23..a7dd4ca8b2 100644 --- a/backend/src/main/java/io/metersphere/performance/service/ReportService.java +++ b/backend/src/main/java/io/metersphere/performance/service/ReportService.java @@ -168,7 +168,10 @@ public class ReportService { public void checkReportStatus(String reportId) { LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId); - String reportStatus = loadTestReport.getStatus(); + String reportStatus=""; + if(loadTestReport!=null){ + reportStatus = loadTestReport.getStatus(); + } if (StringUtils.equals(PerformanceTestStatus.Error.name(), reportStatus)) { MSException.throwException("Report generation error!"); } diff --git a/frontend/src/login/Login.vue b/frontend/src/login/Login.vue index 7c4e25cf23..2e783bc085 100644 --- a/frontend/src/login/Login.vue +++ b/frontend/src/login/Login.vue @@ -28,7 +28,7 @@ + maxlength="30" show-word-limit/>
@@ -81,7 +81,7 @@ export default { ], password: [ {required: true, message: this.$t('commons.input_password'), trigger: 'blur'}, - {min: 6, max: 20, message: this.$t('commons.input_limit', [6, 20]), trigger: 'blur'} + {min: 6, max: 20, message: this.$t('commons.input_limit', [6, 30]), trigger: 'blur'} ] }, msg: '', From d3862866fe92b19b4ae15242be44df26c8c79b8e Mon Sep 17 00:00:00 2001 From: wenyann <64353056+wenyann@users.noreply.github.com> Date: Fri, 13 Nov 2020 14:19:14 +0800 Subject: [PATCH 04/56] =?UTF-8?q?fix:=20=E7=99=BB=E9=99=86=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E9=95=BF=E5=BA=A6=EF=BC=8C=E9=82=AE=E7=AE=B1=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/login/Login.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/login/Login.vue b/frontend/src/login/Login.vue index 2e783bc085..fd3487e192 100644 --- a/frontend/src/login/Login.vue +++ b/frontend/src/login/Login.vue @@ -81,7 +81,7 @@ export default { ], password: [ {required: true, message: this.$t('commons.input_password'), trigger: 'blur'}, - {min: 6, max: 20, message: this.$t('commons.input_limit', [6, 30]), trigger: 'blur'} + {min: 6, max: 30, message: this.$t('commons.input_limit', [6, 30]), trigger: 'blur'} ] }, msg: '', From 7127f9eb3f000e84785b683b990e21131cf92e33 Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Fri, 13 Nov 2020 15:53:24 +0800 Subject: [PATCH 05/56] =?UTF-8?q?refactor(=E6=80=A7=E8=83=BD=E6=B5=8B?= =?UTF-8?q?=E8=AF=95):=20=E6=80=A7=E8=83=BD=E6=B5=8B=E8=AF=95=E4=BF=9D?= =?UTF-8?q?=E5=AD=98jtl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/db/migration/V42__modify_load_test_report.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 backend/src/main/resources/db/migration/V42__modify_load_test_report.sql diff --git a/backend/src/main/resources/db/migration/V42__modify_load_test_report.sql b/backend/src/main/resources/db/migration/V42__modify_load_test_report.sql new file mode 100644 index 0000000000..77ad67bd9a --- /dev/null +++ b/backend/src/main/resources/db/migration/V42__modify_load_test_report.sql @@ -0,0 +1,2 @@ +ALTER TABLE load_test_report + ADD file_id VARCHAR(50) NULL; \ No newline at end of file From e26d3a668eabe83a6d010e051767af41d2660e94 Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Fri, 13 Nov 2020 15:55:57 +0800 Subject: [PATCH 06/56] =?UTF-8?q?refactor(=E6=80=A7=E8=83=BD=E6=B5=8B?= =?UTF-8?q?=E8=AF=95):=20=E6=80=A7=E8=83=BD=E6=B5=8B=E8=AF=95=E4=BF=9D?= =?UTF-8?q?=E5=AD=98jtl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base/domain/LoadTestReport.java | 2 + .../base/domain/LoadTestReportExample.java | 70 +++++++++++++++++++ .../base/mapper/LoadTestReportMapper.xml | 43 ++++++++---- 3 files changed, 102 insertions(+), 13 deletions(-) diff --git a/backend/src/main/java/io/metersphere/base/domain/LoadTestReport.java b/backend/src/main/java/io/metersphere/base/domain/LoadTestReport.java index d587d581ae..9f7c9e77ba 100644 --- a/backend/src/main/java/io/metersphere/base/domain/LoadTestReport.java +++ b/backend/src/main/java/io/metersphere/base/domain/LoadTestReport.java @@ -22,5 +22,7 @@ public class LoadTestReport implements Serializable { private String triggerMode; + private String fileId; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/domain/LoadTestReportExample.java b/backend/src/main/java/io/metersphere/base/domain/LoadTestReportExample.java index 38edf86b0b..17743bbca4 100644 --- a/backend/src/main/java/io/metersphere/base/domain/LoadTestReportExample.java +++ b/backend/src/main/java/io/metersphere/base/domain/LoadTestReportExample.java @@ -643,6 +643,76 @@ public class LoadTestReportExample { addCriterion("trigger_mode not between", value1, value2, "triggerMode"); return (Criteria) this; } + + public Criteria andFileIdIsNull() { + addCriterion("file_id is null"); + return (Criteria) this; + } + + public Criteria andFileIdIsNotNull() { + addCriterion("file_id is not null"); + return (Criteria) this; + } + + public Criteria andFileIdEqualTo(String value) { + addCriterion("file_id =", value, "fileId"); + return (Criteria) this; + } + + public Criteria andFileIdNotEqualTo(String value) { + addCriterion("file_id <>", value, "fileId"); + return (Criteria) this; + } + + public Criteria andFileIdGreaterThan(String value) { + addCriterion("file_id >", value, "fileId"); + return (Criteria) this; + } + + public Criteria andFileIdGreaterThanOrEqualTo(String value) { + addCriterion("file_id >=", value, "fileId"); + return (Criteria) this; + } + + public Criteria andFileIdLessThan(String value) { + addCriterion("file_id <", value, "fileId"); + return (Criteria) this; + } + + public Criteria andFileIdLessThanOrEqualTo(String value) { + addCriterion("file_id <=", value, "fileId"); + return (Criteria) this; + } + + public Criteria andFileIdLike(String value) { + addCriterion("file_id like", value, "fileId"); + return (Criteria) this; + } + + public Criteria andFileIdNotLike(String value) { + addCriterion("file_id not like", value, "fileId"); + return (Criteria) this; + } + + public Criteria andFileIdIn(List values) { + addCriterion("file_id in", values, "fileId"); + return (Criteria) this; + } + + public Criteria andFileIdNotIn(List values) { + addCriterion("file_id not in", values, "fileId"); + return (Criteria) this; + } + + public Criteria andFileIdBetween(String value1, String value2) { + addCriterion("file_id between", value1, value2, "fileId"); + return (Criteria) this; + } + + public Criteria andFileIdNotBetween(String value1, String value2) { + addCriterion("file_id not between", value1, value2, "fileId"); + return (Criteria) this; + } } public static class Criteria extends GeneratedCriteria { diff --git a/backend/src/main/java/io/metersphere/base/mapper/LoadTestReportMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/LoadTestReportMapper.xml index 9b1b3543bc..0b238045cf 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/LoadTestReportMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/LoadTestReportMapper.xml @@ -10,6 +10,7 @@ + @@ -74,7 +75,7 @@ - id, test_id, `name`, create_time, update_time, `status`, user_id, trigger_mode + id, test_id, `name`, create_time, update_time, `status`, user_id, trigger_mode, file_id description, load_configuration @@ -130,12 +131,12 @@ INSERT INTO load_test_report (id, test_id, `name`, create_time, update_time, `status`, - user_id, trigger_mode, description, - load_configuration) + user_id, trigger_mode, file_id, + description, load_configuration) VALUES (#{id,jdbcType=VARCHAR}, #{testId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{status,jdbcType=VARCHAR}, - #{userId,jdbcType=VARCHAR}, #{triggerMode,jdbcType=VARCHAR}, #{description,jdbcType=LONGVARCHAR}, - #{loadConfiguration,jdbcType=LONGVARCHAR}) + #{userId,jdbcType=VARCHAR}, #{triggerMode,jdbcType=VARCHAR}, #{fileId,jdbcType=VARCHAR}, + #{description,jdbcType=LONGVARCHAR}, #{loadConfiguration,jdbcType=LONGVARCHAR}) insert into load_test_report @@ -164,6 +165,9 @@ trigger_mode, + + file_id, + description, @@ -196,6 +200,9 @@ #{triggerMode,jdbcType=VARCHAR}, + + #{fileId,jdbcType=VARCHAR}, + #{description,jdbcType=LONGVARCHAR}, @@ -237,6 +244,9 @@ trigger_mode = #{record.triggerMode,jdbcType=VARCHAR}, + + file_id = #{record.fileId,jdbcType=VARCHAR}, + description = #{record.description,jdbcType=LONGVARCHAR}, @@ -258,6 +268,7 @@ `status` = #{record.status,jdbcType=VARCHAR}, user_id = #{record.userId,jdbcType=VARCHAR}, trigger_mode = #{record.triggerMode,jdbcType=VARCHAR}, + file_id = #{record.fileId,jdbcType=VARCHAR}, description = #{record.description,jdbcType=LONGVARCHAR}, load_configuration = #{record.loadConfiguration,jdbcType=LONGVARCHAR} @@ -273,7 +284,8 @@ update_time = #{record.updateTime,jdbcType=BIGINT}, `status` = #{record.status,jdbcType=VARCHAR}, user_id = #{record.userId,jdbcType=VARCHAR}, - trigger_mode = #{record.triggerMode,jdbcType=VARCHAR} + trigger_mode = #{record.triggerMode,jdbcType=VARCHAR}, + file_id = #{record.fileId,jdbcType=VARCHAR} @@ -302,6 +314,9 @@ trigger_mode = #{triggerMode,jdbcType=VARCHAR}, + + file_id = #{fileId,jdbcType=VARCHAR}, + description = #{description,jdbcType=LONGVARCHAR}, @@ -312,27 +327,29 @@ where id = #{id,jdbcType=VARCHAR} - update load_test_report - set test_id = #{testId,jdbcType=VARCHAR}, + UPDATE load_test_report + SET test_id = #{testId,jdbcType=VARCHAR}, `name` = #{name,jdbcType=VARCHAR}, create_time = #{createTime,jdbcType=BIGINT}, update_time = #{updateTime,jdbcType=BIGINT}, `status` = #{status,jdbcType=VARCHAR}, user_id = #{userId,jdbcType=VARCHAR}, trigger_mode = #{triggerMode,jdbcType=VARCHAR}, + file_id = #{fileId,jdbcType=VARCHAR}, description = #{description,jdbcType=LONGVARCHAR}, load_configuration = #{loadConfiguration,jdbcType=LONGVARCHAR} - where id = #{id,jdbcType=VARCHAR} + WHERE id = #{id,jdbcType=VARCHAR} - update load_test_report - set test_id = #{testId,jdbcType=VARCHAR}, + UPDATE load_test_report + SET test_id = #{testId,jdbcType=VARCHAR}, `name` = #{name,jdbcType=VARCHAR}, create_time = #{createTime,jdbcType=BIGINT}, update_time = #{updateTime,jdbcType=BIGINT}, `status` = #{status,jdbcType=VARCHAR}, user_id = #{userId,jdbcType=VARCHAR}, - trigger_mode = #{triggerMode,jdbcType=VARCHAR} - where id = #{id,jdbcType=VARCHAR} + trigger_mode = #{triggerMode,jdbcType=VARCHAR}, + file_id = #{fileId,jdbcType=VARCHAR} + WHERE id = #{id,jdbcType=VARCHAR} \ No newline at end of file From f40f0bbedec4735f53d634ab12ba0d100dc5f3ef Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Fri, 13 Nov 2020 16:28:53 +0800 Subject: [PATCH 07/56] =?UTF-8?q?refactor:=20=E4=B8=8B=E8=BD=BDjtl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PerformanceReportController.java | 12 ++++++++ .../performance/service/ReportService.java | 14 +++++++-- .../report/PerformanceReportView.vue | 29 +++++++++++++++++++ frontend/src/i18n/en-US.js | 1 + frontend/src/i18n/zh-CN.js | 1 + frontend/src/i18n/zh-TW.js | 1 + 6 files changed, 55 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/io/metersphere/performance/controller/PerformanceReportController.java b/backend/src/main/java/io/metersphere/performance/controller/PerformanceReportController.java index 2e2c5a651e..dd07e05aaa 100644 --- a/backend/src/main/java/io/metersphere/performance/controller/PerformanceReportController.java +++ b/backend/src/main/java/io/metersphere/performance/controller/PerformanceReportController.java @@ -16,6 +16,9 @@ import io.metersphere.performance.controller.request.ReportRequest; import io.metersphere.performance.service.ReportService; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresRoles; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -130,4 +133,13 @@ public class PerformanceReportController { public void deleteReportBatch(@RequestBody DeleteReportRequest reportRequest) { reportService.deleteReportBatch(reportRequest); } + + @GetMapping("/jtl/download/{reportId}") + public ResponseEntity downloadJtl(@PathVariable String reportId) { + byte[] bytes = reportService.downloadJtl(reportId); + return ResponseEntity.ok() + .contentType(MediaType.parseMediaType("application/octet-stream")) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + reportId + ".jtl\"") + .body(bytes); + } } diff --git a/backend/src/main/java/io/metersphere/performance/service/ReportService.java b/backend/src/main/java/io/metersphere/performance/service/ReportService.java index a7dd4ca8b2..95ae5c3736 100644 --- a/backend/src/main/java/io/metersphere/performance/service/ReportService.java +++ b/backend/src/main/java/io/metersphere/performance/service/ReportService.java @@ -18,6 +18,7 @@ import io.metersphere.performance.controller.request.DeleteReportRequest; import io.metersphere.performance.controller.request.ReportRequest; import io.metersphere.performance.engine.Engine; import io.metersphere.performance.engine.EngineFactory; +import io.metersphere.service.FileService; import io.metersphere.service.TestResourceService; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; @@ -47,6 +48,8 @@ public class ReportService { private TestResourceService testResourceService; @Resource private LoadTestReportDetailMapper loadTestReportDetailMapper; + @Resource + private FileService fileService; public List getRecentReportList(ReportRequest request) { List orders = new ArrayList<>(); @@ -168,9 +171,9 @@ public class ReportService { public void checkReportStatus(String reportId) { LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId); - String reportStatus=""; - if(loadTestReport!=null){ - reportStatus = loadTestReport.getStatus(); + String reportStatus = ""; + if (loadTestReport != null) { + reportStatus = loadTestReport.getStatus(); } if (StringUtils.equals(PerformanceTestStatus.Error.name(), reportStatus)) { MSException.throwException("Report generation error!"); @@ -271,4 +274,9 @@ public class ReportService { String content = getContent(id, ReportKeys.ResponseCodeChart); return JSON.parseArray(content, ChartsData.class); } + + public byte[] downloadJtl(String reportId) { + LoadTestReportWithBLOBs report = getReport(reportId); + return fileService.loadFileAsBytes(report.getFileId()); + } } diff --git a/frontend/src/business/components/performance/report/PerformanceReportView.vue b/frontend/src/business/components/performance/report/PerformanceReportView.vue index 0493330f33..2cd890a9c8 100644 --- a/frontend/src/business/components/performance/report/PerformanceReportView.vue +++ b/frontend/src/business/components/performance/report/PerformanceReportView.vue @@ -25,6 +25,9 @@ {{ $t('test_track.plan_view.export_report') }} + + 下载JTL + @@ -95,6 +98,7 @@ import MsMainContainer from "../../common/components/MsMainContainer"; import {checkoutTestManagerOrTestUser, exportPdf} from "@/common/js/utils"; import html2canvas from 'html2canvas'; import MsPerformanceReportExport from "./PerformanceReportExport"; +import {Message} from "element-ui"; export default { @@ -281,6 +285,31 @@ export default { this.reportExportVisible = false; this.result.loading = false; }, + downloadJtl() { + let config = { + url: "/performance/report/jtl/download/" + this.reportId, + method: 'get', + responseType: 'blob' + }; + this.result = this.$request(config).then(response => { + const content = response.data; + const blob = new Blob([content]); + if ("download" in document.createElement("a")) { + // 非IE下载 + // chrome/firefox + let aTag = document.createElement('a'); + aTag.download = this.reportId + ".jtl"; + aTag.href = URL.createObjectURL(blob); + aTag.click(); + URL.revokeObjectURL(aTag.href) + } else { + // IE10+下载 + navigator.msSaveBlob(blob, this.filename) + } + }).catch(e => { + Message.error({message: e.message, showClose: true}); + }); + } }, created() { this.isReadOnly = false; diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 2fbdc80cc1..dfcd80d015 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -360,6 +360,7 @@ export default { test_stop_now_confirm: 'Are you sure you want to stop the current test immediately?', test_rerun_confirm: 'Are you sure you want to rerun the current test immediately?', test_stop_success: 'Test stop successfully', + downloadJtl: 'Download JTL', test_execute_again: 'Test Execute Again', export: 'Export', compare: 'Compare', diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index b77911f571..18ce960f57 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -360,6 +360,7 @@ export default { test_rerun_confirm: '确定要再次执行当前测试吗?', test_stop_success: '停止成功', test_execute_again: '再次执行', + downloadJtl: '下载JTL', export: '导出', compare: '比较', generation_error: '报告生成错误, 无法查看, 请检查日志详情!', diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index 43cc46c469..da33a1d4ca 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -360,6 +360,7 @@ export default { test_stop_now: '立即停止', test_stop_now_confirm: '確定要立即停止當前測試嗎?', test_rerun_confirm: '確定要再次執行當前測試嗎?', + downloadJtl: '下載JTL', test_stop_success: '停止成功', test_execute_again: '再次執行', export: '導出', From b9e79cec6e195ce77cd9094c82d70e6c9f145d76 Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Fri, 13 Nov 2020 16:37:56 +0800 Subject: [PATCH 08/56] =?UTF-8?q?refactor(=E6=80=A7=E8=83=BD=E6=B5=8B?= =?UTF-8?q?=E8=AF=95):=20=E6=80=A7=E8=83=BD=E6=B5=8B=E8=AF=95=E4=BF=9D?= =?UTF-8?q?=E5=AD=98jtl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/performance/service/ReportService.java | 4 ++++ backend/src/main/resources/i18n/messages_en_US.properties | 1 + backend/src/main/resources/i18n/messages_zh_CN.properties | 1 + backend/src/main/resources/i18n/messages_zh_TW.properties | 1 + 4 files changed, 7 insertions(+) diff --git a/backend/src/main/java/io/metersphere/performance/service/ReportService.java b/backend/src/main/java/io/metersphere/performance/service/ReportService.java index 95ae5c3736..c92f68298e 100644 --- a/backend/src/main/java/io/metersphere/performance/service/ReportService.java +++ b/backend/src/main/java/io/metersphere/performance/service/ReportService.java @@ -13,6 +13,7 @@ import io.metersphere.commons.utils.ServiceUtils; import io.metersphere.controller.request.OrderRequest; import io.metersphere.dto.LogDetailDTO; import io.metersphere.dto.ReportDTO; +import io.metersphere.i18n.Translator; import io.metersphere.performance.base.*; import io.metersphere.performance.controller.request.DeleteReportRequest; import io.metersphere.performance.controller.request.ReportRequest; @@ -277,6 +278,9 @@ public class ReportService { public byte[] downloadJtl(String reportId) { LoadTestReportWithBLOBs report = getReport(reportId); + if (StringUtils.isBlank(report.getFileId())) { + MSException.throwException(Translator.get("load_test_report_file_not_exist")); + } return fileService.loadFileAsBytes(report.getFileId()); } } diff --git a/backend/src/main/resources/i18n/messages_en_US.properties b/backend/src/main/resources/i18n/messages_en_US.properties index ea9fe501cc..604cf385c7 100644 --- a/backend/src/main/resources/i18n/messages_en_US.properties +++ b/backend/src/main/resources/i18n/messages_en_US.properties @@ -48,6 +48,7 @@ related_case_del_fail_prefix=Connected to related_case_del_fail_suffix=TestCase, please disassociate first jmx_content_valid=JMX content is invalid container_delete_fail=The container failed to stop, please try again +load_test_report_file_not_exist=There is no JTL file in the current report, please execute it again to get it #workspace workspace_name_is_null=Workspace name cannot be null workspace_name_already_exists=The workspace name already exists diff --git a/backend/src/main/resources/i18n/messages_zh_CN.properties b/backend/src/main/resources/i18n/messages_zh_CN.properties index 7745c3acd2..72ae06238d 100644 --- a/backend/src/main/resources/i18n/messages_zh_CN.properties +++ b/backend/src/main/resources/i18n/messages_zh_CN.properties @@ -48,6 +48,7 @@ related_case_del_fail_prefix=已关联到 related_case_del_fail_suffix=测试用例,请先解除关联 jmx_content_valid=JMX 内容无效,请检查 container_delete_fail=容器由于网络原因停止失败,请重试 +load_test_report_file_not_exist=当前报告没有JTL文件,请重新执行以便获取 #workspace workspace_name_is_null=工作空间名不能为空 workspace_name_already_exists=工作空间名已存在 diff --git a/backend/src/main/resources/i18n/messages_zh_TW.properties b/backend/src/main/resources/i18n/messages_zh_TW.properties index 32411f615d..1d6e4d8889 100644 --- a/backend/src/main/resources/i18n/messages_zh_TW.properties +++ b/backend/src/main/resources/i18n/messages_zh_TW.properties @@ -48,6 +48,7 @@ related_case_del_fail_prefix=已關聯到 related_case_del_fail_suffix=測試用例,請先解除關聯 jmx_content_valid=JMX 內容無效,請檢查 container_delete_fail=容器由於網絡原因停止失敗,請重試 +load_test_report_file_not_exist=當前報告沒有JTL文件,請重新執行以便獲取 #workspace workspace_name_is_null=工作空間名不能為空 workspace_name_already_exists=工作空間名已存在 From abd12d5d77b60bb0b9c206dea185fcc1a20e71ba Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Fri, 13 Nov 2020 16:58:57 +0800 Subject: [PATCH 09/56] =?UTF-8?q?refactor:=20=E4=B8=8B=E8=BD=BDjtl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/performance/service/ReportService.java | 2 +- .../performance/report/PerformanceReportView.vue | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/io/metersphere/performance/service/ReportService.java b/backend/src/main/java/io/metersphere/performance/service/ReportService.java index c92f68298e..3bc2fabaf6 100644 --- a/backend/src/main/java/io/metersphere/performance/service/ReportService.java +++ b/backend/src/main/java/io/metersphere/performance/service/ReportService.java @@ -279,7 +279,7 @@ public class ReportService { public byte[] downloadJtl(String reportId) { LoadTestReportWithBLOBs report = getReport(reportId); if (StringUtils.isBlank(report.getFileId())) { - MSException.throwException(Translator.get("load_test_report_file_not_exist")); + throw new RuntimeException(Translator.get("load_test_report_file_not_exist")); } return fileService.loadFileAsBytes(report.getFileId()); } diff --git a/frontend/src/business/components/performance/report/PerformanceReportView.vue b/frontend/src/business/components/performance/report/PerformanceReportView.vue index 2cd890a9c8..b4a87e4dfd 100644 --- a/frontend/src/business/components/performance/report/PerformanceReportView.vue +++ b/frontend/src/business/components/performance/report/PerformanceReportView.vue @@ -26,7 +26,7 @@ {{ $t('test_track.plan_view.export_report') }} - 下载JTL + {{ $t('report.downloadJtl') }} @@ -307,7 +307,10 @@ export default { navigator.msSaveBlob(blob, this.filename) } }).catch(e => { - Message.error({message: e.message, showClose: true}); + let text = e.response.data.text(); + text.then((data) => { + Message.error({message: JSON.parse(data).message || e.message, showClose: true}); + }); }); } }, From 919f08431d078bb989918f849572ab2cbaada9f3 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Fri, 13 Nov 2020 17:01:36 +0800 Subject: [PATCH 10/56] =?UTF-8?q?feat:=20=E9=9B=86=E6=88=90zentao?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constants/IssuesManagePlatform.java | 2 +- .../metersphere/track/issue/IssueFactory.java | 10 +- .../{JiraIssue.java => JiraPlatform.java} | 4 +- .../{LocalIssue.java => LocalPlatform.java} | 4 +- .../{TapdIssue.java => TapdPlatform.java} | 4 +- .../track/issue/ZentaoPlatform.java | 219 ++++++++++++++++++ .../metersphere/track/issue/ZentaoUtils.java | 26 +++ 7 files changed, 258 insertions(+), 11 deletions(-) rename backend/src/main/java/io/metersphere/track/issue/{JiraIssue.java => JiraPlatform.java} (98%) rename backend/src/main/java/io/metersphere/track/issue/{LocalIssue.java => LocalPlatform.java} (94%) rename backend/src/main/java/io/metersphere/track/issue/{TapdIssue.java => TapdPlatform.java} (98%) create mode 100644 backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java create mode 100644 backend/src/main/java/io/metersphere/track/issue/ZentaoUtils.java diff --git a/backend/src/main/java/io/metersphere/commons/constants/IssuesManagePlatform.java b/backend/src/main/java/io/metersphere/commons/constants/IssuesManagePlatform.java index d1ace27122..0e6540740d 100644 --- a/backend/src/main/java/io/metersphere/commons/constants/IssuesManagePlatform.java +++ b/backend/src/main/java/io/metersphere/commons/constants/IssuesManagePlatform.java @@ -1,5 +1,5 @@ package io.metersphere.commons.constants; public enum IssuesManagePlatform { - Tapd, Jira, Local + Tapd, Jira, Local, Zentao } diff --git a/backend/src/main/java/io/metersphere/track/issue/IssueFactory.java b/backend/src/main/java/io/metersphere/track/issue/IssueFactory.java index 3592094890..b578caac05 100644 --- a/backend/src/main/java/io/metersphere/track/issue/IssueFactory.java +++ b/backend/src/main/java/io/metersphere/track/issue/IssueFactory.java @@ -10,11 +10,13 @@ import java.util.List; public class IssueFactory { public static AbstractIssuePlatform createPlatform(String platform, IssuesRequest addIssueRequest) { if (StringUtils.equals(IssuesManagePlatform.Tapd.toString(), platform)) { - return new TapdIssue(addIssueRequest); + return new TapdPlatform(addIssueRequest); } else if (StringUtils.equals(IssuesManagePlatform.Jira.toString(), platform)) { - return new JiraIssue(addIssueRequest); - } else if (StringUtils.equals("LOCAL", platform)) { - return new LocalIssue(addIssueRequest); + return new JiraPlatform(addIssueRequest); + } else if (StringUtils.equals(IssuesManagePlatform.Zentao.toString(), platform)) { + return new ZentaoPlatform(addIssueRequest); + } else if (StringUtils.equals("LOCAL", platform)) { + return new LocalPlatform(addIssueRequest); } return null; } diff --git a/backend/src/main/java/io/metersphere/track/issue/JiraIssue.java b/backend/src/main/java/io/metersphere/track/issue/JiraPlatform.java similarity index 98% rename from backend/src/main/java/io/metersphere/track/issue/JiraIssue.java rename to backend/src/main/java/io/metersphere/track/issue/JiraPlatform.java index 40a1277f90..981b76e2ef 100644 --- a/backend/src/main/java/io/metersphere/track/issue/JiraIssue.java +++ b/backend/src/main/java/io/metersphere/track/issue/JiraPlatform.java @@ -28,10 +28,10 @@ import java.util.List; import java.util.UUID; import java.util.stream.Collectors; -public class JiraIssue extends AbstractIssuePlatform { +public class JiraPlatform extends AbstractIssuePlatform { - public JiraIssue(IssuesRequest issuesRequest) { + public JiraPlatform(IssuesRequest issuesRequest) { super(issuesRequest); } diff --git a/backend/src/main/java/io/metersphere/track/issue/LocalIssue.java b/backend/src/main/java/io/metersphere/track/issue/LocalPlatform.java similarity index 94% rename from backend/src/main/java/io/metersphere/track/issue/LocalIssue.java rename to backend/src/main/java/io/metersphere/track/issue/LocalPlatform.java index b75946b726..bbbd12df8f 100644 --- a/backend/src/main/java/io/metersphere/track/issue/LocalIssue.java +++ b/backend/src/main/java/io/metersphere/track/issue/LocalPlatform.java @@ -10,9 +10,9 @@ import io.metersphere.track.request.testcase.IssuesRequest; import java.util.List; import java.util.UUID; -public class LocalIssue extends AbstractIssuePlatform { +public class LocalPlatform extends AbstractIssuePlatform { - public LocalIssue(IssuesRequest issuesRequest) { + public LocalPlatform(IssuesRequest issuesRequest) { super(issuesRequest); } diff --git a/backend/src/main/java/io/metersphere/track/issue/TapdIssue.java b/backend/src/main/java/io/metersphere/track/issue/TapdPlatform.java similarity index 98% rename from backend/src/main/java/io/metersphere/track/issue/TapdIssue.java rename to backend/src/main/java/io/metersphere/track/issue/TapdPlatform.java index 3df46f4291..2b01f5b468 100644 --- a/backend/src/main/java/io/metersphere/track/issue/TapdIssue.java +++ b/backend/src/main/java/io/metersphere/track/issue/TapdPlatform.java @@ -24,10 +24,10 @@ import java.util.List; import java.util.UUID; import java.util.stream.Collectors; -public class TapdIssue extends AbstractIssuePlatform { +public class TapdPlatform extends AbstractIssuePlatform { - public TapdIssue(IssuesRequest issueRequest) { + public TapdPlatform(IssuesRequest issueRequest) { super(issueRequest); } diff --git a/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java b/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java new file mode 100644 index 0000000000..e0b7a99fa7 --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java @@ -0,0 +1,219 @@ +package io.metersphere.track.issue; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import io.metersphere.base.domain.*; +import io.metersphere.commons.constants.IssuesManagePlatform; +import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.utils.LogUtil; +import io.metersphere.track.request.testcase.IssuesRequest; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.util.*; +import java.util.stream.Collectors; + +public class ZentaoPlatform extends AbstractIssuePlatform { + + public ZentaoPlatform(IssuesRequest issuesRequest) { + super(issuesRequest); + } + + @Override + String getProjectId() { +// TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId); +// Project project = projectService.getProjectById(testCase.getProjectId()); + // todo return getZentao ID + return "002"; + } + + @Override + public List getIssue() { + List list = new ArrayList<>(); + + TestCaseIssuesExample example = new TestCaseIssuesExample(); + example.createCriteria().andTestCaseIdEqualTo(testCaseId); + + List issues = extIssuesMapper.getIssues(testCaseId, IssuesManagePlatform.Zentao.toString()); + + List issuesIds = issues.stream().map(Issues::getId).collect(Collectors.toList()); + issuesIds.forEach(issuesId -> { + Issues dto = getZentaoIssues(issuesId); + if (StringUtils.isBlank(dto.getId())) { + // 缺陷不存在,解除用例和缺陷的关联 + TestCaseIssuesExample issuesExample = new TestCaseIssuesExample(); + issuesExample.createCriteria() + .andTestCaseIdEqualTo(testCaseId) + .andIssuesIdEqualTo(issuesId); + testCaseIssuesMapper.deleteByExample(issuesExample); + issuesMapper.deleteByPrimaryKey(issuesId); + } else { + dto.setPlatform(IssuesManagePlatform.Zentao.toString()); + // 缺陷状态为 关闭,则不显示 + if (!StringUtils.equals("closed", dto.getStatus())) { + list.add(dto); + } + } + }); + return list; + + } + + private Issues getZentaoIssues(String bugId) { + String projectId = getProjectId(); + + String session = login(); + + String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString()); + JSONObject object = JSON.parseObject(config); + String account = object.getString("account"); + String password = object.getString("password"); + String url = object.getString("url"); + url = ZentaoUtils.getUrl(url, account, password); + System.out.println(url); + HttpEntity requestEntity = new HttpEntity<>(new HttpHeaders()); + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity responseEntity = restTemplate.exchange("http://xx/zentao/bug-view-"+ bugId +".json?zentaosid=" + session, HttpMethod.POST, requestEntity, String.class); + String body = responseEntity.getBody(); + JSONObject obj = JSONObject.parseObject(body); + System.out.println(obj); + if (obj != null) { + JSONObject data = obj.getJSONObject("data"); + JSONArray bugs = data.getJSONArray("bugs"); + for (int j = 0; j < bugs.size(); j++) { + JSONObject bug = bugs.getJSONObject(j); + String id = bug.getString("id"); + String title = bug.getString("title"); + String description = bug.getString("steps"); + Long createTime = bug.getLong("openedDate"); + String status = bug.getString("status"); + String reporter = bug.getString("openedBy"); + + Issues issues = new Issues(); + issues.setId(id); + issues.setTitle(title); + issues.setDescription(description); + issues.setCreateTime(createTime); + issues.setStatus(status); + issues.setReporter(reporter); + return issues; + } + } + return new Issues(); + } + + @Override + public void addIssue(IssuesRequest issuesRequest) { + String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString()); + String session = login(); + JSONObject object = JSON.parseObject(config); +// String account = object.getString("account"); +// String password = object.getString("password"); + + MultiValueMap paramMap = new LinkedMultiValueMap<>(); + paramMap.add("product", "003"); + paramMap.add("title", issuesRequest.getTitle()); + paramMap.add("openedBuild", "123"); + paramMap.add("steps", issuesRequest.getContent()); + paramMap.add("assignedTo", "admin"); + + HttpEntity requestEntity = new HttpEntity<>(paramMap, new HttpHeaders()); + RestTemplate restTemplate = new RestTemplate(); + System.out.println("zentao add bug"); + ResponseEntity responseEntity = restTemplate.exchange("http://xx/zentao/bug-create-3.json?zentaosid=" + session, HttpMethod.POST, requestEntity, String.class); + String body = responseEntity.getBody(); + JSONObject obj = JSONObject.parseObject(body); + if (obj != null) { + String id = obj.getString("data"); + if (StringUtils.isNotBlank(id)) { + // 用例与第三方缺陷平台中的缺陷关联 + TestCaseIssues testCaseIssues = new TestCaseIssues(); + testCaseIssues.setId(UUID.randomUUID().toString()); + testCaseIssues.setIssuesId(id); + testCaseIssues.setTestCaseId(testCaseId); + testCaseIssuesMapper.insert(testCaseIssues); + + // 插入缺陷表 + Issues issues = new Issues(); + issues.setId(id); + issues.setPlatform(IssuesManagePlatform.Zentao.toString()); + issuesMapper.insert(issues); + } + } + + System.out.println(obj); +// return responseEntity.getBody(); + } + + @Override + public void deleteIssue(String id) { + + } + + @Override + public void testAuth() { + try { + String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString()); + JSONObject object = JSON.parseObject(config); + String account = object.getString("account"); + String password = object.getString("password"); + String url = object.getString("url"); + url = ZentaoUtils.getUrl(url, account, password); + HttpEntity requestEntity = new HttpEntity<>(new HttpHeaders()); + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity exchange = restTemplate.exchange(url + "&m=user&f=apilogin", HttpMethod.GET, requestEntity, String.class); + + String body = exchange.getBody(); + JSONObject obj = JSONObject.parseObject(body); + System.out.println(obj); + if (obj != null) { + String errcode = obj.getString("errcode"); + String errmsg = obj.getString("errmsg"); + if (StringUtils.isNotBlank(errcode)) { + MSException.throwException(errmsg); + } + } + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + MSException.throwException("验证失败!"); + } + + } + + + private String login() { + String session = getSession(); + String loginUrl = "http://xx/zentao/user-login.json?zentaosid=" + session; + MultiValueMap paramMap = new LinkedMultiValueMap<>(); + paramMap.add("account", "admin"); + paramMap.add("password", "xx"); + + HttpEntity requestEntity = new HttpEntity<>(paramMap, new HttpHeaders()); + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity responseEntity = restTemplate.exchange(loginUrl, HttpMethod.POST, requestEntity, String.class); + return session; + } + + private String getSession() { + RestTemplate restTemplate = new RestTemplate(); + HttpEntity requestEntity = new HttpEntity<>(new HttpHeaders()); + ResponseEntity responseEntity = restTemplate.exchange("http://xx.xxx.xxx.xxx/zentao/api-getsessionid.json", HttpMethod.GET, requestEntity, String.class); + String body = responseEntity.getBody(); + JSONObject obj = JSONObject.parseObject(body); + JSONObject data = obj.getJSONObject("data"); + String session = data.getString("sessionID"); + return session; + } + + @Override + public List getPlatformUser() { + return null; + } +} diff --git a/backend/src/main/java/io/metersphere/track/issue/ZentaoUtils.java b/backend/src/main/java/io/metersphere/track/issue/ZentaoUtils.java new file mode 100644 index 0000000000..fa34a39224 --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/issue/ZentaoUtils.java @@ -0,0 +1,26 @@ +package io.metersphere.track.issue; + +import io.metersphere.commons.utils.EncryptUtils; + +public class ZentaoUtils { + + /** + * @param code Zentao 应用代号 + * @param key Zentao 密钥 + * @return token + */ + public static String getToken(String code, String key, String time) { + return (String) EncryptUtils.md5Encrypt(code + key + time); + } + + /** + * @param url Zentao url + * @param code Zentao 应用代号 + * @param key Zentao 密钥 + * @return url + */ + public static String getUrl(String url, String code, String key) { + String time = String.valueOf(System.currentTimeMillis());; + return url + "api.php?" + "code=" + code + "&time=" + time + "&token=" + getToken(code, key, time); + } +} From eba91d88d2891b539c794b7103be0453c5491959 Mon Sep 17 00:00:00 2001 From: wenyann <64353056+wenyann@users.noreply.github.com> Date: Fri, 13 Nov 2020 17:06:40 +0800 Subject: [PATCH 11/56] fix: i18n --- .../metersphere/notice/service/MailService.java | 17 +++++++++++------ .../resources/i18n/messages_en_US.properties | 4 ++-- .../resources/i18n/messages_zh_CN.properties | 4 ++-- .../resources/i18n/messages_zh_TW.properties | 4 ++-- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/backend/src/main/java/io/metersphere/notice/service/MailService.java b/backend/src/main/java/io/metersphere/notice/service/MailService.java index 14479ce941..0cc1c5e44e 100644 --- a/backend/src/main/java/io/metersphere/notice/service/MailService.java +++ b/backend/src/main/java/io/metersphere/notice/service/MailService.java @@ -24,6 +24,7 @@ import org.apache.commons.collections4.MapUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RegExUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.mail.MailException; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; @@ -99,10 +100,10 @@ public class MailService { MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setFrom(javaMailSender.getUsername()); if (StringUtils.equals(type, NoticeConstants.API)) { - helper.setSubject("MeterSphere平台" + Translator.get("task_notification")); + helper.setSubject("MeterSphere平台" + Translator.get("task_notification_jenkins")); } if (StringUtils.equals(type, NoticeConstants.SCHEDULE)) { - helper.setSubject("MeterSphere平台" + Translator.get("task_notification_")); + helper.setSubject("MeterSphere平台" + Translator.get("task_notification")); } String[] users; List emails = new ArrayList<>(); @@ -113,7 +114,11 @@ public class MailService { users = emails.toArray(new String[0]); helper.setText(getContent(Template, context), true); helper.setTo(users); - javaMailSender.send(mimeMessage); + try { + javaMailSender.send(mimeMessage); + } catch (MailException e) { + LogUtil.error(e); + } } //测试评审 @@ -341,7 +346,7 @@ public class MailService { JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); List paramList = systemParameterService.getParamList(ParamConstants.Classify.MAIL.getValue()); javaMailSender.setDefaultEncoding("UTF-8"); - javaMailSender.setProtocol("smtp"); + javaMailSender.setProtocol("smtps"); for (SystemParameter p : paramList) { switch (p.getParamKey()) { case "smtp.host": @@ -362,8 +367,8 @@ public class MailService { } Properties props = new Properties(); props.put("mail.smtp.auth", "true"); - props.put("mail.smtp.starttls.enable", "false"); - props.put("mail.smtp.starttls.required", "false"); + props.put("mail.smtp.starttls.enable", "true"); + props.put("mail.smtp.starttls.required", "true"); props.put("mail.smtp.timeout", "30000"); props.put("mail.smtp.connectiontimeout", "5000"); javaMailSender.setJavaMailProperties(props); diff --git a/backend/src/main/resources/i18n/messages_en_US.properties b/backend/src/main/resources/i18n/messages_en_US.properties index ea9fe501cc..76724a4100 100644 --- a/backend/src/main/resources/i18n/messages_en_US.properties +++ b/backend/src/main/resources/i18n/messages_en_US.properties @@ -167,8 +167,8 @@ check_owner_comment=The current user does not have permission to manipulate this upload_content_is_null=Imported content is empty test_plan_notification=Test plan notification task_defect_notification=Task defect notification -task_notification=Jenkins Task notification -task_notification_=Timing task result notification +task_notification_jenkins=Jenkins Task notification +task_notification=Result notification diff --git a/backend/src/main/resources/i18n/messages_zh_CN.properties b/backend/src/main/resources/i18n/messages_zh_CN.properties index 7745c3acd2..3d87761b8d 100644 --- a/backend/src/main/resources/i18n/messages_zh_CN.properties +++ b/backend/src/main/resources/i18n/messages_zh_CN.properties @@ -168,5 +168,5 @@ check_owner_comment=当前用户没有操作此评论的权限 upload_content_is_null=导入内容为空 test_plan_notification=测试计划通知 task_defect_notification=缺陷任务通知 -task_notification=jenkins任务通知 -task_notification_=定时任务结果通知 \ No newline at end of file +task_notification_jenkins=jenkins任务通知 +task_notification=任务通知 \ No newline at end of file diff --git a/backend/src/main/resources/i18n/messages_zh_TW.properties b/backend/src/main/resources/i18n/messages_zh_TW.properties index 32411f615d..597db40028 100644 --- a/backend/src/main/resources/i18n/messages_zh_TW.properties +++ b/backend/src/main/resources/i18n/messages_zh_TW.properties @@ -169,6 +169,6 @@ check_owner_comment=當前用戶沒有操作此評論的權限 upload_content_is_null=導入內容為空 test_plan_notification=測試計畫通知 task_defect_notification=缺陷任務通知 -task_notification=jenkins任務通知 -task_notification_=定時任務通知 +task_notification_jenkins=jenkins任務通知 +task_notification=任務通知 From 0c7acfebeae3081bd65ed515cef2ee40bb2d42bd Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Mon, 16 Nov 2020 15:45:07 +0800 Subject: [PATCH 12/56] =?UTF-8?q?refactor:=20=E9=A1=B9=E7=9B=AE=E8=A1=A8?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0zentao=E5=85=B3=E8=81=94=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/base/domain/Project.java | 2 + .../base/domain/ProjectExample.java | 70 +++++++++++++++++++ .../metersphere/base/mapper/ProjectMapper.xml | 28 ++++++-- .../migration/V43__project_add_zentao_id.sql | 1 + 4 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 backend/src/main/resources/db/migration/V43__project_add_zentao_id.sql diff --git a/backend/src/main/java/io/metersphere/base/domain/Project.java b/backend/src/main/java/io/metersphere/base/domain/Project.java index 4b934ac658..25403e763e 100644 --- a/backend/src/main/java/io/metersphere/base/domain/Project.java +++ b/backend/src/main/java/io/metersphere/base/domain/Project.java @@ -21,5 +21,7 @@ public class Project implements Serializable { private String jiraKey; + private String zentaoId; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/domain/ProjectExample.java b/backend/src/main/java/io/metersphere/base/domain/ProjectExample.java index 7c93737e82..8f83d6ad88 100644 --- a/backend/src/main/java/io/metersphere/base/domain/ProjectExample.java +++ b/backend/src/main/java/io/metersphere/base/domain/ProjectExample.java @@ -643,6 +643,76 @@ public class ProjectExample { addCriterion("jira_key not between", value1, value2, "jiraKey"); return (Criteria) this; } + + public Criteria andZentaoIdIsNull() { + addCriterion("zentao_id is null"); + return (Criteria) this; + } + + public Criteria andZentaoIdIsNotNull() { + addCriterion("zentao_id is not null"); + return (Criteria) this; + } + + public Criteria andZentaoIdEqualTo(String value) { + addCriterion("zentao_id =", value, "zentaoId"); + return (Criteria) this; + } + + public Criteria andZentaoIdNotEqualTo(String value) { + addCriterion("zentao_id <>", value, "zentaoId"); + return (Criteria) this; + } + + public Criteria andZentaoIdGreaterThan(String value) { + addCriterion("zentao_id >", value, "zentaoId"); + return (Criteria) this; + } + + public Criteria andZentaoIdGreaterThanOrEqualTo(String value) { + addCriterion("zentao_id >=", value, "zentaoId"); + return (Criteria) this; + } + + public Criteria andZentaoIdLessThan(String value) { + addCriterion("zentao_id <", value, "zentaoId"); + return (Criteria) this; + } + + public Criteria andZentaoIdLessThanOrEqualTo(String value) { + addCriterion("zentao_id <=", value, "zentaoId"); + return (Criteria) this; + } + + public Criteria andZentaoIdLike(String value) { + addCriterion("zentao_id like", value, "zentaoId"); + return (Criteria) this; + } + + public Criteria andZentaoIdNotLike(String value) { + addCriterion("zentao_id not like", value, "zentaoId"); + return (Criteria) this; + } + + public Criteria andZentaoIdIn(List values) { + addCriterion("zentao_id in", values, "zentaoId"); + return (Criteria) this; + } + + public Criteria andZentaoIdNotIn(List values) { + addCriterion("zentao_id not in", values, "zentaoId"); + return (Criteria) this; + } + + public Criteria andZentaoIdBetween(String value1, String value2) { + addCriterion("zentao_id between", value1, value2, "zentaoId"); + return (Criteria) this; + } + + public Criteria andZentaoIdNotBetween(String value1, String value2) { + addCriterion("zentao_id not between", value1, value2, "zentaoId"); + return (Criteria) this; + } } public static class Criteria extends GeneratedCriteria { diff --git a/backend/src/main/java/io/metersphere/base/mapper/ProjectMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ProjectMapper.xml index a5939ef7bd..4ed30cebfe 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ProjectMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ProjectMapper.xml @@ -10,6 +10,7 @@ + @@ -70,7 +71,8 @@ - id, workspace_id, `name`, description, create_time, update_time, tapd_id, jira_key + id, workspace_id, `name`, description, create_time, update_time, tapd_id, jira_key, + zentao_id @@ -198,6 +208,9 @@ jira_key = #{record.jiraKey,jdbcType=VARCHAR}, + + zentao_id = #{record.zentaoId,jdbcType=VARCHAR}, + @@ -212,7 +225,8 @@ create_time = #{record.createTime,jdbcType=BIGINT}, update_time = #{record.updateTime,jdbcType=BIGINT}, tapd_id = #{record.tapdId,jdbcType=VARCHAR}, - jira_key = #{record.jiraKey,jdbcType=VARCHAR} + jira_key = #{record.jiraKey,jdbcType=VARCHAR}, + zentao_id = #{record.zentaoId,jdbcType=VARCHAR} @@ -241,6 +255,9 @@ jira_key = #{jiraKey,jdbcType=VARCHAR}, + + zentao_id = #{zentaoId,jdbcType=VARCHAR}, + where id = #{id,jdbcType=VARCHAR} @@ -252,7 +269,8 @@ create_time = #{createTime,jdbcType=BIGINT}, update_time = #{updateTime,jdbcType=BIGINT}, tapd_id = #{tapdId,jdbcType=VARCHAR}, - jira_key = #{jiraKey,jdbcType=VARCHAR} + jira_key = #{jiraKey,jdbcType=VARCHAR}, + zentao_id = #{zentaoId,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR} \ No newline at end of file diff --git a/backend/src/main/resources/db/migration/V43__project_add_zentao_id.sql b/backend/src/main/resources/db/migration/V43__project_add_zentao_id.sql new file mode 100644 index 0000000000..11e373adc8 --- /dev/null +++ b/backend/src/main/resources/db/migration/V43__project_add_zentao_id.sql @@ -0,0 +1 @@ +alter table project add zentao_id varchar(50) null; \ No newline at end of file From acaddcbe7a8a275349dd93d57bcd0813d43f6d68 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Mon, 16 Nov 2020 15:53:03 +0800 Subject: [PATCH 13/56] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=BB=84?= =?UTF-8?q?=E7=BB=87=E6=88=90=E5=91=98=E8=A7=92=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- .../base/mapper/ext/ExtUserRoleMapper.xml | 12 ++++++-- .../commons/constants/RoleConstants.java | 1 + .../service/OrganizationService.java | 3 +- .../resources/db/migration/V43__add_role.sql | 2 ++ .../organization/OrganizationMember.vue | 5 ++++ .../components/settings/system/User.vue | 30 +++++++++++++++++++ frontend/src/i18n/en-US.js | 1 + frontend/src/i18n/zh-CN.js | 1 + frontend/src/i18n/zh-TW.js | 1 + 10 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 backend/src/main/resources/db/migration/V43__add_role.sql diff --git a/.gitignore b/.gitignore index 832cb0b18e..165db4e885 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,5 @@ target .settings .project .classpath -.jython_cache \ No newline at end of file +.jython_cache +qywx.json \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtUserRoleMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtUserRoleMapper.xml index 87fb487b28..3a53df48e8 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtUserRoleMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtUserRoleMapper.xml @@ -49,8 +49,16 @@ select p.id, p.workspace_id, p.name, p.description, p.update_time, - p.create_time, w.id as workspaceId, w.name as workspaceName, p.tapd_id, p.jira_key + p.create_time, w.id as workspaceId, w.name as workspaceName, p.tapd_id, p.jira_key, p.zentao_id from project p join workspace w on p.workspace_id = w.id diff --git a/backend/src/main/java/io/metersphere/dto/ProjectDTO.java b/backend/src/main/java/io/metersphere/dto/ProjectDTO.java index e869d8f12a..12b4c46d37 100644 --- a/backend/src/main/java/io/metersphere/dto/ProjectDTO.java +++ b/backend/src/main/java/io/metersphere/dto/ProjectDTO.java @@ -16,5 +16,5 @@ public class ProjectDTO { private Long updateTime; private String tapdId; private String jiraKey; - + private String zentaoId; } diff --git a/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java b/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java index e0b7a99fa7..077d5ca757 100644 --- a/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java @@ -21,17 +21,33 @@ import java.util.*; import java.util.stream.Collectors; public class ZentaoPlatform extends AbstractIssuePlatform { + /** + * zentao account + */ + private final String account; + /** + * zentao password + */ + private final String password; + /** + * zentao url eg:http://x.x.x.x/zentao + */ + private final String url; public ZentaoPlatform(IssuesRequest issuesRequest) { super(issuesRequest); + String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString()); + JSONObject object = JSON.parseObject(config); + this.account = object.getString("account"); + this.password = object.getString("password"); + this.url = object.getString("url"); } @Override String getProjectId() { -// TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId); -// Project project = projectService.getProjectById(testCase.getProjectId()); - // todo return getZentao ID - return "002"; + TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId); + Project project = projectService.getProjectById(testCase.getProjectId()); + return project.getZentaoId(); } @Override @@ -63,62 +79,59 @@ public class ZentaoPlatform extends AbstractIssuePlatform { } }); return list; - + } private Issues getZentaoIssues(String bugId) { - String projectId = getProjectId(); - String session = login(); - - String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString()); - JSONObject object = JSON.parseObject(config); - String account = object.getString("account"); - String password = object.getString("password"); - String url = object.getString("url"); - url = ZentaoUtils.getUrl(url, account, password); - System.out.println(url); HttpEntity requestEntity = new HttpEntity<>(new HttpHeaders()); RestTemplate restTemplate = new RestTemplate(); - ResponseEntity responseEntity = restTemplate.exchange("http://xx/zentao/bug-view-"+ bugId +".json?zentaosid=" + session, HttpMethod.POST, requestEntity, String.class); + ResponseEntity responseEntity = restTemplate.exchange(url + "api-getModel-bug-getById-bugID={bugId}?zentaosid=" + session, + HttpMethod.POST, requestEntity, String.class, bugId); String body = responseEntity.getBody(); + System.out.println(body); JSONObject obj = JSONObject.parseObject(body); System.out.println(obj); if (obj != null) { - JSONObject data = obj.getJSONObject("data"); - JSONArray bugs = data.getJSONArray("bugs"); - for (int j = 0; j < bugs.size(); j++) { - JSONObject bug = bugs.getJSONObject(j); - String id = bug.getString("id"); - String title = bug.getString("title"); - String description = bug.getString("steps"); - Long createTime = bug.getLong("openedDate"); - String status = bug.getString("status"); - String reporter = bug.getString("openedBy"); - - Issues issues = new Issues(); - issues.setId(id); - issues.setTitle(title); - issues.setDescription(description); - issues.setCreateTime(createTime); - issues.setStatus(status); - issues.setReporter(reporter); - return issues; + JSONObject bug = obj.getJSONObject("data"); + String id = bug.getString("id"); + String title = bug.getString("title"); + String description = bug.getString("steps"); + Long createTime = bug.getLong("openedDate"); + String status = bug.getString("status"); + String reporter = bug.getString("openedBy"); + int deleted = bug.getInteger("deleted"); + if (deleted == 1) { + return new Issues(); } + Issues issues = new Issues(); + issues.setId(id); + issues.setTitle(title); + issues.setDescription(description); + issues.setCreateTime(createTime); + issues.setStatus(status); + issues.setReporter(reporter); + return issues; } return new Issues(); } @Override public void addIssue(IssuesRequest issuesRequest) { - String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString()); + String session = login(); - JSONObject object = JSON.parseObject(config); -// String account = object.getString("account"); -// String password = object.getString("password"); + String projectId = getProjectId(); + + if (StringUtils.isBlank(projectId)) { + MSException.throwException("add zentao bug fail, project zentao id is null"); + } + + if (StringUtils.isBlank(session)) { + MSException.throwException("session is null"); + } MultiValueMap paramMap = new LinkedMultiValueMap<>(); - paramMap.add("product", "003"); + paramMap.add("product", projectId); paramMap.add("title", issuesRequest.getTitle()); paramMap.add("openedBuild", "123"); paramMap.add("steps", issuesRequest.getContent()); @@ -126,12 +139,12 @@ public class ZentaoPlatform extends AbstractIssuePlatform { HttpEntity requestEntity = new HttpEntity<>(paramMap, new HttpHeaders()); RestTemplate restTemplate = new RestTemplate(); - System.out.println("zentao add bug"); - ResponseEntity responseEntity = restTemplate.exchange("http://xx/zentao/bug-create-3.json?zentaosid=" + session, HttpMethod.POST, requestEntity, String.class); + ResponseEntity responseEntity = restTemplate.exchange(url + "api-getModel-bug-create.json?zentaosid=" + session, HttpMethod.POST, requestEntity, String.class); String body = responseEntity.getBody(); JSONObject obj = JSONObject.parseObject(body); if (obj != null) { - String id = obj.getString("data"); + JSONObject data = obj.getJSONObject("data"); + String id = data.getString("id"); if (StringUtils.isNotBlank(id)) { // 用例与第三方缺陷平台中的缺陷关联 TestCaseIssues testCaseIssues = new TestCaseIssues(); @@ -147,9 +160,6 @@ public class ZentaoPlatform extends AbstractIssuePlatform { issuesMapper.insert(issues); } } - - System.out.println(obj); -// return responseEntity.getBody(); } @Override @@ -160,26 +170,7 @@ public class ZentaoPlatform extends AbstractIssuePlatform { @Override public void testAuth() { try { - String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString()); - JSONObject object = JSON.parseObject(config); - String account = object.getString("account"); - String password = object.getString("password"); - String url = object.getString("url"); - url = ZentaoUtils.getUrl(url, account, password); - HttpEntity requestEntity = new HttpEntity<>(new HttpHeaders()); - RestTemplate restTemplate = new RestTemplate(); - ResponseEntity exchange = restTemplate.exchange(url + "&m=user&f=apilogin", HttpMethod.GET, requestEntity, String.class); - - String body = exchange.getBody(); - JSONObject obj = JSONObject.parseObject(body); - System.out.println(obj); - if (obj != null) { - String errcode = obj.getString("errcode"); - String errmsg = obj.getString("errmsg"); - if (StringUtils.isNotBlank(errcode)) { - MSException.throwException(errmsg); - } - } + login(); } catch (Exception e) { LogUtil.error(e.getMessage(), e); MSException.throwException("验证失败!"); @@ -190,21 +181,34 @@ public class ZentaoPlatform extends AbstractIssuePlatform { private String login() { String session = getSession(); - String loginUrl = "http://xx/zentao/user-login.json?zentaosid=" + session; + String loginUrl = url + "user-login.json?zentaosid=" + session; MultiValueMap paramMap = new LinkedMultiValueMap<>(); - paramMap.add("account", "admin"); - paramMap.add("password", "xx"); - + paramMap.add("account", account); + paramMap.add("password", password); HttpEntity requestEntity = new HttpEntity<>(paramMap, new HttpHeaders()); RestTemplate restTemplate = new RestTemplate(); ResponseEntity responseEntity = restTemplate.exchange(loginUrl, HttpMethod.POST, requestEntity, String.class); - return session; + String body = responseEntity.getBody(); + JSONObject obj = JSONObject.parseObject(body); + JSONObject user = obj.getJSONObject("user"); + if (user == null) { + LogUtil.error("login fail"); + LogUtil.error(obj); + // 登录失败,获取的session无效,置空session + MSException.throwException("zentao login fail"); + } + String username = user.getString("account"); + if (!StringUtils.equals(username, account)) { + LogUtil.error("login fail,inconsistent users"); + MSException.throwException("zentao login fail"); + } + return session; } private String getSession() { RestTemplate restTemplate = new RestTemplate(); HttpEntity requestEntity = new HttpEntity<>(new HttpHeaders()); - ResponseEntity responseEntity = restTemplate.exchange("http://xx.xxx.xxx.xxx/zentao/api-getsessionid.json", HttpMethod.GET, requestEntity, String.class); + ResponseEntity responseEntity = restTemplate.exchange(url + "api-getsessionid.json", HttpMethod.GET, requestEntity, String.class); String body = responseEntity.getBody(); JSONObject obj = JSONObject.parseObject(body); JSONObject data = obj.getJSONObject("data"); diff --git a/backend/src/main/java/io/metersphere/track/service/IssuesService.java b/backend/src/main/java/io/metersphere/track/service/IssuesService.java index 6353e08bfd..19471144f0 100644 --- a/backend/src/main/java/io/metersphere/track/service/IssuesService.java +++ b/backend/src/main/java/io/metersphere/track/service/IssuesService.java @@ -63,9 +63,11 @@ public class IssuesService { boolean tapd = isIntegratedPlatform(orgId, IssuesManagePlatform.Tapd.toString()); boolean jira = isIntegratedPlatform(orgId, IssuesManagePlatform.Jira.toString()); + boolean zentao = isIntegratedPlatform(orgId, IssuesManagePlatform.Zentao.toString()); String tapdId = getTapdProjectId(issuesRequest.getTestCaseId()); String jiraKey = getJiraProjectKey(issuesRequest.getTestCaseId()); + String zentaoId = getZentaoProjectId(issuesRequest.getTestCaseId()); List platforms = new ArrayList<>(); @@ -82,7 +84,13 @@ public class IssuesService { } } - if (StringUtils.isBlank(tapdId) && StringUtils.isBlank(jiraKey)) { + if (zentao) { + if (StringUtils.isNotBlank(zentaoId)) { + platforms.add(IssuesManagePlatform.Zentao.name()); + } + } + + if (StringUtils.isBlank(tapdId) && StringUtils.isBlank(jiraKey) && StringUtils.isBlank(zentaoId)) { platforms.add("LOCAL"); } @@ -122,6 +130,7 @@ public class IssuesService { boolean tapd = isIntegratedPlatform(orgId, IssuesManagePlatform.Tapd.toString()); boolean jira = isIntegratedPlatform(orgId, IssuesManagePlatform.Jira.toString()); + boolean zentao = isIntegratedPlatform(orgId, IssuesManagePlatform.Zentao.toString()); List platforms = new ArrayList<>(); if (tapd) { @@ -140,6 +149,13 @@ public class IssuesService { } } + if (zentao) { + String zentaoId = getZentaoProjectId(caseId); + if (StringUtils.isNotBlank(zentaoId)) { + platforms.add(IssuesManagePlatform.Zentao.name()); + } + } + platforms.add("LOCAL"); IssuesRequest issueRequest = new IssuesRequest(); issueRequest.setTestCaseId(caseId); @@ -152,18 +168,24 @@ public class IssuesService { return list; } - public String getTapdProjectId(String testCaseId) { + private String getTapdProjectId(String testCaseId) { TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId); Project project = projectService.getProjectById(testCase.getProjectId()); return project.getTapdId(); } - public String getJiraProjectKey(String testCaseId) { + private String getJiraProjectKey(String testCaseId) { TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId); Project project = projectService.getProjectById(testCase.getProjectId()); return project.getJiraKey(); } + private String getZentaoProjectId(String testCaseId) { + TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId); + Project project = projectService.getProjectById(testCase.getProjectId()); + return project.getZentaoId(); + } + /** * 是否关联平台 */ diff --git a/frontend/src/business/components/project/MsProject.vue b/frontend/src/business/components/project/MsProject.vue index f5805adda8..ac5eab7234 100644 --- a/frontend/src/business/components/project/MsProject.vue +++ b/frontend/src/business/components/project/MsProject.vue @@ -63,6 +63,9 @@ + + + - +