From f42a920fcf6796f8f61277f0b568920e89443bcf Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Thu, 13 Aug 2020 17:15:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=9B=86=E6=88=90TAPD=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/service/IssuesService.java | 90 +++++++++++++++++-- .../controller/TestCaseIssuesController.java | 27 ++++++ .../io/metersphere/track/dto/IssuesDTO.java | 13 +++ .../track/request/testcase/IssuesRequest.java | 13 +++ .../view/comonents/TestPlanTestCaseEdit.vue | 70 +++++++++++---- 5 files changed, 189 insertions(+), 24 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/track/controller/TestCaseIssuesController.java create mode 100644 backend/src/main/java/io/metersphere/track/dto/IssuesDTO.java create mode 100644 backend/src/main/java/io/metersphere/track/request/testcase/IssuesRequest.java diff --git a/backend/src/main/java/io/metersphere/service/IssuesService.java b/backend/src/main/java/io/metersphere/service/IssuesService.java index 40256412d9..d8135f9222 100644 --- a/backend/src/main/java/io/metersphere/service/IssuesService.java +++ b/backend/src/main/java/io/metersphere/service/IssuesService.java @@ -2,7 +2,8 @@ package io.metersphere.service; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; -import io.metersphere.base.domain.ServiceIntegration; +import io.metersphere.base.domain.*; +import io.metersphere.base.mapper.TestCaseIssuesMapper; import io.metersphere.commons.constants.IssuesManagePlatform; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.user.SessionUser; @@ -11,20 +12,35 @@ import io.metersphere.commons.utils.RestTemplateUtils; import io.metersphere.commons.utils.SessionUtils; import io.metersphere.controller.ResultHolder; import io.metersphere.controller.request.IntegrationRequest; +import io.metersphere.track.dto.IssuesDTO; +import io.metersphere.track.request.testcase.IssuesRequest; +import io.metersphere.track.service.TestCaseService; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.apache.commons.lang3.StringUtils; import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; @Service +@Transactional(rollbackFor = Exception.class) public class IssuesService { @Resource private IntegrationService integrationService; + @Resource + private TestCaseIssuesMapper testCaseIssuesMapper; + @Resource + private ProjectService projectService; + @Resource + private TestCaseService testCaseService; public void testAuth() { @@ -33,14 +49,32 @@ public class IssuesService { System.out.println(call.getData()); } - public void addIssues() { + public void addIssues(IssuesRequest issuesRequest) { String url = "https://api.tapd.cn/bugs"; + String testCaseId = issuesRequest.getTestCaseId(); + String tapdId = getTapdProjectId(testCaseId); + + if (StringUtils.isBlank(tapdId)) { + MSException.throwException("未关联Tapd 项目ID"); + } + MultiValueMap paramMap = new LinkedMultiValueMap<>(); - paramMap.add("title", "20200812bug2"); - paramMap.add("workspace_id", "55049933"); - paramMap.add("description", "20200812 api add bug 2"); - ResultHolder call = call(url, HttpMethod.POST, paramMap); - System.out.println(call.getData()); + paramMap.add("title", issuesRequest.getTitle()); + paramMap.add("workspace_id", tapdId); + paramMap.add("description", issuesRequest.getContent()); + + ResultHolder result = call(url, HttpMethod.POST, paramMap); + + String listJson = JSON.toJSONString(result.getData()); + JSONObject jsonObject = JSONObject.parseObject(listJson); + String issuesId = jsonObject.getObject("Bug", IssuesDTO.class).getId(); + + // 用例与第三方缺陷平台中的缺陷关联 + TestCaseIssues issues = new TestCaseIssues(); + issues.setId(UUID.randomUUID().toString()); + issues.setIssuesId(issuesId); + issues.setTestCaseId(testCaseId); + testCaseIssuesMapper.insert(issues); } private ResultHolder call(String url) { @@ -98,4 +132,46 @@ public class IssuesService { headers.add("Authorization", "Basic " + authKey); return headers; } + + public IssuesDTO getTapdIssues(String projectId, String issuesId) { + String url = "https://api.tapd.cn/bugs?workspace_id=" + projectId + "&id=" + issuesId; + ResultHolder call = call(url); + String listJson = JSON.toJSONString(call.getData()); + if (StringUtils.equals(Boolean.FALSE.toString(), listJson)) { + return new IssuesDTO(); + } + JSONObject jsonObject = JSONObject.parseObject(listJson); + return jsonObject.getObject("Bug", IssuesDTO.class); + } + + public List getIssues(String caseId) { + List list = new ArrayList<>(); + String tapdId = getTapdProjectId(caseId); + + TestCaseIssuesExample example = new TestCaseIssuesExample(); + example.createCriteria().andTestCaseIdEqualTo(caseId); + + List issues = testCaseIssuesMapper.selectByExample(example); + List issuesIds = issues.stream().map(issue -> issue.getIssuesId()).collect(Collectors.toList()); + issuesIds.forEach(issuesId -> { + IssuesDTO dto = getTapdIssues(tapdId, issuesId); + if (StringUtils.isBlank(dto.getId())) { + // 缺陷不存在,解除用例和缺陷的关联 + TestCaseIssuesExample issuesExample = new TestCaseIssuesExample(); + issuesExample.createCriteria() + .andTestCaseIdEqualTo(caseId) + .andIssuesIdEqualTo(issuesId); + testCaseIssuesMapper.deleteByExample(issuesExample); + } else { + list.add(dto); + } + }); + return list; + } + + public String getTapdProjectId(String testCaseId) { + TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId); + Project project = projectService.getProjectById(testCase.getProjectId()); + return project.getTapdId(); + } } diff --git a/backend/src/main/java/io/metersphere/track/controller/TestCaseIssuesController.java b/backend/src/main/java/io/metersphere/track/controller/TestCaseIssuesController.java new file mode 100644 index 0000000000..f832b05940 --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/controller/TestCaseIssuesController.java @@ -0,0 +1,27 @@ +package io.metersphere.track.controller; + +import io.metersphere.service.IssuesService; +import io.metersphere.track.dto.IssuesDTO; +import io.metersphere.track.request.testcase.IssuesRequest; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +@RequestMapping("issues") +@RestController +public class TestCaseIssuesController { + + @Resource + private IssuesService issuesService; + + @PostMapping("/add") + public void addIssues(@RequestBody IssuesRequest issuesRequest) { + issuesService.addIssues(issuesRequest); + } + + @GetMapping("/get/{id}") + public List getIssues(@PathVariable String id) { + return issuesService.getIssues(id); + } +} diff --git a/backend/src/main/java/io/metersphere/track/dto/IssuesDTO.java b/backend/src/main/java/io/metersphere/track/dto/IssuesDTO.java new file mode 100644 index 0000000000..c9dc0a985b --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/dto/IssuesDTO.java @@ -0,0 +1,13 @@ +package io.metersphere.track.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class IssuesDTO { + private String id; + private String title; + private String status; + private String description; +} diff --git a/backend/src/main/java/io/metersphere/track/request/testcase/IssuesRequest.java b/backend/src/main/java/io/metersphere/track/request/testcase/IssuesRequest.java new file mode 100644 index 0000000000..e5658e3684 --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/request/testcase/IssuesRequest.java @@ -0,0 +1,13 @@ +package io.metersphere.track.request.testcase; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class IssuesRequest { + private String title; + private String content; + private String projectId; + private String testCaseId; +} diff --git a/frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseEdit.vue b/frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseEdit.vue index 78c827baaa..4603afece3 100644 --- a/frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseEdit.vue +++ b/frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseEdit.vue @@ -172,11 +172,11 @@ - + @@ -188,7 +188,7 @@ - + - {{$t('commons.save')}} - {{$t('commons.cancel')}} + {{$t('commons.save')}} + {{$t('commons.cancel')}} + + + + + + + + + + + @@ -240,6 +251,7 @@ import PerformanceTestDetail from "./test/PerformanceTestDetail"; import PerformanceTestResult from "./test/PerformanceTestResult"; import {listenGoBack, removeGoBackListener} from "../../../../../../common/js/utils"; + import {CURRENT_PROJECT} from "../../../../../../common/js/constants"; export default { name: "TestPlanTestCaseEdit", @@ -256,7 +268,9 @@ showDialog: false, testCase: {}, index: 0, + issuesSwitch: false, testCases: [], + issues: [], editor: ClassicEditor, editorConfig: { // 'increaseIndent','decreaseIndent' @@ -365,6 +379,7 @@ this.activeTab = 'detail'; listenGoBack(this.handleClose); this.initData(testCase); + this.getIssues(testCase.caseId); }, initTest() { this.$nextTick(() => { @@ -417,18 +432,18 @@ } }, issuesChange() { - if (this.testCase.issues.hasIssues) { - let desc = this.addPLabel('[' + this.$t('test_track.plan_view.operate_step') + ']'); - let result = this.addPLabel('[' + this.$t('test_track.case.expected_results') + ']'); - let executeResult = this.addPLabel('[' + this.$t('test_track.plan_view.actual_result') + ']'); - this.testCase.steps.forEach(step => { - let stepPrefix = this.$t('test_track.plan_view.step') + step.num + ':'; - desc += this.addPLabel(stepPrefix + (step.desc == undefined ? '' : step.desc)); - result += this.addPLabel(stepPrefix + (step.result == undefined ? '' : step.result)); - executeResult += this.addPLabel(stepPrefix + (step.executeResult == undefined ? '' : step.executeResult)); - }); - this.testCase.issues.content = desc + this.addPLabel('') + result + this.addPLabel('') + executeResult + this.addPLabel(''); - } + // if (this.testCase.issues.hasIssues) { + // let desc = this.addPLabel('[' + this.$t('test_track.plan_view.operate_step') + ']'); + // let result = this.addPLabel('[' + this.$t('test_track.case.expected_results') + ']'); + // let executeResult = this.addPLabel('[' + this.$t('test_track.plan_view.actual_result') + ']'); + // this.testCase.steps.forEach(step => { + // let stepPrefix = this.$t('test_track.plan_view.step') + step.num + ':'; + // desc += this.addPLabel(stepPrefix + (step.desc == undefined ? '' : step.desc)); + // result += this.addPLabel(stepPrefix + (step.result == undefined ? '' : step.result)); + // executeResult += this.addPLabel(stepPrefix + (step.executeResult == undefined ? '' : step.executeResult)); + // }); + // this.testCase.issues.content = desc + this.addPLabel('') + result + this.addPLabel('') + executeResult + this.addPLabel(''); + // } }, addPLabel(str) { return "

" + str + "

"; @@ -443,6 +458,27 @@ }).length > 0; } + }, + saveIssues() { + if (!this.testCase.issues.title || !this.testCase.issues.content) { + this.$warning("标题和描述必填"); + return; + } + let param = {}; + param.title = this.testCase.issues.title; + param.content = this.testCase.issues.content; + param.testCaseId = this.testCase.caseId; + this.result = this.$post("/issues/add", param, () => { + this.$success(this.$t('commons.save_success')); + this.getIssues(param.testCaseId); + }) + }, + getIssues(caseId) { + this.result = this.$get("/issues/get/"+caseId,response => { + let data = response.data; + this.issues = data; + console.log(data); + }) } } }