From a64a4319b1c273c9fc0f0b8c21ec57e1d0fb41da Mon Sep 17 00:00:00 2001 From: zhaoqian Date: Tue, 29 Mar 2022 19:48:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:azure=20devops=E5=B9=B3=E5=8F=B0=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E7=9A=84bug=E6=9C=AA=E5=90=8C=E6=AD=A5=E5=88=B0meters?= =?UTF-8?q?phere(#ID1010762)=20fix:github#11072=EF=BC=8CAzure=20Devops=20?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E7=BC=BA=E9=99=B7=20=EF=BC=8C=E4=B8=8D?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=B8=8A=E4=BC=A0=E5=9B=BE=E7=89=87(#ID10107?= =?UTF-8?q?59)=20feat:tfs=20=E7=BC=BA=E9=99=B7=E5=92=8C=E9=9C=80=E6=B1=82?= =?UTF-8?q?=E5=85=B3=E8=81=94=EF=BC=8C=E7=BC=BA=E9=99=B7=E8=83=BD=E5=A4=9F?= =?UTF-8?q?=E6=8C=82=E5=9C=A8=E9=9C=80=E6=B1=82=E4=B8=8B(ID1004746)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metersphere/commons/utils/FileUtils.java | 15 +++++++++++++ .../track/issue/AbstractIssuePlatform.java | 22 +++++++++++++++++++ .../track/issue/IssuesPlatform.java | 14 ++++++++++++ .../AzureDevopsWorkItemsBatchResponse.java | 10 +++++++++ .../request/testcase/IssuesUpdateRequest.java | 4 ++++ .../track/service/IssuesService.java | 10 +++++++++ .../track/service/TestCaseService.java | 21 ++++++++++++++++++ .../case/components/TestCaseIssueRelate.vue | 8 ++++++- 8 files changed, 103 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/io/metersphere/commons/utils/FileUtils.java b/backend/src/main/java/io/metersphere/commons/utils/FileUtils.java index 76f580b9e3..16fc76749a 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/FileUtils.java +++ b/backend/src/main/java/io/metersphere/commons/utils/FileUtils.java @@ -310,6 +310,21 @@ public class FileUtils { return buffer; } + public static String fileToStr(File tradeFile) { + String buffer = null; + try (FileInputStream fis = new FileInputStream(tradeFile); + ByteArrayOutputStream bos = new ByteArrayOutputStream();) { + byte[] b = new byte[1024]; + int n; + while ((n = fis.read(b)) != -1) { + bos.write(b, 0, n); + } + buffer = bos.toString(); + } catch (Exception e) { + } + return buffer; + } + public List getZipJar() { List jarFiles = new LinkedList<>(); // jar 包 diff --git a/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java b/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java index 2dab21ace5..ee4a349536 100644 --- a/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java @@ -18,6 +18,7 @@ import io.metersphere.dto.IssueTemplateDao; import io.metersphere.dto.UserDTO; import io.metersphere.service.*; import io.metersphere.track.issue.domain.ProjectIssueConfig; +import io.metersphere.track.request.testcase.EditTestCaseRequest; import io.metersphere.track.request.testcase.IssuesRequest; import io.metersphere.track.request.testcase.IssuesUpdateRequest; import io.metersphere.track.service.IssuesService; @@ -527,4 +528,25 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform { public Boolean checkProjectExist(String relateId) { return null; } + + /** + * 移除缺陷的Parent关联 + * @param request + */ + @Override + public void removeIssueParentLink(IssuesUpdateRequest request) { + // 添加方法体逻辑可重写改方法 + } + + /** + * 更新需求与缺陷的关联关系 + * @param testCase + * @param project + */ + @Override + public void updateDemandIssueLink(EditTestCaseRequest testCase, Project project) { + // 添加方法体逻辑可重写改方法 + } + + } diff --git a/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java b/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java index c2e540a8be..4fcbdeffd9 100644 --- a/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java @@ -7,6 +7,7 @@ import io.metersphere.dto.IssueTemplateDao; import io.metersphere.dto.UserDTO; import io.metersphere.track.dto.DemandDTO; import io.metersphere.track.issue.domain.PlatformUser; +import io.metersphere.track.request.testcase.EditTestCaseRequest; import io.metersphere.track.request.testcase.IssuesRequest; import io.metersphere.track.request.testcase.IssuesUpdateRequest; @@ -85,4 +86,17 @@ public interface IssuesPlatform { * @return Boolean */ Boolean checkProjectExist(String relateId); + + /** + * 更新缺陷关联关系 + * @param request + */ + void removeIssueParentLink(IssuesUpdateRequest request); + + /** + * 更新需求与缺陷关联关系 + * + * @param testCase + */ + void updateDemandIssueLink(EditTestCaseRequest testCase, Project project); } diff --git a/backend/src/main/java/io/metersphere/track/issue/domain/azure/AzureDevopsWorkItemsBatchResponse.java b/backend/src/main/java/io/metersphere/track/issue/domain/azure/AzureDevopsWorkItemsBatchResponse.java index f1ed149436..0041c019ea 100644 --- a/backend/src/main/java/io/metersphere/track/issue/domain/azure/AzureDevopsWorkItemsBatchResponse.java +++ b/backend/src/main/java/io/metersphere/track/issue/domain/azure/AzureDevopsWorkItemsBatchResponse.java @@ -31,6 +31,16 @@ public class AzureDevopsWorkItemsBatchResponse { private String systemWorkItemType; @JSONField(name = "System.Title") private String systemTitle; + @JSONField(name = "System.State") + private String state; + @JSONField(name = "System.Description") + private String description; + @JSONField(name = "System.AssignedTo") + private String assignedTo; + @JSONField(name = "System.ChangedBy") + private String changedBy; + @JSONField(name = "System.CreatedBy") + private String createdBy; } } } diff --git a/backend/src/main/java/io/metersphere/track/request/testcase/IssuesUpdateRequest.java b/backend/src/main/java/io/metersphere/track/request/testcase/IssuesUpdateRequest.java index c31333e0c4..02b54bf38b 100644 --- a/backend/src/main/java/io/metersphere/track/request/testcase/IssuesUpdateRequest.java +++ b/backend/src/main/java/io/metersphere/track/request/testcase/IssuesUpdateRequest.java @@ -30,4 +30,8 @@ public class IssuesUpdateRequest extends IssuesWithBLOBs { private List deleteResourceIds; private Boolean isPlanEdit = false; private String refId; + /** + * azure devops bug同步fields + */ + private String devopsFields; } 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 3b10effef4..16012757cc 100644 --- a/backend/src/main/java/io/metersphere/track/service/IssuesService.java +++ b/backend/src/main/java/io/metersphere/track/service/IssuesService.java @@ -288,6 +288,16 @@ public class IssuesService { testCaseIssuesMapper.deleteByExample(example); testCaseIssueService.updateIssuesCount(caseResourceId); } else { + IssuesUpdateRequest updateRequest = new IssuesUpdateRequest(); + updateRequest.setId(request.getId()); + updateRequest.setResourceId(request.getCaseResourceId()); + updateRequest.setProjectId(request.getProjectId()); + updateRequest.setWorkspaceId(request.getWorkspaceId()); + List platformList = getUpdatePlatforms(updateRequest); + platformList.forEach(platform -> { + platform.removeIssueParentLink(updateRequest); + }); + extIssuesMapper.deleteIssues(id, caseResourceId); TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample(); testPlanTestCaseExample.createCriteria().andCaseIdEqualTo(caseResourceId); 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 872d6499bb..ee8ce5bb96 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java @@ -71,6 +71,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.BufferedInputStream; import java.io.IOException; import java.io.OutputStream; +import java.lang.reflect.Method; import java.net.URLEncoder; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; @@ -288,6 +289,10 @@ public class TestCaseService { if (StringUtils.isNotBlank(testCase.getVersionId())) { example.getOredCriteria().get(0).andVersionIdEqualTo(testCase.getVersionId()); } + updateThirdPartyIssuesLink(testCase); + if (StringUtils.isEmpty(testCase.getDemandId())) { + testCase.setDemandId(""); + } createNewVersionOrNot(testCase, example); if (StringUtils.isNotBlank(testCase.getCustomNum()) && StringUtils.isNotBlank(testCase.getId())) { @@ -306,6 +311,22 @@ public class TestCaseService { return testCaseMapper.selectByPrimaryKey(testCase.getId()); } + /** + * 判断azure devops用例关联的需求是否发生变更,若发生变更,则重新建立需求与缺陷的关联关系 + * @param testCase + */ + private void updateThirdPartyIssuesLink(EditTestCaseRequest testCase) { + try { + if (Class.forName("io.metersphere.xpack.issue.service.XpackIssueService") != null) { + Class clazz = Class.forName("io.metersphere.xpack.issue.service.XpackIssueService"); + Method method = clazz.getMethod("updateThirdPartyIssuesLink", EditTestCaseRequest.class); + method.invoke(CommonBeanFactory.getBean("xpackIssueService"), testCase); + } + } catch (Exception exception) { + LogUtil.error("不存在XpackIssueService类"); + } + } + /** * 根据前后端 verionId 判定是编辑旧数据还是创建新版本 * diff --git a/frontend/src/business/components/track/case/components/TestCaseIssueRelate.vue b/frontend/src/business/components/track/case/components/TestCaseIssueRelate.vue index 7dacedbaaa..d0659da422 100644 --- a/frontend/src/business/components/track/case/components/TestCaseIssueRelate.vue +++ b/frontend/src/business/components/track/case/components/TestCaseIssueRelate.vue @@ -111,6 +111,7 @@ import IssueRelateList from "@/business/components/track/case/components/IssueRe import {deleteIssueRelate, getIssuePartTemplateWithProject, getIssuesByCaseId} from "@/network/Issue"; import {getCustomFieldValue, getTableHeaderWithCustomFields} from "@/common/js/tableUtils"; import {LOCAL} from "@/common/js/constants"; +import {getCurrentProjectID, getCurrentWorkspaceId} from "@/common/js/utils"; export default { name: "TestCaseIssueRelate", components: {IssueRelateList, IssueDescriptionTableItem, MsTableColumn, MsTable, TestPlanIssueEdit}, @@ -148,6 +149,9 @@ export default { }, notInIds() { return this.page.data ? this.page.data.map(i => i.id) : []; + }, + projectId() { + return getCurrentProjectID(); } }, created() { @@ -236,7 +240,9 @@ export default { this.page.result = deleteIssueRelate({ id: row.id, caseResourceId: this.getCaseResourceId(), - isPlanEdit: this.planId ? true : false + isPlanEdit: this.planId ? true : false, + projectId: this.projectId, + workspaceId: getCurrentWorkspaceId() }, () => { this.getIssues(); this.$success(this.$t('commons.delete_success'));