feat: jira、tapd支持复制编辑删除

This commit is contained in:
chenjianxing 2021-09-15 16:54:46 +08:00 committed by jianxing
parent b44282d2a3
commit a27cca0733
10 changed files with 152 additions and 107 deletions

View File

@ -91,6 +91,14 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
} }
public AbstractIssuePlatform(IssuesRequest issuesRequest) { public AbstractIssuePlatform(IssuesRequest issuesRequest) {
this();
this.testCaseId = issuesRequest.getTestCaseId();
this.projectId = issuesRequest.getProjectId();
this.orgId = issuesRequest.getOrganizationId();
this.userId = issuesRequest.getUserId();
}
public AbstractIssuePlatform() {
this.integrationService = CommonBeanFactory.getBean(IntegrationService.class); this.integrationService = CommonBeanFactory.getBean(IntegrationService.class);
this.testCaseIssuesMapper = CommonBeanFactory.getBean(TestCaseIssuesMapper.class); this.testCaseIssuesMapper = CommonBeanFactory.getBean(TestCaseIssuesMapper.class);
this.projectService = CommonBeanFactory.getBean(ProjectService.class); this.projectService = CommonBeanFactory.getBean(ProjectService.class);
@ -99,10 +107,6 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
this.issuesMapper = CommonBeanFactory.getBean(IssuesMapper.class); this.issuesMapper = CommonBeanFactory.getBean(IssuesMapper.class);
this.extIssuesMapper = CommonBeanFactory.getBean(ExtIssuesMapper.class); this.extIssuesMapper = CommonBeanFactory.getBean(ExtIssuesMapper.class);
this.resourceService = CommonBeanFactory.getBean(ResourceService.class); this.resourceService = CommonBeanFactory.getBean(ResourceService.class);
this.testCaseId = issuesRequest.getTestCaseId();
this.projectId = issuesRequest.getProjectId();
this.orgId = issuesRequest.getOrganizationId();
this.userId = issuesRequest.getUserId();
this.restTemplateIgnoreSSL = restTemplate; this.restTemplateIgnoreSSL = restTemplate;
} }
@ -324,4 +328,13 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
protected UserDTO.PlatformInfo getUserPlatInfo(String orgId) { protected UserDTO.PlatformInfo getUserPlatInfo(String orgId) {
return userService.getCurrentPlatformInfo(orgId); return userService.getCurrentPlatformInfo(orgId);
} }
@Override
public void deleteIssue(String id) {
issuesMapper.deleteByPrimaryKey(id);
TestCaseIssuesExample example = new TestCaseIssuesExample();
example.createCriteria()
.andIssuesIdEqualTo(id);
testCaseIssuesMapper.deleteByExample(example);
}
} }

View File

