mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-12-02 12:09:13 +08:00
refactor(缺陷管理): 优化第三方插件模板字段&&同步逻辑
This commit is contained in:
parent
3f6ba6680c
commit
a4e739eee8
@ -9,9 +9,9 @@ import java.util.Map;
|
||||
public class DemandRelatePageResponse {
|
||||
|
||||
/**
|
||||
* 自定义表头字段
|
||||
* 自定义表头字段(支持过滤)
|
||||
*/
|
||||
private Map<String, String> customHeaderMap;
|
||||
private List<PlatformCustomFieldItemDTO> customHeaders;
|
||||
/**
|
||||
* 需求列表数据
|
||||
*/
|
||||
|
@ -19,5 +19,5 @@ public class PlatformBugDTO extends MsSyncBugDTO {
|
||||
/**
|
||||
* 缺陷同步所需处理的平台自定义字段ID(同步第三方平台到MS时需要, 非默认模板时使用)
|
||||
*/
|
||||
private List<String> needSyncCustomFields;
|
||||
private List<PlatformCustomFieldItemDTO> needSyncCustomFields;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import lombok.Data;
|
||||
@Data
|
||||
public class PluginPager<T> {
|
||||
|
||||
private T list;
|
||||
private T data;
|
||||
private long total;
|
||||
private long pageSize;
|
||||
private long current;
|
||||
@ -13,8 +13,15 @@ public class PluginPager<T> {
|
||||
public PluginPager() {
|
||||
}
|
||||
|
||||
public PluginPager(long pageSize, long current) {
|
||||
this.data = null;
|
||||
this.total = 0;
|
||||
this.pageSize = pageSize;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
public PluginPager(T list, long total, long pageSize, long current) {
|
||||
this.list = list;
|
||||
this.data = list;
|
||||
this.total = total;
|
||||
this.pageSize = pageSize;
|
||||
this.current = current;
|
||||
|
@ -394,8 +394,14 @@ public class BugService {
|
||||
// 非平台默认模板, 需处理MS模板中映射的字段
|
||||
if (!platformBug.getPlatformDefaultTemplate()) {
|
||||
List<TemplateCustomField> templateCustomFields = templateFieldMap.get(platformBug.getTemplateId());
|
||||
List<String> needSyncApiFields = templateCustomFields.stream().map(TemplateCustomField::getApiFieldId).filter(StringUtils::isNotBlank).toList();
|
||||
platformBug.setNeedSyncCustomFields(needSyncApiFields);
|
||||
List<PlatformCustomFieldItemDTO> needSyncFields = templateCustomFields.stream().filter(templateCustomField -> StringUtils.isNotBlank(templateCustomField.getApiFieldId())).map(templateCustomField -> {
|
||||
PlatformCustomFieldItemDTO needSyncField = new PlatformCustomFieldItemDTO();
|
||||
needSyncField.setId(templateCustomField.getFieldId());
|
||||
needSyncField.setCustomData(templateCustomField.getApiFieldId());
|
||||
return needSyncField;
|
||||
}).toList();
|
||||
// 需同步的自定义字段
|
||||
platformBug.setNeedSyncCustomFields(needSyncFields);
|
||||
}
|
||||
});
|
||||
request.setBugs(platformBugs);
|
||||
@ -467,13 +473,16 @@ public class BugService {
|
||||
// 来自平台模板
|
||||
templateDTO.setPlatformDefault(false);
|
||||
String platformName = projectApplicationService.getPlatformName(projectId);
|
||||
// TODO: 严重程度
|
||||
|
||||
// 状态字段
|
||||
attachTemplateStatusField(templateDTO, projectId, fromStatusId, platformBugKey);
|
||||
|
||||
// 处理人字段
|
||||
if (!StringUtils.equals(platformName, BugPlatform.LOCAL.getName())) {
|
||||
// 获取插件中自定义的注入字段(处理人)
|
||||
ServiceIntegration serviceIntegration = projectApplicationService.getPlatformServiceIntegrationWithSyncOrDemand(projectId, true);
|
||||
if (serviceIntegration == null) {
|
||||
return null;
|
||||
}
|
||||
// 状态选项获取时, 获取平台校验了服务集成配置, 所以此处不需要再次校验
|
||||
Platform platform = platformPluginService.getPlatform(serviceIntegration.getPluginId(), serviceIntegration.getOrganizationId(),
|
||||
new String(serviceIntegration.getConfiguration()));
|
||||
AbstractPlatformPlugin platformPlugin = (AbstractPlatformPlugin) pluginLoadService.getMsPluginManager().getPlugin(serviceIntegration.getPluginId()).getPlugin();
|
||||
@ -489,7 +498,7 @@ public class BugService {
|
||||
request.setOptionMethod(injectField.getOptionMethod());
|
||||
request.setProjectConfig(projectApplicationService.getProjectBugThirdPartConfig(projectId));
|
||||
templateCustomFieldDTO.setPlatformOptionJson(JSON.toJSONString(platform.getFormOptions(request)));
|
||||
templateDTO.getCustomFields().addLast(templateCustomFieldDTO);
|
||||
templateDTO.getCustomFields().addFirst(templateCustomFieldDTO);
|
||||
}
|
||||
} else {
|
||||
// Local(处理人)
|
||||
@ -508,11 +517,10 @@ public class BugService {
|
||||
handleUserField.setType(CustomFieldType.SELECT.getType());
|
||||
handleUserField.setPlatformOptionJson(JSON.toJSONString(projectMemberOptions));
|
||||
handleUserField.setRequired(true);
|
||||
templateDTO.getCustomFields().addLast(handleUserField);
|
||||
templateDTO.getCustomFields().addFirst(handleUserField);
|
||||
}
|
||||
// TODO: 严重程度
|
||||
// 状态字段
|
||||
return attachTemplateStatusField(templateDTO, projectId, fromStatusId, platformBugKey);
|
||||
|
||||
return templateDTO;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -523,14 +531,17 @@ public class BugService {
|
||||
* @param platformBugKey 平台缺陷key
|
||||
* @return 模板
|
||||
*/
|
||||
private TemplateDTO attachTemplateStatusField(TemplateDTO templateDTO , String projectId, String fromStatusId, String platformBugKey) {
|
||||
public TemplateDTO attachTemplateStatusField(TemplateDTO templateDTO , String projectId, String fromStatusId, String platformBugKey) {
|
||||
if (templateDTO == null) {
|
||||
return null;
|
||||
}
|
||||
TemplateCustomFieldDTO statusField = new TemplateCustomFieldDTO();
|
||||
statusField.setFieldId(BugTemplateCustomField.STATUS.getId());
|
||||
statusField.setFieldName(BugTemplateCustomField.STATUS.getName());
|
||||
statusField.setType(CustomFieldType.SELECT.getType());
|
||||
statusField.setPlatformOptionJson(JSON.toJSONString(bugStatusService.getToStatusItemOption(projectId, fromStatusId, platformBugKey)));
|
||||
statusField.setRequired(true);
|
||||
templateDTO.getCustomFields().addLast(statusField);
|
||||
templateDTO.getCustomFields().addFirst(statusField);
|
||||
return templateDTO;
|
||||
}
|
||||
|
||||
@ -556,8 +567,8 @@ public class BugService {
|
||||
|
||||
// 设置基础字段
|
||||
if (StringUtils.equalsIgnoreCase(BugPlatform.LOCAL.getName(), platformName)) {
|
||||
bug.setPlatformBugId(null);
|
||||
// Local缺陷处理人从自定义字段中获取
|
||||
bug.setPlatformBugId(null);
|
||||
// Local缺陷处理人从自定义字段中获取
|
||||
Optional<BugCustomFieldDTO> handleUserField = request.getCustomFields().stream().filter(field -> StringUtils.equals(field.getId(), BugTemplateCustomField.HANDLE_USER.getId())).findFirst();
|
||||
if (handleUserField.isPresent()) {
|
||||
bug.setHandleUser(handleUserField.get().getValue());
|
||||
@ -566,19 +577,21 @@ public class BugService {
|
||||
throw new MSException(Translator.get("handle_user_can_not_be_empty"));
|
||||
}
|
||||
} else {
|
||||
bug.setPlatformBugId(platformBug.getPlatformBugKey());
|
||||
if (StringUtils.isNotBlank(platformBug.getPlatformTitle())) {
|
||||
bug.setPlatformBugId(platformBug.getPlatformBugKey());
|
||||
if (StringUtils.isNotBlank(platformBug.getPlatformTitle())) {
|
||||
bug.setTitle(platformBug.getPlatformTitle());
|
||||
}
|
||||
if (StringUtils.isNotBlank(platformBug.getPlatformDescription())) {
|
||||
}
|
||||
if (StringUtils.isNotBlank(platformBug.getPlatformDescription())) {
|
||||
request.setDescription(platformBug.getPlatformDescription());
|
||||
}
|
||||
if (StringUtils.isNotBlank(platformBug.getPlatformHandleUser())) {
|
||||
}
|
||||
if (StringUtils.isNotBlank(platformBug.getPlatformHandleUser())) {
|
||||
bug.setHandleUser(platformBug.getPlatformHandleUser());
|
||||
}
|
||||
if (StringUtils.isNotBlank(platformBug.getPlatformStatus())) {
|
||||
}
|
||||
if (StringUtils.isNotBlank(platformBug.getPlatformStatus())) {
|
||||
bug.setStatus(platformBug.getPlatformStatus());
|
||||
}
|
||||
}
|
||||
// 第三方平台内置的处理人字段需要从自定义字段中移除
|
||||
request.getCustomFields().removeIf(field -> StringUtils.startsWith(field.getName(), BugTemplateCustomField.HANDLE_USER.getName()));
|
||||
}
|
||||
|
||||
//保存基础信息
|
||||
@ -857,7 +870,7 @@ public class BugService {
|
||||
*/
|
||||
TemplateDTO pluginDefaultTemplate = getPluginBugDefaultTemplate(request.getProjectId(), false);
|
||||
// 参数模板为插件默认模板, 处理所有自定义字段, 无需过滤API映射
|
||||
boolean noApiFilter = StringUtils.equals(pluginDefaultTemplate.getId(), request.getTemplateId());
|
||||
boolean noApiFilter = pluginDefaultTemplate != null && StringUtils.equals(pluginDefaultTemplate.getId(), request.getTemplateId());
|
||||
platformRequest.setCustomFieldList(transferCustomToPlatformField(request.getTemplateId(), request.getCustomFields(), noApiFilter));
|
||||
// TITLE, DESCRIPTION 传到平台插件处理
|
||||
platformRequest.setTitle(request.getTitle());
|
||||
@ -971,6 +984,9 @@ public class BugService {
|
||||
ServiceIntegration serviceIntegration = projectApplicationService.getPlatformServiceIntegrationWithSyncOrDemand(projectId, true);
|
||||
TemplateDTO template = new TemplateDTO();
|
||||
Template pluginTemplate = projectTemplateService.getPluginBugTemplate(projectId);
|
||||
if (pluginTemplate == null) {
|
||||
return null;
|
||||
}
|
||||
BeanUtils.copyBean(template, pluginTemplate);
|
||||
if (setPluginTemplateField) {
|
||||
Platform platform = platformPluginService.getPlatform(serviceIntegration.getPluginId(), serviceIntegration.getOrganizationId(),
|
||||
@ -1000,7 +1016,7 @@ public class BugService {
|
||||
* @param projectId 项目ID
|
||||
*/
|
||||
public void clearAssociate(String bugId, String projectId) {
|
||||
// 清空附件关系表及附件表
|
||||
// 清空附件关系及本地附件
|
||||
FileAssociationExample example = new FileAssociationExample();
|
||||
example.createCriteria().andSourceIdEqualTo(bugId).andSourceTypeEqualTo(FileAssociationSourceUtil.SOURCE_TYPE_BUG);
|
||||
fileAssociationMapper.deleteByExample(example);
|
||||
@ -1016,7 +1032,7 @@ public class BugService {
|
||||
}
|
||||
});
|
||||
bugLocalAttachmentMapper.deleteByExample(attachmentExample);
|
||||
// 清空关联用例表
|
||||
// 清空关联用例
|
||||
BugRelationCaseExample relationCaseExample = new BugRelationCaseExample();
|
||||
relationCaseExample.createCriteria().andBugIdEqualTo(bugId);
|
||||
bugRelationCaseMapper.deleteByExample(relationCaseExample);
|
||||
@ -1024,6 +1040,10 @@ public class BugService {
|
||||
BugCustomFieldExample customFieldExample = new BugCustomFieldExample();
|
||||
customFieldExample.createCriteria().andBugIdEqualTo(bugId);
|
||||
bugCustomFieldMapper.deleteByExample(customFieldExample);
|
||||
// 清空缺陷内容
|
||||
BugContentExample contentExample = new BugContentExample();
|
||||
contentExample.createCriteria().andBugIdEqualTo(bugId);
|
||||
bugContentMapper.deleteByExample(contentExample);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -535,14 +535,16 @@ public class BugControllerTests extends BaseTest {
|
||||
request.setId("default-bug-template-not-exist");
|
||||
request.setProjectId("default-project-for-bug");
|
||||
this.requestPostWithOk(BUG_TEMPLATE_DETAIL, request);
|
||||
// 关闭集成
|
||||
// 关闭插件集成
|
||||
ServiceIntegration record = new ServiceIntegration();
|
||||
record.setId("621103810617344");
|
||||
record.setEnable(false);
|
||||
serviceIntegrationMapper.updateByPrimaryKeySelective(record);
|
||||
this.requestPostWithOk(BUG_TEMPLATE_DETAIL, request);
|
||||
this.requestPost(BUG_TEMPLATE_DETAIL, request, status().is5xxServerError());
|
||||
// 开启插件集成
|
||||
record.setEnable(true);
|
||||
serviceIntegrationMapper.updateByPrimaryKeySelective(record);
|
||||
this.requestPostWithOk(BUG_TEMPLATE_DETAIL, request);
|
||||
// 关闭同步
|
||||
ProjectApplicationExample example = new ProjectApplicationExample();
|
||||
example.createCriteria().andProjectIdEqualTo("default-project-for-bug").andTypeEqualTo("BUG_SYNC_PLATFORM_KEY");
|
||||
@ -581,6 +583,11 @@ public class BugControllerTests extends BaseTest {
|
||||
this.requestMultipartWithOkAndReturn(BUG_ADD, addParam2);
|
||||
this.requestGetWithOk(BUG_SYNC + "/default-project-for-bug");
|
||||
|
||||
// 添加使用Jira默认模板的缺陷
|
||||
addRequest.setTemplateId("jira");
|
||||
MultiValueMap<String, Object> addParam3 = getDefaultMultiPartParam(addRequest, null);
|
||||
this.requestMultipart(BUG_ADD, addParam3).andExpect(status().is5xxServerError());
|
||||
|
||||
// 更新Jira缺陷
|
||||
BugEditRequest updateRequest = buildJiraBugRequest(true);
|
||||
updateRequest.setUnLinkRefIds(List.of(getAddJiraAssociateFile().getId()));
|
||||
@ -665,6 +672,27 @@ public class BugControllerTests extends BaseTest {
|
||||
rollBackApiField();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(99)
|
||||
void coverZentaoBugTests() throws Exception {
|
||||
// 上传禅道插件
|
||||
addZentaoPlugin();
|
||||
// 同步配置更改为禅道
|
||||
ProjectApplicationExample example = new ProjectApplicationExample();
|
||||
example.createCriteria().andProjectIdEqualTo("default-project-for-bug").andTypeEqualTo("BUG_SYNC_PLATFORM_KEY");
|
||||
ProjectApplication record = new ProjectApplication();
|
||||
record.setTypeValue("zentao");
|
||||
projectApplicationMapper.updateByExampleSelective(record, example);
|
||||
// 添加禅道缺陷
|
||||
BugEditRequest addRequest = buildRequest(false);
|
||||
String filePath = Objects.requireNonNull(this.getClass().getClassLoader().getResource("file/test.xlsx")).getPath();
|
||||
File file = new File(filePath);
|
||||
MultiValueMap<String, Object> addParam = getDefaultMultiPartParam(addRequest, file);
|
||||
this.requestMultipart(BUG_ADD, addParam).andExpect(status().is5xxServerError());
|
||||
// 获取禅道模板(删除默认项目模板)
|
||||
bugService.attachTemplateStatusField(null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求过滤参数
|
||||
* @return filter param
|
||||
@ -800,7 +828,23 @@ public class BugControllerTests extends BaseTest {
|
||||
File jiraTestFile = new File(Objects.requireNonNull(this.getClass().getClassLoader().getResource("file/metersphere-jira-test.jar")).getPath());
|
||||
FileInputStream inputStream = new FileInputStream(jiraTestFile);
|
||||
MockMultipartFile mockMultipartFile = new MockMultipartFile(jiraTestFile.getName(), jiraTestFile.getName(), "jar", inputStream);
|
||||
request.setName("测试插件");
|
||||
request.setName("测试插件-JIRA");
|
||||
request.setGlobal(true);
|
||||
request.setEnable(true);
|
||||
request.setCreateUser(ADMIN.name());
|
||||
pluginService.add(request, mockMultipartFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加Jira插件,供测试使用
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
public void addZentaoPlugin() throws Exception {
|
||||
PluginUpdateRequest request = new PluginUpdateRequest();
|
||||
File jiraTestFile = new File(Objects.requireNonNull(this.getClass().getClassLoader().getResource("file/metersphere-zentao-test.jar")).getPath());
|
||||
FileInputStream inputStream = new FileInputStream(jiraTestFile);
|
||||
MockMultipartFile mockMultipartFile = new MockMultipartFile(jiraTestFile.getName(), jiraTestFile.getName(), "jar", inputStream);
|
||||
request.setName("测试插件-ZENTAO");
|
||||
request.setGlobal(true);
|
||||
request.setEnable(true);
|
||||
request.setCreateUser(ADMIN.name());
|
||||
|
@ -14,7 +14,8 @@ INSERT INTO bug (id, num, title, handle_users, handle_user, create_user, create_
|
||||
('default-bug-id-tapd1', 100000, 'default-bug', 'oasis', 'oasis', 'admin', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'default-project-for-bug', 'default-bug-template-id', 'Tapd', 'open', '["default-tag"]', null, 0),
|
||||
('default-bug-id-tapd2', 100000, 'default-bug', 'oasis', 'oasis', 'admin', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'default-project-for-bug-no-local', 'default-bug-template-id', 'Tapd', 'open', '["default-tag"]', null, 0),
|
||||
('default-bug-id-single', 100000, 'default-bug', 'oasis', 'oasis', 'admin', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'default-project-for-bug-single', 'default-bug-template-id', 'Tapd', 'open', '["default-tag"]', null, 0),
|
||||
('default-bug-id-jira', 100000, 'default-bug', 'oasis', 'oasis', 'admin', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'default-project-for-bug-single', 'default-bug-template-id', 'Jira', 'open', '["default-tag"]', 'TES-TEST', 0);
|
||||
('default-bug-id-jira', 100000, 'default-bug', 'oasis', 'oasis', 'admin', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'default-project-for-bug-single', 'default-bug-template-id', 'Jira', 'open', '["default-tag"]', 'TES-TEST', 0),
|
||||
('default-bug-id-jira-sync', 100000, 'default-bug', 'oasis', 'oasis', 'admin', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'default-project-for-bug', 'jira', 'Jira', 'open', '["default-tag"]', 'TES-TEST', 0);
|
||||
|
||||
INSERT INTO bug_custom_field (bug_id, field_id, value) VALUE ('default-bug-id', 'test_field', '["default", "default-1"]');
|
||||
|
||||
@ -61,7 +62,9 @@ INSERT INTO project_application (project_id, type, type_value) VALUES
|
||||
|
||||
|
||||
INSERT INTO service_integration(`id`, `plugin_id`, `enable`, `configuration`, `organization_id`) VALUES
|
||||
('621103810617344', 'jira', true, 0x504B0304140008080800BC517657000000000000000000000000030000007A6970258DC10EC2201044FF65CF06D2C498D89347B5574FBD6D8158222CD85D6268E3BF4BE3F5CDBC990DD0DAC531430FB348E65EEBE06B41AAA9289480CC1E4991130D07C022F3A366D7DA13B2373B32261592469AF1572FCF883E289362CB735BF8A4C5EE073474C3CB8E59A6F85EEFF12AE676EC4E67F8FE00504B0708384DA4307800000087000000504B01021400140008080800BC517657384DA43078000000870000000300000000000000000000000000000000007A6970504B0506000000000100010031000000A90000000000, '100001');
|
||||
('621103810617344', 'jira', true, 0x504B0304140008080800BC517657000000000000000000000000030000007A6970258DC10EC2201044FF65CF06D2C498D89347B5574FBD6D8158222CD85D6268E3BF4BE3F5CDBC990DD0DAC531430FB348E65EEBE06B41AAA9289480CC1E4991130D07C022F3A366D7DA13B2373B32261592469AF1572FCF883E289362CB735BF8A4C5EE073474C3CB8E59A6F85EEFF12AE676EC4E67F8FE00504B0708384DA4307800000087000000504B01021400140008080800BC517657384DA43078000000870000000300000000000000000000000000000000007A6970504B0506000000000100010031000000A90000000000, '100001'),
|
||||
('652096294625281', 'zentao', true, 0x504B03041400080808003B939C57000000000000000000000000030000007A6970AB564A4C49294A2D2E56B252CA282929B0D2D7373437D23334D33334D03333D3AF4ACD2B49CCD757D2514A4C4ECE2FCD2B01AA4B4CC9CDCC038A1424161797E717A500859C1373F2F3D21D8C0C0C4D811245A985A5A9C525219505A940B900C7108F784F3F377FA55A00504B07081BBBB5766A0000006E000000504B010214001400080808003B939C571BBBB5766A0000006E0000000300000000000000000000000000000000007A6970504B05060000000001000100310000009B0000000000, '100001');
|
||||
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user