From 782f32ce8e0f8f1722b2c9acbc8a7f358b892f23 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Tue, 13 Oct 2020 17:44:52 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):?= =?UTF-8?q?=20=E4=B8=80=E9=94=AE=E6=89=A7=E8=A1=8C=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=8E=A5=E5=8F=A3=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/controller/APITestController.java | 5 +++ .../api/service/APITestService.java | 18 +++++++- .../components/api/test/OneClickOperation.vue | 44 ++++--------------- 3 files changed, 29 insertions(+), 38 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/controller/APITestController.java b/backend/src/main/java/io/metersphere/api/controller/APITestController.java index 3eb82dddba..8df2169b88 100644 --- a/backend/src/main/java/io/metersphere/api/controller/APITestController.java +++ b/backend/src/main/java/io/metersphere/api/controller/APITestController.java @@ -73,6 +73,11 @@ public class APITestController { apiTestService.create(request, file, bodyFiles); } + @PostMapping(value = "/create/merge", consumes = {"multipart/form-data"}) + public void mergeCreate(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "selectIds") List selectIds) { + apiTestService.mergeCreate(request, file, selectIds); + } + @PostMapping(value = "/update", consumes = {"multipart/form-data"}) public void update(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "files") List bodyFiles) { checkownerService.checkApiTestOwner(request.getId()); diff --git a/backend/src/main/java/io/metersphere/api/service/APITestService.java b/backend/src/main/java/io/metersphere/api/service/APITestService.java index 44dd35677b..cc9238c205 100644 --- a/backend/src/main/java/io/metersphere/api/service/APITestService.java +++ b/backend/src/main/java/io/metersphere/api/service/APITestService.java @@ -83,15 +83,19 @@ public class APITestService { } public void create(SaveAPITestRequest request, MultipartFile file, List bodyFiles) { + List bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()); + ApiTest test = createTest(request, file); + createBodyFiles(test, bodyUploadIds, bodyFiles); + } + private ApiTest createTest(SaveAPITestRequest request, MultipartFile file) { if (file == null) { throw new IllegalArgumentException(Translator.get("file_cannot_be_null")); } checkQuota(); - List bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()); request.setBodyUploadIds(null); ApiTest test = createTest(request); - createBodyFiles(test, bodyUploadIds, bodyFiles); saveFile(test.getId(), file); + return test; } public void update(SaveAPITestRequest request, MultipartFile file, List bodyFiles) { @@ -108,6 +112,9 @@ public class APITestService { } private void createBodyFiles(ApiTest test, List bodyUploadIds, List bodyFiles) { + if (bodyUploadIds.size() <= 0) { + return; + } String dir = BODY_FILE_DIR + "/" + test.getId(); File testDir = new File(dir); if (!testDir.exists()) { @@ -436,4 +443,11 @@ public class APITestService { quotaService.checkAPITestQuota(); } } + + public void mergeCreate(SaveAPITestRequest request, MultipartFile file, List selectIds) { + ApiTest test = createTest(request, file); + selectIds.forEach(sourceId -> { + copyBodyFiles(test.getId(), sourceId); + }); + } } diff --git a/frontend/src/business/components/api/test/OneClickOperation.vue b/frontend/src/business/components/api/test/OneClickOperation.vue index 579dea0d8c..d2f5ecf3f8 100644 --- a/frontend/src/business/components/api/test/OneClickOperation.vue +++ b/frontend/src/business/components/api/test/OneClickOperation.vue @@ -156,37 +156,11 @@ }, save(callback) { this.change = false; - let url = "/api/create"; - let bodyFiles = this.getBodyUploadFiles(); - this.result = this.$request(this.getOptions(url, bodyFiles), () => { + let url = "/api/create/merge"; + this.result = this.$request(this.getOptions(url, this.selectIds), () => { if (callback) callback(); }); }, - getBodyUploadFiles() { - let bodyUploadFiles = []; - this.test.bodyUploadIds = []; - this.test.scenarioDefinition.forEach(scenario => { - scenario.requests.forEach(request => { - if (request.body) { - request.body.kvs.forEach(param => { - if (param.files) { - param.files.forEach(item => { - if (item.file) { - let fileId = getUUID().substring(0, 8); - item.name = item.file.name; - item.id = fileId; - this.test.bodyUploadIds.push(fileId); - bodyUploadFiles.push(item.file); - // item.file = undefined; - } - }); - } - }); - } - }); - }); - return bodyUploadFiles; - }, runTest() { this.result = this.$post("/api/run", {id: this.test.id, triggerMode: 'MANUAL'}, (response) => { this.$success(this.$t('api_test.running')); @@ -196,16 +170,14 @@ this.test = "" }); }, - getOptions(url, bodyFiles) { + getOptions(url, selectIds) { let formData = new FormData(); - if (bodyFiles) { - bodyFiles.forEach(f => { - formData.append("files", f); - }) - } - let requestJson = JSON.stringify(this.test); - formData.append('request', new Blob([requestJson], { + formData.append('request', new Blob([JSON.stringify(this.test)], { + type: "application/json" + })); + + formData.append('selectIds', new Blob([JSON.stringify(Array.from(selectIds))], { type: "application/json" })); From 7b69e810ef2ff6259fb54db1afae849aa0319673 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Tue, 13 Oct 2020 17:55:08 +0800 Subject: [PATCH 2/3] =?UTF-8?q?refactor(=E6=B5=8B=E8=AF=95=E8=B7=9F?= =?UTF-8?q?=E8=B8=AA):=20=E9=87=8D=E6=9E=84=E7=BC=BA=E9=99=B7=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E9=83=A8=E5=88=86=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/TestCaseIssuesController.java | 4 +- .../track/issue/AbstractIssuePlatform.java | 77 +++ .../metersphere/track/issue/IssueFactory.java | 32 ++ .../track/issue/IssuesPlatform.java | 39 ++ .../io/metersphere/track/issue/JiraIssue.java | 264 ++++++++++ .../metersphere/track/issue/LocalIssue.java | 72 +++ .../metersphere/track/issue/PlatformUser.java | 12 + .../io/metersphere/track/issue/TapdIssue.java | 200 ++++++++ .../track/service/IssuesService.java | 469 ++---------------- 9 files changed, 729 insertions(+), 440 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java create mode 100644 backend/src/main/java/io/metersphere/track/issue/IssueFactory.java create mode 100644 backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java create mode 100644 backend/src/main/java/io/metersphere/track/issue/JiraIssue.java create mode 100644 backend/src/main/java/io/metersphere/track/issue/LocalIssue.java create mode 100644 backend/src/main/java/io/metersphere/track/issue/PlatformUser.java create mode 100644 backend/src/main/java/io/metersphere/track/issue/TapdIssue.java diff --git a/backend/src/main/java/io/metersphere/track/controller/TestCaseIssuesController.java b/backend/src/main/java/io/metersphere/track/controller/TestCaseIssuesController.java index c276a6fcef..18357447da 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestCaseIssuesController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestCaseIssuesController.java @@ -1,7 +1,7 @@ package io.metersphere.track.controller; import io.metersphere.base.domain.Issues; -import io.metersphere.track.domain.TapdUser; +import io.metersphere.track.issue.PlatformUser; import io.metersphere.track.service.IssuesService; import io.metersphere.track.request.testcase.IssuesRequest; import org.springframework.web.bind.annotation.*; @@ -42,7 +42,7 @@ public class TestCaseIssuesController { } @GetMapping("/tapd/user/{caseId}") - public List getTapdUsers(@PathVariable String caseId) { + public List getPlatformUsers(@PathVariable String caseId) { return issuesService.getTapdProjectUsers(caseId); } diff --git a/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java b/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java new file mode 100644 index 0000000000..a5e8dd6bf1 --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java @@ -0,0 +1,77 @@ +package io.metersphere.track.issue; + +import io.metersphere.base.domain.ServiceIntegration; +import io.metersphere.base.mapper.IssuesMapper; +import io.metersphere.base.mapper.TestCaseIssuesMapper; +import io.metersphere.base.mapper.ext.ExtIssuesMapper; +import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.user.SessionUser; +import io.metersphere.commons.utils.CommonBeanFactory; +import io.metersphere.commons.utils.EncryptUtils; +import io.metersphere.commons.utils.SessionUtils; +import io.metersphere.controller.request.IntegrationRequest; +import io.metersphere.service.IntegrationService; +import io.metersphere.service.ProjectService; +import io.metersphere.track.request.testcase.IssuesRequest; +import io.metersphere.track.service.TestCaseService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpHeaders; + +public abstract class AbstractIssuePlatform implements IssuesPlatform { + + protected IntegrationService integrationService; + protected TestCaseIssuesMapper testCaseIssuesMapper; + protected ProjectService projectService; + protected TestCaseService testCaseService; + protected IssuesMapper issuesMapper; + protected ExtIssuesMapper extIssuesMapper; + + protected String testCaseId; + + public AbstractIssuePlatform(IssuesRequest issuesRequest) { + this.integrationService = CommonBeanFactory.getBean(IntegrationService.class); + this.testCaseIssuesMapper = CommonBeanFactory.getBean(TestCaseIssuesMapper.class); + this.projectService = CommonBeanFactory.getBean(ProjectService.class); + this.testCaseService = CommonBeanFactory.getBean(TestCaseService.class); + this.issuesMapper = CommonBeanFactory.getBean(IssuesMapper.class); + this.extIssuesMapper = CommonBeanFactory.getBean(ExtIssuesMapper.class); + this.testCaseId = issuesRequest.getTestCaseId(); + } + + protected String getPlatformConfig(String platform) { + SessionUser user = SessionUtils.getUser(); + String orgId = user.getLastOrganizationId(); + + IntegrationRequest request = new IntegrationRequest(); + if (StringUtils.isBlank(orgId)) { + MSException.throwException("organization id is null"); + } + request.setOrgId(orgId); + request.setPlatform(platform); + + ServiceIntegration integration = integrationService.get(request); + return integration.getConfiguration(); + } + + protected HttpHeaders auth(String apiUser, String password) { + String authKey = EncryptUtils.base64Encoding(apiUser + ":" + password); + HttpHeaders headers = new HttpHeaders(); + headers.add("Authorization", "Basic " + authKey); + return headers; + } + + /** + * 获取平台与项目相关的属性 + * @return + */ + abstract String getProjectId(); + + protected boolean isIntegratedPlatform(String orgId, String platform) { + IntegrationRequest request = new IntegrationRequest(); + request.setPlatform(platform); + request.setOrgId(orgId); + ServiceIntegration integration = integrationService.get(request); + return StringUtils.isNotBlank(integration.getId()); + } + +} diff --git a/backend/src/main/java/io/metersphere/track/issue/IssueFactory.java b/backend/src/main/java/io/metersphere/track/issue/IssueFactory.java new file mode 100644 index 0000000000..3592094890 --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/issue/IssueFactory.java @@ -0,0 +1,32 @@ +package io.metersphere.track.issue; + +import io.metersphere.commons.constants.IssuesManagePlatform; +import io.metersphere.track.request.testcase.IssuesRequest; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +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); + } else if (StringUtils.equals(IssuesManagePlatform.Jira.toString(), platform)) { + return new JiraIssue(addIssueRequest); + } else if (StringUtils.equals("LOCAL", platform)) { + return new LocalIssue(addIssueRequest); + } + return null; + } + + public static List createPlatforms(List types, IssuesRequest addIssueRequest) { + List platforms = new ArrayList<>(); + types.forEach(type -> { + AbstractIssuePlatform abstractIssuePlatform = createPlatform(type, addIssueRequest); + if (abstractIssuePlatform != null) { + platforms.add(abstractIssuePlatform); + } + }); + return platforms; + } +} diff --git a/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java b/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java new file mode 100644 index 0000000000..a80d225733 --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java @@ -0,0 +1,39 @@ +package io.metersphere.track.issue; + +import io.metersphere.base.domain.Issues; +import io.metersphere.track.request.testcase.IssuesRequest; + +import java.util.List; + +public interface IssuesPlatform { + + /** + * 获取平台相关联的缺陷 + * @return + */ + List getIssue(); + + /** + * 添加缺陷到缺陷平台 + * @param issuesRequest + */ + void addIssue(IssuesRequest issuesRequest); + + /** + * 删除缺陷平台缺陷 + * @param id + */ + void deleteIssue(String id); + + /** + * 测试缺陷平台连通性 + * @param + */ + void testAuth(); + + /** + * 获取缺陷平台项目下的相关人员 + * @return + */ + List getPlatformUser(); +} diff --git a/backend/src/main/java/io/metersphere/track/issue/JiraIssue.java b/backend/src/main/java/io/metersphere/track/issue/JiraIssue.java new file mode 100644 index 0000000000..40a1277f90 --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/issue/JiraIssue.java @@ -0,0 +1,264 @@ +package io.metersphere.track.issue; + +import com.alibaba.fastjson.JSON; +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.EncryptUtils; +import io.metersphere.commons.utils.LogUtil; +import io.metersphere.track.request.testcase.IssuesRequest; +import org.apache.commons.lang3.StringUtils; +import org.commonmark.node.Node; +import org.commonmark.parser.Parser; +import org.commonmark.renderer.html.HtmlRenderer; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.safety.Whitelist; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +public class JiraIssue extends AbstractIssuePlatform { + + + public JiraIssue(IssuesRequest issuesRequest) { + super(issuesRequest); + } + + @Override + public List getIssue() { + List list = new ArrayList<>(); + + String config = getPlatformConfig(IssuesManagePlatform.Jira.toString()); + JSONObject object = JSON.parseObject(config); + + if (object == null) { + MSException.throwException("tapd config is null"); + } + + String account = object.getString("account"); + String password = object.getString("password"); + String url = object.getString("url"); + HttpHeaders headers = auth(account, password); + + TestCaseIssuesExample example = new TestCaseIssuesExample(); + example.createCriteria().andTestCaseIdEqualTo(testCaseId); + + List issues = extIssuesMapper.getIssues(testCaseId, IssuesManagePlatform.Jira.toString()); + + List issuesIds = issues.stream().map(Issues::getId).collect(Collectors.toList()); + issuesIds.forEach(issuesId -> { + Issues dto = getJiraIssues(headers, url, issuesId); + if (StringUtils.isBlank(dto.getId())) { + // 缺陷不存在,解除用例和缺陷的关联 + TestCaseIssuesExample issuesExample = new TestCaseIssuesExample(); + issuesExample.createCriteria() + .andTestCaseIdEqualTo(testCaseId) + .andIssuesIdEqualTo(issuesId); + testCaseIssuesMapper.deleteByExample(issuesExample); + issuesMapper.deleteByPrimaryKey(issuesId); + } else { + // 缺陷状态为 完成,则不显示 + if (!StringUtils.equals("done", dto.getStatus())) { + list.add(dto); + } + } + }); + return list; + } + + @Override + public void addIssue(IssuesRequest issuesRequest) { + String config = getPlatformConfig(IssuesManagePlatform.Jira.toString()); + JSONObject object = JSON.parseObject(config); + + if (object == null) { + MSException.throwException("jira config is null"); + } + + String account = object.getString("account"); + String password = object.getString("password"); + String url = object.getString("url"); + String issuetype = object.getString("issuetype"); + if (StringUtils.isBlank(issuetype)) { + MSException.throwException("Jira 问题类型为空"); + } + String auth = EncryptUtils.base64Encoding(account + ":" + password); + + String testCaseId = issuesRequest.getTestCaseId(); + String jiraKey = getProjectId(); + + + if (StringUtils.isBlank(jiraKey)) { + MSException.throwException("未关联Jira 项目Key"); + } + + String content = issuesRequest.getContent(); + + Document document = Jsoup.parse(content); + document.outputSettings(new Document.OutputSettings().prettyPrint(false)); + document.select("br").append("\\n"); + document.select("p").prepend("\\n\\n"); + String s = document.html().replaceAll("\\\\n", "\n"); + String desc = Jsoup.clean(s, "", Whitelist.none(), new Document.OutputSettings().prettyPrint(false)); + desc = desc.replace(" ", ""); + + String json = "{\n" + + " \"fields\":{\n" + + " \"project\":{\n" + + " \"key\":\"" + jiraKey + "\"\n" + + " },\n" + + " \"summary\":\"" + issuesRequest.getTitle() + "\",\n" + + " \"description\": " + JSON.toJSONString(desc) + ",\n" + + " \"issuetype\":{\n" + + " \"name\":\"" + issuetype + "\"\n" + + " }\n" + + " }\n" + + "}"; + + String result = addJiraIssue(url, auth, json); + + JSONObject jsonObject = JSON.parseObject(result); + String id = jsonObject.getString("key"); + + // 用例与第三方缺陷平台中的缺陷关联 + 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.Jira.toString()); + issuesMapper.insert(issues); + } + + private String addJiraIssue(String url, String auth, String json) { + HttpHeaders requestHeaders = new HttpHeaders(); + requestHeaders.add("Authorization", "Basic " + auth); + requestHeaders.setContentType(org.springframework.http.MediaType.APPLICATION_JSON); + //HttpEntity + HttpEntity requestEntity = new HttpEntity<>(json, requestHeaders); + RestTemplate restTemplate = new RestTemplate(); + //post + ResponseEntity responseEntity = null; + try { + responseEntity = restTemplate.exchange(url + "/rest/api/2/issue", HttpMethod.POST, requestEntity, String.class); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + MSException.throwException("调用Jira接口创建缺陷失败"); + } + + return responseEntity.getBody(); + } + + @Override + public void deleteIssue(String id) { + + } + + @Override + public void testAuth() { + try { + String config = getPlatformConfig(IssuesManagePlatform.Jira.toString()); + JSONObject object = JSON.parseObject(config); + String account = object.getString("account"); + String password = object.getString("password"); + String url = object.getString("url"); + HttpHeaders headers = auth(account, password); + HttpEntity requestEntity = new HttpEntity<>(headers); + RestTemplate restTemplate = new RestTemplate(); + restTemplate.exchange(url + "rest/api/2/issue/createmeta", HttpMethod.GET, requestEntity, String.class); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + MSException.throwException("验证失败!"); + } + } + + @Override + public List getPlatformUser() { + return null; + } + + @Override + String getProjectId() { + TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId); + Project project = projectService.getProjectById(testCase.getProjectId()); + return project.getJiraKey(); + } + + private Issues getJiraIssues(HttpHeaders headers, String url, String issuesId) { + HttpEntity requestEntity = new HttpEntity<>(headers); + RestTemplate restTemplate = new RestTemplate(); + //post + ResponseEntity responseEntity; + Issues issues = new Issues(); + try { + responseEntity = restTemplate.exchange(url + "/rest/api/2/issue/" + issuesId, HttpMethod.GET, requestEntity, String.class); + String body = responseEntity.getBody(); + + JSONObject obj = JSONObject.parseObject(body); + LogUtil.info(obj); + + String lastmodify = ""; + String status = ""; + + JSONObject fields = (JSONObject) obj.get("fields"); + JSONObject statusObj = (JSONObject) fields.get("status"); + JSONObject assignee = (JSONObject) fields.get("assignee"); + + if (statusObj != null) { + JSONObject statusCategory = (JSONObject) statusObj.get("statusCategory"); + status = statusCategory.getString("key"); + } + + String id = obj.getString("key"); + String title = fields.getString("summary"); + String description = fields.getString("description"); + + Parser parser = Parser.builder().build(); + Node document = parser.parse(description); + HtmlRenderer renderer = HtmlRenderer.builder().build(); + description = renderer.render(document); + + Long createTime = fields.getLong("created"); + + if (assignee != null) { + lastmodify = assignee.getString("displayName"); + } + + issues.setId(id); + issues.setTitle(title); + issues.setCreateTime(createTime); + issues.setLastmodify(lastmodify); + issues.setDescription(description); + issues.setStatus(status); + issues.setPlatform(IssuesManagePlatform.Jira.toString()); + } catch (HttpClientErrorException.NotFound e) { + LogUtil.error(e.getStackTrace(), e); + return new Issues(); + } catch (HttpClientErrorException.Unauthorized e) { + LogUtil.error(e.getStackTrace(), e); + MSException.throwException("获取Jira缺陷失败,检查Jira配置信息"); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + MSException.throwException("调用Jira接口获取缺陷失败"); + } + + return issues; + + } + +} diff --git a/backend/src/main/java/io/metersphere/track/issue/LocalIssue.java b/backend/src/main/java/io/metersphere/track/issue/LocalIssue.java new file mode 100644 index 0000000000..b75946b726 --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/issue/LocalIssue.java @@ -0,0 +1,72 @@ +package io.metersphere.track.issue; + +import io.metersphere.base.domain.Issues; +import io.metersphere.base.domain.TestCaseIssues; +import io.metersphere.commons.constants.IssuesManagePlatform; +import io.metersphere.commons.user.SessionUser; +import io.metersphere.commons.utils.SessionUtils; +import io.metersphere.track.request.testcase.IssuesRequest; + +import java.util.List; +import java.util.UUID; + +public class LocalIssue extends AbstractIssuePlatform { + + public LocalIssue(IssuesRequest issuesRequest) { + super(issuesRequest); + } + + @Override + public List getIssue() { + return extIssuesMapper.getIssues(testCaseId, IssuesManagePlatform.Local.toString()); + } + + @Override + public void addIssue(IssuesRequest issuesRequest) { + SessionUser user = SessionUtils.getUser(); + String id = UUID.randomUUID().toString(); + Issues issues = new Issues(); + issues.setId(id); + issues.setStatus("new"); + issues.setReporter(user.getId()); + issues.setTitle(issuesRequest.getTitle()); + issues.setDescription(issuesRequest.getContent()); + issues.setCreateTime(System.currentTimeMillis()); + issues.setUpdateTime(System.currentTimeMillis()); + issues.setPlatform(IssuesManagePlatform.Local.toString()); + issuesMapper.insert(issues); + + TestCaseIssues testCaseIssues = new TestCaseIssues(); + testCaseIssues.setId(UUID.randomUUID().toString()); + testCaseIssues.setIssuesId(id); + testCaseIssues.setTestCaseId(issuesRequest.getTestCaseId()); + testCaseIssuesMapper.insert(testCaseIssues); + } + + @Override + public void deleteIssue(String id) { + issuesMapper.deleteByPrimaryKey(id); + } + + @Override + public void testAuth() { + + } + + @Override + public List getPlatformUser() { + return null; + } + + @Override + String getProjectId() { + return null; + } + + public void closeIssue(String issueId) { + Issues issues = new Issues(); + issues.setId(issueId); + issues.setStatus("closed"); + issuesMapper.updateByPrimaryKeySelective(issues); + } +} diff --git a/backend/src/main/java/io/metersphere/track/issue/PlatformUser.java b/backend/src/main/java/io/metersphere/track/issue/PlatformUser.java new file mode 100644 index 0000000000..ac913343ae --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/issue/PlatformUser.java @@ -0,0 +1,12 @@ +package io.metersphere.track.issue; + +import lombok.Data; + +import java.util.List; + +@Data +public class PlatformUser { + private List roleId; + private String name; + private String user; +} diff --git a/backend/src/main/java/io/metersphere/track/issue/TapdIssue.java b/backend/src/main/java/io/metersphere/track/issue/TapdIssue.java new file mode 100644 index 0000000000..3df46f4291 --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/issue/TapdIssue.java @@ -0,0 +1,200 @@ +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.commons.utils.RestTemplateUtils; +import io.metersphere.commons.utils.SessionUtils; +import io.metersphere.controller.ResultHolder; +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.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +public class TapdIssue extends AbstractIssuePlatform { + + + public TapdIssue(IssuesRequest issueRequest) { + super(issueRequest); + } + + @Override + public List getIssue() { + List list = new ArrayList<>(); + String tapdId = getProjectId(); + + TestCaseIssuesExample example = new TestCaseIssuesExample(); + example.createCriteria().andTestCaseIdEqualTo(testCaseId); + + List issues = extIssuesMapper.getIssues(testCaseId, IssuesManagePlatform.Tapd.toString()); + + List issuesIds = issues.stream().map(Issues::getId).collect(Collectors.toList()); + issuesIds.forEach(issuesId -> { + Issues dto = getTapdIssues(tapdId, 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.Tapd.toString()); + // 缺陷状态为 关闭,则不显示 + if (!StringUtils.equals("closed", dto.getStatus())) { + list.add(dto); + } + } + }); + return list; + } + + private Issues 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 Issues(); + } + JSONObject jsonObject = JSONObject.parseObject(listJson); + JSONObject bug = jsonObject.getJSONObject("Bug"); + Long created = bug.getLong("created"); + Issues issues = jsonObject.getObject("Bug", Issues.class); + issues.setCreateTime(created); + return issues; + } + + @Override + public void addIssue(IssuesRequest issuesRequest) { + String url = "https://api.tapd.cn/bugs"; + String testCaseId = issuesRequest.getTestCaseId(); + String tapdId = getProjectId(); + + if (StringUtils.isBlank(tapdId)) { + MSException.throwException("未关联Tapd 项目ID"); + } + + List PlatformUsers = issuesRequest.getTapdUsers(); + String usersStr = String.join(";", PlatformUsers); + + String username = SessionUtils.getUser().getName(); + + MultiValueMap paramMap = new LinkedMultiValueMap<>(); + paramMap.add("title", issuesRequest.getTitle()); + paramMap.add("workspace_id", tapdId); + paramMap.add("description", issuesRequest.getContent()); + paramMap.add("reporter", username); + paramMap.add("current_owner", usersStr); + + ResultHolder result = call(url, HttpMethod.POST, paramMap); + + String listJson = JSON.toJSONString(result.getData()); + JSONObject jsonObject = JSONObject.parseObject(listJson); + String issuesId = jsonObject.getObject("Bug", Issues.class).getId(); + + // 用例与第三方缺陷平台中的缺陷关联 + TestCaseIssues testCaseIssues = new TestCaseIssues(); + testCaseIssues.setId(UUID.randomUUID().toString()); + testCaseIssues.setIssuesId(issuesId); + testCaseIssues.setTestCaseId(testCaseId); + testCaseIssuesMapper.insert(testCaseIssues); + + // 插入缺陷表 + Issues issues = new Issues(); + issues.setId(issuesId); + issues.setPlatform(IssuesManagePlatform.Tapd.toString()); + issuesMapper.insert(issues); + } + + @Override + public void deleteIssue(String id) {} + + @Override + public void testAuth() { + try { + String tapdConfig = getPlatformConfig(IssuesManagePlatform.Tapd.toString()); + JSONObject object = JSON.parseObject(tapdConfig); + String account = object.getString("account"); + String password = object.getString("password"); + HttpHeaders headers = auth(account, password); + HttpEntity requestEntity = new HttpEntity<>(headers); + RestTemplate restTemplate = new RestTemplate(); + restTemplate.exchange("https://api.tapd.cn/quickstart/testauth", HttpMethod.GET, requestEntity, String.class); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + MSException.throwException("验证失败!"); + } + } + + @Override + public List getPlatformUser() { + List users = new ArrayList<>(); + String projectId = getProjectId(); + String url = "https://api.tapd.cn/workspaces/users?workspace_id=" + projectId; + ResultHolder call = call(url); + String listJson = JSON.toJSONString(call.getData()); + JSONArray jsonArray = JSON.parseArray(listJson); + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject o = jsonArray.getJSONObject(i); + PlatformUser user = o.getObject("UserWorkspace", PlatformUser.class); + users.add(user); + } + return users; + } + + @Override + String getProjectId() { + TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId); + Project project = projectService.getProjectById(testCase.getProjectId()); + return project.getTapdId(); + } + + private ResultHolder call(String url) { + return call(url, HttpMethod.GET, null); + } + + private ResultHolder call(String url, HttpMethod httpMethod, Object params) { + String responseJson; + + String config = getPlatformConfig(IssuesManagePlatform.Tapd.toString()); + JSONObject object = JSON.parseObject(config); + + if (object == null) { + MSException.throwException("tapd config is null"); + } + + String account = object.getString("account"); + String password = object.getString("password"); + + HttpHeaders header = auth(account, password); + + if (httpMethod.equals(HttpMethod.GET)) { + responseJson = RestTemplateUtils.get(url, header); + } else { + responseJson = RestTemplateUtils.post(url, params, header); + } + + ResultHolder result = JSON.parseObject(responseJson, ResultHolder.class); + + if (!result.isSuccess()) { + MSException.throwException(result.getMessage()); + } + return JSON.parseObject(responseJson, ResultHolder.class); + + } + +} 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 f07e697471..8030b09b74 100644 --- a/backend/src/main/java/io/metersphere/track/service/IssuesService.java +++ b/backend/src/main/java/io/metersphere/track/service/IssuesService.java @@ -1,45 +1,23 @@ package io.metersphere.track.service; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; import io.metersphere.base.domain.*; import io.metersphere.base.mapper.IssuesMapper; -import io.metersphere.base.mapper.TestCaseIssuesMapper; -import io.metersphere.base.mapper.ext.ExtIssuesMapper; import io.metersphere.commons.constants.IssuesManagePlatform; -import io.metersphere.commons.exception.MSException; import io.metersphere.commons.user.SessionUser; -import io.metersphere.commons.utils.EncryptUtils; -import io.metersphere.commons.utils.LogUtil; -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.service.IntegrationService; import io.metersphere.service.ProjectService; -import io.metersphere.track.domain.TapdUser; +import io.metersphere.track.issue.AbstractIssuePlatform; +import io.metersphere.track.issue.IssueFactory; +import io.metersphere.track.issue.PlatformUser; import io.metersphere.track.request.testcase.IssuesRequest; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.safety.Whitelist; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; 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 org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RestTemplate; -import org.commonmark.node.*; -import org.commonmark.parser.Parser; -import org.commonmark.renderer.html.HtmlRenderer; + import javax.annotation.Resource; import java.util.*; -import java.util.stream.Collectors; @Service @Transactional(rollbackFor = Exception.class) @@ -48,108 +26,16 @@ public class IssuesService { @Resource private IntegrationService integrationService; @Resource - private TestCaseIssuesMapper testCaseIssuesMapper; - @Resource private ProjectService projectService; @Resource private TestCaseService testCaseService; @Resource private IssuesMapper issuesMapper; - @Resource - private ExtIssuesMapper extIssuesMapper; public void testAuth(String platform) { - if (StringUtils.equals(platform, IssuesManagePlatform.Tapd.toString())) { - - try { - String tapdConfig = platformConfig(IssuesManagePlatform.Tapd.toString()); - JSONObject object = JSON.parseObject(tapdConfig); - String account = object.getString("account"); - String password = object.getString("password"); - HttpHeaders headers = auth(account, password); - HttpEntity requestEntity = new HttpEntity<>(headers); - RestTemplate restTemplate = new RestTemplate(); - restTemplate.exchange("https://api.tapd.cn/quickstart/testauth", HttpMethod.GET, requestEntity, String.class); - } catch (Exception e) { - LogUtil.error(e.getMessage(), e); - MSException.throwException("验证失败!"); - } - - } else { - - try { - String config = platformConfig(IssuesManagePlatform.Jira.toString()); - JSONObject object = JSON.parseObject(config); - String account = object.getString("account"); - String password = object.getString("password"); - String url = object.getString("url"); - HttpHeaders headers = auth(account, password); - HttpEntity requestEntity = new HttpEntity<>(headers); - RestTemplate restTemplate = new RestTemplate(); - restTemplate.exchange(url + "rest/api/2/issue/createmeta", HttpMethod.GET, requestEntity, String.class); - } catch (Exception e) { - LogUtil.error(e.getMessage(), e); - MSException.throwException("验证失败!"); - } - } - - } - - private ResultHolder call(String url) { - return call(url, HttpMethod.GET, null); - } - - private ResultHolder call(String url, HttpMethod httpMethod, Object params) { - String responseJson; - - String config = platformConfig(IssuesManagePlatform.Tapd.toString()); - JSONObject object = JSON.parseObject(config); - - if (object == null) { - MSException.throwException("tapd config is null"); - } - - String account = object.getString("account"); - String password = object.getString("password"); - - HttpHeaders header = auth(account, password); - - if (httpMethod.equals(HttpMethod.GET)) { - responseJson = RestTemplateUtils.get(url, header); - } else { - responseJson = RestTemplateUtils.post(url, params, header); - } - - ResultHolder result = JSON.parseObject(responseJson, ResultHolder.class); - - if (!result.isSuccess()) { - MSException.throwException(result.getMessage()); - } - return JSON.parseObject(responseJson, ResultHolder.class); - - } - - private String platformConfig(String platform) { - SessionUser user = SessionUtils.getUser(); - String orgId = user.getLastOrganizationId(); - - IntegrationRequest request = new IntegrationRequest(); - if (StringUtils.isBlank(orgId)) { - MSException.throwException("organization id is null"); - } - request.setOrgId(orgId); - request.setPlatform(platform); - - ServiceIntegration integration = integrationService.get(request); - return integration.getConfiguration(); - } - - private HttpHeaders auth(String apiUser, String password) { - String authKey = EncryptUtils.base64Encoding(apiUser + ":" + password); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic " + authKey); - return headers; + AbstractIssuePlatform abstractPlatform = IssueFactory.createPlatform(platform, new IssuesRequest()); + abstractPlatform.testAuth(); } public void addIssues(IssuesRequest issuesRequest) { @@ -162,247 +48,29 @@ public class IssuesService { String tapdId = getTapdProjectId(issuesRequest.getTestCaseId()); String jiraKey = getJiraProjectKey(issuesRequest.getTestCaseId()); + List platforms = new ArrayList<>(); + if (tapd) { // 是否关联了项目 if (StringUtils.isNotBlank(tapdId)) { - addTapdIssues(issuesRequest); + platforms.add(IssuesManagePlatform.Tapd.name()); } } if (jira) { if (StringUtils.isNotBlank(jiraKey)) { - addJiraIssues(issuesRequest); + platforms.add(IssuesManagePlatform.Jira.name()); } } if (StringUtils.isBlank(tapdId) && StringUtils.isBlank(jiraKey)) { - addLocalIssues(issuesRequest); + platforms.add("LOCAL"); } - } - - public void addTapdIssues(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"); - } - - List tapdUsers = issuesRequest.getTapdUsers(); - String usersStr = String.join(";", tapdUsers); - - String username = SessionUtils.getUser().getName(); - - MultiValueMap paramMap = new LinkedMultiValueMap<>(); - paramMap.add("title", issuesRequest.getTitle()); - paramMap.add("workspace_id", tapdId); - paramMap.add("description", issuesRequest.getContent()); - paramMap.add("reporter", username); - paramMap.add("current_owner", usersStr); - - ResultHolder result = call(url, HttpMethod.POST, paramMap); - - String listJson = JSON.toJSONString(result.getData()); - JSONObject jsonObject = JSONObject.parseObject(listJson); - String issuesId = jsonObject.getObject("Bug", Issues.class).getId(); - - // 用例与第三方缺陷平台中的缺陷关联 - TestCaseIssues testCaseIssues = new TestCaseIssues(); - testCaseIssues.setId(UUID.randomUUID().toString()); - testCaseIssues.setIssuesId(issuesId); - testCaseIssues.setTestCaseId(testCaseId); - testCaseIssuesMapper.insert(testCaseIssues); - - // 插入缺陷表 - Issues issues = new Issues(); - issues.setId(issuesId); - issues.setPlatform(IssuesManagePlatform.Tapd.toString()); - issuesMapper.insert(issues); - } - - public void addJiraIssues(IssuesRequest issuesRequest) { - String config = platformConfig(IssuesManagePlatform.Jira.toString()); - JSONObject object = JSON.parseObject(config); - - if (object == null) { - MSException.throwException("jira config is null"); - } - - String account = object.getString("account"); - String password = object.getString("password"); - String url = object.getString("url"); - String issuetype = object.getString("issuetype"); - if (StringUtils.isBlank(issuetype)) { - MSException.throwException("Jira 问题类型为空"); - } - String auth = EncryptUtils.base64Encoding(account + ":" + password); - - String testCaseId = issuesRequest.getTestCaseId(); - String jiraKey = getJiraProjectKey(testCaseId); - - - if (StringUtils.isBlank(jiraKey)) { - MSException.throwException("未关联Jira 项目Key"); - } - - String content = issuesRequest.getContent(); - - Document document = Jsoup.parse(content); - document.outputSettings(new Document.OutputSettings().prettyPrint(false)); - document.select("br").append("\\n"); - document.select("p").prepend("\\n\\n"); - String s = document.html().replaceAll("\\\\n", "\n"); - String desc = Jsoup.clean(s, "", Whitelist.none(), new Document.OutputSettings().prettyPrint(false)); - desc = desc.replace(" ", ""); - - String json = "{\n" + - " \"fields\":{\n" + - " \"project\":{\n" + - " \"key\":\"" + jiraKey + "\"\n" + - " },\n" + - " \"summary\":\"" + issuesRequest.getTitle() + "\",\n" + - " \"description\": " + JSON.toJSONString(desc) + ",\n" + - " \"issuetype\":{\n" + - " \"name\":\"" + issuetype + "\"\n" + - " }\n" + - " }\n" + - "}"; - - String result = addJiraIssue(url, auth, json); - - JSONObject jsonObject = JSON.parseObject(result); - String id = jsonObject.getString("key"); - - // 用例与第三方缺陷平台中的缺陷关联 - 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.Jira.toString()); - issuesMapper.insert(issues); - } - - private String addJiraIssue(String url, String auth, String json) { - HttpHeaders requestHeaders = new HttpHeaders(); - requestHeaders.add("Authorization", "Basic " + auth); - requestHeaders.setContentType(org.springframework.http.MediaType.APPLICATION_JSON); - //HttpEntity - HttpEntity requestEntity = new HttpEntity<>(json, requestHeaders); - RestTemplate restTemplate = new RestTemplate(); - //post - ResponseEntity responseEntity = null; - try { - responseEntity = restTemplate.exchange(url + "/rest/api/2/issue", HttpMethod.POST, requestEntity, String.class); - } catch (Exception e) { - LogUtil.error(e.getMessage(), e); - MSException.throwException("调用Jira接口创建缺陷失败"); - } - - return responseEntity.getBody(); - } - - public void addLocalIssues(IssuesRequest request) { - SessionUser user = SessionUtils.getUser(); - String id = UUID.randomUUID().toString(); - Issues issues = new Issues(); - issues.setId(id); - issues.setStatus("new"); - issues.setReporter(user.getId()); - issues.setTitle(request.getTitle()); - issues.setDescription(request.getContent()); - issues.setCreateTime(System.currentTimeMillis()); - issues.setUpdateTime(System.currentTimeMillis()); - issues.setPlatform(IssuesManagePlatform.Local.toString()); - issuesMapper.insert(issues); - - TestCaseIssues testCaseIssues = new TestCaseIssues(); - testCaseIssues.setId(UUID.randomUUID().toString()); - testCaseIssues.setIssuesId(id); - testCaseIssues.setTestCaseId(request.getTestCaseId()); - testCaseIssuesMapper.insert(testCaseIssues); - } - - public Issues 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 Issues(); - } - JSONObject jsonObject = JSONObject.parseObject(listJson); - JSONObject bug = jsonObject.getJSONObject("Bug"); - Long created = bug.getLong("created"); - Issues issues = jsonObject.getObject("Bug", Issues.class); - issues.setCreateTime(created); - return issues; - } - - public Issues getJiraIssues(HttpHeaders headers, String url, String issuesId) { - HttpEntity requestEntity = new HttpEntity<>(headers); - RestTemplate restTemplate = new RestTemplate(); - //post - ResponseEntity responseEntity; - Issues issues = new Issues(); - try { - responseEntity = restTemplate.exchange(url + "/rest/api/2/issue/" + issuesId, HttpMethod.GET, requestEntity, String.class); - String body = responseEntity.getBody(); - - JSONObject obj = JSONObject.parseObject(body); - LogUtil.info(obj); - - String lastmodify = ""; - String status = ""; - - JSONObject fields = (JSONObject) obj.get("fields"); - JSONObject statusObj = (JSONObject) fields.get("status"); - JSONObject assignee = (JSONObject) fields.get("assignee"); - - if (statusObj != null) { - JSONObject statusCategory = (JSONObject) statusObj.get("statusCategory"); - status = statusCategory.getString("key"); - } - - String id = obj.getString("key"); - String title = fields.getString("summary"); - String description = fields.getString("description"); - - Parser parser = Parser.builder().build(); - Node document = parser.parse(description); - HtmlRenderer renderer = HtmlRenderer.builder().build(); - description = renderer.render(document); - - Long createTime = fields.getLong("created"); - - if (assignee != null) { - lastmodify = assignee.getString("displayName"); - } - - issues.setId(id); - issues.setTitle(title); - issues.setCreateTime(createTime); - issues.setLastmodify(lastmodify); - issues.setDescription(description); - issues.setStatus(status); - issues.setPlatform(IssuesManagePlatform.Jira.toString()); - } catch (HttpClientErrorException.NotFound e) { - LogUtil.error(e.getStackTrace(), e); - return new Issues(); - } catch (HttpClientErrorException.Unauthorized e) { - LogUtil.error(e.getStackTrace(), e); - MSException.throwException("获取Jira缺陷失败,检查Jira配置信息"); - } catch (Exception e) { - LogUtil.error(e.getMessage(), e); - MSException.throwException("调用Jira接口获取缺陷失败"); - } - - return issues; + List platformList = IssueFactory.createPlatforms(platforms, issuesRequest); + platformList.forEach(platform -> { + platform.addIssue(issuesRequest); + }); } @@ -414,11 +82,12 @@ public class IssuesService { boolean tapd = isIntegratedPlatform(orgId, IssuesManagePlatform.Tapd.toString()); boolean jira = isIntegratedPlatform(orgId, IssuesManagePlatform.Jira.toString()); + List platforms = new ArrayList<>(); if (tapd) { // 是否关联了项目 String tapdId = getTapdProjectId(caseId); if (StringUtils.isNotBlank(tapdId)) { - list.addAll(getTapdIssues(caseId)); + platforms.add(IssuesManagePlatform.Tapd.name()); } } @@ -426,90 +95,22 @@ public class IssuesService { if (jira) { String jiraKey = getJiraProjectKey(caseId); if (StringUtils.isNotBlank(jiraKey)) { - list.addAll(getJiraIssues(caseId)); + platforms.add(IssuesManagePlatform.Jira.name()); } } - list.addAll(getLocalIssues(caseId)); - return list; - } - - public List getTapdIssues(String caseId) { - List list = new ArrayList<>(); - String tapdId = getTapdProjectId(caseId); - - TestCaseIssuesExample example = new TestCaseIssuesExample(); - example.createCriteria().andTestCaseIdEqualTo(caseId); - - List issues = extIssuesMapper.getIssues(caseId, IssuesManagePlatform.Tapd.toString()); - - List issuesIds = issues.stream().map(Issues::getId).collect(Collectors.toList()); - issuesIds.forEach(issuesId -> { - Issues dto = getTapdIssues(tapdId, issuesId); - if (StringUtils.isBlank(dto.getId())) { - // 缺陷不存在,解除用例和缺陷的关联 - TestCaseIssuesExample issuesExample = new TestCaseIssuesExample(); - issuesExample.createCriteria() - .andTestCaseIdEqualTo(caseId) - .andIssuesIdEqualTo(issuesId); - testCaseIssuesMapper.deleteByExample(issuesExample); - issuesMapper.deleteByPrimaryKey(issuesId); - } else { - dto.setPlatform(IssuesManagePlatform.Tapd.toString()); - // 缺陷状态为 关闭,则不显示 - if (!StringUtils.equals("closed", dto.getStatus())) { - list.add(dto); - } - } + platforms.add("LOCAL"); + IssuesRequest issueRequest = new IssuesRequest(); + issueRequest.setTestCaseId(caseId); + List platformList = IssueFactory.createPlatforms(platforms, issueRequest); + platformList.forEach(platform -> { + List issue = platform.getIssue(); + list.addAll(issue); }); + return list; } - public List getJiraIssues(String caseId) { - List list = new ArrayList<>(); - - String config = platformConfig(IssuesManagePlatform.Jira.toString()); - JSONObject object = JSON.parseObject(config); - - if (object == null) { - MSException.throwException("tapd config is null"); - } - - String account = object.getString("account"); - String password = object.getString("password"); - String url = object.getString("url"); - HttpHeaders headers = auth(account, password); - - TestCaseIssuesExample example = new TestCaseIssuesExample(); - example.createCriteria().andTestCaseIdEqualTo(caseId); - - List issues = extIssuesMapper.getIssues(caseId, IssuesManagePlatform.Jira.toString()); - - List issuesIds = issues.stream().map(Issues::getId).collect(Collectors.toList()); - issuesIds.forEach(issuesId -> { - Issues dto = getJiraIssues(headers, url, issuesId); - if (StringUtils.isBlank(dto.getId())) { - // 缺陷不存在,解除用例和缺陷的关联 - TestCaseIssuesExample issuesExample = new TestCaseIssuesExample(); - issuesExample.createCriteria() - .andTestCaseIdEqualTo(caseId) - .andIssuesIdEqualTo(issuesId); - testCaseIssuesMapper.deleteByExample(issuesExample); - issuesMapper.deleteByPrimaryKey(issuesId); - } else { - // 缺陷状态为 完成,则不显示 - if (!StringUtils.equals("done", dto.getStatus())) { - list.add(dto); - } - } - }); - return list; - } - - public List getLocalIssues(String caseId) { - return extIssuesMapper.getIssues(caseId, IssuesManagePlatform.Local.toString()); - } - public String getTapdProjectId(String testCaseId) { TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId); Project project = projectService.getProjectById(testCase.getProjectId()); @@ -540,19 +141,11 @@ public class IssuesService { issuesMapper.updateByPrimaryKeySelective(issues); } - public List getTapdProjectUsers(String caseId) { - List users = new ArrayList<>(); - String projectId = getTapdProjectId(caseId); - String url = "https://api.tapd.cn/workspaces/users?workspace_id=" + projectId; - ResultHolder call = call(url); - String listJson = JSON.toJSONString(call.getData()); - JSONArray jsonArray = JSON.parseArray(listJson); - for (int i = 0; i < jsonArray.size(); i++) { - JSONObject o = jsonArray.getJSONObject(i); - TapdUser user = o.getObject("UserWorkspace", TapdUser.class); - users.add(user); - } - return users; + public List getTapdProjectUsers(String caseId) { + IssuesRequest issueRequest = new IssuesRequest(); + issueRequest.setTestCaseId(caseId); + AbstractIssuePlatform platform = IssueFactory.createPlatform(IssuesManagePlatform.Tapd.name(), issueRequest); + return platform.getPlatformUser(); } public void deleteIssue(String id) { From 70c513099a4fef80e7dd0499b2ae622bee56722a Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Wed, 14 Oct 2020 11:00:16 +0800 Subject: [PATCH 3/3] =?UTF-8?q?refactor:=20=E5=8E=BB=E6=8E=89=20show-more-?= =?UTF-8?q?btn=20=E7=9A=84=E8=83=8C=E6=99=AF=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business/components/track/case/components/ShowMoreBtn.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/business/components/track/case/components/ShowMoreBtn.vue b/frontend/src/business/components/track/case/components/ShowMoreBtn.vue index e7e6022138..3a4a8b3b01 100644 --- a/frontend/src/business/components/track/case/components/ShowMoreBtn.vue +++ b/frontend/src/business/components/track/case/components/ShowMoreBtn.vue @@ -45,7 +45,6 @@ width: 20px; height: 25px; line-height: 25px; - background-color: #FFF; } .show-more-btn-title {