@ -1,11 +1,11 @@
package io.metersphere.track.issue; package io.metersphere.track.issue;
import io.metersphere.commons.constants.IssuesManagePlatform; import io.metersphere.commons.constants.IssuesManagePlatform;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.track.request.testcase.IssuesRequest; import io.metersphere.track.request.testcase.IssuesRequest;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*; import java.util.*;
public class IssueFactory { public class IssueFactory {
@ -23,16 +23,8 @@ public class IssueFactory {
Constructor cons = clazz.getDeclaredConstructor(new Class[] { IssuesRequest.class }); Constructor cons = clazz.getDeclaredConstructor(new Class[] { IssuesRequest.class });
AbstractIssuePlatform azureDevopsPlatform = (AbstractIssuePlatform) cons.newInstance(addIssueRequest); AbstractIssuePlatform azureDevopsPlatform = (AbstractIssuePlatform) cons.newInstance(addIssueRequest);
return azureDevopsPlatform; return azureDevopsPlatform;
} catch (ClassNotFoundException e) { } catch (Throwable e) {
e.printStackTrace(); LogUtil.error(e);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} }
} else if (StringUtils.equalsIgnoreCase(IssuesManagePlatform.Local.toString(), platform)) { } else if (StringUtils.equalsIgnoreCase(IssuesManagePlatform.Local.toString(), platform)) {
return new LocalPlatform(addIssueRequest); return new LocalPlatform(addIssueRequest);

View File

@ -9,7 +9,6 @@ import io.metersphere.commons.constants.IssuesStatus;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.EncryptUtils; import io.metersphere.commons.utils.EncryptUtils;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.dto.CustomFieldItemDTO; import io.metersphere.dto.CustomFieldItemDTO;
import io.metersphere.dto.UserDTO; import io.metersphere.dto.UserDTO;
import io.metersphere.track.dto.DemandDTO; import io.metersphere.track.dto.DemandDTO;
@ -197,6 +196,30 @@ public class JiraPlatform extends AbstractIssuePlatform {
@Override @Override
public void addIssue(IssuesUpdateRequest issuesRequest) { public void addIssue(IssuesUpdateRequest issuesRequest) {
JSONObject addJiraIssueParam = buildUpdateParam(issuesRequest);
JiraAddIssueResponse result = jiraClientV2.addIssue(JSONObject.toJSONString(addJiraIssueParam));
JiraIssue issues = jiraClientV2.getIssues(result.getId());
List<File> imageFiles = getImageFiles(issuesRequest.getDescription());
imageFiles.forEach(img -> {
jiraClientV2.uploadAttachment(result.getKey(), img);
});
String status = getStatus(issues.getFields());
issuesRequest.setPlatformStatus(status);
issuesRequest.setId(result.getKey());
// 用例与第三方缺陷平台中的缺陷关联
handleTestCaseIssues(issuesRequest);
// 插入缺陷表
insertIssues(result.getKey(), issuesRequest);
}
private JSONObject buildUpdateParam(IssuesUpdateRequest issuesRequest) {
issuesRequest.setPlatform(IssuesManagePlatform.Jira.toString()); issuesRequest.setPlatform(IssuesManagePlatform.Jira.toString());
JiraConfig config = getUserConfig(); JiraConfig config = getUserConfig();
@ -208,7 +231,6 @@ public class JiraPlatform extends AbstractIssuePlatform {
JSONObject project = new JSONObject(); JSONObject project = new JSONObject();
String desc = issuesRequest.getDescription(); String desc = issuesRequest.getDescription();
List<File> imageFiles = getImageFiles(desc);
desc = removeImage(desc); desc = removeImage(desc);
fields.put("project", project); fields.put("project", project);
@ -238,7 +260,7 @@ public class JiraPlatform extends AbstractIssuePlatform {
fields.put(item.getCustomData(), param); fields.put(item.getCustomData(), param);
} else if (StringUtils.isNotBlank(item.getType()) && } else if (StringUtils.isNotBlank(item.getType()) &&
StringUtils.equalsAny(item.getType(), "multipleSelect", "checkbox", "multipleMember")) { StringUtils.equalsAny(item.getType(), "multipleSelect", "checkbox", "multipleMember")) {
JSONArray attrs = new JSONArray(); JSONArray attrs = new JSONArray();
if (StringUtils.isNotBlank(item.getValue())) { if (StringUtils.isNotBlank(item.getValue())) {
JSONArray values = JSONObject.parseArray(item.getValue()); JSONArray values = JSONObject.parseArray(item.getValue());
values.forEach(v -> { values.forEach(v -> {
@ -254,32 +276,22 @@ public class JiraPlatform extends AbstractIssuePlatform {
} }
} }
}); });
JiraAddIssueResponse result = jiraClientV2.addIssue(JSONObject.toJSONString(addJiraIssueParam));
JiraIssue issues = jiraClientV2.getIssues(result.getId());
imageFiles.forEach(img -> { return addJiraIssueParam;
jiraClientV2.uploadAttachment(result.getKey(), img);
});
String status = getStatus(issues.getFields());
issuesRequest.setPlatformStatus(status);
issuesRequest.setId(result.getKey());
// 用例与第三方缺陷平台中的缺陷关联
handleTestCaseIssues(issuesRequest);
// 插入缺陷表
insertIssues(result.getKey(), issuesRequest);
} }
@Override @Override
public void updateIssue(IssuesUpdateRequest request) { public void updateIssue(IssuesUpdateRequest request) {
// todo 调用接口 JSONObject param = buildUpdateParam(request);
request.setDescription(null);
handleIssueUpdate(request); handleIssueUpdate(request);
jiraClientV2.updateIssue(request.getId(), JSONObject.toJSONString(param));
} }
@Override @Override
public void deleteIssue(String id) { public void deleteIssue(String id) {
super.deleteIssue(id);
setConfig();
jiraClientV2.deleteIssue(id);
} }
@Override @Override

View File

@ -60,9 +60,4 @@ public class LocalPlatform extends LocalAbstractPlatform {
public void updateIssue(IssuesUpdateRequest request) { public void updateIssue(IssuesUpdateRequest request) {
handleIssueUpdate(request); handleIssueUpdate(request);
} }
@Override
public void deleteIssue(String id) {
issuesMapper.deleteByPrimaryKey(id);
}
} }

View File

@ -86,7 +86,31 @@ public class TapdPlatform extends AbstractIssuePlatform {
@Override @Override
public void addIssue(IssuesUpdateRequest issuesRequest) { public void addIssue(IssuesUpdateRequest issuesRequest) {
MultiValueMap<String, String> param = buildUpdateParam(issuesRequest);
TapdBug bug = tapdClient.addIssue(param);
Map<String, String> statusMap = tapdClient.getStatusMap(getProjectId(this.projectId));
issuesRequest.setPlatformStatus(statusMap.get(bug.getStatus()));
issuesRequest.setId(bug.getId());
// 用例与第三方缺陷平台中的缺陷关联
handleTestCaseIssues(issuesRequest);
// 插入缺陷表
insertIssues(bug.getId(), issuesRequest);
}
@Override
public void updateIssue(IssuesUpdateRequest request) {
MultiValueMap<String, String> param = buildUpdateParam(request);
param.add("id", request.getId());
handleIssueUpdate(request);
tapdClient.updateIssue(param);
}
private MultiValueMap<String, String> buildUpdateParam(IssuesUpdateRequest issuesRequest) {
issuesRequest.setPlatform(IssuesManagePlatform.Tapd.toString()); issuesRequest.setPlatform(IssuesManagePlatform.Tapd.toString());
setConfig();
List<CustomFieldItemDTO> customFields = getCustomFields(issuesRequest.getCustomFields()); List<CustomFieldItemDTO> customFields = getCustomFields(issuesRequest.getCustomFields());
@ -107,7 +131,7 @@ public class TapdPlatform extends AbstractIssuePlatform {
reporter = SessionUtils.getUser().getName(); reporter = SessionUtils.getUser().getName();
} }
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>(); MultiValueMap<String, String> paramMap = new LinkedMultiValueMap<>();
paramMap.add("title", issuesRequest.getTitle()); paramMap.add("title", issuesRequest.getTitle());
paramMap.add("workspace_id", tapdId); paramMap.add("workspace_id", tapdId);
paramMap.add("description", msDescription2Tapd(issuesRequest.getDescription())); paramMap.add("description", msDescription2Tapd(issuesRequest.getDescription()));
@ -119,25 +143,7 @@ public class TapdPlatform extends AbstractIssuePlatform {
} }
}); });
paramMap.add("reporter", reporter); paramMap.add("reporter", reporter);
return paramMap;
setConfig();
TapdBug bug = tapdClient.addIssue(paramMap);
Map<String, String> statusMap = tapdClient.getStatusMap(getProjectId(this.projectId));
issuesRequest.setPlatformStatus(statusMap.get(bug.getStatus()));
issuesRequest.setId(bug.getId());
// 用例与第三方缺陷平台中的缺陷关联
handleTestCaseIssues(issuesRequest);
// 插入缺陷表
insertIssues(bug.getId(), issuesRequest);
}
@Override
public void updateIssue(IssuesUpdateRequest request) {
// todo 调用接口
request.setDescription(null);
handleIssueUpdate(request);
} }
private String msDescription2Tapd(String msDescription) { private String msDescription2Tapd(String msDescription) {
@ -147,7 +153,10 @@ public class TapdPlatform extends AbstractIssuePlatform {
} }
@Override @Override
public void deleteIssue(String id) {} public void deleteIssue(String id) {
super.deleteIssue(id);
// todo 暂无删除API
}
@Override @Override
public void testAuth() { public void testAuth() {

View File

@ -172,6 +172,35 @@ public class ZentaoPlatform extends AbstractIssuePlatform {
@Override @Override
public void addIssue(IssuesUpdateRequest issuesRequest) { public void addIssue(IssuesUpdateRequest issuesRequest) {
MultiValueMap<String, Object> param = buildUpdateParam(issuesRequest);
AddIssueResponse.Issue issue = zentaoClient.addIssue(param);
issuesRequest.setPlatformStatus(issue.getStatus());
String id = issue.getId();
if (StringUtils.isNotBlank(id)) {
issuesRequest.setId(id);
// 用例与第三方缺陷平台中的缺陷关联
handleTestCaseIssues(issuesRequest);
IssuesExample issuesExample = new IssuesExample();
issuesExample.createCriteria().andIdEqualTo(id)
.andPlatformEqualTo(IssuesManagePlatform.Zentao.toString());
if (issuesMapper.selectByExample(issuesExample).size() <= 0) {
// 插入缺陷表
insertIssues(id, issuesRequest);
}
}
}
@Override
public void updateIssue(IssuesUpdateRequest request) {
// todo 调用接口
request.setDescription(null);
handleIssueUpdate(request);
}
private MultiValueMap<String, Object> buildUpdateParam(IssuesUpdateRequest issuesRequest) {
issuesRequest.setPlatform(IssuesManagePlatform.Zentao.toString()); issuesRequest.setPlatform(IssuesManagePlatform.Zentao.toString());
List<CustomFieldItemDTO> customFields = getCustomFields(issuesRequest.getCustomFields()); List<CustomFieldItemDTO> customFields = getCustomFields(issuesRequest.getCustomFields());
@ -212,32 +241,7 @@ public class ZentaoPlatform extends AbstractIssuePlatform {
if (StringUtils.isNotBlank(issuesRequest.getZentaoAssigned())) { if (StringUtils.isNotBlank(issuesRequest.getZentaoAssigned())) {
paramMap.add("assignedTo", issuesRequest.getZentaoAssigned()); paramMap.add("assignedTo", issuesRequest.getZentaoAssigned());
} }
return paramMap;
AddIssueResponse.Issue issue = zentaoClient.addIssue(paramMap);
issuesRequest.setPlatformStatus(issue.getStatus());
String id = issue.getId();
if (StringUtils.isNotBlank(id)) {
issuesRequest.setId(id);
// 用例与第三方缺陷平台中的缺陷关联
handleTestCaseIssues(issuesRequest);
IssuesExample issuesExample = new IssuesExample();
issuesExample.createCriteria().andIdEqualTo(id)
.andPlatformEqualTo(IssuesManagePlatform.Zentao.toString());
if (issuesMapper.selectByExample(issuesExample).size() <= 0) {
// 插入缺陷表
insertIssues(id, issuesRequest);
}
}
}
@Override
public void updateIssue(IssuesUpdateRequest request) {
// todo 调用接口
request.setDescription(null);
handleIssueUpdate(request);
} }
@Override @Override

View File

@ -52,6 +52,25 @@ public abstract class JiraAbstractClient extends BaseClient {
return (JiraAddIssueResponse) getResultForObject(JiraAddIssueResponse.class, response); return (JiraAddIssueResponse) getResultForObject(JiraAddIssueResponse.class, response);
} }
public void updateIssue(String id, String body) {
LogUtil.info("addIssue: " + body);
HttpHeaders headers = getAuthHeader();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> requestEntity = new HttpEntity<>(body, headers);
try {
restTemplate.exchange(getBaseUrl() + "/issue/" + id, HttpMethod.PUT, requestEntity, String.class);
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
MSException.throwException(e.getMessage());
}
}
public void deleteIssue(String id) {
LogUtil.info("deleteIssue: " + id);
restTemplate.exchange(getBaseUrl() + "/issue/" + id, HttpMethod.DELETE, getAuthHttpEntity(), String.class);
}
public void uploadAttachment(String issueKey, File file) { public void uploadAttachment(String issueKey, File file) {
HttpHeaders authHeader = getAuthHeader(); HttpHeaders authHeader = getAuthHeader();
authHeader.add("X-Atlassian-Token", "no-check"); authHeader.add("X-Atlassian-Token", "no-check");

View File

@ -57,9 +57,9 @@ public class TapdClient extends BaseClient {
return (TapdGetIssueResponse) getResultForObject(TapdGetIssueResponse.class, response); return (TapdGetIssueResponse) getResultForObject(TapdGetIssueResponse.class, response);
} }
public TapdBug addIssue(MultiValueMap<String, Object> paramMap) { public TapdBug addIssue(MultiValueMap<String, String> paramMap) {
String url = getBaseUrl() + "/bugs"; String url = getBaseUrl() + "/bugs";
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(paramMap, getAuthHeader()); HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(paramMap, getAuthHeader());
ResponseEntity<String> response = null; ResponseEntity<String> response = null;
try { try {
response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
@ -70,6 +70,11 @@ public class TapdClient extends BaseClient {
return ((AddTapdIssueResponse) getResultForObject(AddTapdIssueResponse.class, response)).getData().getBug(); return ((AddTapdIssueResponse) getResultForObject(AddTapdIssueResponse.class, response)).getData().getBug();
} }
public TapdBug updateIssue(MultiValueMap<String, String> paramMap) {
// 带id为更新
return addIssue(paramMap);
}
protected HttpEntity<MultiValueMap> getAuthHttpEntity() { protected HttpEntity<MultiValueMap> getAuthHttpEntity() {
return new HttpEntity<>(getAuthHeader()); return new HttpEntity<>(getAuthHeader());
} }

View File

@ -43,7 +43,6 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*; import java.util.*;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -295,11 +294,16 @@ public class IssuesService {
} }
public void delete(String id) { public void delete(String id) {
issuesMapper.deleteByPrimaryKey(id); IssuesWithBLOBs issuesWithBLOBs = issuesMapper.selectByPrimaryKey(id);
TestCaseIssuesExample example = new TestCaseIssuesExample(); List platforms = new ArrayList<>();
example.createCriteria() platforms.add(issuesWithBLOBs.getPlatform());
.andIssuesIdEqualTo(id); String projectId = issuesWithBLOBs.getProjectId();
testCaseIssuesMapper.deleteByExample(example); Project project = projectService.getProjectById(projectId);
Workspace workspace = workspaceMapper.selectByPrimaryKey(project.getWorkspaceId());
IssuesRequest issuesRequest = new IssuesRequest();
issuesRequest.setOrganizationId(workspace.getOrganizationId());
AbstractIssuePlatform platform = IssueFactory.createPlatform(issuesWithBLOBs.getPlatform(), issuesRequest);
platform.deleteIssue(id);
} }
public IssuesWithBLOBs get(String id) { public IssuesWithBLOBs get(String id) {
@ -461,16 +465,8 @@ public class IssuesService {
Constructor cons = clazz.getDeclaredConstructor(new Class[]{IssuesRequest.class}); Constructor cons = clazz.getDeclaredConstructor(new Class[]{IssuesRequest.class});
AbstractIssuePlatform azureDevopsPlatform = (AbstractIssuePlatform) cons.newInstance(issuesRequest); AbstractIssuePlatform azureDevopsPlatform = (AbstractIssuePlatform) cons.newInstance(issuesRequest);
syncThirdPartyIssues(azureDevopsPlatform::syncIssues, project, azureDevopsIssues); syncThirdPartyIssues(azureDevopsPlatform::syncIssues, project, azureDevopsIssues);
} catch (ClassNotFoundException e) { } catch (Throwable e) {
e.printStackTrace(); LogUtil.error(e);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} }
} }
} }

View File

@ -314,10 +314,10 @@ export default {
}); });
}, },
btnDisable(row) { btnDisable(row) {
if (row.platform === 'Local') { // if (row.platform === 'Local' || row.platform === 'Jira') {
return false; return false;
} // }
return true; // return true;
}, },
syncIssues() { syncIssues() {
this.page.result = syncIssues(() => { this.page.result = syncIssues(() => {