refactor: 开源自动获取Jira模板功能
This commit is contained in:
parent
3ab559ef19
commit
7152640161
|
@ -160,7 +160,7 @@ public class ApiTestEnvironmentService {
|
|||
}
|
||||
|
||||
String apiName = MockConfigStaticData.MOCK_EVN_NAME;
|
||||
ApiTestEnvironmentWithBLOBs returnModel = null;
|
||||
ApiTestEnvironmentWithBLOBs returnModel;
|
||||
ApiTestEnvironmentExample example = new ApiTestEnvironmentExample();
|
||||
example.createCriteria().andProjectIdEqualTo(projectId).andNameEqualTo(apiName);
|
||||
List<ApiTestEnvironmentWithBLOBs> list = this.selectByExampleWithBLOBs(example);
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.metersphere.base.mapper.*;
|
|||
import io.metersphere.base.mapper.ext.ExtProjectMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtUserGroupMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtUserMapper;
|
||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||
import io.metersphere.commons.constants.UserGroupConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
|
@ -105,6 +106,9 @@ public class ProjectService {
|
|||
if (projectMapper.countByExample(example) > 0) {
|
||||
MSException.throwException(Translator.get("project_name_already_exists"));
|
||||
}
|
||||
if (StringUtils.isBlank(project.getPlatform())) {
|
||||
project.setPlatform(IssuesManagePlatform.Local.name());
|
||||
}
|
||||
project.setId(UUID.randomUUID().toString());
|
||||
|
||||
String systemId = this.genSystemId();
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.metersphere.commons.constants.NoticeConstants;
|
|||
import io.metersphere.commons.constants.OperLogConstants;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.dto.IssueTemplateDao;
|
||||
import io.metersphere.log.annotation.MsAuditLog;
|
||||
import io.metersphere.notice.annotation.SendNotice;
|
||||
import io.metersphere.track.issue.domain.PlatformUser;
|
||||
|
@ -144,4 +145,9 @@ public class IssuesController {
|
|||
public void saveFollows(@PathVariable String issueId,@RequestBody List<String> follows) {
|
||||
issuesService.saveFollows(issueId,follows);
|
||||
}
|
||||
|
||||
@GetMapping("/thirdpart/template/{projectId}")
|
||||
public IssueTemplateDao getThirdPartTemplate(@PathVariable String projectId) {
|
||||
return issuesService.getThirdPartTemplate(projectId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -492,7 +492,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
|
|||
|
||||
public boolean isThirdPartTemplate() {
|
||||
Project project = projectService.getProjectById(projectId);
|
||||
if (project.getThirdPartTemplate() != null && project.getThirdPartTemplate() && LicenseUtils.valid()) {
|
||||
if (project.getThirdPartTemplate() != null && project.getThirdPartTemplate()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -5,19 +5,20 @@ import com.alibaba.fastjson.JSONObject;
|
|||
import io.metersphere.base.domain.IssuesDao;
|
||||
import io.metersphere.base.domain.IssuesWithBLOBs;
|
||||
import io.metersphere.base.domain.Project;
|
||||
import io.metersphere.commons.constants.CustomFieldType;
|
||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||
import io.metersphere.commons.constants.IssuesStatus;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.dto.CustomFieldDao;
|
||||
import io.metersphere.dto.CustomFieldItemDTO;
|
||||
import io.metersphere.dto.IssueTemplateDao;
|
||||
import io.metersphere.dto.UserDTO;
|
||||
import io.metersphere.service.CustomFieldService;
|
||||
import io.metersphere.track.dto.DemandDTO;
|
||||
import io.metersphere.track.issue.client.JiraClientV2;
|
||||
import io.metersphere.track.issue.domain.PlatformUser;
|
||||
import io.metersphere.track.issue.domain.jira.JiraAddIssueResponse;
|
||||
import io.metersphere.track.issue.domain.jira.JiraConfig;
|
||||
import io.metersphere.track.issue.domain.jira.JiraIssue;
|
||||
import io.metersphere.track.issue.domain.jira.*;
|
||||
import io.metersphere.track.request.testcase.IssuesRequest;
|
||||
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
@ -28,9 +29,11 @@ import org.commonmark.renderer.html.HtmlRenderer;
|
|||
import org.springframework.web.client.HttpClientErrorException;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class JiraPlatform extends AbstractIssuePlatform {
|
||||
|
||||
|
@ -348,4 +351,179 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
public JiraConfig setUserConfig() {
|
||||
return setUserConfig(getUserPlatInfo(this.workspaceId));
|
||||
}
|
||||
|
||||
public IssueTemplateDao getThirdPartTemplate() {
|
||||
Set<String> ignoreSet = new HashSet() {{
|
||||
add("timetracking");
|
||||
add("attachment");
|
||||
}};
|
||||
JiraConfig config = getConfig();
|
||||
String projectKey = getProjectId(this.projectId);
|
||||
Map<String, JiraCreateMetadataResponse.Field> createMetadata = jiraClientV2.getCreateMetadata(projectKey, config.getIssuetype());
|
||||
String userOptions = getUserOptions(projectKey);
|
||||
List<CustomFieldDao> fields = new ArrayList<>();
|
||||
char filedKey = 'A';
|
||||
for (String name : createMetadata.keySet()) {
|
||||
JiraCreateMetadataResponse.Field item = createMetadata.get(name);
|
||||
if (ignoreSet.contains(name)) continue; // timetracking, attachment todo
|
||||
JiraCreateMetadataResponse.Schema schema = item.getSchema();
|
||||
CustomFieldDao customFieldDao = new CustomFieldDao();
|
||||
customFieldDao.setKey(String.valueOf(filedKey++));
|
||||
customFieldDao.setId(name);
|
||||
customFieldDao.setCustomData(name);
|
||||
customFieldDao.setName(item.getName());
|
||||
customFieldDao.setRequired(item.isRequired());
|
||||
setCustomFiledType(schema, customFieldDao, userOptions);
|
||||
setCustomFiledDefaultValue(customFieldDao, item);
|
||||
JSONArray options = getAllowedValuesOptions(item.getAllowedValues());
|
||||
if (options != null)
|
||||
customFieldDao.setOptions(options.toJSONString());
|
||||
fields.add(customFieldDao);
|
||||
}
|
||||
|
||||
fields = fields.stream().filter(i -> StringUtils.isNotBlank(i.getType()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 按类型排序,富文本排最后,input 排最前面,summary 排第一个
|
||||
fields.sort((a, b) -> {
|
||||
if (a.getType().equals(CustomFieldType.RICH_TEXT.getValue())) return 1;
|
||||
if (b.getType().equals(CustomFieldType.RICH_TEXT.getValue())) return -1;
|
||||
if (a.getId().equals("summary")) return -1;
|
||||
if (b.getId().equals("summary")) return 1;
|
||||
if (a.getType().equals(CustomFieldType.INPUT.getValue())) return -1;
|
||||
if (b.getType().equals(CustomFieldType.INPUT.getValue())) return 1;
|
||||
return a.getType().compareTo(b.getType());
|
||||
});
|
||||
IssueTemplateDao issueTemplateDao = new IssueTemplateDao();
|
||||
issueTemplateDao.setCustomFields(fields);
|
||||
issueTemplateDao.setPlatform(this.key);
|
||||
return issueTemplateDao;
|
||||
}
|
||||
|
||||
private void setCustomFiledType(JiraCreateMetadataResponse.Schema schema, CustomFieldDao customFieldDao, String userOptions) {
|
||||
Map<String, String> fieldTypeMap = new HashMap() {{
|
||||
put("summary", CustomFieldType.INPUT.getValue());
|
||||
put("description", CustomFieldType.RICH_TEXT.getValue());
|
||||
put("components", CustomFieldType.MULTIPLE_SELECT.getValue());
|
||||
put("fixVersions", CustomFieldType.MULTIPLE_SELECT.getValue());
|
||||
put("versions", CustomFieldType.MULTIPLE_SELECT.getValue());
|
||||
put("priority", CustomFieldType.SELECT.getValue());
|
||||
put("environment", CustomFieldType.RICH_TEXT.getValue());
|
||||
put("labels", CustomFieldType.MULTIPLE_INPUT.getValue());
|
||||
}};
|
||||
String customType = schema.getCustom();
|
||||
String value = null;
|
||||
if (StringUtils.isNotBlank(customType)) {
|
||||
// 自定义字段
|
||||
if (customType.contains("multiselect")) {
|
||||
value = CustomFieldType.MULTIPLE_SELECT.getValue();
|
||||
} else if (customType.contains("cascadingselect")) {
|
||||
value = "cascadingSelect";
|
||||
} else if (customType.contains("userpicker")) {
|
||||
value = CustomFieldType.SELECT.getValue();
|
||||
customFieldDao.setOptions(userOptions);
|
||||
} else if (customType.contains("multicheckboxes")) {
|
||||
value = CustomFieldType.CHECKBOX.getValue();
|
||||
customFieldDao.setDefaultValue(JSONObject.toJSONString(new ArrayList<>()));
|
||||
} else if (customType.contains("radiobuttons")) {
|
||||
value = CustomFieldType.RADIO.getValue();
|
||||
} else if (customType.contains("textfield")) {
|
||||
value = CustomFieldType.INPUT.getValue();
|
||||
} else if (customType.contains("datetime")) {
|
||||
value = CustomFieldType.DATETIME.getValue();
|
||||
} else if (customType.contains("datepicker")) {
|
||||
value = CustomFieldType.DATE.getValue();
|
||||
} else if (customType.contains("float")) {
|
||||
value = CustomFieldType.FLOAT.getValue();
|
||||
} else if (customType.contains("select")) {
|
||||
value = CustomFieldType.SELECT.getValue();
|
||||
} else if (customType.contains("url")) {
|
||||
value = CustomFieldType.INPUT.getValue();
|
||||
} else if (customType.contains("textarea")) {
|
||||
value = CustomFieldType.TEXTAREA.getValue();
|
||||
} else if (customType.contains("labels")) {
|
||||
value = CustomFieldType.MULTIPLE_INPUT.getValue();
|
||||
}
|
||||
} else {
|
||||
// 系统字段
|
||||
value = fieldTypeMap.get(customFieldDao.getId());
|
||||
String type = schema.getType();
|
||||
if ("user".equals(type)) {
|
||||
value = CustomFieldType.SELECT.getValue();
|
||||
customFieldDao.setOptions(userOptions);
|
||||
} else if ("date".equals(type)) {
|
||||
value = CustomFieldType.DATE.getValue();
|
||||
} else if ("datetime".equals(type)) {
|
||||
value = CustomFieldType.DATETIME.getValue();
|
||||
}
|
||||
}
|
||||
customFieldDao.setType(value);
|
||||
}
|
||||
|
||||
private void setCustomFiledDefaultValue(CustomFieldDao customFieldDao, JiraCreateMetadataResponse.Field item) {
|
||||
if (item.isHasDefaultValue()) {
|
||||
Object defaultValue = item.getDefaultValue();
|
||||
if (defaultValue != null) {
|
||||
Object msDefaultValue;
|
||||
if (defaultValue instanceof JSONObject) {
|
||||
msDefaultValue = ((JSONObject) defaultValue).get("id");
|
||||
} else if (defaultValue instanceof JSONArray) {
|
||||
List defaultList = new ArrayList();
|
||||
((JSONArray) defaultValue).forEach(i -> {
|
||||
if (i instanceof JSONObject) {
|
||||
JSONObject obj = (JSONObject) i;
|
||||
defaultList.add(obj.get("id"));
|
||||
} else {
|
||||
defaultList.add(i);
|
||||
}
|
||||
});
|
||||
|
||||
msDefaultValue = defaultList;
|
||||
} else {
|
||||
if (customFieldDao.getType().equals(CustomFieldType.DATE.getValue())) {
|
||||
msDefaultValue = Instant.ofEpochMilli((Long) defaultValue).atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
} else if (customFieldDao.getType().equals(CustomFieldType.DATETIME.getValue())) {
|
||||
msDefaultValue = LocalDateTime.ofInstant(Instant.ofEpochMilli((Long) defaultValue), ZoneId.systemDefault()).toString();
|
||||
} else {
|
||||
msDefaultValue = defaultValue;
|
||||
}
|
||||
}
|
||||
customFieldDao.setDefaultValue(JSONObject.toJSONString(msDefaultValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JSONArray getAllowedValuesOptions(List<JiraCreateMetadataResponse.AllowedValues> allowedValues) {
|
||||
if (allowedValues != null) {
|
||||
JSONArray options = new JSONArray();
|
||||
allowedValues.forEach(val -> {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("value", val.getId());
|
||||
if (StringUtils.isNotBlank(val.getName())) {
|
||||
jsonObject.put("text", val.getName());
|
||||
} else {
|
||||
jsonObject.put("text", val.getValue());
|
||||
}
|
||||
JSONArray children = getAllowedValuesOptions(val.getChildren());
|
||||
if (children != null) {
|
||||
jsonObject.put("children", children);
|
||||
}
|
||||
options.add(jsonObject);
|
||||
});
|
||||
return options;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getUserOptions(String projectKey) {
|
||||
List<JiraUser> userOptions = jiraClientV2.getAssignableUser(projectKey);
|
||||
JSONArray options = new JSONArray();
|
||||
userOptions.forEach(val -> {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("value", val.getAccountId());
|
||||
jsonObject.put("text", val.getDisplayName());
|
||||
options.add(jsonObject);
|
||||
});
|
||||
return options.toJSONString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -635,4 +635,15 @@ public class IssuesService {
|
|||
return issuesMapper.selectByExampleWithBLOBs(example);
|
||||
}
|
||||
|
||||
public IssueTemplateDao getThirdPartTemplate(String projectId) {
|
||||
if (StringUtils.isNotBlank(projectId)) {
|
||||
Project project = projectService.getProjectById(projectId);
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setProjectId(projectId);
|
||||
issuesRequest.setWorkspaceId(project.getWorkspaceId());
|
||||
return IssueFactory.createPlatform(IssuesManagePlatform.Jira.toString(), issuesRequest)
|
||||
.getThirdPartTemplate();
|
||||
}
|
||||
return new IssueTemplateDao();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit b0c13798836a8bfbc1d415bc5a9610c56df61833
|
||||
Subproject commit a618ef0fb1ae45790e0c7de9805c8ff17c9df5be
|
|
@ -7,7 +7,7 @@
|
|||
<el-input v-model="form.name" autocomplete="off"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="platformOptions.length > 1" :label-width="labelWidth" :label="$t('集成第三方平台')"
|
||||
<el-form-item v-if="platformOptions.length > 1" :label-width="labelWidth" :label="$t('test_track.issue.third_party_integrated')"
|
||||
prop="platform">
|
||||
<el-select filterable v-model="form.platform">
|
||||
<el-option v-for="item in platformOptions" :key="item.value" :label="item.text" :value="item.value">
|
||||
|
@ -19,11 +19,11 @@
|
|||
<template-select :data="form" scene="API_CASE" prop="caseTemplateId" ref="caseTemplate"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="xpackEable" :label-width="labelWidth" :label="$t('使用第三方平台模板')" prop="scenarioCustomNum">
|
||||
<el-form-item v-if="form.platform == 'Jira'" :label-width="labelWidth" :label="$t('test_track.issue.use_third_party')" prop="scenarioCustomNum">
|
||||
<el-switch v-model="form.thirdPartTemplate"></el-switch>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="!xpackEable || !form.thirdPartTemplate" :label-width="labelWidth"
|
||||
<el-form-item v-if="!form.thirdPartTemplate" :label-width="labelWidth"
|
||||
:label="$t('workspace.issue_template_manage')" prop="issueTemplateId">
|
||||
<template-select :platform="form.platform" :data="form" scene="ISSUE" prop="issueTemplateId"
|
||||
ref="issueTemplate"/>
|
||||
|
@ -164,8 +164,7 @@ export default {
|
|||
},
|
||||
screenHeight: 'calc(100vh - 195px)',
|
||||
labelWidth: '150px',
|
||||
platformOptions: [],
|
||||
xpackEable: false
|
||||
platformOptions: []
|
||||
};
|
||||
},
|
||||
props: {
|
||||
|
@ -183,7 +182,6 @@ export default {
|
|||
this.create();
|
||||
this.$router.replace('/setting/project/all');
|
||||
}
|
||||
this.xpackEable = hasLicense();
|
||||
},
|
||||
computed: {
|
||||
currentUser: () => {
|
||||
|
@ -242,7 +240,7 @@ export default {
|
|||
if (platforms.indexOf(platform) === -1) {
|
||||
for (let i = 0; i < this.platformOptions.length; i++) {
|
||||
if (this.platformOptions[i].value === platform) {
|
||||
this.platformOptions.splice(1, i);
|
||||
this.platformOptions.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ export function deleteIssueRelate(param, callback) {
|
|||
|
||||
export function getIssueThirdPartTemplate() {
|
||||
return new Promise(resolve => {
|
||||
baseGet('/xpack/issue/template/' + getCurrentProjectID(), (data) => {
|
||||
baseGet('/issues/thirdpart/template/' + getCurrentProjectID(), (data) => {
|
||||
let template = data;
|
||||
if (template.customFields) {
|
||||
template.customFields.forEach(item => {
|
||||
|
@ -129,7 +129,7 @@ export function getIssuePartTemplateWithProject(callback) {
|
|||
}
|
||||
|
||||
export function enableThirdPartTemplate(currentProject) {
|
||||
return hasLicense() && currentProject && currentProject.thirdPartTemplate && currentProject.platform === JIRA;
|
||||
return currentProject && currentProject.thirdPartTemplate && currentProject.platform === JIRA;
|
||||
}
|
||||
|
||||
export function isThirdPartEnable(callback) {
|
||||
|
|
Loading…
Reference in New Issue