mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-11-29 18:48:13 +08:00
feat(测试跟踪): 缺陷管理插件化
This commit is contained in:
parent
b887a660c4
commit
bed338813b
2
pom.xml
2
pom.xml
@ -23,7 +23,7 @@
|
||||
<spring-cloud.version>2021.0.5</spring-cloud.version>
|
||||
<spring-security.version>5.7.5</spring-security.version>
|
||||
<dubbo.version>2.7.15</dubbo.version>
|
||||
<platform-plugin-sdk.version>main</platform-plugin-sdk.version>
|
||||
<platform-plugin-sdk.version>1.0.0</platform-plugin-sdk.version>
|
||||
<flyway.version>7.15.0</flyway.version>
|
||||
<shiro.version>1.10.0</shiro.version>
|
||||
<mssql-jdbc.version>7.4.1.jre8</mssql-jdbc.version>
|
||||
|
@ -1,7 +1,7 @@
|
||||
package io.metersphere.controller.remote;
|
||||
|
||||
import io.metersphere.remote.service.PlatformPluginService;
|
||||
import io.metersphere.remote.service.SystemSettingService;
|
||||
import io.metersphere.service.remote.SystemSettingService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
@ -1,12 +0,0 @@
|
||||
package io.metersphere.remote.service;
|
||||
|
||||
import io.metersphere.commons.constants.MicroServiceName;
|
||||
import io.metersphere.service.RemoteService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SystemSettingService extends RemoteService {
|
||||
public SystemSettingService() {
|
||||
super(MicroServiceName.SYSTEM_SETTING);
|
||||
}
|
||||
}
|
@ -49,7 +49,6 @@ import draggable from 'vuedraggable';
|
||||
import TemplateComponentEditHeader
|
||||
from "./ext/TemplateComponentEditHeader";
|
||||
import MsFormDivider from "metersphere-frontend/src/components/MsFormDivider";
|
||||
import {ISSUE_PLATFORM_OPTION} from "metersphere-frontend/src/utils/table-constants";
|
||||
import CustomFieldFormList from "./CustomFieldFormList";
|
||||
import CustomFieldRelateList from "./CustomFieldRelateList";
|
||||
import FieldTemplateEdit from "./FieldTemplateEdit";
|
||||
@ -90,10 +89,10 @@ export default {
|
||||
url: '',
|
||||
};
|
||||
},
|
||||
props: {
|
||||
platformOption: Array
|
||||
},
|
||||
computed: {
|
||||
platformOption() {
|
||||
return ISSUE_PLATFORM_OPTION;
|
||||
},
|
||||
isSystem() {
|
||||
return this.form.system;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@
|
||||
:total="total"/>
|
||||
|
||||
<issue-template-copy ref="templateCopy" @refresh="initTableData"/>
|
||||
<issue-template-edit ref="templateEdit" @refresh="initTableData"/>
|
||||
<issue-template-edit :platform-option="platformFilters" ref="templateEdit" @refresh="initTableData"/>
|
||||
<ms-delete-confirm :title="$t('commons.template_delete')" @delete="_handleDelete" ref="deleteConfirm"/>
|
||||
</el-card>
|
||||
</template>
|
||||
@ -95,6 +95,7 @@ import IssueTemplateEdit from "./IssueTemplateEdit";
|
||||
import {deleteIssueFieldTemplateById, getIssueFieldTemplatePages} from "../../../api/template";
|
||||
import MsDeleteConfirm from "metersphere-frontend/src/components/MsDeleteConfirm";
|
||||
import IssueTemplateCopy from "./IssueTemplateCopy";
|
||||
import {getPlatformOption} from "@/api/platform-plugin";
|
||||
|
||||
export default {
|
||||
name: "IssuesTemplateList",
|
||||
@ -102,7 +103,7 @@ export default {
|
||||
IssueTemplateEdit,
|
||||
IssueTemplateCopy,
|
||||
MsTableHeader,
|
||||
MsTablePagination, MsTableButton, MsTableOperators, MsTableColumn, MsTable , MsDeleteConfirm
|
||||
MsTablePagination, MsTableButton, MsTableOperators, MsTableColumn, MsTable, MsDeleteConfirm
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -113,9 +114,9 @@ export default {
|
||||
currentPage: 1,
|
||||
result: {},
|
||||
loading: false,
|
||||
platformOptions: [],
|
||||
issuePlatformMap: {
|
||||
Local: 'Metersphere',
|
||||
Jira: 'JIRA',
|
||||
Tapd: 'Tapd',
|
||||
Zentao: '禅道',
|
||||
AzureDevops: 'Azure Devops',
|
||||
@ -135,6 +136,10 @@ export default {
|
||||
};
|
||||
},
|
||||
created() {
|
||||
getPlatformOption()
|
||||
.then((r) => {
|
||||
this.platformOptions = r.data;
|
||||
});
|
||||
this.initTableData();
|
||||
},
|
||||
computed: {
|
||||
@ -142,7 +147,12 @@ export default {
|
||||
return ISSUE_TEMPLATE_LIST;
|
||||
},
|
||||
platformFilters() {
|
||||
return ISSUE_PLATFORM_OPTION;
|
||||
this.platformOptions.forEach(item => {
|
||||
this.issuePlatformMap[item.value] = item.text;
|
||||
});
|
||||
let options = [...ISSUE_PLATFORM_OPTION];
|
||||
options.push(...this.platformOptions);
|
||||
return options;
|
||||
},
|
||||
tableHeight() {
|
||||
return document.documentElement.clientHeight - 200;
|
||||
|
@ -26,6 +26,12 @@
|
||||
<artifactId>metersphere-platform-plugin-sdk</artifactId>
|
||||
<groupId>io.metersphere</groupId>
|
||||
<version>${platform-plugin-sdk.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>io.metersphere</groupId>
|
||||
<artifactId>domain</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.metersphere.controller;
|
||||
|
||||
import io.metersphere.domain.SelectOption;
|
||||
import io.metersphere.platform.domain.SelectOption;
|
||||
import io.metersphere.dto.PlatformProjectOptionRequest;
|
||||
import io.metersphere.service.PlatformPluginService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package io.metersphere.service;
|
||||
|
||||
import io.metersphere.api.Platform;
|
||||
import io.metersphere.api.PluginMetaInfo;
|
||||
import io.metersphere.platform.api.Platform;
|
||||
import io.metersphere.platform.api.PluginMetaInfo;
|
||||
import io.metersphere.base.domain.PluginWithBLOBs;
|
||||
import io.metersphere.base.domain.ServiceIntegration;
|
||||
import io.metersphere.base.mapper.PluginMapper;
|
||||
@ -11,11 +11,9 @@ import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.domain.GetOptionRequest;
|
||||
import io.metersphere.domain.PlatformRequest;
|
||||
import io.metersphere.domain.SelectOption;
|
||||
import io.metersphere.platform.domain.*;
|
||||
import io.metersphere.dto.PlatformProjectOptionRequest;
|
||||
import io.metersphere.loader.PlatformPluginManager;
|
||||
import io.metersphere.platform.loader.PlatformPluginManager;
|
||||
import io.metersphere.request.IntegrationRequest;
|
||||
import io.metersphere.utils.PluginManagerUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.metersphere.service.plugin;
|
||||
|
||||
import im.metersphere.storage.StorageStrategy;
|
||||
import im.metersphere.plugin.storage.StorageStrategy;
|
||||
import io.metersphere.commons.constants.StorageConstants;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.metadata.service.FileManagerService;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.metersphere.utils;
|
||||
|
||||
import im.metersphere.loader.PluginManager;
|
||||
import im.metersphere.plugin.loader.PluginManager;
|
||||
import io.metersphere.base.domain.PluginWithBLOBs;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
|
@ -17,13 +17,11 @@ import io.metersphere.log.annotation.MsAuditLog;
|
||||
import io.metersphere.notice.annotation.SendNotice;
|
||||
import io.metersphere.request.issues.IssueExportRequest;
|
||||
import io.metersphere.request.issues.IssueImportRequest;
|
||||
import io.metersphere.request.issues.JiraIssueTypeRequest;
|
||||
import io.metersphere.request.issues.PlatformIssueTypeRequest;
|
||||
import io.metersphere.request.testcase.AuthUserIssueRequest;
|
||||
import io.metersphere.request.testcase.IssuesCountRequest;
|
||||
import io.metersphere.service.BaseCheckPermissionService;
|
||||
import io.metersphere.service.IssuesService;
|
||||
import io.metersphere.service.issue.domain.jira.JiraIssueType;
|
||||
import io.metersphere.service.issue.domain.zentao.ZentaoBuild;
|
||||
import io.metersphere.xpack.track.dto.*;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||
@ -186,14 +184,14 @@ public class IssuesController {
|
||||
return issuesService.getThirdPartTemplate(projectId);
|
||||
}
|
||||
|
||||
@PostMapping("/jira/issuetype")
|
||||
public List<JiraIssueType> getJiraIssueType(@RequestBody JiraIssueTypeRequest request) {
|
||||
return issuesService.getIssueTypes(request);
|
||||
@GetMapping("/demand/list/{projectId}")
|
||||
public List getDemandList(@PathVariable String projectId) {
|
||||
return issuesService.getDemandList(projectId);
|
||||
}
|
||||
|
||||
@GetMapping("/demand/list/{projectId}")
|
||||
public List<DemandDTO> getDemandList(@PathVariable String projectId) {
|
||||
return issuesService.getDemandList(projectId);
|
||||
@GetMapping("/third/part/template/enable/{projectId}")
|
||||
public boolean thirdPartTemplateEnable(@PathVariable String projectId) {
|
||||
return issuesService.thirdPartTemplateEnable(projectId);
|
||||
}
|
||||
|
||||
@PostMapping("/platform/transitions")
|
||||
|
@ -295,14 +295,14 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
||||
Map<String, List<CustomFieldDao>> customFieldMap = customFields.stream().collect(Collectors.groupingBy(CustomFieldDao::getName));
|
||||
issueExcelData.getCustomData().forEach((k, v) -> {
|
||||
try {
|
||||
List<CustomFieldDao> customFieldDaos = customFieldMap.get(k);
|
||||
if (CollectionUtils.isNotEmpty(customFieldDaos) && customFieldDaos.size() > 0) {
|
||||
CustomFieldDao customFieldDao = customFieldDaos.get(0);
|
||||
List<CustomFieldDao> customFieldDaoList = customFieldMap.get(k);
|
||||
if (CollectionUtils.isNotEmpty(customFieldDaoList) && customFieldDaoList.size() > 0) {
|
||||
CustomFieldDao customFieldDao = customFieldDaoList.get(0);
|
||||
String type = customFieldDao.getType();
|
||||
// addfield
|
||||
// add field
|
||||
CustomFieldResourceDTO customFieldResourceDTO = new CustomFieldResourceDTO();
|
||||
customFieldResourceDTO.setFieldId(customFieldDao.getId());
|
||||
// requestfield
|
||||
// request field
|
||||
CustomFieldItemDTO customFieldItemDTO = new CustomFieldItemDTO();
|
||||
BeanUtils.copyBean(customFieldItemDTO, customFieldDao);
|
||||
if (StringUtils.isEmpty(v.toString())) {
|
||||
|
@ -8,16 +8,17 @@ import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.FileUtils;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.xpack.track.dto.AttachmentSyncType;
|
||||
import io.metersphere.constants.AttachmentType;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.metadata.service.FileMetadataService;
|
||||
import io.metersphere.metadata.utils.MetadataUtils;
|
||||
import io.metersphere.platform.domain.SyncIssuesAttachmentRequest;
|
||||
import io.metersphere.request.attachment.AttachmentRequest;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesUpdateRequest;
|
||||
import io.metersphere.service.issue.platform.IssueFactory;
|
||||
import io.metersphere.xmind.utils.FileUtil;
|
||||
import io.metersphere.xpack.track.dto.AttachmentSyncType;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesUpdateRequest;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
@ -35,7 +36,7 @@ import javax.annotation.Resource;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
/**
|
||||
* @author songcc
|
||||
@ -68,6 +69,8 @@ public class AttachmentService {
|
||||
private BaseUserService baseUserService;
|
||||
@Resource
|
||||
SqlSessionFactory sqlSessionFactory;
|
||||
@Resource
|
||||
PlatformPluginService platformPluginService;
|
||||
|
||||
public void uploadAttachment(AttachmentRequest request, MultipartFile file) {
|
||||
// 附件上传的前置校验
|
||||
@ -98,11 +101,16 @@ public class AttachmentService {
|
||||
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
||||
updateRequest.setPlatformId(issues.getPlatformId());
|
||||
File uploadFile = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
||||
.syncIssuesAttachment(updateRequest, uploadFile, AttachmentSyncType.UPLOAD);
|
||||
|
||||
if (PlatformPluginService.isPluginPlatform(issues.getPlatform())) {
|
||||
syncIssuesAttachment(issues, uploadFile, AttachmentSyncType.UPLOAD);
|
||||
} else {
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
||||
.syncIssuesAttachment(updateRequest, uploadFile, AttachmentSyncType.UPLOAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,11 +127,16 @@ public class AttachmentService {
|
||||
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
||||
updateRequest.setPlatformId(issues.getPlatformId());
|
||||
File deleteFile = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
||||
.syncIssuesAttachment(updateRequest, deleteFile, AttachmentSyncType.DELETE);
|
||||
|
||||
if (PlatformPluginService.isPluginPlatform(issues.getPlatform())) {
|
||||
syncIssuesAttachment(issues, deleteFile, AttachmentSyncType.DELETE);
|
||||
} else {
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
||||
.syncIssuesAttachment(updateRequest, deleteFile, AttachmentSyncType.DELETE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,17 +191,31 @@ public class AttachmentService {
|
||||
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
||||
updateRequest.setPlatformId(issues.getPlatformId());
|
||||
File refFile = downloadMetadataFile(metadataRefId, fileMetadata.getName());
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
||||
.syncIssuesAttachment(updateRequest, refFile, AttachmentSyncType.UPLOAD);
|
||||
|
||||
if (PlatformPluginService.isPluginPlatform(issues.getPlatform())) {
|
||||
syncIssuesAttachment(issues, refFile, AttachmentSyncType.UPLOAD);
|
||||
} else {
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
||||
.syncIssuesAttachment(updateRequest, refFile, AttachmentSyncType.UPLOAD);
|
||||
}
|
||||
FileUtils.deleteFile(FileUtils.ATTACHMENT_TMP_DIR + File.separator + fileMetadata.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void syncIssuesAttachment(IssuesWithBLOBs issues, File refFile, AttachmentSyncType attachmentSyncType) {
|
||||
SyncIssuesAttachmentRequest attachmentRequest = new SyncIssuesAttachmentRequest();
|
||||
attachmentRequest.setPlatformId(issues.getPlatformId());
|
||||
attachmentRequest.setFile(refFile);
|
||||
attachmentRequest.setSyncType(attachmentSyncType.syncOperateType());
|
||||
platformPluginService.getPlatform(issues.getPlatform())
|
||||
.syncIssuesAttachment(attachmentRequest);
|
||||
}
|
||||
|
||||
public List<FileAttachmentMetadata> listMetadata(AttachmentRequest request) {
|
||||
List<FileAttachmentMetadata> attachments = new ArrayList<FileAttachmentMetadata>();
|
||||
AttachmentModuleRelationExample example = new AttachmentModuleRelationExample();
|
||||
@ -276,12 +303,17 @@ public class AttachmentService {
|
||||
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
||||
updateRequest.setPlatformId(issues.getPlatformId());
|
||||
File refFile = downloadMetadataFile(metadataRefId, fileMetadata.getName());
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
||||
.syncIssuesAttachment(updateRequest, refFile, AttachmentSyncType.UPLOAD);
|
||||
FileUtils.deleteFile(FileUtils.ATTACHMENT_TMP_DIR + File.separator + fileMetadata.getName());
|
||||
|
||||
if (PlatformPluginService.isPluginPlatform(issues.getPlatform())) {
|
||||
syncIssuesAttachment(issues, refFile, AttachmentSyncType.UPLOAD);
|
||||
} else {
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
||||
.syncIssuesAttachment(updateRequest, refFile, AttachmentSyncType.UPLOAD);
|
||||
FileUtils.deleteFile(FileUtils.ATTACHMENT_TMP_DIR + File.separator + fileMetadata.getName());
|
||||
}
|
||||
}
|
||||
});
|
||||
sqlSession.flushStatements();
|
||||
@ -301,11 +333,16 @@ public class AttachmentService {
|
||||
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
||||
updateRequest.setPlatformId(issues.getPlatformId());
|
||||
File deleteFile = new File(FileUtils.ATTACHMENT_TMP_DIR + File.separator + fileAttachmentMetadata.getName());
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
||||
.syncIssuesAttachment(updateRequest, deleteFile, AttachmentSyncType.DELETE);
|
||||
|
||||
if (PlatformPluginService.isPluginPlatform(issues.getPlatform())) {
|
||||
syncIssuesAttachment(issues, deleteFile, AttachmentSyncType.UPLOAD);
|
||||
} else {
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
||||
.syncIssuesAttachment(updateRequest, deleteFile, AttachmentSyncType.DELETE);
|
||||
}
|
||||
});
|
||||
}
|
||||
AttachmentModuleRelationExample example = new AttachmentModuleRelationExample();
|
||||
|
@ -4,6 +4,7 @@ import com.alibaba.excel.EasyExcelFactory;
|
||||
import com.alibaba.excel.util.DateUtils;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.platform.api.Platform;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtIssueCommentMapper;
|
||||
@ -13,6 +14,7 @@ import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.constants.AttachmentType;
|
||||
import io.metersphere.constants.SystemCustomField;
|
||||
import io.metersphere.platform.domain.*;
|
||||
import io.metersphere.dto.*;
|
||||
import io.metersphere.excel.constants.IssueExportHeadField;
|
||||
import io.metersphere.excel.domain.ExcelErrData;
|
||||
@ -37,17 +39,18 @@ import io.metersphere.request.IntegrationRequest;
|
||||
import io.metersphere.request.attachment.AttachmentRequest;
|
||||
import io.metersphere.request.issues.IssueExportRequest;
|
||||
import io.metersphere.request.issues.IssueImportRequest;
|
||||
import io.metersphere.request.issues.JiraIssueTypeRequest;
|
||||
import io.metersphere.request.issues.PlatformIssueTypeRequest;
|
||||
import io.metersphere.request.testcase.AuthUserIssueRequest;
|
||||
import io.metersphere.request.testcase.IssuesCountRequest;
|
||||
import io.metersphere.service.issue.domain.jira.JiraIssueType;
|
||||
import io.metersphere.service.issue.domain.zentao.ZentaoBuild;
|
||||
import io.metersphere.service.issue.platform.*;
|
||||
import io.metersphere.service.remote.project.TrackCustomFieldTemplateService;
|
||||
import io.metersphere.service.remote.project.TrackIssueTemplateService;
|
||||
import io.metersphere.service.wapper.TrackProjectService;
|
||||
import io.metersphere.service.wapper.UserService;
|
||||
import io.metersphere.utils.DistinctKeyUtil;
|
||||
import io.metersphere.xpack.track.dto.PlatformStatusDTO;
|
||||
import io.metersphere.xpack.track.dto.PlatformUser;
|
||||
import io.metersphere.xpack.track.dto.*;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesUpdateRequest;
|
||||
@ -124,6 +127,8 @@ public class IssuesService {
|
||||
@Resource
|
||||
private AttachmentService attachmentService;
|
||||
@Resource
|
||||
private AttachmentModuleRelationMapper attachmentModuleRelationMapper;
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
@Resource
|
||||
SqlSessionFactory sqlSessionFactory;
|
||||
@ -131,6 +136,10 @@ public class IssuesService {
|
||||
private FileMetadataMapper fileMetadataMapper;
|
||||
@Resource
|
||||
private ExtIssueCommentMapper extIssueCommentMapper;
|
||||
@Resource
|
||||
private PlatformPluginService platformPluginService;
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
private static final String SYNC_THIRD_PARTY_ISSUES_KEY = "ISSUE:SYNC";
|
||||
|
||||
@ -143,19 +152,56 @@ public class IssuesService {
|
||||
|
||||
|
||||
public IssuesWithBLOBs addIssues(IssuesUpdateRequest issuesRequest, List<MultipartFile> files) {
|
||||
List<IssuesPlatform> platformList = getAddPlatforms(issuesRequest);
|
||||
Project project = baseProjectService.getProjectById(issuesRequest.getProjectId());
|
||||
IssuesWithBLOBs issues = null;
|
||||
for (IssuesPlatform platform : platformList) {
|
||||
issues = platform.addIssue(issuesRequest);
|
||||
if (PlatformPluginService.isPluginPlatform(project.getPlatform())) {
|
||||
PlatformIssuesUpdateRequest platformIssuesUpdateRequest =
|
||||
JSON.parseObject(JSON.toJSONString(issuesRequest), PlatformIssuesUpdateRequest.class);
|
||||
List<PlatformCustomFieldItemDTO> customFieldItemDTOS =
|
||||
JSON.parseArray(JSON.toJSONString(issuesRequest.getRequestFields()), PlatformCustomFieldItemDTO.class);
|
||||
platformIssuesUpdateRequest.setCustomFieldList(customFieldItemDTOS); // todo 全部插件化后去掉
|
||||
platformIssuesUpdateRequest.setUserPlatformUserConfig(userService.getCurrentPlatformInfoStr(SessionUtils.getCurrentWorkspaceId()));
|
||||
platformIssuesUpdateRequest.setProjectConfig(PlatformPluginService.getCompatibleProjectConfig(project));
|
||||
|
||||
issues = platformPluginService.getPlatform(project.getPlatform())
|
||||
.addIssue(platformIssuesUpdateRequest);
|
||||
|
||||
insertIssues(issues);
|
||||
issuesRequest.setId(issues.getId());
|
||||
|
||||
// 用例与第三方缺陷平台中的缺陷关联
|
||||
handleTestCaseIssues(issuesRequest);
|
||||
|
||||
// 如果是复制新增, 同步MS附件到Jira
|
||||
if (StringUtils.isNotEmpty(issuesRequest.getCopyIssueId())) {
|
||||
AttachmentRequest attachmentRequest = new AttachmentRequest();
|
||||
attachmentRequest.setBelongId(issuesRequest.getCopyIssueId());
|
||||
attachmentRequest.setBelongType(AttachmentType.ISSUE.type());
|
||||
List<String> attachmentIds = attachmentService.getAttachmentIdsByParam(attachmentRequest);
|
||||
if (CollectionUtils.isNotEmpty(attachmentIds)) {
|
||||
for (String attachmentId : attachmentIds) {
|
||||
FileAttachmentMetadata fileAttachmentMetadata = attachmentService.getFileAttachmentMetadataByFileId(attachmentId);
|
||||
File file = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
||||
attachmentService.syncIssuesAttachment(issues, file, AttachmentSyncType.UPLOAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<IssuesPlatform> platformList = getAddPlatforms(issuesRequest);
|
||||
for (IssuesPlatform platform : platformList) {
|
||||
issues = platform.addIssue(issuesRequest);
|
||||
}
|
||||
}
|
||||
|
||||
if (issuesRequest.getIsPlanEdit()) {
|
||||
issuesRequest.getAddResourceIds().forEach(l -> {
|
||||
testCaseIssueService.updateIssuesCount(l);
|
||||
});
|
||||
}
|
||||
saveFollows(issuesRequest.getId(), issuesRequest.getFollows());
|
||||
customFieldIssuesService.addFields(issuesRequest.getId(), issuesRequest.getAddFields());
|
||||
customFieldIssuesService.editFields(issuesRequest.getId(), issuesRequest.getEditFields());
|
||||
String issuesId = issues.getId();
|
||||
saveFollows(issuesId, issuesRequest.getFollows());
|
||||
customFieldIssuesService.addFields(issuesId, issuesRequest.getAddFields());
|
||||
customFieldIssuesService.editFields(issuesId, issuesRequest.getEditFields());
|
||||
if (StringUtils.isNotEmpty(issuesRequest.getCopyIssueId())) {
|
||||
final String platformId = issues.getPlatformId();
|
||||
// 复制新增, 同步缺陷的MS附件
|
||||
@ -215,11 +261,15 @@ public class IssuesService {
|
||||
fileAttachmentMetadataBatchMapper.insert(fileAttachmentMetadata);
|
||||
// 下载文件管理文件, 同步到第三方平台
|
||||
File refFile = attachmentService.downloadMetadataFile(filemetaId, fileMetadata.getName());
|
||||
IssuesRequest addIssueRequest = new IssuesRequest();
|
||||
addIssueRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
addIssueRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
Objects.requireNonNull(IssueFactory.createPlatform(platform, addIssueRequest))
|
||||
.syncIssuesAttachment(issuesRequest, refFile, AttachmentSyncType.UPLOAD);
|
||||
if (PlatformPluginService.isPluginPlatform(platform)) {
|
||||
attachmentService.syncIssuesAttachment(issuesRequest, refFile, AttachmentSyncType.UPLOAD);
|
||||
} else {
|
||||
IssuesRequest addIssueRequest = new IssuesRequest();
|
||||
addIssueRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
addIssueRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
Objects.requireNonNull(IssueFactory.createPlatform(platform, addIssueRequest))
|
||||
.syncIssuesAttachment(issuesRequest, refFile, AttachmentSyncType.UPLOAD);
|
||||
}
|
||||
FileUtils.deleteFile(FileUtils.ATTACHMENT_TMP_DIR + File.separator + fileMetadata.getName());
|
||||
});
|
||||
sqlSession.flushStatements();
|
||||
@ -231,11 +281,90 @@ public class IssuesService {
|
||||
return getIssue(issues.getId());
|
||||
}
|
||||
|
||||
protected IssuesWithBLOBs insertIssues(IssuesWithBLOBs issues) {
|
||||
if (StringUtils.isBlank(issues.getId())) {
|
||||
issues.setId(UUID.randomUUID().toString());
|
||||
}
|
||||
issues.setCreateTime(System.currentTimeMillis());
|
||||
issues.setUpdateTime(System.currentTimeMillis());
|
||||
issues.setNum(getNextNum(issues.getProjectId()));
|
||||
issues.setCreator(SessionUtils.getUserId());
|
||||
issuesMapper.insert(issues);
|
||||
return issues;
|
||||
}
|
||||
|
||||
protected int getNextNum(String projectId) {
|
||||
Issues issue = extIssuesMapper.getNextNum(projectId);
|
||||
if (issue == null || issue.getNum() == null) {
|
||||
return 100001;
|
||||
} else {
|
||||
return Optional.of(issue.getNum() + 1).orElse(100001);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleTestCaseIssues(IssuesUpdateRequest issuesRequest) {
|
||||
String issuesId = issuesRequest.getId();
|
||||
List<String> deleteCaseIds = issuesRequest.getDeleteResourceIds();
|
||||
|
||||
if (!org.springframework.util.CollectionUtils.isEmpty(deleteCaseIds)) {
|
||||
TestCaseIssuesExample example = new TestCaseIssuesExample();
|
||||
example.createCriteria().andResourceIdIn(deleteCaseIds);
|
||||
// 测试计划的用例 deleteCaseIds 是空的, 不会进到这里
|
||||
example.or(example.createCriteria().andRefIdIn(deleteCaseIds));
|
||||
testCaseIssuesMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
List<String> addCaseIds = issuesRequest.getAddResourceIds();
|
||||
TestCaseIssueService testCaseIssueService = CommonBeanFactory.getBean(TestCaseIssueService.class);
|
||||
|
||||
if (!org.springframework.util.CollectionUtils.isEmpty(addCaseIds)) {
|
||||
if (issuesRequest.getIsPlanEdit()) {
|
||||
addCaseIds.forEach(caseId -> {
|
||||
testCaseIssueService.add(issuesId, caseId, issuesRequest.getRefId(), IssueRefType.PLAN_FUNCTIONAL.name());
|
||||
testCaseIssueService.updateIssuesCount(caseId);
|
||||
});
|
||||
} else {
|
||||
addCaseIds.forEach(caseId -> testCaseIssueService.add(issuesId, caseId, null, IssueRefType.FUNCTIONAL.name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IssuesWithBLOBs updateIssues(IssuesUpdateRequest issuesRequest) {
|
||||
List<IssuesPlatform> platformList = getUpdatePlatforms(issuesRequest);
|
||||
platformList.forEach(platform -> {
|
||||
platform.updateIssue(issuesRequest);
|
||||
});
|
||||
PlatformIssuesUpdateRequest platformIssuesUpdateRequest = JSON.parseObject(JSON.toJSONString(issuesRequest), PlatformIssuesUpdateRequest.class);
|
||||
Project project = baseProjectService.getProjectById(issuesRequest.getProjectId());
|
||||
if (PlatformPluginService.isPluginPlatform(project.getPlatform())) {
|
||||
|
||||
Platform platform = platformPluginService.getPlatform(project.getPlatform());
|
||||
|
||||
if (platform.isAttachmentUploadSupport()) {
|
||||
AttachmentRequest attachmentRequest = new AttachmentRequest();
|
||||
attachmentRequest.setBelongId(issuesRequest.getId());
|
||||
attachmentRequest.setBelongType(AttachmentType.ISSUE.type());
|
||||
List<FileAttachmentMetadata> fileAttachmentMetadata = attachmentService.listMetadata(attachmentRequest);
|
||||
Set<String> msAttachmentNames = fileAttachmentMetadata.stream()
|
||||
.map(FileAttachmentMetadata::getName)
|
||||
.collect(Collectors.toSet());
|
||||
// 获得缺陷MS附件名称
|
||||
platformIssuesUpdateRequest.setMsAttachmentNames(msAttachmentNames);
|
||||
}
|
||||
|
||||
List<PlatformCustomFieldItemDTO> customFieldItemDTOS = JSON.parseArray(JSON.toJSONString(issuesRequest.getRequestFields()), PlatformCustomFieldItemDTO.class);
|
||||
platformIssuesUpdateRequest.setCustomFieldList(customFieldItemDTOS); // todo 全部插件化后去掉
|
||||
platformIssuesUpdateRequest.setUserPlatformUserConfig(userService.getCurrentPlatformInfoStr(SessionUtils.getCurrentWorkspaceId()));
|
||||
platformIssuesUpdateRequest.setProjectConfig(PlatformPluginService.getCompatibleProjectConfig(project));
|
||||
IssuesWithBLOBs issue = platformPluginService.getPlatform(project.getPlatform())
|
||||
.updateIssue(platformIssuesUpdateRequest);
|
||||
|
||||
issue.setUpdateTime(System.currentTimeMillis());
|
||||
issuesMapper.updateByPrimaryKeySelective(issue);
|
||||
handleTestCaseIssues(issuesRequest);
|
||||
} else {
|
||||
List<IssuesPlatform> platformList = getUpdatePlatforms(issuesRequest);
|
||||
platformList.forEach(platform -> {
|
||||
platform.updateIssue(issuesRequest);
|
||||
});
|
||||
}
|
||||
|
||||
customFieldIssuesService.editFields(issuesRequest.getId(), issuesRequest.getEditFields());
|
||||
customFieldIssuesService.addFields(issuesRequest.getId(), issuesRequest.getAddFields());
|
||||
|
||||
@ -377,7 +506,7 @@ public class IssuesService {
|
||||
|
||||
if (jira) {
|
||||
String jiraKey = project.getJiraKey();
|
||||
if (StringUtils.isNotBlank(jiraKey) && StringUtils.equals(project.getPlatform(), IssuesManagePlatform.Jira.toString())) {
|
||||
if (StringUtils.isNotBlank(jiraKey) && PlatformPluginService.isPluginPlatform(project.getPlatform())) {
|
||||
platforms.add(IssuesManagePlatform.Jira.name());
|
||||
}
|
||||
}
|
||||
@ -479,8 +608,15 @@ public class IssuesService {
|
||||
Project project = baseProjectService.getProjectById(projectId);
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setWorkspaceId(project.getWorkspaceId());
|
||||
IssuesPlatform platform = IssueFactory.createPlatform(issuesWithBLOBs.getPlatform(), issuesRequest);
|
||||
platform.deleteIssue(id);
|
||||
if (PlatformPluginService.isPluginPlatform(issuesWithBLOBs.getPlatform())) {
|
||||
platformPluginService.getPlatform(issuesWithBLOBs.getPlatform())
|
||||
.deleteIssue(issuesWithBLOBs.getPlatformId());
|
||||
deleteIssue(id);
|
||||
} else {
|
||||
IssuesPlatform platform = IssueFactory.createPlatform(issuesWithBLOBs.getPlatform(), issuesRequest);
|
||||
platform.deleteIssue(id);
|
||||
}
|
||||
|
||||
// 删除缺陷对应的附件
|
||||
AttachmentRequest request = new AttachmentRequest();
|
||||
request.setBelongId(id);
|
||||
@ -750,13 +886,6 @@ public class IssuesService {
|
||||
return issueMap;
|
||||
}
|
||||
|
||||
public Map<String, IssuesPlatform> getPlatformMap(IssuesRequest request) {
|
||||
Project project = baseProjectService.getProjectById(request.getProjectId());
|
||||
List<String> platforms = getPlatforms(project);
|
||||
platforms.add(IssuesManagePlatform.Local.toString());
|
||||
return IssueFactory.createPlatformsForMap(platforms, request);
|
||||
}
|
||||
|
||||
public void syncThirdPartyIssues() {
|
||||
List<String> projectIds = trackProjectService.getThirdPartProjectIds();
|
||||
projectIds.forEach(id -> {
|
||||
@ -834,8 +963,14 @@ public class IssuesService {
|
||||
String defaultCustomFields = getDefaultCustomFields(syncRequest.getProjectId());
|
||||
issuesRequest.setDefaultCustomFields(defaultCustomFields);
|
||||
}
|
||||
IssuesPlatform platform = IssueFactory.createPlatform(project.getPlatform(), issuesRequest);
|
||||
syncThirdPartyIssues(platform::syncIssues, project, issues);
|
||||
if (PlatformPluginService.isPluginPlatform(project.getPlatform())) {
|
||||
// 分批处理
|
||||
SubListUtil.dealForSubList(issues, 500, (subIssue) ->
|
||||
syncPluginThirdPartyIssues(subIssue, project));
|
||||
} else {
|
||||
IssuesPlatform platform = IssueFactory.createPlatform(project.getPlatform(), issuesRequest);
|
||||
syncThirdPartyIssues(platform::syncIssues, project, issues);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
} finally {
|
||||
@ -845,6 +980,118 @@ public class IssuesService {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void syncPluginThirdPartyIssues(List<IssuesDao> issues, Project project) {
|
||||
List<PlatformIssuesDTO> platformIssues = JSON.parseArray(JSON.toJSONString(issues), PlatformIssuesDTO.class);
|
||||
platformIssues.stream().forEach(item -> {
|
||||
// 给缺陷添加自定义字段
|
||||
List<PlatformCustomFieldItemDTO> platformCustomFieldList = extIssuesMapper.getIssueCustomField(item.getId()).stream()
|
||||
.map(field -> {
|
||||
PlatformCustomFieldItemDTO platformCustomFieldItemDTO = new PlatformCustomFieldItemDTO();
|
||||
BeanUtils.copyBean(platformCustomFieldItemDTO, field);
|
||||
return platformCustomFieldItemDTO;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
item.setCustomFieldList(platformCustomFieldList);
|
||||
});
|
||||
SyncIssuesRequest request = new SyncIssuesRequest();
|
||||
request.setIssues(platformIssues);
|
||||
request.setProjectConfig(PlatformPluginService.getCompatibleProjectConfig(project));
|
||||
Platform platform = platformPluginService.getPlatform(project.getPlatform());
|
||||
|
||||
// 获取需要变更的缺陷
|
||||
SyncIssuesResult syncIssuesResult = platform.syncIssues(request);
|
||||
List<IssuesWithBLOBs> updateIssues = syncIssuesResult.getUpdateIssues();
|
||||
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
IssuesMapper issueBatchMapper = sqlSession.getMapper(IssuesMapper.class);
|
||||
AttachmentModuleRelationMapper batchAttachmentModuleRelationMapper = sqlSession.getMapper(AttachmentModuleRelationMapper.class);
|
||||
|
||||
// 批量更新
|
||||
updateIssues.stream()
|
||||
.map(item -> {
|
||||
IssuesWithBLOBs issuesWithBLOBs = new IssuesWithBLOBs();
|
||||
BeanUtils.copyBean(issuesWithBLOBs, item);
|
||||
return issuesWithBLOBs;
|
||||
})
|
||||
.forEach(issueBatchMapper::updateByPrimaryKeySelective);
|
||||
|
||||
// 批量删除
|
||||
syncIssuesResult.getDeleteIssuesIds()
|
||||
.stream()
|
||||
.forEach(issueBatchMapper::deleteByPrimaryKey);
|
||||
|
||||
try {
|
||||
// 同步附件
|
||||
syncPluginIssueAttachment(platform, syncIssuesResult, batchAttachmentModuleRelationMapper);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
|
||||
HashMap<String, List<CustomFieldResourceDTO>> customFieldMap = new HashMap<>();
|
||||
updateIssues.forEach(item -> {
|
||||
List<CustomFieldResourceDTO> customFieldResource = baseCustomFieldService.getCustomFieldResourceDTO(item.getCustomFields());
|
||||
customFieldMap.put(item.getId(), customFieldResource);
|
||||
});
|
||||
|
||||
// 修改自定义字段
|
||||
customFieldIssuesService.batchEditFields(customFieldMap);
|
||||
}
|
||||
|
||||
private void syncPluginIssueAttachment(Platform platform, SyncIssuesResult syncIssuesResult, AttachmentModuleRelationMapper batchAttachmentModuleRelationMapper) {
|
||||
Map<String, List<PlatformAttachment>> attachmentMap = syncIssuesResult.getAttachmentMap();
|
||||
if (MapUtils.isNotEmpty(attachmentMap)) {
|
||||
for (String issueId : attachmentMap.keySet()) {
|
||||
// 查询我们平台的附件
|
||||
Set<String> jiraAttachmentSet = new HashSet<>();
|
||||
AttachmentRequest attachmentRequest = new AttachmentRequest();
|
||||
attachmentRequest.setBelongType(AttachmentType.ISSUE.type());
|
||||
attachmentRequest.setBelongId(issueId);
|
||||
List<FileAttachmentMetadata> allMsAttachments = attachmentService.listMetadata(attachmentRequest);
|
||||
Set<String> attachmentsNameSet = allMsAttachments.stream()
|
||||
.map(FileAttachmentMetadata::getName)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
List<PlatformAttachment> syncAttachments = attachmentMap.get(issueId);
|
||||
for (PlatformAttachment syncAttachment : syncAttachments) {
|
||||
jiraAttachmentSet.add(syncAttachment.getFileName());
|
||||
if (!attachmentsNameSet.contains(syncAttachment.getFileName())) {
|
||||
try {
|
||||
byte[] content = platform.getAttachmentContent(syncAttachment.getFileKey());
|
||||
if (content == null) {
|
||||
continue;
|
||||
}
|
||||
FileAttachmentMetadata fileAttachmentMetadata = attachmentService
|
||||
.saveAttachmentByBytes(content, AttachmentType.ISSUE.type(), issueId, syncAttachment.getFileName());
|
||||
AttachmentModuleRelation attachmentModuleRelation = new AttachmentModuleRelation();
|
||||
attachmentModuleRelation.setAttachmentId(fileAttachmentMetadata.getId());
|
||||
attachmentModuleRelation.setRelationId(issueId);
|
||||
attachmentModuleRelation.setRelationType(AttachmentType.ISSUE.type());
|
||||
batchAttachmentModuleRelationMapper.insert(attachmentModuleRelation);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除Jira中不存在的附件
|
||||
if (CollectionUtils.isNotEmpty(allMsAttachments)) {
|
||||
List<FileAttachmentMetadata> deleteMsAttachments = allMsAttachments.stream()
|
||||
.filter(msAttachment -> !jiraAttachmentSet.contains(msAttachment.getName()))
|
||||
.collect(Collectors.toList());
|
||||
deleteMsAttachments.forEach(fileAttachmentMetadata -> {
|
||||
List<String> ids = List.of(fileAttachmentMetadata.getId());
|
||||
AttachmentModuleRelationExample example = new AttachmentModuleRelationExample();
|
||||
example.createCriteria().andAttachmentIdIn(ids).andRelationTypeEqualTo(AttachmentType.ISSUE.type());
|
||||
// 删除MS附件及关联数据
|
||||
attachmentService.deleteAttachmentByIds(ids);
|
||||
attachmentService.deleteFileAttachmentByIds(ids);
|
||||
batchAttachmentModuleRelationMapper.deleteByExample(example);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取默认的自定义字段的取值,同步之后更新成第三方平台的值
|
||||
@ -967,6 +1214,7 @@ public class IssuesService {
|
||||
|
||||
/**
|
||||
* 获取缺陷状态的自定义字段替换
|
||||
*
|
||||
* @param planIssues
|
||||
* @param planId
|
||||
*/
|
||||
@ -1063,38 +1311,17 @@ public class IssuesService {
|
||||
return issuesMapper.selectByExampleWithBLOBs(example);
|
||||
}
|
||||
|
||||
public List<IssuesDao> getPlatformIssueByIds(List<String> platformIds, String projectId) {
|
||||
// todo 是否保留
|
||||
List<IssuesDao> issues = extIssuesMapper.getPlatformIssueByIds(platformIds, projectId);
|
||||
if (CollectionUtils.isEmpty(issues)) {
|
||||
return issues;
|
||||
}
|
||||
List<String> issueIds = issues.stream().map(IssuesDao::getId).collect(Collectors.toList());
|
||||
List<IssuesDao> issuesList = extIssuesMapper.getIssueCustomFields(issueIds);
|
||||
Map<String, List<CustomFieldItemDTO>> map = new HashMap<>();
|
||||
issuesList.forEach(f -> {
|
||||
CustomFieldItemDTO dto = new CustomFieldItemDTO();
|
||||
dto.setId(f.getFieldId());
|
||||
dto.setName(f.getFieldName());
|
||||
dto.setType(f.getFieldType());
|
||||
dto.setValue(f.getFieldValue());
|
||||
dto.setCustomData(f.getCustomData());
|
||||
List<CustomFieldItemDTO> list = Optional.ofNullable(map.get(f.getId())).orElse(new ArrayList<>());
|
||||
map.put(f.getId(), list);
|
||||
list.add(dto);
|
||||
});
|
||||
issues.forEach(i -> i.setCustomFieldList(map.getOrDefault(i.getId(), new ArrayList<>())));
|
||||
return issues;
|
||||
}
|
||||
|
||||
|
||||
public IssueTemplateDao getThirdPartTemplate(String projectId) {
|
||||
IssueTemplateDao issueTemplateDao = new IssueTemplateDao();
|
||||
if (StringUtils.isNotBlank(projectId)) {
|
||||
Project project = baseProjectService.getProjectById(projectId);
|
||||
return IssueFactory.createPlatform(IssuesManagePlatform.Jira.toString(), getDefaultIssueRequest(projectId, project.getWorkspaceId()))
|
||||
.getThirdPartTemplate();
|
||||
List<PlatformCustomFieldItemDTO> thirdPartCustomField = platformPluginService.getPlatform(project.getPlatform(), project.getWorkspaceId())
|
||||
.getThirdPartCustomField(PlatformPluginService.getCompatibleProjectConfig(project));
|
||||
List<CustomFieldDao> customFieldDaoList = JSON.parseArray(JSON.toJSONString(thirdPartCustomField), CustomFieldDao.class);
|
||||
issueTemplateDao.setCustomFields(customFieldDaoList);
|
||||
issueTemplateDao.setPlatform(project.getPlatform());
|
||||
}
|
||||
return new IssueTemplateDao();
|
||||
return issueTemplateDao;
|
||||
}
|
||||
|
||||
public IssuesRequest getDefaultIssueRequest(String projectId, String workspaceId) {
|
||||
@ -1104,24 +1331,20 @@ public class IssuesService {
|
||||
return issuesRequest;
|
||||
}
|
||||
|
||||
public List<JiraIssueType> getIssueTypes(JiraIssueTypeRequest request) {
|
||||
IssuesRequest issuesRequest = getDefaultIssueRequest(request.getProjectId(), request.getWorkspaceId());
|
||||
JiraPlatform platform = (JiraPlatform) IssueFactory.createPlatform(IssuesManagePlatform.Jira.toString(), issuesRequest);
|
||||
if (StringUtils.isNotBlank(request.getJiraKey())) {
|
||||
return platform.getIssueTypes(request.getJiraKey());
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<DemandDTO> getDemandList(String projectId) {
|
||||
public List getDemandList(String projectId) {
|
||||
Project project = baseProjectService.getProjectById(projectId);
|
||||
String workspaceId = project.getWorkspaceId();
|
||||
IssuesRequest issueRequest = new IssuesRequest();
|
||||
issueRequest.setWorkspaceId(workspaceId);
|
||||
issueRequest.setProjectId(projectId);
|
||||
IssuesPlatform platform = IssueFactory.createPlatform(project.getPlatform(), issueRequest);
|
||||
return platform.getDemandList(projectId);
|
||||
|
||||
if (PlatformPluginService.isPluginPlatform(project.getPlatform())) {
|
||||
return platformPluginService.getPlatform(project.getPlatform())
|
||||
.getDemands(PlatformPluginService.getCompatibleProjectConfig(project));
|
||||
} else {
|
||||
IssuesRequest issueRequest = new IssuesRequest();
|
||||
issueRequest.setWorkspaceId(workspaceId);
|
||||
issueRequest.setProjectId(projectId);
|
||||
IssuesPlatform platform = IssueFactory.createPlatform(project.getPlatform(), issueRequest);
|
||||
return platform.getDemandList(projectId);
|
||||
}
|
||||
}
|
||||
|
||||
public List<IssuesDao> listByWorkspaceId(IssuesRequest request) {
|
||||
@ -1134,47 +1357,36 @@ public class IssuesService {
|
||||
|
||||
if (!StringUtils.isBlank(request.getPlatformKey())) {
|
||||
Project project = baseProjectService.getProjectById(request.getProjectId());
|
||||
List<String> platforms = getPlatforms(project);
|
||||
if (CollectionUtils.isEmpty(platforms)) {
|
||||
return platformStatusDTOS;
|
||||
}
|
||||
String platform = project.getPlatform();
|
||||
if (PlatformPluginService.isPluginPlatform(platform)) {
|
||||
return platformPluginService.getPlatform(platform)
|
||||
.getStatusList(request.getPlatformKey())
|
||||
.stream().map(item -> {
|
||||
PlatformStatusDTO platformStatusDTO = new PlatformStatusDTO();
|
||||
platformStatusDTO.setLabel(item.getLabel());
|
||||
platformStatusDTO.setValue(item.getValue());
|
||||
return platformStatusDTO;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
List<String> platforms = getPlatforms(project);
|
||||
if (CollectionUtils.isEmpty(platforms)) {
|
||||
return platformStatusDTOS;
|
||||
}
|
||||
|
||||
IssuesRequest issuesRequest = getDefaultIssueRequest(request.getProjectId(), request.getWorkspaceId());
|
||||
Map<String, IssuesPlatform> platformMap = IssueFactory.createPlatformsForMap(platforms, issuesRequest);
|
||||
try {
|
||||
if (platformMap.size() > 1) {
|
||||
MSException.throwException(Translator.get("project_reference_multiple_plateform"));
|
||||
}
|
||||
Optional<IssuesPlatform> platformOptional = platformMap.values().stream().findFirst();
|
||||
if (platformOptional.isPresent()) {
|
||||
platformStatusDTOS = platformOptional.get().getTransitions(request.getPlatformKey());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
IssuesRequest issuesRequest = getDefaultIssueRequest(request.getProjectId(), request.getWorkspaceId());
|
||||
return IssueFactory.createPlatform(platform, issuesRequest).getTransitions(request.getPlatformKey());
|
||||
}
|
||||
}
|
||||
|
||||
return platformStatusDTOS;
|
||||
}
|
||||
|
||||
public void deleteIssueAttachments(String issueId) {
|
||||
attachmentService.deleteAttachment(AttachmentType.ISSUE.type(), issueId);
|
||||
IssueFileExample example = new IssueFileExample();
|
||||
example.createCriteria().andIssueIdEqualTo(issueId);
|
||||
List<IssueFile> issueFiles = issueFileMapper.selectByExample(example);
|
||||
if (issueFiles.size() == 0) {
|
||||
return;
|
||||
}
|
||||
List<String> ids = issueFiles.stream().map(IssueFile::getFileId).collect(Collectors.toList());
|
||||
attachmentService.deleteFileAttachmentByIds(ids);
|
||||
issueFileMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
public boolean isThirdPartTemplate(Project project) {
|
||||
return project.getThirdPartTemplate() != null && project.getThirdPartTemplate() && project.getPlatform().equals(IssuesManagePlatform.Jira.name());
|
||||
return project.getThirdPartTemplate() != null
|
||||
&& project.getThirdPartTemplate()
|
||||
&& PlatformPluginService.isPluginPlatform(project.getPlatform());
|
||||
}
|
||||
|
||||
|
||||
public void checkThirdProjectExist(Project project) {
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
if (StringUtils.isBlank(project.getId())) {
|
||||
@ -1373,9 +1585,10 @@ public class IssuesService {
|
||||
}
|
||||
|
||||
private IssueTemplateDao getIssueTemplateByProjectId(String projectId) {
|
||||
IssueTemplateDao issueTemplateDao = new IssueTemplateDao();
|
||||
IssueTemplateDao issueTemplateDao;
|
||||
Project project = baseProjectService.getProjectById(projectId);
|
||||
if (StringUtils.equals(project.getPlatform(), IssuesManagePlatform.Jira.name()) && project.getThirdPartTemplate()) {
|
||||
if (PlatformPluginService.isPluginPlatform(project.getPlatform())
|
||||
&& project.getThirdPartTemplate()) {
|
||||
// 第三方Jira平台
|
||||
issueTemplateDao = getThirdPartTemplate(project.getId());
|
||||
issueTemplateDao.setIsThirdTemplate(Boolean.TRUE);
|
||||
@ -1407,7 +1620,7 @@ public class IssuesService {
|
||||
return filterIssues;
|
||||
}
|
||||
|
||||
private void uploadAzureCopyAttachment(AttachmentRequest attachmentRequest, String platform, String platformId) {
|
||||
private void uploadAzureCopyAttachment(AttachmentRequest attachmentRequest, String platform, String platformId) {
|
||||
List<String> attachmentIds = attachmentService.getAttachmentIdsByParam(attachmentRequest);
|
||||
if (CollectionUtils.isNotEmpty(attachmentIds)) {
|
||||
attachmentIds.forEach(attachmentId -> {
|
||||
@ -1478,4 +1691,10 @@ public class IssuesService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean thirdPartTemplateEnable(String projectId) {
|
||||
Project project = baseProjectService.getProjectById(projectId);
|
||||
return BooleanUtils.isTrue(project.getThirdPartTemplate())
|
||||
&& platformPluginService.isThirdPartTemplateSupport(project.getPlatform());
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,26 @@
|
||||
package io.metersphere.service;
|
||||
|
||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.platform.api.Platform;
|
||||
import io.metersphere.platform.api.PluginMetaInfo;
|
||||
import io.metersphere.base.domain.PluginWithBLOBs;
|
||||
import io.metersphere.base.domain.Project;
|
||||
import io.metersphere.base.domain.ServiceIntegration;
|
||||
import io.metersphere.commons.constants.PluginScenario;
|
||||
import io.metersphere.loader.PlatformPluginManager;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.platform.domain.PlatformRequest;
|
||||
import io.metersphere.platform.loader.PlatformPluginManager;
|
||||
import io.metersphere.request.IntegrationRequest;
|
||||
import io.metersphere.utils.PluginManagerUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@ -19,6 +30,8 @@ public class PlatformPluginService {
|
||||
private BasePluginService basePluginService;
|
||||
@Resource
|
||||
private BaseIntegrationService baseIntegrationService;
|
||||
@Resource
|
||||
private BaseProjectService baseProjectService;
|
||||
|
||||
private PlatformPluginManager pluginManager;
|
||||
|
||||
@ -46,4 +59,48 @@ public class PlatformPluginService {
|
||||
public void unloadPlugin(String pluginId) {
|
||||
pluginManager.deletePlugin(pluginId);
|
||||
}
|
||||
|
||||
public boolean isThirdPartTemplateSupport(String platform) {
|
||||
if (StringUtils.isBlank(platform)) {
|
||||
return false;
|
||||
}
|
||||
PluginMetaInfo pluginMetaInfo = pluginManager.getPluginMetaInfoByKey(platform);
|
||||
return pluginMetaInfo.isThirdPartTemplateSupport();
|
||||
}
|
||||
|
||||
public Platform getPlatform(String platformKey, String workspaceId) {
|
||||
IntegrationRequest integrationRequest = new IntegrationRequest();
|
||||
integrationRequest.setPlatform(platformKey);
|
||||
integrationRequest.setWorkspaceId(StringUtils.isBlank(workspaceId) ? SessionUtils.getCurrentWorkspaceId() : workspaceId);
|
||||
ServiceIntegration serviceIntegration = baseIntegrationService.get(integrationRequest);
|
||||
|
||||
PlatformRequest pluginRequest = new PlatformRequest();
|
||||
pluginRequest.setIntegrationConfig(serviceIntegration.getConfiguration());
|
||||
return pluginManager.getPlatformByKey(platformKey, pluginRequest);
|
||||
}
|
||||
|
||||
public Platform getPlatform(String platformKey) {
|
||||
return this.getPlatform(platformKey, null);
|
||||
}
|
||||
|
||||
|
||||
public static String getCompatibleProjectConfig(Project project) {
|
||||
String issueConfig = project.getIssueConfig();
|
||||
Map map = JSON.parseMap(issueConfig);
|
||||
map.put("jiraKey", project.getJiraKey());
|
||||
map.put("tapdId", project.getTapdId());
|
||||
map.put("azureDevopsId", project.getAzureDevopsId());
|
||||
map.put("zentaoId", project.getZentaoId());
|
||||
map.put("thirdPartTemplate", project.getThirdPartTemplate());
|
||||
return JSON.toJSONString(map);
|
||||
}
|
||||
|
||||
public static boolean isPluginPlatform(String platform) {
|
||||
if (StringUtils.equalsAnyIgnoreCase(platform,
|
||||
IssuesManagePlatform.Tapd.name(), IssuesManagePlatform.AzureDevops.name(),
|
||||
IssuesManagePlatform.Zentao.name(), IssuesManagePlatform.Local.name())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -11,19 +11,16 @@ import io.metersphere.commons.constants.IssuesStatus;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.dto.CustomFieldItemDTO;
|
||||
import io.metersphere.xpack.track.dto.IssueSyncRequest;
|
||||
import io.metersphere.xpack.track.dto.IssueTemplateDao;
|
||||
import io.metersphere.xpack.track.dto.PlatformStatusDTO;
|
||||
import io.metersphere.dto.UserDTO;
|
||||
import io.metersphere.request.IntegrationRequest;
|
||||
import io.metersphere.xpack.track.dto.EditTestCaseRequest;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesUpdateRequest;
|
||||
import io.metersphere.service.*;
|
||||
import io.metersphere.xpack.track.issue.IssuesPlatform;
|
||||
import io.metersphere.service.issue.domain.ProjectIssueConfig;
|
||||
import io.metersphere.service.wapper.TrackProjectService;
|
||||
import io.metersphere.service.wapper.UserService;
|
||||
import io.metersphere.xpack.track.dto.*;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesUpdateRequest;
|
||||
import io.metersphere.xpack.track.issue.IssuesPlatform;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
@ -654,4 +651,8 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IssuesDao> getIssue(IssuesRequest request) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,6 @@ public class IssueFactory {
|
||||
public static IssuesPlatform createPlatform(String platform, IssuesRequest addIssueRequest) {
|
||||
if (StringUtils.equals(IssuesManagePlatform.Tapd.toString(), platform)) {
|
||||
return new TapdPlatform(addIssueRequest);
|
||||
} else if (StringUtils.equals(IssuesManagePlatform.Jira.toString(), platform)) {
|
||||
return new JiraPlatform(addIssueRequest);
|
||||
} else if (StringUtils.equals(IssuesManagePlatform.Zentao.toString(), platform)) {
|
||||
return new ZentaoPlatform(addIssueRequest);
|
||||
} else if (StringUtils.equals(IssuesManagePlatform.AzureDevops.toString(), platform)) {
|
||||
@ -46,15 +44,4 @@ public class IssueFactory {
|
||||
});
|
||||
return platforms;
|
||||
}
|
||||
|
||||
public static Map<String, IssuesPlatform> createPlatformsForMap(List<String> types, IssuesRequest addIssueRequest) {
|
||||
Map<String, IssuesPlatform> platformMap = new HashMap<>();
|
||||
types.forEach(type -> {
|
||||
IssuesPlatform abstractIssuePlatform = createPlatform(type, addIssueRequest);
|
||||
if (abstractIssuePlatform != null) {
|
||||
platformMap.put(type, abstractIssuePlatform);
|
||||
}
|
||||
});
|
||||
return platformMap;
|
||||
}
|
||||
}
|
||||
|
@ -2,19 +2,17 @@ package io.metersphere.service.issue.platform;
|
||||
|
||||
|
||||
import io.metersphere.base.domain.IssuesWithBLOBs;
|
||||
|
||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||
import io.metersphere.commons.user.SessionUser;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.xpack.track.dto.AttachmentSyncType;
|
||||
import io.metersphere.dto.CustomFieldItemDTO;
|
||||
import io.metersphere.request.testcase.TestCaseBatchRequest;
|
||||
import io.metersphere.xpack.track.dto.AttachmentSyncType;
|
||||
import io.metersphere.xpack.track.dto.DemandDTO;
|
||||
import io.metersphere.xpack.track.dto.IssuesDao;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesUpdateRequest;
|
||||
import io.metersphere.request.testcase.TestCaseBatchRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
@ -29,16 +27,6 @@ public class LocalPlatform extends LocalAbstractPlatform {
|
||||
super(issuesRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IssuesDao> getIssue(IssuesRequest issuesRequest) {
|
||||
String projectId = issuesRequest.getProjectId();
|
||||
issuesRequest.setPlatform(IssuesManagePlatform.Local.toString());
|
||||
if (StringUtils.isNotBlank(projectId)) {
|
||||
return extIssuesMapper.getIssues(issuesRequest);
|
||||
}
|
||||
return extIssuesMapper.getIssuesByCaseId(issuesRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DemandDTO> getDemandList(String projectId) {
|
||||
return null;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.metersphere.service.plugin;
|
||||
|
||||
import im.metersphere.storage.StorageStrategy;
|
||||
import im.metersphere.plugin.storage.StorageStrategy;
|
||||
import io.metersphere.commons.constants.StorageConstants;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.metadata.service.FileManagerService;
|
||||
|
@ -1,10 +1,9 @@
|
||||
package io.metersphere.service.wapper;
|
||||
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.service.PlatformPluginService;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||
import io.metersphere.service.issue.platform.IssueFactory;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@ -20,6 +19,8 @@ public class IssueProxyResourceService {
|
||||
|
||||
@Resource
|
||||
private RestTemplate restTemplate;
|
||||
@Resource
|
||||
private PlatformPluginService platformPluginService;
|
||||
|
||||
/**
|
||||
* http 代理
|
||||
@ -37,8 +38,9 @@ public class IssueProxyResourceService {
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setProjectId(projectId);
|
||||
issuesRequest.setWorkspaceId(workspaceId);
|
||||
return IssueFactory.createPlatform(platform, issuesRequest)
|
||||
return platformPluginService.getPlatform(platform)
|
||||
.proxyForGet(url, byte[].class);
|
||||
|
||||
}
|
||||
return restTemplate.exchange(url, HttpMethod.GET, null, byte[].class);
|
||||
}
|
||||
|
@ -34,4 +34,9 @@ public class UserService {
|
||||
}
|
||||
return JSON.parseObject(JSON.toJSONString(platformInfo), UserDTO.PlatformInfo.class);
|
||||
}
|
||||
|
||||
public String getCurrentPlatformInfoStr(String workspaceId) {
|
||||
UserDTO.PlatformInfo currentPlatformInfo = getCurrentPlatformInfo(workspaceId);
|
||||
return currentPlatformInfo == null ? null : JSON.toJSONString(currentPlatformInfo);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.metersphere.utils;
|
||||
|
||||
import im.metersphere.loader.PluginManager;
|
||||
import im.metersphere.plugin.loader.PluginManager;
|
||||
import io.metersphere.base.domain.PluginWithBLOBs;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
|
@ -4,7 +4,7 @@ import {getUUID} from "metersphere-frontend/src/utils";
|
||||
import {getCurrentProjectID, getCurrentWorkspaceId} from "metersphere-frontend/src/utils/token";
|
||||
import {hasLicense} from "metersphere-frontend/src/utils/permission";
|
||||
import {getCurrentProject} from "./project";
|
||||
import {JIRA, LOCAL} from "metersphere-frontend/src/utils/constants";
|
||||
import {LOCAL} from "metersphere-frontend/src/utils/constants";
|
||||
import {getIssueTemplate} from "./custom-field-template";
|
||||
import {$success, $warning} from "metersphere-frontend/src/plugins/message";
|
||||
import i18n from "../i18n";
|
||||
@ -212,8 +212,8 @@ export function getPlatformTransitions(param) {
|
||||
return post('/issues/platform/transitions', param);
|
||||
}
|
||||
|
||||
export function enableThirdPartTemplate(currentProject) {
|
||||
return currentProject && currentProject.thirdPartTemplate && currentProject.platform === JIRA;
|
||||
export function enableThirdPartTemplate(projectId) {
|
||||
return get(BASE_URL + '/third/part/template/enable/' + projectId);
|
||||
}
|
||||
|
||||
export function buildIssues(page) {
|
||||
@ -230,18 +230,21 @@ export function buildIssues(page) {
|
||||
export function getIssuePartTemplateWithProject(callback) {
|
||||
getCurrentProject().then((response) => {
|
||||
let currentProject = response.data;
|
||||
if (enableThirdPartTemplate(currentProject)) {
|
||||
getIssueThirdPartTemplate()
|
||||
.then((template) => {
|
||||
if (callback)
|
||||
callback(template, currentProject);
|
||||
});
|
||||
} else {
|
||||
getIssueTemplate()
|
||||
.then((template) => {
|
||||
if (callback)
|
||||
callback(template, currentProject);
|
||||
});
|
||||
}
|
||||
enableThirdPartTemplate(currentProject.id)
|
||||
.then((r) => {
|
||||
if (r.data) {
|
||||
getIssueThirdPartTemplate()
|
||||
.then((template) => {
|
||||
if (callback)
|
||||
callback(template, currentProject);
|
||||
});
|
||||
} else {
|
||||
getIssueTemplate()
|
||||
.then((template) => {
|
||||
if (callback)
|
||||
callback(template, currentProject);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -6,25 +6,33 @@
|
||||
<ms-form-divider :title="$t('test_track.plan_view.base_info')"/>
|
||||
<el-form-item v-if="!enableThirdPartTemplate" :label="$t('commons.title')" prop="title">
|
||||
<el-row>
|
||||
<el-col :span="22">
|
||||
<el-col :span="22">
|
||||
<el-input v-model="form.title" autocomplete="off" class="top-input-class"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!showFollow">
|
||||
<i class="el-icon-star-off" style="color: #783987; font-size: 25px; margin-left: 15px;cursor: pointer;position: relative;top: 5px" @click="saveFollow" />
|
||||
<el-col :span="2">
|
||||
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!showFollow">
|
||||
<i class="el-icon-star-off"
|
||||
style="color: #783987; font-size: 25px; margin-left: 15px;cursor: pointer;position: relative;top: 5px"
|
||||
@click="saveFollow"/>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="showFollow" >
|
||||
<i class="el-icon-star-on" style="color: #783987; font-size: 28px; margin-left: 15px; cursor: pointer;position: relative;top: 5px" @click="saveFollow" />
|
||||
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="showFollow">
|
||||
<i class="el-icon-star-on"
|
||||
style="color: #783987; font-size: 28px; margin-left: 15px; cursor: pointer;position: relative;top: 5px"
|
||||
@click="saveFollow"/>
|
||||
</el-tooltip>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<div v-else style="text-align: right; margin-bottom: 5px">
|
||||
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!showFollow">
|
||||
<i class="el-icon-star-off" style="color: #783987; font-size: 25px; margin-left: 15px;cursor: pointer;position: relative;top: 5px" @click="saveFollow" />
|
||||
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!showFollow">
|
||||
<i class="el-icon-star-off"
|
||||
style="color: #783987; font-size: 25px; margin-left: 15px;cursor: pointer;position: relative;top: 5px"
|
||||
@click="saveFollow"/>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="showFollow" >
|
||||
<i class="el-icon-star-on" style="color: #783987; font-size: 28px; margin-left: 15px; cursor: pointer;position: relative;top: 5px" @click="saveFollow" />
|
||||
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="showFollow">
|
||||
<i class="el-icon-star-on"
|
||||
style="color: #783987; font-size: 28px; margin-left: 15px; cursor: pointer;position: relative;top: 5px"
|
||||
@click="saveFollow"/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
@ -118,10 +126,14 @@
|
||||
:on-success="handleSuccess"
|
||||
:on-error="handleError"
|
||||
:disabled="readOnly || type === 'copy'">
|
||||
<el-button :disabled="readOnly || type === 'copy'" type="text">{{$t('permission.project_file.local_upload')}}</el-button>
|
||||
<el-button :disabled="readOnly || type === 'copy'" type="text">
|
||||
{{ $t('permission.project_file.local_upload') }}
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
<el-button type="text" :disabled="readOnly || type === 'copy'" @click="associationFile">{{ $t('permission.project_file.associated_files') }}</el-button>
|
||||
<el-button type="text" :disabled="readOnly || type === 'copy'" @click="associationFile">
|
||||
{{ $t('permission.project_file.associated_files') }}
|
||||
</el-button>
|
||||
<i class="el-icon-plus" slot="reference"/>
|
||||
</el-popover>
|
||||
</div>
|
||||
@ -198,7 +210,12 @@ import CustomFiledComponent from "metersphere-frontend/src/components/template/C
|
||||
import TestCaseIssueList from "@/business/issue/TestCaseIssueList";
|
||||
import IssueEditDetail from "@/business/issue/IssueEditDetail";
|
||||
import {byteToSize, getTypeByFileName, getUUID} from "metersphere-frontend/src/utils";
|
||||
import {getCurrentProjectID, getCurrentUser, getCurrentWorkspaceId, getCurrentUserId} from "metersphere-frontend/src/utils/token"
|
||||
import {
|
||||
getCurrentProjectID,
|
||||
getCurrentUser,
|
||||
getCurrentWorkspaceId,
|
||||
getCurrentUserId
|
||||
} from "metersphere-frontend/src/utils/token"
|
||||
import {hasLicense} from "metersphere-frontend/src/utils/permission";
|
||||
import {
|
||||
enableThirdPartTemplate,
|
||||
@ -250,7 +267,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
type: null,
|
||||
issueId:'',
|
||||
issueId: '',
|
||||
result: {
|
||||
loading: false
|
||||
},
|
||||
@ -275,8 +292,8 @@ export default {
|
||||
description: '',
|
||||
creator: null,
|
||||
remark: null,
|
||||
tapdUsers:[],
|
||||
zentaoBuilds:[],
|
||||
tapdUsers: [],
|
||||
zentaoBuilds: [],
|
||||
zentaoAssigned: '',
|
||||
platformStatus: null,
|
||||
copyIssueId: ''
|
||||
@ -335,6 +352,7 @@ export default {
|
||||
relateFiles: [],
|
||||
unRelateFiles: [],
|
||||
dumpFile: {},
|
||||
enableThirdPartTemplate: false
|
||||
};
|
||||
},
|
||||
props: {
|
||||
@ -356,9 +374,6 @@ export default {
|
||||
projectId() {
|
||||
return getCurrentProjectID();
|
||||
},
|
||||
enableThirdPartTemplate() {
|
||||
return enableThirdPartTemplate(this.currentProject);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
tabActiveName() {
|
||||
@ -376,8 +391,8 @@ export default {
|
||||
description: '',
|
||||
creator: null,
|
||||
remark: null,
|
||||
tapdUsers:[],
|
||||
zentaoBuilds:[],
|
||||
tapdUsers: [],
|
||||
zentaoBuilds: [],
|
||||
zentaoAssigned: '',
|
||||
platformStatus: null
|
||||
};
|
||||
@ -403,6 +418,11 @@ export default {
|
||||
this.currentProject = project;
|
||||
this.init(template, data);
|
||||
this.getDataInfoAsync(data);
|
||||
|
||||
enableThirdPartTemplate(this.currentProject.id)
|
||||
.then(r => {
|
||||
this.enableThirdPartTemplate = r.data;
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
@ -460,21 +480,21 @@ export default {
|
||||
if (platform === 'Zentao') {
|
||||
this.hasZentaoId = true;
|
||||
getZentaoBuilds(data)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
this.Builds = response.data;
|
||||
}
|
||||
getZentaoUser(data)
|
||||
.then((response) => {
|
||||
this.zentaoUsers = response.data;
|
||||
if (response.data) {
|
||||
this.Builds = response.data;
|
||||
}
|
||||
getZentaoUser(data)
|
||||
.then((response) => {
|
||||
this.zentaoUsers = response.data;
|
||||
})
|
||||
})
|
||||
})
|
||||
} else if (platform === 'Tapd') {
|
||||
this.hasTapdId = true;
|
||||
getTapdUser(data)
|
||||
.then((response) => {
|
||||
this.tapdUsers = response.data;
|
||||
})
|
||||
.then((response) => {
|
||||
this.tapdUsers = response.data;
|
||||
})
|
||||
}
|
||||
},
|
||||
initEdit(data) {
|
||||
@ -627,30 +647,30 @@ export default {
|
||||
}
|
||||
};
|
||||
},
|
||||
saveFollow(){
|
||||
if(!this.form.follows){
|
||||
saveFollow() {
|
||||
if (!this.form.follows) {
|
||||
this.form.follows = [];
|
||||
}
|
||||
if(this.showFollow){
|
||||
if (this.showFollow) {
|
||||
this.showFollow = false;
|
||||
for (let i = 0; i < this.form.follows.length; i++) {
|
||||
if(this.form.follows[i]===this.currentUser().id){
|
||||
this.form.follows.splice(i,1)
|
||||
if (this.form.follows[i] === this.currentUser().id) {
|
||||
this.form.follows.splice(i, 1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(this.url === "issues/update"){
|
||||
if (this.url === "issues/update") {
|
||||
saveFollow(this.issueId, this.form.follows).then(() => {
|
||||
this.$success(this.$t('commons.cancel_follow_success'));
|
||||
})
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
this.showFollow = true;
|
||||
if(!this.form.follows){
|
||||
if (!this.form.follows) {
|
||||
this.form.follows = [];
|
||||
}
|
||||
this.form.follows.push(this.currentUser().id)
|
||||
if(this.url === "issues/update"){
|
||||
if (this.url === "issues/update") {
|
||||
saveFollow(this.issueId, this.form.follows).then(() => {
|
||||
this.$success(this.$t('commons.follow_success'));
|
||||
})
|
||||
@ -679,8 +699,8 @@ export default {
|
||||
name: file.name,
|
||||
size: byteToSize(file.size),
|
||||
updateTime: new Date().getTime(),
|
||||
progress: this.type === 'add' || this.isCaseEdit? 100 : 0,
|
||||
status: this.type === 'add' || this.isCaseEdit? 'toUpload' : 0,
|
||||
progress: this.type === 'add' || this.isCaseEdit ? 100 : 0,
|
||||
status: this.type === 'add' || this.isCaseEdit ? 'toUpload' : 0,
|
||||
creator: user.name,
|
||||
type: getTypeByFileName(file.name),
|
||||
isLocal: true
|
||||
@ -702,27 +722,27 @@ export default {
|
||||
let CancelToken = axios.CancelToken
|
||||
let self = this;
|
||||
uploadIssueAttachment(file, data, CancelToken, self.cancelFileToken, progressCallback)
|
||||
.then(response => { // 成功回调
|
||||
progress = 100;
|
||||
param.onSuccess(response);
|
||||
progressCallback({progress, status: 'success'});
|
||||
self.cancelFileToken.forEach((token, index, array)=>{
|
||||
if(token.name == file.name){
|
||||
array.splice(token,1)
|
||||
}
|
||||
})
|
||||
}).catch(({error}) => { // 失败回调
|
||||
.then(response => { // 成功回调
|
||||
progress = 100;
|
||||
param.onSuccess(response);
|
||||
progressCallback({progress, status: 'success'});
|
||||
self.cancelFileToken.forEach((token, index, array) => {
|
||||
if (token.name == file.name) {
|
||||
array.splice(token, 1)
|
||||
}
|
||||
})
|
||||
}).catch(({error}) => { // 失败回调
|
||||
progress = 100;
|
||||
progressCallback({progress, status: 'error'});
|
||||
self.cancelFileToken.forEach((token, index, array)=>{
|
||||
if(token.name == file.name){
|
||||
array.splice(token,1)
|
||||
self.cancelFileToken.forEach((token, index, array) => {
|
||||
if (token.name == file.name) {
|
||||
array.splice(token, 1)
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
showProgress(file, params) {
|
||||
const { progress, status } = params
|
||||
const {progress, status} = params
|
||||
const arr = [...this.tableData].map(item => {
|
||||
if (item.name === file.name) {
|
||||
item.progress = progress
|
||||
@ -737,18 +757,18 @@ export default {
|
||||
},
|
||||
handleSuccess(response, file, fileList) {
|
||||
let readyFiles = fileList.filter(item => item.status === 'success')
|
||||
if (readyFiles.length === fileList.length ) {
|
||||
if (readyFiles.length === fileList.length) {
|
||||
this.getFileMetaData(this.issueId);
|
||||
}
|
||||
},
|
||||
handleError(err, file, fileList) {
|
||||
let readyFiles = fileList.filter(item => item.status === 'success')
|
||||
if (readyFiles.length === fileList.length ) {
|
||||
if (readyFiles.length === fileList.length) {
|
||||
this.getFileMetaData(this.issueId);
|
||||
}
|
||||
},
|
||||
handleDelete(file, index) {
|
||||
this.$alert((this.cancelFileToken.length > 0 ? this.$t('load_test.delete_file_when_uploading') + '<br/>': "") + this.$t('load_test.delete_file_confirm') + file.name + "?", '', {
|
||||
this.$alert((this.cancelFileToken.length > 0 ? this.$t('load_test.delete_file_when_uploading') + '<br/>' : "") + this.$t('load_test.delete_file_confirm') + file.name + "?", '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
dangerouslyUseHTMLString: true,
|
||||
callback: (action) => {
|
||||
@ -772,10 +792,10 @@ export default {
|
||||
this.uploadFiles.splice(delIndex, 1);
|
||||
} else {
|
||||
deleteIssueAttachment(file.id)
|
||||
.then(() => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.getFileMetaData(this.issueId);
|
||||
});
|
||||
.then(() => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.getFileMetaData(this.issueId);
|
||||
});
|
||||
}
|
||||
},
|
||||
handleUnRelate(file, index) {
|
||||
@ -797,11 +817,11 @@ export default {
|
||||
let data = {'belongType': 'issue', 'belongId': this.issueId, 'metadataRefIds': this.unRelateFiles};
|
||||
this.result.loading = true;
|
||||
unrelatedAttachment(data)
|
||||
.then(() => {
|
||||
this.$success(this.$t('commons.unrelated_success'));
|
||||
this.result.loading = false;
|
||||
this.getFileMetaData(this.issueId);
|
||||
})
|
||||
.then(() => {
|
||||
this.$success(this.$t('commons.unrelated_success'));
|
||||
this.result.loading = false;
|
||||
this.getFileMetaData(this.issueId);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -827,7 +847,7 @@ export default {
|
||||
for (let row of rows) {
|
||||
let rowIndex = this.tableData.findIndex(item => item.name === row.name);
|
||||
if (rowIndex >= 0) {
|
||||
this.$error(this.$t('load_test.exist_related_file') + ": " + row.name);
|
||||
this.$error(this.$t('load_test.exist_related_file') + ": " + row.name);
|
||||
repeatRecord = true;
|
||||
break;
|
||||
}
|
||||
@ -856,21 +876,23 @@ export default {
|
||||
let data = {'belongType': 'issue', 'belongId': this.issueId, 'metadataRefIds': metadataRefIds};
|
||||
this.result.loading = true;
|
||||
relatedAttachment(data)
|
||||
.then(() => {
|
||||
this.$success(this.$t('commons.relate_success'));
|
||||
this.result.loading = false;
|
||||
this.getFileMetaData(this.issueId);
|
||||
});
|
||||
.then(() => {
|
||||
this.$success(this.$t('commons.relate_success'));
|
||||
this.result.loading = false;
|
||||
this.getFileMetaData(this.issueId);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
setModuleId(moduleId) {
|
||||
let data = {id: getUUID(), resourceId: getCurrentProjectID(), moduleId: moduleId,
|
||||
projectId: getCurrentProjectID(), fileName: this.dumpFile.name, attachmentId: this.dumpFile.id};
|
||||
let data = {
|
||||
id: getUUID(), resourceId: getCurrentProjectID(), moduleId: moduleId,
|
||||
projectId: getCurrentProjectID(), fileName: this.dumpFile.name, attachmentId: this.dumpFile.id
|
||||
};
|
||||
dumpAttachment(data)
|
||||
.then(() => {
|
||||
this.$success(this.$t("organization.integration.successful_operation"));
|
||||
});
|
||||
.then(() => {
|
||||
this.$success(this.$t("organization.integration.successful_operation"));
|
||||
});
|
||||
},
|
||||
getFileMetaData(id) {
|
||||
if (this.type === 'edit') {
|
||||
@ -926,7 +948,7 @@ export default {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.top-input-class{
|
||||
.top-input-class {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user