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 556d045f00..3f6b29b454 100644 --- a/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java @@ -61,6 +61,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform { protected String key; protected String workspaceId; protected String userId; + protected String defaultCustomFields; public String getKey() { @@ -92,6 +93,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform { this.projectId = issuesRequest.getProjectId(); this.workspaceId = issuesRequest.getWorkspaceId(); this.userId = issuesRequest.getUserId(); + this.defaultCustomFields = issuesRequest.getDefaultCustomFields(); } public AbstractIssuePlatform() { @@ -382,7 +384,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform { } @Override - public void syncAllIssues(Project project, String defaultCustomFields) {} + public void syncAllIssues(Project project) {} protected List getIssuesByPlatformIds(List platformIds) { IssuesService issuesService = CommonBeanFactory.getBean(IssuesService.class); @@ -418,4 +420,26 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform { } return syncDeleteIds; } + + protected void mergeCustomField(IssuesWithBLOBs issues, String defaultCustomField) { + if (StringUtils.isNotBlank(defaultCustomField)) { + String issuesCustomFields = issues.getCustomFields(); + if (StringUtils.isNotBlank(issuesCustomFields) || issuesCustomFields.startsWith("{")) issuesCustomFields = "[]"; + JSONArray issueFields = JSONArray.parseArray(issuesCustomFields); + Set ids = issueFields.stream().map(i -> ((JSONObject) i).getString("id")).collect(Collectors.toSet()); + JSONArray defaultFields = JSONArray.parseArray(defaultCustomField); + defaultFields.forEach(item -> { // 如果自定义字段里没有模板新加的字段,就把新字段加上 + if (!ids.contains(((JSONObject) item).getString("id"))) { + issueFields.add(item); + } + }); + issues.setCustomFields(issueFields.toJSONString()); + } + } + + public T getConfig(String platform, Class clazz) { + String config = getPlatformConfig(platform); + if (StringUtils.isBlank(config)) MSException.throwException("配置为空"); + return JSONObject.parseObject(config, clazz); + } } 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 58ff42bc45..140664d934 100644 --- a/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java @@ -69,5 +69,5 @@ public interface IssuesPlatform { * 同步缺陷全量的缺陷 * @param project */ - void syncAllIssues(Project project, String defaultCustomFields); + void syncAllIssues(Project project); } diff --git a/backend/src/main/java/io/metersphere/track/issue/JiraPlatform.java b/backend/src/main/java/io/metersphere/track/issue/JiraPlatform.java index 64a0951e73..9d3c493c5e 100644 --- a/backend/src/main/java/io/metersphere/track/issue/JiraPlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/JiraPlatform.java @@ -40,33 +40,12 @@ public class JiraPlatform extends AbstractIssuePlatform { protected String key = IssuesManagePlatform.Jira.toString(); - private JiraClientV2 jiraClientV2 = new JiraClientV2(); + protected JiraClientV2 jiraClientV2; public JiraPlatform(IssuesRequest issuesRequest) { super(issuesRequest); - } - - public JiraConfig getConfig() { - String config = getPlatformConfig(IssuesManagePlatform.Jira.toString()); - JiraConfig jiraConfig = JSONObject.parseObject(config, JiraConfig.class); - validateConfig(jiraConfig); - return jiraConfig; - } - - public JiraConfig getUserConfig() { - JiraConfig jiraConfig = null; - String config = getPlatformConfig(IssuesManagePlatform.Jira.toString()); - if (StringUtils.isNotBlank(config)) { - jiraConfig = JSONObject.parseObject(config, JiraConfig.class); - UserDTO.PlatformInfo userPlatInfo = getUserPlatInfo(this.workspaceId); - if (userPlatInfo != null && StringUtils.isNotBlank(userPlatInfo.getJiraAccount()) - && StringUtils.isNotBlank(userPlatInfo.getJiraPassword())) { - jiraConfig.setAccount(userPlatInfo.getJiraAccount()); - jiraConfig.setPassword(userPlatInfo.getJiraPassword()); - } - } - validateConfig(jiraConfig); - return jiraConfig; + jiraClientV2 = new JiraClientV2(); + setConfig(); } @Override @@ -81,12 +60,16 @@ public class JiraPlatform extends AbstractIssuePlatform { return issues; } - public void parseIssue(IssuesWithBLOBs item, JiraIssue jiraIssue, String customFieldsStr) { - String lastmodify = ""; - JSONObject fields = jiraIssue.getFields(); + public IssuesWithBLOBs getUpdateIssue(IssuesWithBLOBs issue, JiraIssue jiraIssue) { + if (issue == null) { + issue = new IssuesWithBLOBs(); + issue.setCustomFields(defaultCustomFields); + } else { + mergeCustomField(issue, defaultCustomFields); + } + JSONObject fields = jiraIssue.getFields(); String status = getStatus(fields); - JSONObject assignee = (JSONObject) fields.get("assignee"); String description = fields.getString("description"); Parser parser = Parser.builder().build(); @@ -96,16 +79,15 @@ public class JiraPlatform extends AbstractIssuePlatform { description = renderer.render(document); } - if (assignee != null) { - lastmodify = assignee.getString("displayName"); - } - item.setTitle(fields.getString("summary")); - item.setCreateTime(fields.getLong("created")); - item.setLastmodify(lastmodify); - item.setDescription(description); - item.setPlatformStatus(status); - item.setPlatform(IssuesManagePlatform.Jira.toString()); - item.setCustomFields(syncIssueCustomField(customFieldsStr, jiraIssue.getFields())); + JSONObject assignee = (JSONObject) fields.get("assignee"); + issue.setTitle(fields.getString("summary")); + issue.setCreateTime(fields.getLong("created")); + issue.setLastmodify(assignee == null ? "" : assignee.getString("displayName")); + issue.setDescription(description); + issue.setPlatformStatus(status); + issue.setPlatform(IssuesManagePlatform.Jira.toString()); + issue.setCustomFields(syncIssueCustomField(issue.getCustomFields(), jiraIssue.getFields())); + return issue; } private String getStatus(JSONObject fields) { @@ -200,7 +182,8 @@ public class JiraPlatform extends AbstractIssuePlatform { @Override public void addIssue(IssuesUpdateRequest issuesRequest) { - JSONObject addJiraIssueParam = buildUpdateParam(issuesRequest); + JiraConfig jiraConfig = setUserConfig(); + JSONObject addJiraIssueParam = buildUpdateParam(issuesRequest, jiraConfig.getIssuetype()); JiraAddIssueResponse result = jiraClientV2.addIssue(JSONObject.toJSONString(addJiraIssueParam)); JiraIssue issues = jiraClientV2.getIssues(result.getId()); @@ -224,13 +207,10 @@ public class JiraPlatform extends AbstractIssuePlatform { handleTestCaseIssues(issuesRequest); } - private JSONObject buildUpdateParam(IssuesUpdateRequest issuesRequest) { + private JSONObject buildUpdateParam(IssuesUpdateRequest issuesRequest, String issuetypeStr) { issuesRequest.setPlatform(IssuesManagePlatform.Jira.toString()); - JiraConfig config = getUserConfig(); - jiraClientV2.setConfig(config); - String jiraKey = validateJiraKey(issuesRequest.getProjectId()); JSONObject fields = new JSONObject(); @@ -243,7 +223,7 @@ public class JiraPlatform extends AbstractIssuePlatform { project.put("key", jiraKey); JSONObject issuetype = new JSONObject(); - issuetype.put("name", config.getIssuetype()); + issuetype.put("name", issuetypeStr); fields.put("summary", issuesRequest.getTitle()); // fields.put("description", new JiraIssueDescription(desc)); @@ -254,7 +234,6 @@ public class JiraPlatform extends AbstractIssuePlatform { addJiraIssueParam.put("fields", fields); List customFields = CustomFieldService.getCustomFields(issuesRequest.getCustomFields()); - jiraClientV2.setConfig(config); customFields.forEach(item -> { String fieldName = item.getCustomData(); @@ -293,7 +272,8 @@ public class JiraPlatform extends AbstractIssuePlatform { @Override public void updateIssue(IssuesUpdateRequest request) { - JSONObject param = buildUpdateParam(request); + JiraConfig jiraConfig = setUserConfig(); + JSONObject param = buildUpdateParam(request, jiraConfig.getIssuetype()); handleIssueUpdate(request); jiraClientV2.updateIssue(request.getPlatformId(), JSONObject.toJSONString(param)); } @@ -302,24 +282,17 @@ public class JiraPlatform extends AbstractIssuePlatform { public void deleteIssue(String id) { IssuesWithBLOBs issuesWithBLOBs = issuesMapper.selectByPrimaryKey(id); super.deleteIssue(id); - setConfig(); jiraClientV2.deleteIssue(issuesWithBLOBs.getPlatformId()); } @Override public void testAuth() { - setConfig(); jiraClientV2.auth(); } @Override public void userAuth(UserDTO.PlatformInfo userInfo) { - String config = getPlatformConfig(IssuesManagePlatform.Jira.toString()); - JiraConfig jiraConfig = JSONObject.parseObject(config, JiraConfig.class); - jiraConfig.setAccount(userInfo.getJiraAccount()); - jiraConfig.setPassword(userInfo.getJiraPassword()); - validateConfig(jiraConfig); - jiraClientV2.setConfig(jiraConfig); + setUserConfig(userInfo); jiraClientV2.auth(); } @@ -330,12 +303,10 @@ public class JiraPlatform extends AbstractIssuePlatform { @Override public void syncIssues(Project project, List issues) { - setConfig(); issues.forEach(item -> { - setConfig(); try { IssuesWithBLOBs issuesWithBLOBs = issuesMapper.selectByPrimaryKey(item.getId()); - parseIssue(item, jiraClientV2.getIssues(item.getPlatformId()), issuesWithBLOBs.getCustomFields()); + getUpdateIssue(item, jiraClientV2.getIssues(item.getPlatformId())); String desc = htmlDesc2MsDesc(item.getDescription()); // 保留之前上传的图片 String images = getImages(issuesWithBLOBs.getDescription()); @@ -364,9 +335,30 @@ public class JiraPlatform extends AbstractIssuePlatform { return project.getJiraKey(); } + public JiraConfig getConfig() { + return getConfig(IssuesManagePlatform.Jira.toString(), JiraConfig.class); + } + public JiraConfig setConfig() { JiraConfig config = getConfig(); + validateConfig(config); jiraClientV2.setConfig(config); return config; } + + public JiraConfig setUserConfig(UserDTO.PlatformInfo userInfo) { + JiraConfig config = getConfig(); + if (userInfo != null && StringUtils.isNotBlank(userInfo.getJiraAccount()) + && StringUtils.isNotBlank(userInfo.getJiraPassword())) { + config.setAccount(userInfo.getJiraAccount()); + config.setPassword(userInfo.getJiraPassword()); + } + validateConfig(config); + jiraClientV2.setConfig(config); + return config; + } + + public JiraConfig setUserConfig() { + return setUserConfig(getUserPlatInfo(this.workspaceId)); + } } diff --git a/backend/src/main/java/io/metersphere/track/issue/TapdPlatform.java b/backend/src/main/java/io/metersphere/track/issue/TapdPlatform.java index eb58f339e2..1b525cd091 100644 --- a/backend/src/main/java/io/metersphere/track/issue/TapdPlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/TapdPlatform.java @@ -27,12 +27,10 @@ import io.metersphere.track.request.testcase.IssuesRequest; import io.metersphere.track.request.testcase.IssuesUpdateRequest; import org.apache.commons.collections.CollectionUtils; 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; @@ -44,10 +42,12 @@ public class TapdPlatform extends AbstractIssuePlatform { protected String key = IssuesManagePlatform.Tapd.toString(); - protected TapdClient tapdClient = new TapdClient(); + protected TapdClient tapdClient; public TapdPlatform(IssuesRequest issueRequest) { super(issueRequest); + tapdClient = new TapdClient(); + setConfig(); } @Override @@ -111,7 +111,6 @@ public class TapdPlatform extends AbstractIssuePlatform { private MultiValueMap buildUpdateParam(IssuesUpdateRequest issuesRequest) { issuesRequest.setPlatform(IssuesManagePlatform.Tapd.toString()); - setConfig(); String tapdId = getProjectId(issuesRequest.getProjectId()); @@ -156,19 +155,7 @@ public class TapdPlatform extends AbstractIssuePlatform { @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("验证失败!"); - } + tapdClient.auth(); } @Override @@ -179,16 +166,9 @@ public class TapdPlatform extends AbstractIssuePlatform { @Override public List getPlatformUser() { List users = new ArrayList<>(); - String id = getProjectId(projectId); - if (StringUtils.isBlank(id)) { - MSException.throwException("未关联Tapd项目ID"); - } - String url = "https://api.tapd.cn/workspaces/users?workspace_id=" + id; - 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); + JSONArray res = tapdClient.getPlatformUser(projectId); + for (int i = 0; i < res.size(); i++) { + JSONObject o = res.getJSONObject(i); PlatformUser user = o.getObject("UserWorkspace", PlatformUser.class); users.add(user); } @@ -212,8 +192,6 @@ public class TapdPlatform extends AbstractIssuePlatform { return; } - setConfig(); - Map statusMap = tapdClient.getStatusMap(project.getTapdId()); while (count == limit) { @@ -244,7 +222,12 @@ public class TapdPlatform extends AbstractIssuePlatform { } protected IssuesWithBLOBs getUpdateIssue(IssuesWithBLOBs issue, JSONObject bug, Map statusMap) { - if (issue == null) issue = new IssuesWithBLOBs(); + if (issue == null) { + issue = new IssuesWithBLOBs(); + issue.setCustomFields(defaultCustomFields); + } else { + mergeCustomField(issue, defaultCustomFields); + } TapdBug bugObj = JSONObject.parseObject(bug.toJSONString(), TapdBug.class); BeanUtils.copyBean(issue, bugObj); issue.setPlatformStatus(statusMap.get(bugObj.getStatus())); @@ -265,10 +248,13 @@ public class TapdPlatform extends AbstractIssuePlatform { } public TapdConfig getConfig() { - String config = getPlatformConfig(IssuesManagePlatform.Tapd.toString()); - TapdConfig tapdConfig = JSONObject.parseObject(config, TapdConfig.class); -// validateConfig(tapdConfig); - return tapdConfig; + return getConfig(IssuesManagePlatform.Tapd.toString(), TapdConfig.class); + } + + public TapdConfig setConfig() { + TapdConfig config = getConfig(); + tapdClient.setConfig(config); + return config; } public String getReporter() { @@ -279,12 +265,6 @@ public class TapdPlatform extends AbstractIssuePlatform { return null; } - public TapdConfig setConfig() { - TapdConfig config = getConfig(); - tapdClient.setConfig(config); - return config; - } - private ResultHolder call(String url) { return call(url, HttpMethod.GET, null); } diff --git a/backend/src/main/java/io/metersphere/track/issue/ZentaoFactory.java b/backend/src/main/java/io/metersphere/track/issue/ZentaoFactory.java index 495763056d..d2b06bf3f2 100644 --- a/backend/src/main/java/io/metersphere/track/issue/ZentaoFactory.java +++ b/backend/src/main/java/io/metersphere/track/issue/ZentaoFactory.java @@ -7,12 +7,12 @@ import org.apache.commons.lang3.StringUtils; public class ZentaoFactory { - public static ZentaoClient getInstance(String url, String type) { + public static ZentaoClient getInstance(String type) { if (StringUtils.equals(type, "PATH_INFO")) { - return new ZentaoPathInfoClient(url); + return new ZentaoPathInfoClient(); } else if (StringUtils.equals(type, "GET")) { - return new ZentaoGetClient(url); + return new ZentaoGetClient(); } - return new ZentaoPathInfoClient(url); + return new ZentaoPathInfoClient(); } } diff --git a/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java b/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java index 4f6d859768..5c80f4568b 100644 --- a/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java @@ -14,6 +14,7 @@ import io.metersphere.track.dto.DemandDTO; import io.metersphere.track.issue.client.ZentaoClient; import io.metersphere.track.issue.domain.PlatformUser; import io.metersphere.track.issue.domain.zentao.AddIssueResponse; +import io.metersphere.track.issue.domain.zentao.GetIssueResponse; import io.metersphere.track.issue.domain.zentao.ZentaoBuild; import io.metersphere.track.issue.domain.zentao.ZentaoConfig; import io.metersphere.track.request.testcase.IssuesRequest; @@ -34,37 +35,16 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class ZentaoPlatform extends AbstractIssuePlatform { - /** - * zentao account - */ - private final String account; - /** - * zentao password - */ - private final String password; - /** - * zentao url eg:http://x.x.x.x/zentao - */ - private final String url; - - private final ZentaoClient zentaoClient; + protected final ZentaoClient zentaoClient; protected String key = IssuesManagePlatform.Zentao.toString(); public ZentaoPlatform(IssuesRequest issuesRequest) { super(issuesRequest); - String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString()); - // todo - if (StringUtils.isBlank(config)) { - MSException.throwException("未集成禅道平台!"); - } - JSONObject object = JSON.parseObject(config); - this.account = object.getString("account"); - this.password = object.getString("password"); - this.url = object.getString("url"); - String type = object.getString("request"); + ZentaoConfig zentaoConfig = getConfig(); this.workspaceId = issuesRequest.getWorkspaceId(); - this.zentaoClient = ZentaoFactory.getInstance(this.url, type); + this.zentaoClient = ZentaoFactory.getInstance(zentaoConfig.getRequest()); + this.zentaoClient.setConfig(zentaoConfig); } @Override @@ -94,7 +74,6 @@ public class ZentaoPlatform extends AbstractIssuePlatform { //getTestStories List list = new ArrayList<>(); try { - setConfig(); String session = zentaoClient.login(); String key = getProjectId(projectId); HttpEntity> requestEntity = new HttpEntity<>(new HttpHeaders()); @@ -146,31 +125,36 @@ public class ZentaoPlatform extends AbstractIssuePlatform { return list; } - public IssuesDao getZentaoIssues(IssuesDao issue) { - JSONObject bug = zentaoClient.getBugById(issue.getPlatformId()); - String description = bug.getString("steps"); + public IssuesWithBLOBs getUpdateIssues(IssuesWithBLOBs issue, JSONObject bug) { + GetIssueResponse.Issue bugObj = JSONObject.parseObject(bug.toJSONString(), GetIssueResponse.Issue.class); + String description = bugObj.getSteps(); String steps = description; try { steps = zentao2MsDescription(description); } catch (Exception e) { LogUtil.error(e.getMessage(), e); } - IssuesDao issues = new IssuesDao(); - issues.setPlatformStatus(bug.getString("status")); - if (StringUtils.equals(bug.getString("deleted"),"1")) { - issues.setPlatformStatus(IssuesStatus.DELETE.toString()); - issuesMapper.updateByPrimaryKeySelective(issues); + if (issue == null) { + issue = new IssuesWithBLOBs(); + issue.setCustomFields(defaultCustomFields); + } else { + mergeCustomField(issue, defaultCustomFields); } - issues.setTitle(bug.getString("title")); - issues.setDescription(steps); - issues.setReporter(bug.getString("openedBy")); - IssuesWithBLOBs issuesWithBLOBs = issuesMapper.selectByPrimaryKey(issue.getId()); - issuesWithBLOBs.setCustomFields(syncIssueCustomField(issuesWithBLOBs.getCustomFields(), bug)); - return issues; + issue.setPlatformStatus(bugObj.getStatus()); + if (StringUtils.equals(bugObj.getDeleted(),"1")) { + issue.setPlatformStatus(IssuesStatus.DELETE.toString()); + issuesMapper.updateByPrimaryKeySelective(issue); + } + issue.setTitle(bugObj.getTitle()); + issue.setDescription(steps); + issue.setReporter(bugObj.getOpenedBy()); + issue.setCustomFields(syncIssueCustomField(issue.getCustomFields(), bug)); + return issue; } @Override public void addIssue(IssuesUpdateRequest issuesRequest) { + setUserConfig(); MultiValueMap param = buildUpdateParam(issuesRequest); AddIssueResponse.Issue issue = zentaoClient.addIssue(param); @@ -196,16 +180,14 @@ public class ZentaoPlatform extends AbstractIssuePlatform { @Override public void updateIssue(IssuesUpdateRequest request) { + setUserConfig(); MultiValueMap param = buildUpdateParam(request); handleIssueUpdate(request); - zentaoClient.setConfig(getUserConfig()); zentaoClient.updateIssue(request.getPlatformId(), param); } private MultiValueMap buildUpdateParam(IssuesUpdateRequest issuesRequest) { issuesRequest.setPlatform(IssuesManagePlatform.Zentao.toString()); - - zentaoClient.setConfig(getUserConfig()); String projectId = getProjectId(issuesRequest.getProjectId()); if (StringUtils.isBlank(projectId)) { MSException.throwException("未关联禅道项目ID."); @@ -245,59 +227,47 @@ public class ZentaoPlatform extends AbstractIssuePlatform { public void deleteIssue(String id) { IssuesWithBLOBs issuesWithBLOBs = issuesMapper.selectByPrimaryKey(id); super.deleteIssue(id); - zentaoClient.setConfig(getUserConfig()); zentaoClient.deleteIssue(issuesWithBLOBs.getPlatformId()); } @Override public void testAuth() { - setConfig(); zentaoClient.login(); } @Override public void userAuth(UserDTO.PlatformInfo userInfo) { - String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString()); - ZentaoConfig zentaoConfig = JSONObject.parseObject(config, ZentaoConfig.class); - zentaoConfig.setAccount(userInfo.getZentaoUserName()); - zentaoConfig.setPassword(userInfo.getZentaoPassword()); - zentaoClient.setConfig(zentaoConfig); + setUserConfig(); zentaoClient.login(); } + public ZentaoConfig getConfig() { + return getConfig(IssuesManagePlatform.Zentao.toString(), ZentaoConfig.class); + } + public ZentaoConfig setConfig() { ZentaoConfig config = getConfig(); zentaoClient.setConfig(config); return config; } - public ZentaoConfig getConfig() { - ZentaoConfig zentaoConfig = null; - String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString()); - zentaoConfig = JSONObject.parseObject(config, ZentaoConfig.class); -// validateConfig(tapdConfig); - return zentaoConfig; + public ZentaoConfig setUserConfig() { + return setUserConfig(getUserPlatInfo(this.workspaceId)); } - public ZentaoConfig getUserConfig() { - ZentaoConfig zentaoConfig = null; - String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString()); - if (StringUtils.isNotBlank(config)) { - zentaoConfig = JSONObject.parseObject(config, ZentaoConfig.class); - UserDTO.PlatformInfo userPlatInfo = getUserPlatInfo(this.workspaceId); - if (userPlatInfo != null && StringUtils.isNotBlank(userPlatInfo.getZentaoUserName()) - && StringUtils.isNotBlank(userPlatInfo.getZentaoPassword())) { - zentaoConfig.setAccount(userPlatInfo.getZentaoUserName()); - zentaoConfig.setPassword(userPlatInfo.getZentaoPassword()); - } + public ZentaoConfig setUserConfig(UserDTO.PlatformInfo userPlatInfo) { + ZentaoConfig zentaoConfig = getConfig(); + if (userPlatInfo != null && StringUtils.isNotBlank(userPlatInfo.getZentaoUserName()) + && StringUtils.isNotBlank(userPlatInfo.getZentaoPassword())) { + zentaoConfig.setAccount(userPlatInfo.getZentaoUserName()); + zentaoConfig.setPassword(userPlatInfo.getZentaoPassword()); } -// validateConfig(jiraConfig); + zentaoClient.setConfig(zentaoConfig); return zentaoConfig; } @Override public List getPlatformUser() { - setConfig(); String session = zentaoClient.login();; HttpHeaders httpHeaders = new HttpHeaders(); HttpEntity> requestEntity = new HttpEntity<>(httpHeaders); @@ -328,15 +298,15 @@ public class ZentaoPlatform extends AbstractIssuePlatform { @Override public void syncIssues(Project project, List issues) { issues.forEach(item -> { - setConfig(); - IssuesDao issuesDao = getZentaoIssues(item); - issuesDao.setId(item.getId()); - issuesMapper.updateByPrimaryKeySelective(issuesDao); + IssuesWithBLOBs issue = issuesMapper.selectByPrimaryKey(item.getId()); + JSONObject bug = zentaoClient.getBugById(item.getPlatformId()); + issue = getUpdateIssues(issue, bug); + issue.setId(item.getId()); + issuesMapper.updateByPrimaryKeySelective(issue); }); } public List getBuilds() { - setConfig(); String session = zentaoClient.login();; String projectId1 = getProjectId(projectId); HttpHeaders httpHeaders = new HttpHeaders(); @@ -368,7 +338,6 @@ public class ZentaoPlatform extends AbstractIssuePlatform { private String uploadFile(FileSystemResource resource) { String id = ""; - zentaoClient.setConfig(getUserConfig()); String session = zentaoClient.login(); HttpHeaders httpHeaders = new HttpHeaders(); MultiValueMap paramMap = new LinkedMultiValueMap<>(); diff --git a/backend/src/main/java/io/metersphere/track/issue/client/JiraAbstractClient.java b/backend/src/main/java/io/metersphere/track/issue/client/JiraAbstractClient.java index ed5f770166..e3208f4a9f 100644 --- a/backend/src/main/java/io/metersphere/track/issue/client/JiraAbstractClient.java +++ b/backend/src/main/java/io/metersphere/track/issue/client/JiraAbstractClient.java @@ -6,6 +6,7 @@ import io.metersphere.track.issue.domain.Jira.JiraAddIssueResponse; import io.metersphere.track.issue.domain.Jira.JiraConfig; import io.metersphere.track.issue.domain.Jira.JiraField; import io.metersphere.track.issue.domain.Jira.JiraIssue; +import io.metersphere.track.issue.domain.Jira.JiraIssueListResponse; import org.apache.commons.lang3.StringUtils; import org.springframework.core.io.FileSystemResource; import org.springframework.http.*; @@ -124,4 +125,10 @@ public abstract class JiraAbstractClient extends BaseClient { USER_NAME = config.getAccount(); PASSWD = config.getPassword(); } + + public JiraIssueListResponse getProjectIssues(int startAt, int maxResults, String projectKey) { + ResponseEntity responseEntity; + responseEntity = restTemplate.exchange(getBaseUrl() + "/search?startAt={1}&maxResults={2}&jql=project={3}", HttpMethod.GET, getAuthHttpEntity(), String.class, startAt, maxResults, projectKey); + return (JiraIssueListResponse)getResultForObject(JiraIssueListResponse.class, responseEntity); + } } diff --git a/backend/src/main/java/io/metersphere/track/issue/client/TapdClient.java b/backend/src/main/java/io/metersphere/track/issue/client/TapdClient.java index 736d17af72..7d14c6f793 100644 --- a/backend/src/main/java/io/metersphere/track/issue/client/TapdClient.java +++ b/backend/src/main/java/io/metersphere/track/issue/client/TapdClient.java @@ -1,5 +1,6 @@ package io.metersphere.track.issue.client; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.LogUtil; @@ -14,6 +15,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; import java.util.List; import java.util.Map; @@ -41,6 +43,22 @@ public class TapdClient extends BaseClient { return JSONObject.parseObject(data, Map.class); } + public JSONArray getPlatformUser(String projectId) { + String url = getBaseUrl() + "/workspaces/users?workspace_id=" + projectId; + ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, getAuthHttpEntity(), String.class, projectId); + return JSONArray.parseArray(response.getBody()); + } + + public void auth() { + try { + RestTemplate restTemplate = new RestTemplate(); + restTemplate.exchange("https://api.tapd.cn/quickstart/testauth", HttpMethod.GET, getAuthHttpEntity(), String.class); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + MSException.throwException("验证失败: " + e.getMessage()); + } + } + public TapdGetIssueResponse getIssueForPageByIds(String projectId, int pageNum, int limit, List ids) { String url = getBaseUrl() + "/bugs?workspace_id={1}&page={2}&limit={3}&fields={4}"; StringBuilder idStr = new StringBuilder(); diff --git a/backend/src/main/java/io/metersphere/track/issue/client/ZentaoClient.java b/backend/src/main/java/io/metersphere/track/issue/client/ZentaoClient.java index e4d46a72a5..fe85113f45 100644 --- a/backend/src/main/java/io/metersphere/track/issue/client/ZentaoClient.java +++ b/backend/src/main/java/io/metersphere/track/issue/client/ZentaoClient.java @@ -1,5 +1,6 @@ package io.metersphere.track.issue.client; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.LogUtil; @@ -24,9 +25,7 @@ public abstract class ZentaoClient extends BaseClient { public RequestUrl requestUrl; protected String url; - public ZentaoClient(String url) { - ENDPOINT = url; - } + private static final String BUG_LIST_URL="?m=bug&f=browse&productID={0}&branch=&browseType=¶m=0&orderBy=&pageID={1}&recPerPage={2}&t=json&zentaosid="; public String login() { GetUserResponse getUserResponse = new GetUserResponse(); @@ -115,6 +114,13 @@ public abstract class ZentaoClient extends BaseClient { return JSONObject.parseObject(getIssueResponse.getData()); } + public JSONArray getBugsByProjectId(String projectId, int pageNum, int pageSize) { + String sessionId = login(); + ResponseEntity response = restTemplate.exchange(getBaseUrl() + BUG_LIST_URL, + HttpMethod.GET, null, String.class, projectId, pageNum, pageSize, sessionId); + return JSONObject.parseObject(response.getBody()).getJSONObject("data").getJSONArray("bugs"); + } + protected String getBaseUrl() { if (ENDPOINT.endsWith("/")) { return ENDPOINT.substring(0, ENDPOINT.length() - 1); diff --git a/backend/src/main/java/io/metersphere/track/issue/client/ZentaoGetClient.java b/backend/src/main/java/io/metersphere/track/issue/client/ZentaoGetClient.java index 4342a077aa..699ef58fd4 100644 --- a/backend/src/main/java/io/metersphere/track/issue/client/ZentaoGetClient.java +++ b/backend/src/main/java/io/metersphere/track/issue/client/ZentaoGetClient.java @@ -37,10 +37,6 @@ public class ZentaoGetClient extends ZentaoClient { requestUrl = request; } - public ZentaoGetClient(String url) { - super(url); - } - private String getUrl(String url) { return getBaseUrl() + "/?m=api&f=getModel" + url; } diff --git a/backend/src/main/java/io/metersphere/track/issue/client/ZentaoPathInfoClient.java b/backend/src/main/java/io/metersphere/track/issue/client/ZentaoPathInfoClient.java index 68d113c96f..14b0b14144 100644 --- a/backend/src/main/java/io/metersphere/track/issue/client/ZentaoPathInfoClient.java +++ b/backend/src/main/java/io/metersphere/track/issue/client/ZentaoPathInfoClient.java @@ -20,7 +20,7 @@ public class ZentaoPathInfoClient extends ZentaoClient { private static final String REPLACE_IMG_URL = ""; private static final Pattern IMG_PATTERN = Pattern.compile("file-read-(.*?)\"/>"); - RequestUrl request = new RequestUrl(); + protected RequestUrl request = new RequestUrl(); { request.setLogin(getUrl(LOGIN)); @@ -38,11 +38,7 @@ public class ZentaoPathInfoClient extends ZentaoClient { requestUrl = request; } - public ZentaoPathInfoClient(String url) { - super(url); - } - - private String getUrl(String url) { + protected String getUrl(String url) { return getBaseUrl() + url; } } diff --git a/backend/src/main/java/io/metersphere/track/issue/domain/Jira/JiraIssueListResponse.java b/backend/src/main/java/io/metersphere/track/issue/domain/Jira/JiraIssueListResponse.java new file mode 100644 index 0000000000..fce0f42d2c --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/issue/domain/Jira/JiraIssueListResponse.java @@ -0,0 +1,16 @@ +package io.metersphere.track.issue.domain.Jira; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class JiraIssueListResponse { + private String expand; + private int startAt; + private int maxResults; + private int total; + private List issues; +} diff --git a/backend/src/main/java/io/metersphere/track/issue/domain/zentao/ZentaoConfig.java b/backend/src/main/java/io/metersphere/track/issue/domain/zentao/ZentaoConfig.java index 31d3ce1cd3..3b5300e7b7 100644 --- a/backend/src/main/java/io/metersphere/track/issue/domain/zentao/ZentaoConfig.java +++ b/backend/src/main/java/io/metersphere/track/issue/domain/zentao/ZentaoConfig.java @@ -10,4 +10,5 @@ public class ZentaoConfig { private String password; private String url; private String requestType; + private String request; } 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 index eb0b2be41d..24811bce87 100644 --- a/backend/src/main/java/io/metersphere/track/request/testcase/IssuesRequest.java +++ b/backend/src/main/java/io/metersphere/track/request/testcase/IssuesRequest.java @@ -36,4 +36,5 @@ public class IssuesRequest extends BaseQueryRequest { private String requestType; private String status; + private String defaultCustomFields; } 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 716402a21f..fd9b5f9a2d 100644 --- a/backend/src/main/java/io/metersphere/track/service/IssuesService.java +++ b/backend/src/main/java/io/metersphere/track/service/IssuesService.java @@ -1,6 +1,7 @@ package io.metersphere.track.service; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; @@ -12,11 +13,13 @@ import io.metersphere.commons.constants.IssuesStatus; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.*; import io.metersphere.controller.request.IntegrationRequest; +import io.metersphere.dto.CustomFieldTemplateDao; +import io.metersphere.dto.IssueTemplateDao; import io.metersphere.log.utils.ReflexObjectUtil; import io.metersphere.log.vo.DetailColumn; import io.metersphere.log.vo.OperatingLogDetails; import io.metersphere.log.vo.track.TestPlanReference; -import io.metersphere.notice.service.NoticeSendService; +import io.metersphere.service.CustomFieldTemplateService; import io.metersphere.service.IntegrationService; import io.metersphere.service.IssueTemplateService; import io.metersphere.service.ProjectService; @@ -59,15 +62,13 @@ public class IssuesService { @Resource private IssuesMapper issuesMapper; @Resource - private NoticeSendService noticeSendService; - @Resource private TestCaseIssuesMapper testCaseIssuesMapper; @Resource private IssueTemplateMapper issueTemplateMapper; @Resource private ExtIssuesMapper extIssuesMapper; @Resource - private WorkspaceMapper workspaceMapper; + private CustomFieldTemplateService customFieldTemplateService; @Resource private IssueTemplateService issueTemplateService; @Resource @@ -442,6 +443,9 @@ public class IssuesService { IssuesRequest issuesRequest = new IssuesRequest(); issuesRequest.setProjectId(projectId); issuesRequest.setWorkspaceId(project.getWorkspaceId()); + String defaultCustomFields = getDefaultCustomFields(projectId); + issuesRequest.setDefaultCustomFields(defaultCustomFields); + if (CollectionUtils.isNotEmpty(tapdIssues)) { TapdPlatform tapdPlatform = new TapdPlatform(issuesRequest); syncThirdPartyIssues(tapdPlatform::syncIssues, project, tapdIssues); @@ -468,6 +472,33 @@ public class IssuesService { } } + /** + * 获取默认的自定义字段的取值,同步之后更新成第三方平台的值 + * @param projectId + * @return + */ + public String getDefaultCustomFields(String projectId) { + IssueTemplateDao template = issueTemplateService.getTemplate(projectId); + CustomFieldTemplate request = new CustomFieldTemplate(); + request.setTemplateId(template.getId()); + List customFields = customFieldTemplateService.list(request); + + JSONArray fields = new JSONArray(); + customFields.forEach(item -> { + JSONObject field = new JSONObject(true); + field.put("customData", item.getCustomData()); + field.put("id", item.getId()); + field.put("name", item.getName()); + field.put("type", item.getType()); + String defaultValue = item.getDefaultValue(); + if (StringUtils.isNotBlank(defaultValue)) { + field.put("value", JSONObject.parse(defaultValue)); + } + fields.add(field); + }); + return fields.toJSONString(); + } + public void syncThirdPartyIssues(BiConsumer> syncFuc, Project project, List issues) { try { syncFuc.accept(project, issues); diff --git a/backend/src/main/java/io/metersphere/xpack b/backend/src/main/java/io/metersphere/xpack index 1a1a00814f..b699018b5e 160000 --- a/backend/src/main/java/io/metersphere/xpack +++ b/backend/src/main/java/io/metersphere/xpack @@ -1 +1 @@ -Subproject commit 1a1a00814f367d827975b524781771b74a7e7938 +Subproject commit b699018b5e5cd513f24a3db091c97280f859b54e