feat(缺陷管理): 缺陷同步功能开源
--story=1015332 --user=宋昌昌 企业版功能转开源版功能 https://www.tapd.cn/55049933/s/1540450
This commit is contained in:
parent
0a62bc7c80
commit
f87bfd1c1a
|
@ -143,7 +143,7 @@ public class BugController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/sync/{projectId}")
|
@GetMapping("/sync/{projectId}")
|
||||||
@Operation(summary = "缺陷管理-列表-同步缺陷(开源)")
|
@Operation(summary = "缺陷管理-列表-同步存量缺陷")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE)
|
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE)
|
||||||
@CheckOwner(resourceId = "#projectId", resourceType = "project")
|
@CheckOwner(resourceId = "#projectId", resourceType = "project")
|
||||||
public void sync(@PathVariable String projectId) {
|
public void sync(@PathVariable String projectId) {
|
||||||
|
@ -151,11 +151,11 @@ public class BugController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/sync/all")
|
@PostMapping("/sync/all")
|
||||||
@Operation(summary = "缺陷管理-列表-同步缺陷(企业)")
|
@Operation(summary = "缺陷管理-列表-同步全量缺陷")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE)
|
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE)
|
||||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||||
public void syncAll(@RequestBody BugSyncRequest request) {
|
public void syncAll(@RequestBody BugSyncRequest request) {
|
||||||
bugSyncService.syncAllBugs(request, SessionUtils.getUserId(), Objects.requireNonNull(SessionUtils.getUser()).getLanguage());
|
bugSyncService.syncAllBugs(request, SessionUtils.getUserId(), Objects.requireNonNull(SessionUtils.getUser()).getLanguage(), Translator.get("sync_mode.manual"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/sync/check/{projectId}")
|
@GetMapping("/sync/check/{projectId}")
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package io.metersphere.bug.dto;
|
||||||
|
|
||||||
|
import io.metersphere.bug.domain.Bug;
|
||||||
|
import io.metersphere.plugin.platform.dto.response.PlatformBugDTO;
|
||||||
|
import io.metersphere.plugin.platform.spi.Platform;
|
||||||
|
import io.metersphere.project.domain.Project;
|
||||||
|
import io.metersphere.system.domain.Template;
|
||||||
|
import io.metersphere.system.domain.TemplateCustomField;
|
||||||
|
import io.metersphere.system.dto.sdk.TemplateDTO;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class BugSyncSaveModel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平台缺陷
|
||||||
|
*/
|
||||||
|
private PlatformBugDTO platformBug;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MS缺陷
|
||||||
|
*/
|
||||||
|
private Bug msBug;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MS默认模板
|
||||||
|
*/
|
||||||
|
private TemplateDTO msDefaultTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插件默认模板
|
||||||
|
*/
|
||||||
|
private Template pluginDefaultTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板字段映射
|
||||||
|
*/
|
||||||
|
private Map<String, List<TemplateCustomField>> templateFieldMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属平台
|
||||||
|
*/
|
||||||
|
private Platform platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平台名称
|
||||||
|
*/
|
||||||
|
private String platformName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属项目
|
||||||
|
*/
|
||||||
|
private Project project;
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package io.metersphere.bug.service;
|
||||||
import io.metersphere.bug.constants.BugExportColumns;
|
import io.metersphere.bug.constants.BugExportColumns;
|
||||||
import io.metersphere.bug.domain.*;
|
import io.metersphere.bug.domain.*;
|
||||||
import io.metersphere.bug.dto.BugExportHeaderModel;
|
import io.metersphere.bug.dto.BugExportHeaderModel;
|
||||||
|
import io.metersphere.bug.dto.BugSyncSaveModel;
|
||||||
import io.metersphere.bug.dto.BugTemplateInjectField;
|
import io.metersphere.bug.dto.BugTemplateInjectField;
|
||||||
import io.metersphere.bug.dto.request.*;
|
import io.metersphere.bug.dto.request.*;
|
||||||
import io.metersphere.bug.dto.response.*;
|
import io.metersphere.bug.dto.response.*;
|
||||||
|
@ -11,6 +12,7 @@ import io.metersphere.bug.enums.BugPlatform;
|
||||||
import io.metersphere.bug.enums.BugTemplateCustomField;
|
import io.metersphere.bug.enums.BugTemplateCustomField;
|
||||||
import io.metersphere.bug.mapper.*;
|
import io.metersphere.bug.mapper.*;
|
||||||
import io.metersphere.bug.utils.ExportUtils;
|
import io.metersphere.bug.utils.ExportUtils;
|
||||||
|
import io.metersphere.plugin.platform.dto.PlatformAttachment;
|
||||||
import io.metersphere.plugin.platform.dto.SelectOption;
|
import io.metersphere.plugin.platform.dto.SelectOption;
|
||||||
import io.metersphere.plugin.platform.dto.SyncBugResult;
|
import io.metersphere.plugin.platform.dto.SyncBugResult;
|
||||||
import io.metersphere.plugin.platform.dto.request.*;
|
import io.metersphere.plugin.platform.dto.request.*;
|
||||||
|
@ -76,6 +78,10 @@ import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -532,22 +538,8 @@ public class BugService {
|
||||||
* @param currentUser 当前用户
|
* @param currentUser 当前用户
|
||||||
*/
|
*/
|
||||||
@Async
|
@Async
|
||||||
public void syncPlatformAllBugs(BugSyncRequest request, Project project, String currentUser, String language) {
|
public void syncPlatformAllBugs(BugSyncRequest request, Project project, String currentUser, String language, String triggerMode) {
|
||||||
try {
|
doSyncAllPlatformBugs(project, request, currentUser, language, triggerMode);
|
||||||
XpackBugService bugService = CommonBeanFactory.getBean(XpackBugService.class);
|
|
||||||
if (bugService != null) {
|
|
||||||
bugService.syncPlatformBugs(project, request, currentUser, language, Translator.get("sync_mode.manual"));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtils.error(e);
|
|
||||||
// 异常或正常结束都得删除当前项目执行同步的唯一Key
|
|
||||||
bugSyncExtraService.deleteSyncKey(request.getProjectId());
|
|
||||||
// 同步缺陷异常, 当前同步错误信息 -> Redis(check接口获取)
|
|
||||||
bugSyncExtraService.setSyncErrorMsg(request.getProjectId(), e.getMessage());
|
|
||||||
} finally {
|
|
||||||
// 异常或正常结束都得删除当前项目执行同步的唯一Key
|
|
||||||
bugSyncExtraService.deleteSyncKey(request.getProjectId());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -562,13 +554,13 @@ public class BugService {
|
||||||
// 分页同步
|
// 分页同步
|
||||||
SubListUtils.dealForSubList(remainBugs, 100, (subBugs) -> doSyncPlatformBugs(subBugs, project));
|
SubListUtils.dealForSubList(remainBugs, 100, (subBugs) -> doSyncPlatformBugs(subBugs, project));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtils.error("Synchronization bugs exception occurred :" + e.getMessage());
|
LogUtils.error("Sync bugs exception occurred: " + e.getMessage());
|
||||||
// 异常或正常结束都得删除当前项目执行同步的Key
|
// 异常或正常结束都得删除当前项目执行同步的Key
|
||||||
bugSyncExtraService.deleteSyncKey(project.getId());
|
bugSyncExtraService.deleteSyncKey(project.getId());
|
||||||
// 同步缺陷异常, 当前同步错误信息 -> Redis(check接口获取)
|
// 同步缺陷异常, 当前同步错误信息 -> Redis(check接口获取)
|
||||||
bugSyncExtraService.setSyncErrorMsg(project.getId(), e.getMessage());
|
bugSyncExtraService.setSyncErrorMsg(project.getId(), e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
LogUtils.info("Synchronization bugs end......");
|
LogUtils.info("Sync bugs end");
|
||||||
// 异常或正常结束都得删除当前项目执行同步的Key
|
// 异常或正常结束都得删除当前项目执行同步的Key
|
||||||
bugSyncExtraService.deleteSyncKey(project.getId());
|
bugSyncExtraService.deleteSyncKey(project.getId());
|
||||||
// 发送同步通知
|
// 发送同步通知
|
||||||
|
@ -582,7 +574,6 @@ public class BugService {
|
||||||
* @param project 项目
|
* @param project 项目
|
||||||
* @param syncRequest 同步请求参数
|
* @param syncRequest 同步请求参数
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public void execSyncAll(Project project, SyncAllBugRequest syncRequest) {
|
public void execSyncAll(Project project, SyncAllBugRequest syncRequest) {
|
||||||
syncRequest.setProjectConfig(projectApplicationService.getProjectBugThirdPartConfig(project.getId()));
|
syncRequest.setProjectConfig(projectApplicationService.getProjectBugThirdPartConfig(project.getId()));
|
||||||
// 获取平台
|
// 获取平台
|
||||||
|
@ -592,7 +583,7 @@ public class BugService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同步平台缺陷处理
|
* 处理平台存量缺陷
|
||||||
*
|
*
|
||||||
* @param subBugs 同步的分页缺陷
|
* @param subBugs 同步的分页缺陷
|
||||||
* @param project 项目
|
* @param project 项目
|
||||||
|
@ -682,6 +673,158 @@ public class BugService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理平台全量缺陷
|
||||||
|
* @param project 项目
|
||||||
|
* @param request 同步请求参数
|
||||||
|
* @param currentUser 当前用户
|
||||||
|
* @param language 语言
|
||||||
|
* @param triggerMode 触发方式
|
||||||
|
*/
|
||||||
|
private void doSyncAllPlatformBugs(Project project, BugSyncRequest request, String currentUser, String language, String triggerMode) {
|
||||||
|
// 批量操作
|
||||||
|
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||||
|
// 同步条数
|
||||||
|
AtomicInteger syncCount = new AtomicInteger();
|
||||||
|
// 缺陷POS
|
||||||
|
AtomicLong atomicPos = new AtomicLong(getNextPos(project.getId()));
|
||||||
|
// 同步缺陷ID集合(由于是分页同步)
|
||||||
|
AtomicReference<List<String>> allSyncIds = new AtomicReference<>(new ArrayList<>());
|
||||||
|
try {
|
||||||
|
BugMapper batchBugMapper = sqlSession.getMapper(BugMapper.class);
|
||||||
|
BugContentMapper batchBugContentMapper = sqlSession.getMapper(BugContentMapper.class);
|
||||||
|
// 获取项目所属平台
|
||||||
|
String platformName = projectApplicationService.getPlatformName(project.getId());
|
||||||
|
// 获取项目所属平台配置
|
||||||
|
ServiceIntegration serviceIntegration = projectApplicationService.getPlatformServiceIntegrationWithSyncOrDemand(project.getId(), true);
|
||||||
|
if (serviceIntegration == null) {
|
||||||
|
// 项目未配置第三方平台
|
||||||
|
throw new MSException(Translator.get("third_party_not_config"));
|
||||||
|
}
|
||||||
|
// 获取配置平台, 插入平台缺陷
|
||||||
|
Platform platform = platformPluginService.getPlatform(serviceIntegration.getPluginId(), serviceIntegration.getOrganizationId(),
|
||||||
|
new String(serviceIntegration.getConfiguration()));
|
||||||
|
boolean isIncrement = projectApplicationService.isPlatformSyncMethodByIncrement(project.getId());
|
||||||
|
// 获取当前平台下满足同步条件的原始缺陷
|
||||||
|
BugExample bugExample = new BugExample();
|
||||||
|
BugExample.Criteria criteria = bugExample.createCriteria();
|
||||||
|
criteria.andProjectIdEqualTo(project.getId()).andPlatformEqualTo(platformName);
|
||||||
|
if (request.getPre() != null) {
|
||||||
|
if (request.getPre()) {
|
||||||
|
criteria.andCreateTimeLessThan(request.getCreateTime());
|
||||||
|
} else {
|
||||||
|
criteria.andCreateTimeGreaterThan(request.getCreateTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Bug> originalBugs = batchBugMapper.selectByExample(bugExample);
|
||||||
|
Map<String, Bug> msOriginalBugMap = originalBugs.stream().collect(Collectors.toMap(Bug::getPlatformBugId, bug -> bug));
|
||||||
|
// 获取原始缺陷的模板字段信息(同步更新缺陷使用)
|
||||||
|
List<String> templateIds = originalBugs.stream().map(Bug::getTemplateId).distinct().toList();
|
||||||
|
List<TemplateCustomField> templateCustomsFields = baseTemplateCustomFieldService.getByTemplateIds(templateIds);
|
||||||
|
Map<String, List<TemplateCustomField>> templateFieldMap = templateCustomsFields.stream().collect(Collectors.groupingBy(TemplateCustomField::getTemplateId));
|
||||||
|
// 获取当前项目MS默认模板(同步新增缺陷使用)
|
||||||
|
TemplateDTO msDefaultTemplate = new TemplateDTO();
|
||||||
|
// 平台默认模板
|
||||||
|
Template pluginDefaultTemplate = projectTemplateService.getPluginBugTemplate(project.getId());
|
||||||
|
List<ProjectTemplateOptionDTO> templateOption = projectTemplateService.getOption(project.getId(), TemplateScene.BUG.name());
|
||||||
|
ProjectTemplateOptionDTO defaultProjectTemplate = templateOption.stream().filter(ProjectTemplateOptionDTO::getEnableDefault).toList().get(0);
|
||||||
|
if (isPluginDefaultTemplate(defaultProjectTemplate.getId(), pluginDefaultTemplate)) {
|
||||||
|
BeanUtils.copyBean(msDefaultTemplate, pluginDefaultTemplate);
|
||||||
|
} else {
|
||||||
|
// MS默认模板
|
||||||
|
msDefaultTemplate = projectTemplateService.getTemplateDTOById(defaultProjectTemplate.getId(), project.getId(), TemplateScene.BUG.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
TemplateDTO defaultTemplate = msDefaultTemplate;
|
||||||
|
Consumer<SyncPostParamRequest> syncPostProcessFunc = (param) -> {
|
||||||
|
// 准备参数
|
||||||
|
List<PlatformBugDTO> needSyncBugs = param.getNeedSyncBugs();
|
||||||
|
Map<String, List<PlatformAttachment>> attachmentMap = param.getAttachmentMap();
|
||||||
|
|
||||||
|
// 比对MS原始缺陷, 筛选出同步缺陷中需要作为新增的缺陷, 以及需要作为更新的缺陷
|
||||||
|
List<PlatformBugDTO> syncToAddBugList = needSyncBugs.stream().filter(syncBug -> !msOriginalBugMap.containsKey(syncBug.getPlatformBugId())).collect(Collectors.toList());
|
||||||
|
List<PlatformBugDTO> syncToUpdateBugList = needSyncBugs.stream().filter(syncBug -> msOriginalBugMap.containsKey(syncBug.getPlatformBugId())).collect(Collectors.toList());
|
||||||
|
// 聚合每次同步的ID集合
|
||||||
|
allSyncIds.set(ListUtils.union(needSyncBugs.stream().map(PlatformBugDTO::getPlatformBugId).toList(), allSyncIds.get()));
|
||||||
|
|
||||||
|
// 处理缺陷
|
||||||
|
Map<String, List<PlatformAttachment>> handleAttachmentMap = new HashMap<>(16);
|
||||||
|
if (CollectionUtils.isNotEmpty(syncToAddBugList) || CollectionUtils.isNotEmpty(syncToUpdateBugList)) {
|
||||||
|
List<PlatformBugDTO> combinaList;
|
||||||
|
if (isIncrement) {
|
||||||
|
// 增量同步
|
||||||
|
if (CollectionUtils.isNotEmpty(syncToUpdateBugList)) {
|
||||||
|
combinaList = new ArrayList<>(syncToUpdateBugList);
|
||||||
|
} else {
|
||||||
|
combinaList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 全量同步
|
||||||
|
if (CollectionUtils.isNotEmpty(syncToAddBugList)) {
|
||||||
|
combinaList = new ArrayList<>(syncToAddBugList);
|
||||||
|
combinaList.addAll(syncToUpdateBugList);
|
||||||
|
} else {
|
||||||
|
combinaList = new ArrayList<>(syncToUpdateBugList);
|
||||||
|
combinaList.addAll(syncToAddBugList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 同时解析附件
|
||||||
|
BugSyncSaveModel saveModel = BugSyncSaveModel.builder().platformName(platformName).project(project)
|
||||||
|
.msDefaultTemplate(defaultTemplate).pluginDefaultTemplate(pluginDefaultTemplate).platform(platform).templateFieldMap(templateFieldMap).build();
|
||||||
|
for (PlatformBugDTO platformBug : combinaList) {
|
||||||
|
List<PlatformAttachment> bugAttachments = new ArrayList<>();
|
||||||
|
if (attachmentMap.containsKey(platformBug.getId())) {
|
||||||
|
bugAttachments = attachmentMap.get(platformBug.getId());
|
||||||
|
}
|
||||||
|
Bug bug = msOriginalBugMap.get(platformBug.getPlatformBugId());
|
||||||
|
saveModel.setMsBug(bug);
|
||||||
|
saveModel.setPlatformBug(platformBug);
|
||||||
|
handleSaveBug(saveModel, atomicPos, batchBugMapper, batchBugContentMapper);
|
||||||
|
handleAttachmentMap.put(platformBug.getId(), bugAttachments);
|
||||||
|
}
|
||||||
|
// 设置同步条数
|
||||||
|
syncCount.addAndGet(combinaList.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 附件处理
|
||||||
|
if (MapUtils.isNotEmpty(handleAttachmentMap)) {
|
||||||
|
bugAttachmentService.syncAttachmentToMs(platform, handleAttachmentMap, project.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlSession.commit();
|
||||||
|
};
|
||||||
|
SyncAllBugRequest syncAllBugRequest = new SyncAllBugRequest();
|
||||||
|
syncAllBugRequest.setPre(request.getPre());
|
||||||
|
syncAllBugRequest.setCreateTime(request.getCreateTime());
|
||||||
|
syncAllBugRequest.setSyncPostProcessFunc(syncPostProcessFunc);
|
||||||
|
execSyncAll(project, syncAllBugRequest);
|
||||||
|
|
||||||
|
// 删除缺陷在后置方法处理完再执行
|
||||||
|
List<String> syncToDeleteIds = originalBugs.stream().filter(msOriginalBug -> !allSyncIds.get().contains(msOriginalBug.getPlatformBugId())).map(Bug::getId).toList();
|
||||||
|
if (CollectionUtils.isNotEmpty(syncToDeleteIds)) {
|
||||||
|
syncCount.addAndGet(syncToDeleteIds.size());
|
||||||
|
// 删除缺陷(单独处理)
|
||||||
|
BugExample example = new BugExample();
|
||||||
|
example.createCriteria().andIdIn(syncToDeleteIds);
|
||||||
|
bugMapper.deleteByExample(example);
|
||||||
|
bugCommonService.clearAssociateResource(project.getId(), syncToDeleteIds);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.error("Sync bugs exception occurred: " + e.getMessage());
|
||||||
|
// 异常或正常结束都得删除当前项目执行同步的唯一Key
|
||||||
|
bugSyncExtraService.deleteSyncKey(request.getProjectId());
|
||||||
|
// 同步缺陷异常, 当前同步错误信息 -> Redis(check接口获取)
|
||||||
|
bugSyncExtraService.setSyncErrorMsg(request.getProjectId(), e.getMessage());
|
||||||
|
} finally {
|
||||||
|
LogUtils.info("Sync bugs end");
|
||||||
|
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||||
|
// 异常或正常结束都得删除当前项目执行同步的唯一Key
|
||||||
|
bugSyncExtraService.deleteSyncKey(project.getId());
|
||||||
|
// 发送同步成功通知
|
||||||
|
bugSyncNoticeService.sendNotice(syncCount.get(), currentUser, language, triggerMode, project.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注入平台模板缺陷字段
|
* 注入平台模板缺陷字段
|
||||||
*
|
*
|
||||||
|
@ -1241,6 +1384,16 @@ public class BugService {
|
||||||
return pluginTemplate != null && StringUtils.equals(pluginTemplate.getId(), templateId);
|
return pluginTemplate != null && StringUtils.equals(pluginTemplate.getId(), templateId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否插件默认模板
|
||||||
|
* @param templateId 模板ID
|
||||||
|
* @param pluginTemplate 插件模板
|
||||||
|
* @return 是否插件默认模板
|
||||||
|
*/
|
||||||
|
private boolean isPluginDefaultTemplate(String templateId, Template pluginTemplate) {
|
||||||
|
return pluginTemplate != null && StringUtils.equals(pluginTemplate.getId(), templateId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 封装缺陷其他字段
|
* 封装缺陷其他字段
|
||||||
*
|
*
|
||||||
|
@ -1756,4 +1909,163 @@ public class BugService {
|
||||||
return option;
|
return option;
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param atomicPos 位置
|
||||||
|
* @param batchBugMapper 批量操作缺陷
|
||||||
|
* @param batchBugContentMapper 批量操作缺陷内容
|
||||||
|
*/
|
||||||
|
private void handleSaveBug(BugSyncSaveModel saveModel, AtomicLong atomicPos, BugMapper batchBugMapper, BugContentMapper batchBugContentMapper) {
|
||||||
|
try {
|
||||||
|
Map<String, String> needSyncApiFieldMap = new HashMap<>(12);
|
||||||
|
PlatformBugDTO platformBug = saveModel.getPlatformBug();
|
||||||
|
Bug originalBug = saveModel.getMsBug();
|
||||||
|
// 设置缺陷基础信息
|
||||||
|
if (originalBug == null) {
|
||||||
|
// 新增
|
||||||
|
platformBug.setId(IDGenerator.nextStr());
|
||||||
|
platformBug.setNum(Long.valueOf(NumGenerator.nextNum(saveModel.getProject().getId(), ApplicationNumScope.BUG_MANAGEMENT)).intValue());
|
||||||
|
platformBug.setProjectId(saveModel.getProject().getId());
|
||||||
|
platformBug.setTemplateId(saveModel.getMsDefaultTemplate().getId());
|
||||||
|
platformBug.setPlatform(saveModel.getPlatformName());
|
||||||
|
platformBug.setPlatformDefaultTemplate(isPluginDefaultTemplate(platformBug.getTemplateId(), saveModel.getPluginDefaultTemplate()));
|
||||||
|
platformBug.setDeleteUser(platformBug.getCreateUser());
|
||||||
|
platformBug.setDeleteTime(platformBug.getCreateTime());
|
||||||
|
platformBug.setDeleted(false);
|
||||||
|
platformBug.setPos(atomicPos.getAndAdd(INTERVAL_POS));
|
||||||
|
// 非平台默认模板时, 设置需要处理的字段
|
||||||
|
if (!platformBug.getPlatformDefaultTemplate()) {
|
||||||
|
List<TemplateCustomFieldDTO> defaultTemplateCustomFields = saveModel.getMsDefaultTemplate().getCustomFields();
|
||||||
|
needSyncApiFieldMap = defaultTemplateCustomFields.stream().filter(field -> StringUtils.isNotBlank(field.getApiFieldId()))
|
||||||
|
.collect(Collectors.toMap(TemplateCustomFieldDTO::getApiFieldId, TemplateCustomFieldDTO::getFieldId));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 更新
|
||||||
|
platformBug.setId(originalBug.getId());
|
||||||
|
if (!StringUtils.equals(originalBug.getHandleUser(), platformBug.getHandleUser())) {
|
||||||
|
platformBug.setHandleUsers(originalBug.getHandleUsers() + "," + platformBug.getHandleUsers());
|
||||||
|
} else {
|
||||||
|
platformBug.setHandleUser(originalBug.getHandleUser());
|
||||||
|
platformBug.setHandleUsers(originalBug.getHandleUsers());
|
||||||
|
}
|
||||||
|
platformBug.setProjectId(originalBug.getProjectId());
|
||||||
|
platformBug.setTemplateId(originalBug.getTemplateId());
|
||||||
|
platformBug.setPlatform(originalBug.getPlatform());
|
||||||
|
platformBug.setCreateUser(null);
|
||||||
|
platformBug.setPlatformDefaultTemplate(isPluginDefaultTemplate(platformBug.getTemplateId(), saveModel.getPluginDefaultTemplate()));
|
||||||
|
// 非平台默认模板时, 设置需要处理的字段
|
||||||
|
if (!platformBug.getPlatformDefaultTemplate()) {
|
||||||
|
List<TemplateCustomField> templateCustomFields = saveModel.getTemplateFieldMap().get(platformBug.getTemplateId());
|
||||||
|
needSyncApiFieldMap = templateCustomFields.stream().filter(field -> StringUtils.isNotBlank(field.getApiFieldId()))
|
||||||
|
.collect(Collectors.toMap(TemplateCustomField::getApiFieldId, TemplateCustomField::getFieldId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bug bug = new Bug();
|
||||||
|
BeanUtils.copyBean(bug, platformBug);
|
||||||
|
// 如果缺陷需要同步第三方的富文本文件
|
||||||
|
List<BugLocalAttachment> richTextAttachments = new ArrayList<>();
|
||||||
|
if (MapUtils.isNotEmpty(platformBug.getRichTextImageMap())) {
|
||||||
|
Map<String, String> richTextImageMap = platformBug.getRichTextImageMap();
|
||||||
|
// 同步第三方的富文本文件
|
||||||
|
try {
|
||||||
|
Platform platform = saveModel.getPlatform();
|
||||||
|
richTextImageMap.keySet().forEach(key -> platform.getAttachmentContent(key, (in) -> {
|
||||||
|
if (in == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String fileId = IDGenerator.nextStr();
|
||||||
|
// 第三方同步的文件名加上平台前缀, 防止同名
|
||||||
|
String fileName = saveModel.getPlatformName() + "-" + richTextImageMap.get(key);
|
||||||
|
byte[] bytes;
|
||||||
|
try {
|
||||||
|
// 获取第三方平台附件流, 并上传至Minio, 默认不压缩
|
||||||
|
bytes = in.readAllBytes();
|
||||||
|
FileCenter.getDefaultRepository().saveFile(bytes, buildBugFileRequest(platformBug.getProjectId(), platformBug.getId(), fileId, fileName));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new MSException(e.getMessage());
|
||||||
|
}
|
||||||
|
// 保存缺陷附件关系
|
||||||
|
BugLocalAttachment localAttachment = new BugLocalAttachment();
|
||||||
|
localAttachment.setId(IDGenerator.nextStr());
|
||||||
|
localAttachment.setBugId(platformBug.getId());
|
||||||
|
localAttachment.setFileId(fileId);
|
||||||
|
localAttachment.setFileName(fileName);
|
||||||
|
localAttachment.setSize((long) bytes.length);
|
||||||
|
localAttachment.setCreateTime(System.currentTimeMillis());
|
||||||
|
localAttachment.setCreateUser("admin");
|
||||||
|
localAttachment.setSource(BugAttachmentSourceType.RICH_TEXT.name());
|
||||||
|
richTextAttachments.add(localAttachment);
|
||||||
|
// 替换富文本中的临时URL, 注意: 第三方的图片附件暂未存储在压缩目录, 因此不支持压缩访问
|
||||||
|
if (StringUtils.contains(platformBug.getDescription(), "alt=\"" + key + "\"")) {
|
||||||
|
platformBug.setDescription(platformBug.getDescription()
|
||||||
|
.replace("alt=\"" + key + "\"", "src=\"/bug/attachment/preview/md/" + platformBug.getProjectId() + "/" + fileId + "/false\""));
|
||||||
|
if (platformBug.getPlatformDefaultTemplate()) {
|
||||||
|
// 来自富文本自定义字段
|
||||||
|
PlatformCustomFieldItemDTO descriptionField = platformBug.getCustomFieldList().stream().filter(field -> StringUtils.equals(field.getCustomData(), "description")).toList().get(0);
|
||||||
|
descriptionField.setValue(platformBug.getDescription());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 来自富文本自定义字段
|
||||||
|
PlatformCustomFieldItemDTO richTextField = platformBug.getCustomFieldList().stream().filter(field -> StringUtils.equals(field.getType(), PlatformCustomFieldType.RICH_TEXT.name())
|
||||||
|
&& field.getValue() != null && StringUtils.contains(field.getValue().toString(), "alt=\"" + key + "\"")).toList().get(0);
|
||||||
|
richTextField.setValue(richTextField.getValue().toString().replace("alt=\"" + key + "\"", "src=\"/bug/attachment/preview/md/" + platformBug.getProjectId() + "/" + fileId + "/false\""));
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.error("sync platform bug rich text image error : " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BugContent bugContent = new BugContent();
|
||||||
|
bugContent.setBugId(platformBug.getId());
|
||||||
|
bugContent.setDescription(platformBug.getDescription());
|
||||||
|
// 设置缺陷自定义字段参数
|
||||||
|
BugEditRequest customEditRequest = new BugEditRequest();
|
||||||
|
customEditRequest.setId(platformBug.getId());
|
||||||
|
customEditRequest.setProjectId(platformBug.getProjectId());
|
||||||
|
List<PlatformCustomFieldItemDTO> platformCustomFields = platformBug.getCustomFieldList();
|
||||||
|
// 过滤出需要同步的自定义字段{默认模板时, 需要同步所有字段; 非默认模板时, 需要同步模板中映射的字段}
|
||||||
|
final Map<String, String> needSyncApiFieldFilterMap = needSyncApiFieldMap;
|
||||||
|
if (platformBug.getPlatformDefaultTemplate()) {
|
||||||
|
// 平台默认模板创建的缺陷
|
||||||
|
List<BugCustomFieldDTO> bugCustomFieldDTOList = platformCustomFields.stream()
|
||||||
|
.map(platformField -> {
|
||||||
|
BugCustomFieldDTO bugCustomFieldDTO = new BugCustomFieldDTO();
|
||||||
|
bugCustomFieldDTO.setId(platformField.getId());
|
||||||
|
bugCustomFieldDTO.setValue(platformField.getValue() == null ? null : platformField.getValue().toString());
|
||||||
|
return bugCustomFieldDTO;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
customEditRequest.setCustomFields(bugCustomFieldDTOList);
|
||||||
|
} else {
|
||||||
|
// 非平台默认模板创建的缺陷(使用模板API映射字段)
|
||||||
|
List<BugCustomFieldDTO> bugCustomFieldDTOList = platformCustomFields.stream()
|
||||||
|
.filter(field -> needSyncApiFieldFilterMap.containsKey(field.getId()))
|
||||||
|
.map(platformField -> {
|
||||||
|
BugCustomFieldDTO bugCustomFieldDTO = new BugCustomFieldDTO();
|
||||||
|
bugCustomFieldDTO.setId(needSyncApiFieldFilterMap.get(platformField.getId()));
|
||||||
|
bugCustomFieldDTO.setValue(platformField.getValue() == null ? null : platformField.getValue().toString());
|
||||||
|
return bugCustomFieldDTO;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
customEditRequest.setCustomFields(bugCustomFieldDTOList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存缺陷
|
||||||
|
if (originalBug == null) {
|
||||||
|
// 新增
|
||||||
|
batchBugMapper.insertSelective(bug);
|
||||||
|
batchBugContentMapper.insertSelective(bugContent);
|
||||||
|
handleAndSaveCustomFields(customEditRequest, false, null);
|
||||||
|
} else {
|
||||||
|
// 更新
|
||||||
|
batchBugMapper.updateByPrimaryKeySelective(bug);
|
||||||
|
batchBugContentMapper.updateByPrimaryKeyWithBLOBs(bugContent);
|
||||||
|
handleAndSaveCustomFields(customEditRequest, true, null);
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(richTextAttachments)) {
|
||||||
|
extBugLocalAttachmentMapper.batchInsert(richTextAttachments);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -12,7 +12,6 @@ import io.metersphere.project.service.ProjectApplicationService;
|
||||||
import io.metersphere.project.service.ProjectTemplateService;
|
import io.metersphere.project.service.ProjectTemplateService;
|
||||||
import io.metersphere.sdk.constants.TemplateScene;
|
import io.metersphere.sdk.constants.TemplateScene;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
|
||||||
import io.metersphere.sdk.util.Translator;
|
import io.metersphere.sdk.util.Translator;
|
||||||
import io.metersphere.system.domain.Template;
|
import io.metersphere.system.domain.Template;
|
||||||
import io.metersphere.system.domain.TemplateExample;
|
import io.metersphere.system.domain.TemplateExample;
|
||||||
|
@ -51,11 +50,11 @@ public class BugSyncService {
|
||||||
private ProjectApplicationService projectApplicationService;
|
private ProjectApplicationService projectApplicationService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XPACK用户 (同步全量缺陷)
|
* 同步全量缺陷
|
||||||
* @param request 同步全量参数
|
* @param request 同步全量参数
|
||||||
* @param currentUser 当前用户
|
* @param currentUser 当前用户
|
||||||
*/
|
*/
|
||||||
public void syncAllBugs(BugSyncRequest request, String currentUser, String language) {
|
public void syncAllBugs(BugSyncRequest request, String currentUser, String language, String triggerMode) {
|
||||||
try {
|
try {
|
||||||
// 获取当前项目同步缺陷唯一Key
|
// 获取当前项目同步缺陷唯一Key
|
||||||
String syncValue = bugSyncExtraService.getSyncKey(request.getProjectId());
|
String syncValue = bugSyncExtraService.getSyncKey(request.getProjectId());
|
||||||
|
@ -63,7 +62,7 @@ public class BugSyncService {
|
||||||
// 不存在, 设置保证唯一性, 并开始同步
|
// 不存在, 设置保证唯一性, 并开始同步
|
||||||
bugSyncExtraService.setSyncKey(request.getProjectId());
|
bugSyncExtraService.setSyncKey(request.getProjectId());
|
||||||
Project project = getProjectById(request.getProjectId());
|
Project project = getProjectById(request.getProjectId());
|
||||||
bugService.syncPlatformAllBugs(request, project, currentUser, language);
|
bugService.syncPlatformAllBugs(request, project, currentUser, language, triggerMode);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
bugSyncExtraService.deleteSyncKey(request.getProjectId());
|
bugSyncExtraService.deleteSyncKey(request.getProjectId());
|
||||||
|
@ -72,7 +71,7 @@ public class BugSyncService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开源用户 (同步存量缺陷)
|
* 同步存量缺陷
|
||||||
* @param projectId 项目ID
|
* @param projectId 项目ID
|
||||||
*/
|
*/
|
||||||
public void syncBugs(String projectId, String currentUser, String language, String triggerMode) {
|
public void syncBugs(String projectId, String currentUser, String language, String triggerMode) {
|
||||||
|
@ -147,25 +146,9 @@ public class BugSyncService {
|
||||||
* @param scheduleUser 任务触发用户
|
* @param scheduleUser 任务触发用户
|
||||||
*/
|
*/
|
||||||
public void syncPlatformAllBugBySchedule(String projectId, String scheduleUser) {
|
public void syncPlatformAllBugBySchedule(String projectId, String scheduleUser) {
|
||||||
try {
|
|
||||||
String syncValue = bugSyncExtraService.getSyncKey(projectId);
|
|
||||||
if (StringUtils.isEmpty(syncValue)) {
|
|
||||||
// 不存在, 设置保证唯一性, 并开始同步
|
|
||||||
bugSyncExtraService.setSyncKey(projectId);
|
|
||||||
XpackBugService bugService = CommonBeanFactory.getBean(XpackBugService.class);
|
|
||||||
if (bugService != null) {
|
|
||||||
Project project = getProjectById(projectId);
|
|
||||||
BugSyncRequest syncRequest = new BugSyncRequest();
|
BugSyncRequest syncRequest = new BugSyncRequest();
|
||||||
syncRequest.setProjectId(projectId);
|
syncRequest.setProjectId(projectId);
|
||||||
bugService.syncPlatformBugs(project, syncRequest, scheduleUser, Locale.SIMPLIFIED_CHINESE.getLanguage(), Translator.get("sync_mode.auto"));
|
syncAllBugs(syncRequest, scheduleUser, Locale.SIMPLIFIED_CHINESE.getLanguage(), Translator.get("sync_mode.auto"));
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 异常或正常结束都得删除当前项目执行同步的唯一Key
|
|
||||||
bugSyncExtraService.deleteSyncKey(projectId);
|
|
||||||
// 同步缺陷异常, 当前同步错误信息 -> Redis(check接口获取)
|
|
||||||
bugSyncExtraService.setSyncErrorMsg(projectId, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
package io.metersphere.bug.service;
|
|
||||||
|
|
||||||
import io.metersphere.bug.dto.request.BugSyncRequest;
|
|
||||||
import io.metersphere.project.domain.Project;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 缺陷相关企业版功能接口
|
|
||||||
*/
|
|
||||||
public interface XpackBugService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 同步当前项目第三方平台缺陷(前台调用, 支持全量及同步条件区间)
|
|
||||||
* @param project 项目
|
|
||||||
* @param request 同步请求参数
|
|
||||||
* @param currentUser 当前用户
|
|
||||||
* @param language 语言环境
|
|
||||||
* @param triggerMode 同步触发方式
|
|
||||||
*/
|
|
||||||
void syncPlatformBugs(Project project, BugSyncRequest request, String currentUser, String language, String triggerMode);
|
|
||||||
|
|
||||||
}
|
|
|
@ -24,7 +24,6 @@ import io.metersphere.project.service.FileService;
|
||||||
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
||||||
import io.metersphere.sdk.constants.PermissionConstants;
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
import io.metersphere.sdk.constants.StorageType;
|
import io.metersphere.sdk.constants.StorageType;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
|
||||||
import io.metersphere.sdk.file.FileRequest;
|
import io.metersphere.sdk.file.FileRequest;
|
||||||
import io.metersphere.sdk.util.FileAssociationSourceUtil;
|
import io.metersphere.sdk.util.FileAssociationSourceUtil;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
@ -45,14 +44,12 @@ import io.metersphere.system.utils.Pager;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.test.context.jdbc.Sql;
|
import org.springframework.test.context.jdbc.Sql;
|
||||||
import org.springframework.test.context.jdbc.SqlConfig;
|
import org.springframework.test.context.jdbc.SqlConfig;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
|
@ -63,8 +60,6 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static io.metersphere.sdk.constants.InternalUserRole.ADMIN;
|
import static io.metersphere.sdk.constants.InternalUserRole.ADMIN;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
@ -731,13 +726,7 @@ public class BugControllerTests extends BaseTest {
|
||||||
bugSyncExtraService.setSyncKey("default-project-for-bug");
|
bugSyncExtraService.setSyncKey("default-project-for-bug");
|
||||||
this.requestPostWithOk(BUG_SYNC_ALL, request);
|
this.requestPostWithOk(BUG_SYNC_ALL, request);
|
||||||
bugSyncExtraService.deleteSyncKey("default-project-for-bug");
|
bugSyncExtraService.deleteSyncKey("default-project-for-bug");
|
||||||
Project project = projectMapper.selectByPrimaryKey("default-project-for-bug");
|
|
||||||
this.requestPostWithOk(BUG_SYNC_ALL, request);
|
this.requestPostWithOk(BUG_SYNC_ALL, request);
|
||||||
BugService mockBugService = Mockito.mock(BugService.class);
|
|
||||||
Mockito.doThrow(new MSException("sync error!")).when(mockBugService).syncPlatformAllBugs(syncRequest, project, "admin", Locale.SIMPLIFIED_CHINESE.getLanguage());
|
|
||||||
ReflectionTestUtils.setField(bugSyncService, "bugService", mockBugService);
|
|
||||||
MSException msException = assertThrows(MSException.class, () -> bugSyncService.syncAllBugs(syncRequest, "admin", Locale.SIMPLIFIED_CHINESE.getLanguage()));
|
|
||||||
assertEquals(msException.getMessage(), "sync error!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
package io.metersphere.bug.mock;
|
|
||||||
|
|
||||||
import io.metersphere.bug.dto.request.BugSyncRequest;
|
|
||||||
import io.metersphere.bug.service.XpackBugService;
|
|
||||||
import io.metersphere.project.domain.Project;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class XpackBugMockServiceImpl implements XpackBugService {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void syncPlatformBugs(Project project, BugSyncRequest request, String currentUser, String language, String triggerMode) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -181,7 +181,6 @@
|
||||||
getPlatform,
|
getPlatform,
|
||||||
getSyncStatus,
|
getSyncStatus,
|
||||||
syncBugEnterprise,
|
syncBugEnterprise,
|
||||||
syncBugOpenSource,
|
|
||||||
} from '@/api/modules/bug-management';
|
} from '@/api/modules/bug-management';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import useModal from '@/hooks/useModal';
|
import useModal from '@/hooks/useModal';
|
||||||
|
@ -579,23 +578,7 @@
|
||||||
});
|
});
|
||||||
// 同步缺陷按钮触发
|
// 同步缺陷按钮触发
|
||||||
const handleSync = async () => {
|
const handleSync = async () => {
|
||||||
if (isXpack.value) {
|
|
||||||
// 企业版
|
|
||||||
syncVisible.value = true;
|
syncVisible.value = true;
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
// 开源版
|
|
||||||
await syncBugOpenSource(appStore.currentProjectId);
|
|
||||||
Message.warning(t('bugManagement.synchronizing'));
|
|
||||||
isComplete.value = false;
|
|
||||||
isShowCompleteMsg.value = true;
|
|
||||||
// 开始轮询
|
|
||||||
resume();
|
|
||||||
} catch (error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
const handleSyncModalOk = async () => {
|
const handleSyncModalOk = async () => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</a-radio>
|
</a-radio>
|
||||||
<a-radio v-xpack value="full">
|
<a-radio value="full">
|
||||||
<div class="flex flex-row items-center gap-[4px]">
|
<div class="flex flex-row items-center gap-[4px]">
|
||||||
<span class="text-[var(--color-text-1)]">{{ t('project.menu.fullSync') }}</span>
|
<span class="text-[var(--color-text-1)]">{{ t('project.menu.fullSync') }}</span>
|
||||||
<a-tooltip :content="t('project.menu.fullSyncTip')" position="top">
|
<a-tooltip :content="t('project.menu.fullSyncTip')" position="top">
|
||||||
|
|
Loading…
Reference in New Issue