diff --git a/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugLogService.java b/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugLogService.java index a93d60137a..fc674a5e46 100644 --- a/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugLogService.java +++ b/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugLogService.java @@ -2,6 +2,8 @@ package io.metersphere.bug.service; import io.metersphere.bug.domain.Bug; import io.metersphere.bug.domain.BugContent; +import io.metersphere.bug.domain.BugContentExample; +import io.metersphere.bug.domain.BugExample; import io.metersphere.bug.dto.request.BugEditRequest; import io.metersphere.bug.dto.response.BugCustomFieldDTO; import io.metersphere.bug.dto.response.BugDTO; @@ -19,6 +21,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +import java.util.ArrayList; import java.util.List; @Service @@ -126,6 +129,33 @@ public class BugLogService { return bugService.handleCustomField(List.of(originalBug), originalBug.getProjectId()).getFirst(); } + /** + * 获取历史缺陷 + * @param ids 缺陷ID集合 + * @return 缺陷DTO + */ + public List getOriginalValueByIds(List ids) { + // 缺陷基础信息 + List bugOriginalList = new ArrayList<>(); + BugExample example = new BugExample(); + example.createCriteria().andIdIn(ids); + List bugs = bugMapper.selectByExample(example); + BugContentExample contentExample = new BugContentExample(); + contentExample.createCriteria().andBugIdIn(ids); + List bugContents = bugContentMapper.selectByExample(contentExample); + bugs.forEach(bug -> { + BugDTO originalBug = new BugDTO(); + BeanUtils.copyBean(originalBug, bug); + BugContent bugContent = bugContents.stream().filter(content -> StringUtils.equals(content.getBugId(), bug.getId())).findFirst().orElse(null); + if (bugContent != null) { + originalBug.setDescription(bugContent.getDescription()); + } + bugOriginalList.add(originalBug); + }); + // 缺陷自定义字段 + return bugService.handleCustomField(bugOriginalList, bugOriginalList.getFirst().getProjectId()); + } + /** * 获取缺陷的标题 * @param request 请求参数 diff --git a/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugNoticeService.java b/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugNoticeService.java index 7a8ad44bcf..e8cd0e7618 100644 --- a/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugNoticeService.java +++ b/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugNoticeService.java @@ -106,16 +106,43 @@ public class BugNoticeService { return notice; } + /** + * 获取缺陷通知集合 + * @param ids 缺陷ID集合 + */ + public List getNoticeByIds(List ids) { + List bugs = bugLogService.getOriginalValueByIds(ids); + if (CollectionUtils.isEmpty(bugs)) { + return null; + } + List notices = new ArrayList<>(); + bugs.forEach(bug -> { + BugNoticeDTO notice = new BugNoticeDTO(); + BeanUtils.copyBean(notice, bug); + if (CollectionUtils.isNotEmpty(bug.getCustomFields())) { + List fields = new ArrayList<>(); + bug.getCustomFields().forEach(field -> { + // 其他自定义字段 + OptionDTO fieldDTO = new OptionDTO(); + fieldDTO.setId(field.getName()); + fieldDTO.setName(field.getValue()); + fields.add(fieldDTO); + }); + notice.setFields(fields); + } + notices.add(notice); + }); + return notices; + } + /** * 获取批量操作的缺陷通知 * @param request 批量请求参数 * @return 缺陷通知集合 */ public List getBatchNoticeByRequest(BugBatchRequest request) { - List notices = new ArrayList<>(); List batchIds = bugService.getBatchIdsByRequest(request); - batchIds.forEach(id -> notices.add(getNoticeById(id))); - return notices; + return getNoticeByIds(batchIds); } /** diff --git a/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugService.java b/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugService.java index 12881d7a2b..f8477b3da9 100644 --- a/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugService.java +++ b/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugService.java @@ -28,7 +28,10 @@ import io.metersphere.project.dto.filemanagement.FileLogRecord; import io.metersphere.project.mapper.FileAssociationMapper; import io.metersphere.project.mapper.FileMetadataMapper; import io.metersphere.project.mapper.ProjectMapper; -import io.metersphere.project.service.*; +import io.metersphere.project.service.FileAssociationService; +import io.metersphere.project.service.FileMetadataService; +import io.metersphere.project.service.ProjectApplicationService; +import io.metersphere.project.service.ProjectTemplateService; import io.metersphere.sdk.constants.*; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.file.FileCenter; @@ -403,10 +406,57 @@ public class BugService { */ public void batchDelete(BugBatchRequest request, String currentUser) { List batchIds = getBatchIdsByRequest(request); - batchIds.forEach(id -> delete(id, currentUser)); + BugExample example = new BugExample(); + example.createCriteria().andIdIn(batchIds); + List bugs = bugMapper.selectByExample(example); + String currentPlatform = projectApplicationService.getPlatformName(bugs.getFirst().getProjectId()); + List platformBugIds = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(bugs)) { + Map> groupBugs = bugs.stream().collect(Collectors.groupingBy(Bug::getPlatform)); + // 根据不同平台, 删除缺陷 + groupBugs.forEach((platform, bugList) -> { + List bugIds = bugList.stream().map(Bug::getId).toList(); + example.clear(); + example.createCriteria().andIdIn(bugIds); + if (StringUtils.equals(platform, BugPlatform.LOCAL.getName())) { + // Local缺陷 + Bug record = new Bug(); + record.setDeleted(true); + record.setDeleteUser(currentUser); + record.setDeleteTime(System.currentTimeMillis()); + bugMapper.updateByExampleSelective(record, example); + } else { + /* + * 第三方平台缺陷 + * 和当前项目所属平台不一致, 只删除MS缺陷, 不同步删除平台缺陷, 一致时需同步删除平台缺陷 + */ + bugCommonService.clearAssociateResource(bugList.getFirst().getProjectId(), bugIds); + bugMapper.deleteByExample(example); + if (StringUtils.equals(platform, currentPlatform)) { + platformBugIds.addAll(bugList.stream().map(Bug::getPlatformBugId).toList()); + } + } + }); + } + // 批量日志 List logs = getBatchLogByRequest(batchIds, OperationLogType.DELETE.name(), OperationLogModule.BUG_MANAGEMENT_INDEX, "/bug/batch-delete", request.getProjectId(), false, false, null, currentUser); operationLogService.batchAdd(logs); + + // 异步处理第三方平台缺陷, 防止超时 + Thread.startVirtualThread(() -> { + if (CollectionUtils.isNotEmpty(platformBugIds)) { + Platform platform = projectApplicationService.getPlatform(bugs.getFirst().getProjectId(), true); + String projectBugThirdPartConfig = projectApplicationService.getProjectBugThirdPartConfig(bugs.getFirst().getProjectId()); + platformBugIds.forEach(platformBugKey -> { + // 需同步删除平台缺陷 + PlatformBugDeleteRequest deleteRequest = new PlatformBugDeleteRequest(); + deleteRequest.setPlatformBugKey(platformBugKey); + deleteRequest.setProjectConfig(projectBugThirdPartConfig); + platform.deleteBug(deleteRequest); + }); + } + }); } /**