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-cloud.version>2021.0.5</spring-cloud.version>
|
||||||
<spring-security.version>5.7.5</spring-security.version>
|
<spring-security.version>5.7.5</spring-security.version>
|
||||||
<dubbo.version>2.7.15</dubbo.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>
|
<flyway.version>7.15.0</flyway.version>
|
||||||
<shiro.version>1.10.0</shiro.version>
|
<shiro.version>1.10.0</shiro.version>
|
||||||
<mssql-jdbc.version>7.4.1.jre8</mssql-jdbc.version>
|
<mssql-jdbc.version>7.4.1.jre8</mssql-jdbc.version>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package io.metersphere.controller.remote;
|
package io.metersphere.controller.remote;
|
||||||
|
|
||||||
import io.metersphere.remote.service.PlatformPluginService;
|
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 org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
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
|
import TemplateComponentEditHeader
|
||||||
from "./ext/TemplateComponentEditHeader";
|
from "./ext/TemplateComponentEditHeader";
|
||||||
import MsFormDivider from "metersphere-frontend/src/components/MsFormDivider";
|
import MsFormDivider from "metersphere-frontend/src/components/MsFormDivider";
|
||||||
import {ISSUE_PLATFORM_OPTION} from "metersphere-frontend/src/utils/table-constants";
|
|
||||||
import CustomFieldFormList from "./CustomFieldFormList";
|
import CustomFieldFormList from "./CustomFieldFormList";
|
||||||
import CustomFieldRelateList from "./CustomFieldRelateList";
|
import CustomFieldRelateList from "./CustomFieldRelateList";
|
||||||
import FieldTemplateEdit from "./FieldTemplateEdit";
|
import FieldTemplateEdit from "./FieldTemplateEdit";
|
||||||
|
@ -90,10 +89,10 @@ export default {
|
||||||
url: '',
|
url: '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
platformOption: Array
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
platformOption() {
|
|
||||||
return ISSUE_PLATFORM_OPTION;
|
|
||||||
},
|
|
||||||
isSystem() {
|
isSystem() {
|
||||||
return this.form.system;
|
return this.form.system;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
:total="total"/>
|
:total="total"/>
|
||||||
|
|
||||||
<issue-template-copy ref="templateCopy" @refresh="initTableData"/>
|
<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"/>
|
<ms-delete-confirm :title="$t('commons.template_delete')" @delete="_handleDelete" ref="deleteConfirm"/>
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
@ -95,6 +95,7 @@ import IssueTemplateEdit from "./IssueTemplateEdit";
|
||||||
import {deleteIssueFieldTemplateById, getIssueFieldTemplatePages} from "../../../api/template";
|
import {deleteIssueFieldTemplateById, getIssueFieldTemplatePages} from "../../../api/template";
|
||||||
import MsDeleteConfirm from "metersphere-frontend/src/components/MsDeleteConfirm";
|
import MsDeleteConfirm from "metersphere-frontend/src/components/MsDeleteConfirm";
|
||||||
import IssueTemplateCopy from "./IssueTemplateCopy";
|
import IssueTemplateCopy from "./IssueTemplateCopy";
|
||||||
|
import {getPlatformOption} from "@/api/platform-plugin";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "IssuesTemplateList",
|
name: "IssuesTemplateList",
|
||||||
|
@ -102,7 +103,7 @@ export default {
|
||||||
IssueTemplateEdit,
|
IssueTemplateEdit,
|
||||||
IssueTemplateCopy,
|
IssueTemplateCopy,
|
||||||
MsTableHeader,
|
MsTableHeader,
|
||||||
MsTablePagination, MsTableButton, MsTableOperators, MsTableColumn, MsTable , MsDeleteConfirm
|
MsTablePagination, MsTableButton, MsTableOperators, MsTableColumn, MsTable, MsDeleteConfirm
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -113,9 +114,9 @@ export default {
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
result: {},
|
result: {},
|
||||||
loading: false,
|
loading: false,
|
||||||
|
platformOptions: [],
|
||||||
issuePlatformMap: {
|
issuePlatformMap: {
|
||||||
Local: 'Metersphere',
|
Local: 'Metersphere',
|
||||||
Jira: 'JIRA',
|
|
||||||
Tapd: 'Tapd',
|
Tapd: 'Tapd',
|
||||||
Zentao: '禅道',
|
Zentao: '禅道',
|
||||||
AzureDevops: 'Azure Devops',
|
AzureDevops: 'Azure Devops',
|
||||||
|
@ -135,6 +136,10 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
getPlatformOption()
|
||||||
|
.then((r) => {
|
||||||
|
this.platformOptions = r.data;
|
||||||
|
});
|
||||||
this.initTableData();
|
this.initTableData();
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -142,7 +147,12 @@ export default {
|
||||||
return ISSUE_TEMPLATE_LIST;
|
return ISSUE_TEMPLATE_LIST;
|
||||||
},
|
},
|
||||||
platformFilters() {
|
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() {
|
tableHeight() {
|
||||||
return document.documentElement.clientHeight - 200;
|
return document.documentElement.clientHeight - 200;
|
||||||
|
|
|
@ -26,6 +26,12 @@
|
||||||
<artifactId>metersphere-platform-plugin-sdk</artifactId>
|
<artifactId>metersphere-platform-plugin-sdk</artifactId>
|
||||||
<groupId>io.metersphere</groupId>
|
<groupId>io.metersphere</groupId>
|
||||||
<version>${platform-plugin-sdk.version}</version>
|
<version>${platform-plugin-sdk.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>io.metersphere</groupId>
|
||||||
|
<artifactId>domain</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.metersphere.controller;
|
package io.metersphere.controller;
|
||||||
|
|
||||||
import io.metersphere.domain.SelectOption;
|
import io.metersphere.platform.domain.SelectOption;
|
||||||
import io.metersphere.dto.PlatformProjectOptionRequest;
|
import io.metersphere.dto.PlatformProjectOptionRequest;
|
||||||
import io.metersphere.service.PlatformPluginService;
|
import io.metersphere.service.PlatformPluginService;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package io.metersphere.service;
|
package io.metersphere.service;
|
||||||
|
|
||||||
import io.metersphere.api.Platform;
|
import io.metersphere.platform.api.Platform;
|
||||||
import io.metersphere.api.PluginMetaInfo;
|
import io.metersphere.platform.api.PluginMetaInfo;
|
||||||
import io.metersphere.base.domain.PluginWithBLOBs;
|
import io.metersphere.base.domain.PluginWithBLOBs;
|
||||||
import io.metersphere.base.domain.ServiceIntegration;
|
import io.metersphere.base.domain.ServiceIntegration;
|
||||||
import io.metersphere.base.mapper.PluginMapper;
|
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.JSON;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.domain.GetOptionRequest;
|
import io.metersphere.platform.domain.*;
|
||||||
import io.metersphere.domain.PlatformRequest;
|
|
||||||
import io.metersphere.domain.SelectOption;
|
|
||||||
import io.metersphere.dto.PlatformProjectOptionRequest;
|
import io.metersphere.dto.PlatformProjectOptionRequest;
|
||||||
import io.metersphere.loader.PlatformPluginManager;
|
import io.metersphere.platform.loader.PlatformPluginManager;
|
||||||
import io.metersphere.request.IntegrationRequest;
|
import io.metersphere.request.IntegrationRequest;
|
||||||
import io.metersphere.utils.PluginManagerUtil;
|
import io.metersphere.utils.PluginManagerUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.metersphere.service.plugin;
|
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.constants.StorageConstants;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.metadata.service.FileManagerService;
|
import io.metersphere.metadata.service.FileManagerService;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.metersphere.utils;
|
package io.metersphere.utils;
|
||||||
|
|
||||||
import im.metersphere.loader.PluginManager;
|
import im.metersphere.plugin.loader.PluginManager;
|
||||||
import io.metersphere.base.domain.PluginWithBLOBs;
|
import io.metersphere.base.domain.PluginWithBLOBs;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
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.notice.annotation.SendNotice;
|
||||||
import io.metersphere.request.issues.IssueExportRequest;
|
import io.metersphere.request.issues.IssueExportRequest;
|
||||||
import io.metersphere.request.issues.IssueImportRequest;
|
import io.metersphere.request.issues.IssueImportRequest;
|
||||||
import io.metersphere.request.issues.JiraIssueTypeRequest;
|
|
||||||
import io.metersphere.request.issues.PlatformIssueTypeRequest;
|
import io.metersphere.request.issues.PlatformIssueTypeRequest;
|
||||||
import io.metersphere.request.testcase.AuthUserIssueRequest;
|
import io.metersphere.request.testcase.AuthUserIssueRequest;
|
||||||
import io.metersphere.request.testcase.IssuesCountRequest;
|
import io.metersphere.request.testcase.IssuesCountRequest;
|
||||||
import io.metersphere.service.BaseCheckPermissionService;
|
import io.metersphere.service.BaseCheckPermissionService;
|
||||||
import io.metersphere.service.IssuesService;
|
import io.metersphere.service.IssuesService;
|
||||||
import io.metersphere.service.issue.domain.jira.JiraIssueType;
|
|
||||||
import io.metersphere.service.issue.domain.zentao.ZentaoBuild;
|
import io.metersphere.service.issue.domain.zentao.ZentaoBuild;
|
||||||
import io.metersphere.xpack.track.dto.*;
|
import io.metersphere.xpack.track.dto.*;
|
||||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||||
|
@ -186,14 +184,14 @@ public class IssuesController {
|
||||||
return issuesService.getThirdPartTemplate(projectId);
|
return issuesService.getThirdPartTemplate(projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/jira/issuetype")
|
@GetMapping("/demand/list/{projectId}")
|
||||||
public List<JiraIssueType> getJiraIssueType(@RequestBody JiraIssueTypeRequest request) {
|
public List getDemandList(@PathVariable String projectId) {
|
||||||
return issuesService.getIssueTypes(request);
|
return issuesService.getDemandList(projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/demand/list/{projectId}")
|
@GetMapping("/third/part/template/enable/{projectId}")
|
||||||
public List<DemandDTO> getDemandList(@PathVariable String projectId) {
|
public boolean thirdPartTemplateEnable(@PathVariable String projectId) {
|
||||||
return issuesService.getDemandList(projectId);
|
return issuesService.thirdPartTemplateEnable(projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/platform/transitions")
|
@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));
|
Map<String, List<CustomFieldDao>> customFieldMap = customFields.stream().collect(Collectors.groupingBy(CustomFieldDao::getName));
|
||||||
issueExcelData.getCustomData().forEach((k, v) -> {
|
issueExcelData.getCustomData().forEach((k, v) -> {
|
||||||
try {
|
try {
|
||||||
List<CustomFieldDao> customFieldDaos = customFieldMap.get(k);
|
List<CustomFieldDao> customFieldDaoList = customFieldMap.get(k);
|
||||||
if (CollectionUtils.isNotEmpty(customFieldDaos) && customFieldDaos.size() > 0) {
|
if (CollectionUtils.isNotEmpty(customFieldDaoList) && customFieldDaoList.size() > 0) {
|
||||||
CustomFieldDao customFieldDao = customFieldDaos.get(0);
|
CustomFieldDao customFieldDao = customFieldDaoList.get(0);
|
||||||
String type = customFieldDao.getType();
|
String type = customFieldDao.getType();
|
||||||
// addfield
|
// add field
|
||||||
CustomFieldResourceDTO customFieldResourceDTO = new CustomFieldResourceDTO();
|
CustomFieldResourceDTO customFieldResourceDTO = new CustomFieldResourceDTO();
|
||||||
customFieldResourceDTO.setFieldId(customFieldDao.getId());
|
customFieldResourceDTO.setFieldId(customFieldDao.getId());
|
||||||
// requestfield
|
// request field
|
||||||
CustomFieldItemDTO customFieldItemDTO = new CustomFieldItemDTO();
|
CustomFieldItemDTO customFieldItemDTO = new CustomFieldItemDTO();
|
||||||
BeanUtils.copyBean(customFieldItemDTO, customFieldDao);
|
BeanUtils.copyBean(customFieldItemDTO, customFieldDao);
|
||||||
if (StringUtils.isEmpty(v.toString())) {
|
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.BeanUtils;
|
||||||
import io.metersphere.commons.utils.FileUtils;
|
import io.metersphere.commons.utils.FileUtils;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.xpack.track.dto.AttachmentSyncType;
|
|
||||||
import io.metersphere.constants.AttachmentType;
|
import io.metersphere.constants.AttachmentType;
|
||||||
import io.metersphere.i18n.Translator;
|
import io.metersphere.i18n.Translator;
|
||||||
import io.metersphere.metadata.service.FileMetadataService;
|
import io.metersphere.metadata.service.FileMetadataService;
|
||||||
import io.metersphere.metadata.utils.MetadataUtils;
|
import io.metersphere.metadata.utils.MetadataUtils;
|
||||||
|
import io.metersphere.platform.domain.SyncIssuesAttachmentRequest;
|
||||||
import io.metersphere.request.attachment.AttachmentRequest;
|
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.service.issue.platform.IssueFactory;
|
||||||
import io.metersphere.xmind.utils.FileUtil;
|
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.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.ibatis.session.ExecutorType;
|
import org.apache.ibatis.session.ExecutorType;
|
||||||
|
@ -35,7 +36,7 @@ import javax.annotation.Resource;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author songcc
|
* @author songcc
|
||||||
|
@ -68,6 +69,8 @@ public class AttachmentService {
|
||||||
private BaseUserService baseUserService;
|
private BaseUserService baseUserService;
|
||||||
@Resource
|
@Resource
|
||||||
SqlSessionFactory sqlSessionFactory;
|
SqlSessionFactory sqlSessionFactory;
|
||||||
|
@Resource
|
||||||
|
PlatformPluginService platformPluginService;
|
||||||
|
|
||||||
public void uploadAttachment(AttachmentRequest request, MultipartFile file) {
|
public void uploadAttachment(AttachmentRequest request, MultipartFile file) {
|
||||||
// 附件上传的前置校验
|
// 附件上传的前置校验
|
||||||
|
@ -98,11 +101,16 @@ public class AttachmentService {
|
||||||
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
||||||
updateRequest.setPlatformId(issues.getPlatformId());
|
updateRequest.setPlatformId(issues.getPlatformId());
|
||||||
File uploadFile = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
File uploadFile = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
||||||
IssuesRequest issuesRequest = new IssuesRequest();
|
|
||||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
if (PlatformPluginService.isPluginPlatform(issues.getPlatform())) {
|
||||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
syncIssuesAttachment(issues, uploadFile, AttachmentSyncType.UPLOAD);
|
||||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
} else {
|
||||||
.syncIssuesAttachment(updateRequest, uploadFile, AttachmentSyncType.UPLOAD);
|
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();
|
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
||||||
updateRequest.setPlatformId(issues.getPlatformId());
|
updateRequest.setPlatformId(issues.getPlatformId());
|
||||||
File deleteFile = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
File deleteFile = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
||||||
IssuesRequest issuesRequest = new IssuesRequest();
|
|
||||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
if (PlatformPluginService.isPluginPlatform(issues.getPlatform())) {
|
||||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
syncIssuesAttachment(issues, deleteFile, AttachmentSyncType.DELETE);
|
||||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
} else {
|
||||||
.syncIssuesAttachment(updateRequest, deleteFile, AttachmentSyncType.DELETE);
|
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();
|
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
||||||
updateRequest.setPlatformId(issues.getPlatformId());
|
updateRequest.setPlatformId(issues.getPlatformId());
|
||||||
File refFile = downloadMetadataFile(metadataRefId, fileMetadata.getName());
|
File refFile = downloadMetadataFile(metadataRefId, fileMetadata.getName());
|
||||||
IssuesRequest issuesRequest = new IssuesRequest();
|
|
||||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
if (PlatformPluginService.isPluginPlatform(issues.getPlatform())) {
|
||||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
syncIssuesAttachment(issues, refFile, AttachmentSyncType.UPLOAD);
|
||||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
} else {
|
||||||
.syncIssuesAttachment(updateRequest, refFile, AttachmentSyncType.UPLOAD);
|
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());
|
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) {
|
public List<FileAttachmentMetadata> listMetadata(AttachmentRequest request) {
|
||||||
List<FileAttachmentMetadata> attachments = new ArrayList<FileAttachmentMetadata>();
|
List<FileAttachmentMetadata> attachments = new ArrayList<FileAttachmentMetadata>();
|
||||||
AttachmentModuleRelationExample example = new AttachmentModuleRelationExample();
|
AttachmentModuleRelationExample example = new AttachmentModuleRelationExample();
|
||||||
|
@ -276,12 +303,17 @@ public class AttachmentService {
|
||||||
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
||||||
updateRequest.setPlatformId(issues.getPlatformId());
|
updateRequest.setPlatformId(issues.getPlatformId());
|
||||||
File refFile = downloadMetadataFile(metadataRefId, fileMetadata.getName());
|
File refFile = downloadMetadataFile(metadataRefId, fileMetadata.getName());
|
||||||
IssuesRequest issuesRequest = new IssuesRequest();
|
|
||||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
if (PlatformPluginService.isPluginPlatform(issues.getPlatform())) {
|
||||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
syncIssuesAttachment(issues, refFile, AttachmentSyncType.UPLOAD);
|
||||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
} else {
|
||||||
.syncIssuesAttachment(updateRequest, refFile, AttachmentSyncType.UPLOAD);
|
IssuesRequest issuesRequest = new IssuesRequest();
|
||||||
FileUtils.deleteFile(FileUtils.ATTACHMENT_TMP_DIR + File.separator + fileMetadata.getName());
|
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();
|
sqlSession.flushStatements();
|
||||||
|
@ -301,11 +333,16 @@ public class AttachmentService {
|
||||||
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
||||||
updateRequest.setPlatformId(issues.getPlatformId());
|
updateRequest.setPlatformId(issues.getPlatformId());
|
||||||
File deleteFile = new File(FileUtils.ATTACHMENT_TMP_DIR + File.separator + fileAttachmentMetadata.getName());
|
File deleteFile = new File(FileUtils.ATTACHMENT_TMP_DIR + File.separator + fileAttachmentMetadata.getName());
|
||||||
IssuesRequest issuesRequest = new IssuesRequest();
|
|
||||||
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
if (PlatformPluginService.isPluginPlatform(issues.getPlatform())) {
|
||||||
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
syncIssuesAttachment(issues, deleteFile, AttachmentSyncType.UPLOAD);
|
||||||
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
} else {
|
||||||
.syncIssuesAttachment(updateRequest, deleteFile, AttachmentSyncType.DELETE);
|
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();
|
AttachmentModuleRelationExample example = new AttachmentModuleRelationExample();
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.alibaba.excel.EasyExcelFactory;
|
||||||
import com.alibaba.excel.util.DateUtils;
|
import com.alibaba.excel.util.DateUtils;
|
||||||
import com.github.pagehelper.Page;
|
import com.github.pagehelper.Page;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import io.metersphere.platform.api.Platform;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.*;
|
import io.metersphere.base.mapper.*;
|
||||||
import io.metersphere.base.mapper.ext.ExtIssueCommentMapper;
|
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.commons.utils.*;
|
||||||
import io.metersphere.constants.AttachmentType;
|
import io.metersphere.constants.AttachmentType;
|
||||||
import io.metersphere.constants.SystemCustomField;
|
import io.metersphere.constants.SystemCustomField;
|
||||||
|
import io.metersphere.platform.domain.*;
|
||||||
import io.metersphere.dto.*;
|
import io.metersphere.dto.*;
|
||||||
import io.metersphere.excel.constants.IssueExportHeadField;
|
import io.metersphere.excel.constants.IssueExportHeadField;
|
||||||
import io.metersphere.excel.domain.ExcelErrData;
|
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.attachment.AttachmentRequest;
|
||||||
import io.metersphere.request.issues.IssueExportRequest;
|
import io.metersphere.request.issues.IssueExportRequest;
|
||||||
import io.metersphere.request.issues.IssueImportRequest;
|
import io.metersphere.request.issues.IssueImportRequest;
|
||||||
import io.metersphere.request.issues.JiraIssueTypeRequest;
|
|
||||||
import io.metersphere.request.issues.PlatformIssueTypeRequest;
|
import io.metersphere.request.issues.PlatformIssueTypeRequest;
|
||||||
import io.metersphere.request.testcase.AuthUserIssueRequest;
|
import io.metersphere.request.testcase.AuthUserIssueRequest;
|
||||||
import io.metersphere.request.testcase.IssuesCountRequest;
|
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.domain.zentao.ZentaoBuild;
|
||||||
import io.metersphere.service.issue.platform.*;
|
import io.metersphere.service.issue.platform.*;
|
||||||
import io.metersphere.service.remote.project.TrackCustomFieldTemplateService;
|
import io.metersphere.service.remote.project.TrackCustomFieldTemplateService;
|
||||||
import io.metersphere.service.remote.project.TrackIssueTemplateService;
|
import io.metersphere.service.remote.project.TrackIssueTemplateService;
|
||||||
import io.metersphere.service.wapper.TrackProjectService;
|
import io.metersphere.service.wapper.TrackProjectService;
|
||||||
|
import io.metersphere.service.wapper.UserService;
|
||||||
import io.metersphere.utils.DistinctKeyUtil;
|
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.*;
|
||||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||||
import io.metersphere.xpack.track.dto.request.IssuesUpdateRequest;
|
import io.metersphere.xpack.track.dto.request.IssuesUpdateRequest;
|
||||||
|
@ -124,6 +127,8 @@ public class IssuesService {
|
||||||
@Resource
|
@Resource
|
||||||
private AttachmentService attachmentService;
|
private AttachmentService attachmentService;
|
||||||
@Resource
|
@Resource
|
||||||
|
private AttachmentModuleRelationMapper attachmentModuleRelationMapper;
|
||||||
|
@Resource
|
||||||
private ProjectMapper projectMapper;
|
private ProjectMapper projectMapper;
|
||||||
@Resource
|
@Resource
|
||||||
SqlSessionFactory sqlSessionFactory;
|
SqlSessionFactory sqlSessionFactory;
|
||||||
|
@ -131,6 +136,10 @@ public class IssuesService {
|
||||||
private FileMetadataMapper fileMetadataMapper;
|
private FileMetadataMapper fileMetadataMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ExtIssueCommentMapper extIssueCommentMapper;
|
private ExtIssueCommentMapper extIssueCommentMapper;
|
||||||
|
@Resource
|
||||||
|
private PlatformPluginService platformPluginService;
|
||||||
|
@Resource
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
private static final String SYNC_THIRD_PARTY_ISSUES_KEY = "ISSUE:SYNC";
|
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) {
|
public IssuesWithBLOBs addIssues(IssuesUpdateRequest issuesRequest, List<MultipartFile> files) {
|
||||||
List<IssuesPlatform> platformList = getAddPlatforms(issuesRequest);
|
Project project = baseProjectService.getProjectById(issuesRequest.getProjectId());
|
||||||
IssuesWithBLOBs issues = null;
|
IssuesWithBLOBs issues = null;
|
||||||
for (IssuesPlatform platform : platformList) {
|
if (PlatformPluginService.isPluginPlatform(project.getPlatform())) {
|
||||||
issues = platform.addIssue(issuesRequest);
|
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()) {
|
if (issuesRequest.getIsPlanEdit()) {
|
||||||
issuesRequest.getAddResourceIds().forEach(l -> {
|
issuesRequest.getAddResourceIds().forEach(l -> {
|
||||||
testCaseIssueService.updateIssuesCount(l);
|
testCaseIssueService.updateIssuesCount(l);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
saveFollows(issuesRequest.getId(), issuesRequest.getFollows());
|
String issuesId = issues.getId();
|
||||||
customFieldIssuesService.addFields(issuesRequest.getId(), issuesRequest.getAddFields());
|
saveFollows(issuesId, issuesRequest.getFollows());
|
||||||
customFieldIssuesService.editFields(issuesRequest.getId(), issuesRequest.getEditFields());
|
customFieldIssuesService.addFields(issuesId, issuesRequest.getAddFields());
|
||||||
|
customFieldIssuesService.editFields(issuesId, issuesRequest.getEditFields());
|
||||||
if (StringUtils.isNotEmpty(issuesRequest.getCopyIssueId())) {
|
if (StringUtils.isNotEmpty(issuesRequest.getCopyIssueId())) {
|
||||||
final String platformId = issues.getPlatformId();
|
final String platformId = issues.getPlatformId();
|
||||||
// 复制新增, 同步缺陷的MS附件
|
// 复制新增, 同步缺陷的MS附件
|
||||||
|
@ -215,11 +261,15 @@ public class IssuesService {
|
||||||
fileAttachmentMetadataBatchMapper.insert(fileAttachmentMetadata);
|
fileAttachmentMetadataBatchMapper.insert(fileAttachmentMetadata);
|
||||||
// 下载文件管理文件, 同步到第三方平台
|
// 下载文件管理文件, 同步到第三方平台
|
||||||
File refFile = attachmentService.downloadMetadataFile(filemetaId, fileMetadata.getName());
|
File refFile = attachmentService.downloadMetadataFile(filemetaId, fileMetadata.getName());
|
||||||
IssuesRequest addIssueRequest = new IssuesRequest();
|
if (PlatformPluginService.isPluginPlatform(platform)) {
|
||||||
addIssueRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
attachmentService.syncIssuesAttachment(issuesRequest, refFile, AttachmentSyncType.UPLOAD);
|
||||||
addIssueRequest.setProjectId(SessionUtils.getCurrentProjectId());
|
} else {
|
||||||
Objects.requireNonNull(IssueFactory.createPlatform(platform, addIssueRequest))
|
IssuesRequest addIssueRequest = new IssuesRequest();
|
||||||
.syncIssuesAttachment(issuesRequest, refFile, AttachmentSyncType.UPLOAD);
|
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());
|
FileUtils.deleteFile(FileUtils.ATTACHMENT_TMP_DIR + File.separator + fileMetadata.getName());
|
||||||
});
|
});
|
||||||
sqlSession.flushStatements();
|
sqlSession.flushStatements();
|
||||||
|
@ -231,11 +281,90 @@ public class IssuesService {
|
||||||
return getIssue(issues.getId());
|
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) {
|
public IssuesWithBLOBs updateIssues(IssuesUpdateRequest issuesRequest) {
|
||||||
List<IssuesPlatform> platformList = getUpdatePlatforms(issuesRequest);
|
PlatformIssuesUpdateRequest platformIssuesUpdateRequest = JSON.parseObject(JSON.toJSONString(issuesRequest), PlatformIssuesUpdateRequest.class);
|
||||||
platformList.forEach(platform -> {
|
Project project = baseProjectService.getProjectById(issuesRequest.getProjectId());
|
||||||
platform.updateIssue(issuesRequest);
|
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.editFields(issuesRequest.getId(), issuesRequest.getEditFields());
|
||||||
customFieldIssuesService.addFields(issuesRequest.getId(), issuesRequest.getAddFields());
|
customFieldIssuesService.addFields(issuesRequest.getId(), issuesRequest.getAddFields());
|
||||||
|
|
||||||
|
@ -377,7 +506,7 @@ public class IssuesService {
|
||||||
|
|
||||||
if (jira) {
|
if (jira) {
|
||||||
String jiraKey = project.getJiraKey();
|
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());
|
platforms.add(IssuesManagePlatform.Jira.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,8 +608,15 @@ public class IssuesService {
|
||||||
Project project = baseProjectService.getProjectById(projectId);
|
Project project = baseProjectService.getProjectById(projectId);
|
||||||
IssuesRequest issuesRequest = new IssuesRequest();
|
IssuesRequest issuesRequest = new IssuesRequest();
|
||||||
issuesRequest.setWorkspaceId(project.getWorkspaceId());
|
issuesRequest.setWorkspaceId(project.getWorkspaceId());
|
||||||
IssuesPlatform platform = IssueFactory.createPlatform(issuesWithBLOBs.getPlatform(), issuesRequest);
|
if (PlatformPluginService.isPluginPlatform(issuesWithBLOBs.getPlatform())) {
|
||||||
platform.deleteIssue(id);
|
platformPluginService.getPlatform(issuesWithBLOBs.getPlatform())
|
||||||
|
.deleteIssue(issuesWithBLOBs.getPlatformId());
|
||||||
|
deleteIssue(id);
|
||||||
|
} else {
|
||||||
|
IssuesPlatform platform = IssueFactory.createPlatform(issuesWithBLOBs.getPlatform(), issuesRequest);
|
||||||
|
platform.deleteIssue(id);
|
||||||
|
}
|
||||||
|
|
||||||
// 删除缺陷对应的附件
|
// 删除缺陷对应的附件
|
||||||
AttachmentRequest request = new AttachmentRequest();
|
AttachmentRequest request = new AttachmentRequest();
|
||||||
request.setBelongId(id);
|
request.setBelongId(id);
|
||||||
|
@ -750,13 +886,6 @@ public class IssuesService {
|
||||||
return issueMap;
|
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() {
|
public void syncThirdPartyIssues() {
|
||||||
List<String> projectIds = trackProjectService.getThirdPartProjectIds();
|
List<String> projectIds = trackProjectService.getThirdPartProjectIds();
|
||||||
projectIds.forEach(id -> {
|
projectIds.forEach(id -> {
|
||||||
|
@ -834,8 +963,14 @@ public class IssuesService {
|
||||||
String defaultCustomFields = getDefaultCustomFields(syncRequest.getProjectId());
|
String defaultCustomFields = getDefaultCustomFields(syncRequest.getProjectId());
|
||||||
issuesRequest.setDefaultCustomFields(defaultCustomFields);
|
issuesRequest.setDefaultCustomFields(defaultCustomFields);
|
||||||
}
|
}
|
||||||
IssuesPlatform platform = IssueFactory.createPlatform(project.getPlatform(), issuesRequest);
|
if (PlatformPluginService.isPluginPlatform(project.getPlatform())) {
|
||||||
syncThirdPartyIssues(platform::syncIssues, project, issues);
|
// 分批处理
|
||||||
|
SubListUtil.dealForSubList(issues, 500, (subIssue) ->
|
||||||
|
syncPluginThirdPartyIssues(subIssue, project));
|
||||||
|
} else {
|
||||||
|
IssuesPlatform platform = IssueFactory.createPlatform(project.getPlatform(), issuesRequest);
|
||||||
|
syncThirdPartyIssues(platform::syncIssues, project, issues);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -845,6 +980,118 @@ public class IssuesService {
|
||||||
return true;
|
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 planIssues
|
||||||
* @param planId
|
* @param planId
|
||||||
*/
|
*/
|
||||||
|
@ -1063,38 +1311,17 @@ public class IssuesService {
|
||||||
return issuesMapper.selectByExampleWithBLOBs(example);
|
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) {
|
public IssueTemplateDao getThirdPartTemplate(String projectId) {
|
||||||
|
IssueTemplateDao issueTemplateDao = new IssueTemplateDao();
|
||||||
if (StringUtils.isNotBlank(projectId)) {
|
if (StringUtils.isNotBlank(projectId)) {
|
||||||
Project project = baseProjectService.getProjectById(projectId);
|
Project project = baseProjectService.getProjectById(projectId);
|
||||||
return IssueFactory.createPlatform(IssuesManagePlatform.Jira.toString(), getDefaultIssueRequest(projectId, project.getWorkspaceId()))
|
List<PlatformCustomFieldItemDTO> thirdPartCustomField = platformPluginService.getPlatform(project.getPlatform(), project.getWorkspaceId())
|
||||||
.getThirdPartTemplate();
|
.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) {
|
public IssuesRequest getDefaultIssueRequest(String projectId, String workspaceId) {
|
||||||
|
@ -1104,24 +1331,20 @@ public class IssuesService {
|
||||||
return issuesRequest;
|
return issuesRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<JiraIssueType> getIssueTypes(JiraIssueTypeRequest request) {
|
public List getDemandList(String projectId) {
|
||||||
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) {
|
|
||||||
Project project = baseProjectService.getProjectById(projectId);
|
Project project = baseProjectService.getProjectById(projectId);
|
||||||
String workspaceId = project.getWorkspaceId();
|
String workspaceId = project.getWorkspaceId();
|
||||||
IssuesRequest issueRequest = new IssuesRequest();
|
|
||||||
issueRequest.setWorkspaceId(workspaceId);
|
if (PlatformPluginService.isPluginPlatform(project.getPlatform())) {
|
||||||
issueRequest.setProjectId(projectId);
|
return platformPluginService.getPlatform(project.getPlatform())
|
||||||
IssuesPlatform platform = IssueFactory.createPlatform(project.getPlatform(), issueRequest);
|
.getDemands(PlatformPluginService.getCompatibleProjectConfig(project));
|
||||||
return platform.getDemandList(projectId);
|
} 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) {
|
public List<IssuesDao> listByWorkspaceId(IssuesRequest request) {
|
||||||
|
@ -1134,47 +1357,36 @@ public class IssuesService {
|
||||||
|
|
||||||
if (!StringUtils.isBlank(request.getPlatformKey())) {
|
if (!StringUtils.isBlank(request.getPlatformKey())) {
|
||||||
Project project = baseProjectService.getProjectById(request.getProjectId());
|
Project project = baseProjectService.getProjectById(request.getProjectId());
|
||||||
List<String> platforms = getPlatforms(project);
|
String platform = project.getPlatform();
|
||||||
if (CollectionUtils.isEmpty(platforms)) {
|
if (PlatformPluginService.isPluginPlatform(platform)) {
|
||||||
return platformStatusDTOS;
|
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());
|
IssuesRequest issuesRequest = getDefaultIssueRequest(request.getProjectId(), request.getWorkspaceId());
|
||||||
Map<String, IssuesPlatform> platformMap = IssueFactory.createPlatformsForMap(platforms, issuesRequest);
|
return IssueFactory.createPlatform(platform, issuesRequest).getTransitions(request.getPlatformKey());
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return platformStatusDTOS;
|
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) {
|
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) {
|
public void checkThirdProjectExist(Project project) {
|
||||||
IssuesRequest issuesRequest = new IssuesRequest();
|
IssuesRequest issuesRequest = new IssuesRequest();
|
||||||
if (StringUtils.isBlank(project.getId())) {
|
if (StringUtils.isBlank(project.getId())) {
|
||||||
|
@ -1373,9 +1585,10 @@ public class IssuesService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private IssueTemplateDao getIssueTemplateByProjectId(String projectId) {
|
private IssueTemplateDao getIssueTemplateByProjectId(String projectId) {
|
||||||
IssueTemplateDao issueTemplateDao = new IssueTemplateDao();
|
IssueTemplateDao issueTemplateDao;
|
||||||
Project project = baseProjectService.getProjectById(projectId);
|
Project project = baseProjectService.getProjectById(projectId);
|
||||||
if (StringUtils.equals(project.getPlatform(), IssuesManagePlatform.Jira.name()) && project.getThirdPartTemplate()) {
|
if (PlatformPluginService.isPluginPlatform(project.getPlatform())
|
||||||
|
&& project.getThirdPartTemplate()) {
|
||||||
// 第三方Jira平台
|
// 第三方Jira平台
|
||||||
issueTemplateDao = getThirdPartTemplate(project.getId());
|
issueTemplateDao = getThirdPartTemplate(project.getId());
|
||||||
issueTemplateDao.setIsThirdTemplate(Boolean.TRUE);
|
issueTemplateDao.setIsThirdTemplate(Boolean.TRUE);
|
||||||
|
@ -1407,7 +1620,7 @@ public class IssuesService {
|
||||||
return filterIssues;
|
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);
|
List<String> attachmentIds = attachmentService.getAttachmentIdsByParam(attachmentRequest);
|
||||||
if (CollectionUtils.isNotEmpty(attachmentIds)) {
|
if (CollectionUtils.isNotEmpty(attachmentIds)) {
|
||||||
attachmentIds.forEach(attachmentId -> {
|
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;
|
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.PluginWithBLOBs;
|
||||||
|
import io.metersphere.base.domain.Project;
|
||||||
|
import io.metersphere.base.domain.ServiceIntegration;
|
||||||
import io.metersphere.commons.constants.PluginScenario;
|
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 io.metersphere.utils.PluginManagerUtil;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@ -19,6 +30,8 @@ public class PlatformPluginService {
|
||||||
private BasePluginService basePluginService;
|
private BasePluginService basePluginService;
|
||||||
@Resource
|
@Resource
|
||||||
private BaseIntegrationService baseIntegrationService;
|
private BaseIntegrationService baseIntegrationService;
|
||||||
|
@Resource
|
||||||
|
private BaseProjectService baseProjectService;
|
||||||
|
|
||||||
private PlatformPluginManager pluginManager;
|
private PlatformPluginManager pluginManager;
|
||||||
|
|
||||||
|
@ -46,4 +59,48 @@ public class PlatformPluginService {
|
||||||
public void unloadPlugin(String pluginId) {
|
public void unloadPlugin(String pluginId) {
|
||||||
pluginManager.deletePlugin(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.exception.MSException;
|
||||||
import io.metersphere.commons.utils.*;
|
import io.metersphere.commons.utils.*;
|
||||||
import io.metersphere.dto.CustomFieldItemDTO;
|
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.dto.UserDTO;
|
||||||
import io.metersphere.request.IntegrationRequest;
|
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.service.*;
|
||||||
import io.metersphere.xpack.track.issue.IssuesPlatform;
|
|
||||||
import io.metersphere.service.issue.domain.ProjectIssueConfig;
|
import io.metersphere.service.issue.domain.ProjectIssueConfig;
|
||||||
import io.metersphere.service.wapper.TrackProjectService;
|
import io.metersphere.service.wapper.TrackProjectService;
|
||||||
import io.metersphere.service.wapper.UserService;
|
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.apache.commons.lang3.StringUtils;
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.jsoup.nodes.Document;
|
import org.jsoup.nodes.Document;
|
||||||
|
@ -654,4 +651,8 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
|
||||||
return null;
|
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) {
|
public static IssuesPlatform createPlatform(String platform, IssuesRequest addIssueRequest) {
|
||||||
if (StringUtils.equals(IssuesManagePlatform.Tapd.toString(), platform)) {
|
if (StringUtils.equals(IssuesManagePlatform.Tapd.toString(), platform)) {
|
||||||
return new TapdPlatform(addIssueRequest);
|
return new TapdPlatform(addIssueRequest);
|
||||||
} else if (StringUtils.equals(IssuesManagePlatform.Jira.toString(), platform)) {
|
|
||||||
return new JiraPlatform(addIssueRequest);
|
|
||||||
} else if (StringUtils.equals(IssuesManagePlatform.Zentao.toString(), platform)) {
|
} else if (StringUtils.equals(IssuesManagePlatform.Zentao.toString(), platform)) {
|
||||||
return new ZentaoPlatform(addIssueRequest);
|
return new ZentaoPlatform(addIssueRequest);
|
||||||
} else if (StringUtils.equals(IssuesManagePlatform.AzureDevops.toString(), platform)) {
|
} else if (StringUtils.equals(IssuesManagePlatform.AzureDevops.toString(), platform)) {
|
||||||
|
@ -46,15 +44,4 @@ public class IssueFactory {
|
||||||
});
|
});
|
||||||
return platforms;
|
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.base.domain.IssuesWithBLOBs;
|
||||||
|
|
||||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||||
import io.metersphere.commons.user.SessionUser;
|
import io.metersphere.commons.user.SessionUser;
|
||||||
import io.metersphere.commons.utils.BeanUtils;
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
import io.metersphere.commons.utils.JSON;
|
import io.metersphere.commons.utils.JSON;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.xpack.track.dto.AttachmentSyncType;
|
|
||||||
import io.metersphere.dto.CustomFieldItemDTO;
|
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.DemandDTO;
|
||||||
import io.metersphere.xpack.track.dto.IssuesDao;
|
|
||||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||||
import io.metersphere.xpack.track.dto.request.IssuesUpdateRequest;
|
import io.metersphere.xpack.track.dto.request.IssuesUpdateRequest;
|
||||||
import io.metersphere.request.testcase.TestCaseBatchRequest;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -29,16 +27,6 @@ public class LocalPlatform extends LocalAbstractPlatform {
|
||||||
super(issuesRequest);
|
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
|
@Override
|
||||||
public List<DemandDTO> getDemandList(String projectId) {
|
public List<DemandDTO> getDemandList(String projectId) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.metersphere.service.plugin;
|
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.constants.StorageConstants;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.metadata.service.FileManagerService;
|
import io.metersphere.metadata.service.FileManagerService;
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package io.metersphere.service.wapper;
|
package io.metersphere.service.wapper;
|
||||||
|
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
|
||||||
import io.metersphere.i18n.Translator;
|
import io.metersphere.i18n.Translator;
|
||||||
|
import io.metersphere.service.PlatformPluginService;
|
||||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||||
import io.metersphere.service.issue.platform.IssueFactory;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
@ -20,6 +19,8 @@ public class IssueProxyResourceService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private RestTemplate restTemplate;
|
private RestTemplate restTemplate;
|
||||||
|
@Resource
|
||||||
|
private PlatformPluginService platformPluginService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* http 代理
|
* http 代理
|
||||||
|
@ -37,8 +38,9 @@ public class IssueProxyResourceService {
|
||||||
IssuesRequest issuesRequest = new IssuesRequest();
|
IssuesRequest issuesRequest = new IssuesRequest();
|
||||||
issuesRequest.setProjectId(projectId);
|
issuesRequest.setProjectId(projectId);
|
||||||
issuesRequest.setWorkspaceId(workspaceId);
|
issuesRequest.setWorkspaceId(workspaceId);
|
||||||
return IssueFactory.createPlatform(platform, issuesRequest)
|
return platformPluginService.getPlatform(platform)
|
||||||
.proxyForGet(url, byte[].class);
|
.proxyForGet(url, byte[].class);
|
||||||
|
|
||||||
}
|
}
|
||||||
return restTemplate.exchange(url, HttpMethod.GET, null, 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);
|
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;
|
package io.metersphere.utils;
|
||||||
|
|
||||||
import im.metersphere.loader.PluginManager;
|
import im.metersphere.plugin.loader.PluginManager;
|
||||||
import io.metersphere.base.domain.PluginWithBLOBs;
|
import io.metersphere.base.domain.PluginWithBLOBs;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
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 {getCurrentProjectID, getCurrentWorkspaceId} from "metersphere-frontend/src/utils/token";
|
||||||
import {hasLicense} from "metersphere-frontend/src/utils/permission";
|
import {hasLicense} from "metersphere-frontend/src/utils/permission";
|
||||||
import {getCurrentProject} from "./project";
|
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 {getIssueTemplate} from "./custom-field-template";
|
||||||
import {$success, $warning} from "metersphere-frontend/src/plugins/message";
|
import {$success, $warning} from "metersphere-frontend/src/plugins/message";
|
||||||
import i18n from "../i18n";
|
import i18n from "../i18n";
|
||||||
|
@ -212,8 +212,8 @@ export function getPlatformTransitions(param) {
|
||||||
return post('/issues/platform/transitions', param);
|
return post('/issues/platform/transitions', param);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function enableThirdPartTemplate(currentProject) {
|
export function enableThirdPartTemplate(projectId) {
|
||||||
return currentProject && currentProject.thirdPartTemplate && currentProject.platform === JIRA;
|
return get(BASE_URL + '/third/part/template/enable/' + projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildIssues(page) {
|
export function buildIssues(page) {
|
||||||
|
@ -230,18 +230,21 @@ export function buildIssues(page) {
|
||||||
export function getIssuePartTemplateWithProject(callback) {
|
export function getIssuePartTemplateWithProject(callback) {
|
||||||
getCurrentProject().then((response) => {
|
getCurrentProject().then((response) => {
|
||||||
let currentProject = response.data;
|
let currentProject = response.data;
|
||||||
if (enableThirdPartTemplate(currentProject)) {
|
enableThirdPartTemplate(currentProject.id)
|
||||||
getIssueThirdPartTemplate()
|
.then((r) => {
|
||||||
.then((template) => {
|
if (r.data) {
|
||||||
if (callback)
|
getIssueThirdPartTemplate()
|
||||||
callback(template, currentProject);
|
.then((template) => {
|
||||||
});
|
if (callback)
|
||||||
} else {
|
callback(template, currentProject);
|
||||||
getIssueTemplate()
|
});
|
||||||
.then((template) => {
|
} else {
|
||||||
if (callback)
|
getIssueTemplate()
|
||||||
callback(template, currentProject);
|
.then((template) => {
|
||||||
});
|
if (callback)
|
||||||
}
|
callback(template, currentProject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,25 +6,33 @@
|
||||||
<ms-form-divider :title="$t('test_track.plan_view.base_info')"/>
|
<ms-form-divider :title="$t('test_track.plan_view.base_info')"/>
|
||||||
<el-form-item v-if="!enableThirdPartTemplate" :label="$t('commons.title')" prop="title">
|
<el-form-item v-if="!enableThirdPartTemplate" :label="$t('commons.title')" prop="title">
|
||||||
<el-row>
|
<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-input v-model="form.title" autocomplete="off" class="top-input-class"></el-input>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="2">
|
<el-col :span="2">
|
||||||
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!showFollow">
|
<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" />
|
<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>
|
||||||
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="showFollow" >
|
<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" />
|
<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-tooltip>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div v-else style="text-align: right; margin-bottom: 5px">
|
<div v-else style="text-align: right; margin-bottom: 5px">
|
||||||
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!showFollow">
|
<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" />
|
<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>
|
||||||
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="showFollow" >
|
<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" />
|
<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-tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -118,10 +126,14 @@
|
||||||
:on-success="handleSuccess"
|
:on-success="handleSuccess"
|
||||||
:on-error="handleError"
|
:on-error="handleError"
|
||||||
:disabled="readOnly || type === 'copy'">
|
: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>
|
</el-upload>
|
||||||
</div>
|
</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"/>
|
<i class="el-icon-plus" slot="reference"/>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
|
@ -198,7 +210,12 @@ import CustomFiledComponent from "metersphere-frontend/src/components/template/C
|
||||||
import TestCaseIssueList from "@/business/issue/TestCaseIssueList";
|
import TestCaseIssueList from "@/business/issue/TestCaseIssueList";
|
||||||
import IssueEditDetail from "@/business/issue/IssueEditDetail";
|
import IssueEditDetail from "@/business/issue/IssueEditDetail";
|
||||||
import {byteToSize, getTypeByFileName, getUUID} from "metersphere-frontend/src/utils";
|
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 {hasLicense} from "metersphere-frontend/src/utils/permission";
|
||||||
import {
|
import {
|
||||||
enableThirdPartTemplate,
|
enableThirdPartTemplate,
|
||||||
|
@ -250,7 +267,7 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
type: null,
|
type: null,
|
||||||
issueId:'',
|
issueId: '',
|
||||||
result: {
|
result: {
|
||||||
loading: false
|
loading: false
|
||||||
},
|
},
|
||||||
|
@ -275,8 +292,8 @@ export default {
|
||||||
description: '',
|
description: '',
|
||||||
creator: null,
|
creator: null,
|
||||||
remark: null,
|
remark: null,
|
||||||
tapdUsers:[],
|
tapdUsers: [],
|
||||||
zentaoBuilds:[],
|
zentaoBuilds: [],
|
||||||
zentaoAssigned: '',
|
zentaoAssigned: '',
|
||||||
platformStatus: null,
|
platformStatus: null,
|
||||||
copyIssueId: ''
|
copyIssueId: ''
|
||||||
|
@ -335,6 +352,7 @@ export default {
|
||||||
relateFiles: [],
|
relateFiles: [],
|
||||||
unRelateFiles: [],
|
unRelateFiles: [],
|
||||||
dumpFile: {},
|
dumpFile: {},
|
||||||
|
enableThirdPartTemplate: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -356,9 +374,6 @@ export default {
|
||||||
projectId() {
|
projectId() {
|
||||||
return getCurrentProjectID();
|
return getCurrentProjectID();
|
||||||
},
|
},
|
||||||
enableThirdPartTemplate() {
|
|
||||||
return enableThirdPartTemplate(this.currentProject);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
tabActiveName() {
|
tabActiveName() {
|
||||||
|
@ -376,8 +391,8 @@ export default {
|
||||||
description: '',
|
description: '',
|
||||||
creator: null,
|
creator: null,
|
||||||
remark: null,
|
remark: null,
|
||||||
tapdUsers:[],
|
tapdUsers: [],
|
||||||
zentaoBuilds:[],
|
zentaoBuilds: [],
|
||||||
zentaoAssigned: '',
|
zentaoAssigned: '',
|
||||||
platformStatus: null
|
platformStatus: null
|
||||||
};
|
};
|
||||||
|
@ -403,6 +418,11 @@ export default {
|
||||||
this.currentProject = project;
|
this.currentProject = project;
|
||||||
this.init(template, data);
|
this.init(template, data);
|
||||||
this.getDataInfoAsync(data);
|
this.getDataInfoAsync(data);
|
||||||
|
|
||||||
|
enableThirdPartTemplate(this.currentProject.id)
|
||||||
|
.then(r => {
|
||||||
|
this.enableThirdPartTemplate = r.data;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -460,21 +480,21 @@ export default {
|
||||||
if (platform === 'Zentao') {
|
if (platform === 'Zentao') {
|
||||||
this.hasZentaoId = true;
|
this.hasZentaoId = true;
|
||||||
getZentaoBuilds(data)
|
getZentaoBuilds(data)
|
||||||
.then((response) => {
|
|
||||||
if (response.data) {
|
|
||||||
this.Builds = response.data;
|
|
||||||
}
|
|
||||||
getZentaoUser(data)
|
|
||||||
.then((response) => {
|
.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') {
|
} else if (platform === 'Tapd') {
|
||||||
this.hasTapdId = true;
|
this.hasTapdId = true;
|
||||||
getTapdUser(data)
|
getTapdUser(data)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
this.tapdUsers = response.data;
|
this.tapdUsers = response.data;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
initEdit(data) {
|
initEdit(data) {
|
||||||
|
@ -627,30 +647,30 @@ export default {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
saveFollow(){
|
saveFollow() {
|
||||||
if(!this.form.follows){
|
if (!this.form.follows) {
|
||||||
this.form.follows = [];
|
this.form.follows = [];
|
||||||
}
|
}
|
||||||
if(this.showFollow){
|
if (this.showFollow) {
|
||||||
this.showFollow = false;
|
this.showFollow = false;
|
||||||
for (let i = 0; i < this.form.follows.length; i++) {
|
for (let i = 0; i < this.form.follows.length; i++) {
|
||||||
if(this.form.follows[i]===this.currentUser().id){
|
if (this.form.follows[i] === this.currentUser().id) {
|
||||||
this.form.follows.splice(i,1)
|
this.form.follows.splice(i, 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(this.url === "issues/update"){
|
if (this.url === "issues/update") {
|
||||||
saveFollow(this.issueId, this.form.follows).then(() => {
|
saveFollow(this.issueId, this.form.follows).then(() => {
|
||||||
this.$success(this.$t('commons.cancel_follow_success'));
|
this.$success(this.$t('commons.cancel_follow_success'));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
this.showFollow = true;
|
this.showFollow = true;
|
||||||
if(!this.form.follows){
|
if (!this.form.follows) {
|
||||||
this.form.follows = [];
|
this.form.follows = [];
|
||||||
}
|
}
|
||||||
this.form.follows.push(this.currentUser().id)
|
this.form.follows.push(this.currentUser().id)
|
||||||
if(this.url === "issues/update"){
|
if (this.url === "issues/update") {
|
||||||
saveFollow(this.issueId, this.form.follows).then(() => {
|
saveFollow(this.issueId, this.form.follows).then(() => {
|
||||||
this.$success(this.$t('commons.follow_success'));
|
this.$success(this.$t('commons.follow_success'));
|
||||||
})
|
})
|
||||||
|
@ -679,8 +699,8 @@ export default {
|
||||||
name: file.name,
|
name: file.name,
|
||||||
size: byteToSize(file.size),
|
size: byteToSize(file.size),
|
||||||
updateTime: new Date().getTime(),
|
updateTime: new Date().getTime(),
|
||||||
progress: this.type === 'add' || this.isCaseEdit? 100 : 0,
|
progress: this.type === 'add' || this.isCaseEdit ? 100 : 0,
|
||||||
status: this.type === 'add' || this.isCaseEdit? 'toUpload' : 0,
|
status: this.type === 'add' || this.isCaseEdit ? 'toUpload' : 0,
|
||||||
creator: user.name,
|
creator: user.name,
|
||||||
type: getTypeByFileName(file.name),
|
type: getTypeByFileName(file.name),
|
||||||
isLocal: true
|
isLocal: true
|
||||||
|
@ -702,27 +722,27 @@ export default {
|
||||||
let CancelToken = axios.CancelToken
|
let CancelToken = axios.CancelToken
|
||||||
let self = this;
|
let self = this;
|
||||||
uploadIssueAttachment(file, data, CancelToken, self.cancelFileToken, progressCallback)
|
uploadIssueAttachment(file, data, CancelToken, self.cancelFileToken, progressCallback)
|
||||||
.then(response => { // 成功回调
|
.then(response => { // 成功回调
|
||||||
progress = 100;
|
progress = 100;
|
||||||
param.onSuccess(response);
|
param.onSuccess(response);
|
||||||
progressCallback({progress, status: 'success'});
|
progressCallback({progress, status: 'success'});
|
||||||
self.cancelFileToken.forEach((token, index, array)=>{
|
self.cancelFileToken.forEach((token, index, array) => {
|
||||||
if(token.name == file.name){
|
if (token.name == file.name) {
|
||||||
array.splice(token,1)
|
array.splice(token, 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}).catch(({error}) => { // 失败回调
|
}).catch(({error}) => { // 失败回调
|
||||||
progress = 100;
|
progress = 100;
|
||||||
progressCallback({progress, status: 'error'});
|
progressCallback({progress, status: 'error'});
|
||||||
self.cancelFileToken.forEach((token, index, array)=>{
|
self.cancelFileToken.forEach((token, index, array) => {
|
||||||
if(token.name == file.name){
|
if (token.name == file.name) {
|
||||||
array.splice(token,1)
|
array.splice(token, 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
showProgress(file, params) {
|
showProgress(file, params) {
|
||||||
const { progress, status } = params
|
const {progress, status} = params
|
||||||
const arr = [...this.tableData].map(item => {
|
const arr = [...this.tableData].map(item => {
|
||||||
if (item.name === file.name) {
|
if (item.name === file.name) {
|
||||||
item.progress = progress
|
item.progress = progress
|
||||||
|
@ -737,18 +757,18 @@ export default {
|
||||||
},
|
},
|
||||||
handleSuccess(response, file, fileList) {
|
handleSuccess(response, file, fileList) {
|
||||||
let readyFiles = fileList.filter(item => item.status === 'success')
|
let readyFiles = fileList.filter(item => item.status === 'success')
|
||||||
if (readyFiles.length === fileList.length ) {
|
if (readyFiles.length === fileList.length) {
|
||||||
this.getFileMetaData(this.issueId);
|
this.getFileMetaData(this.issueId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleError(err, file, fileList) {
|
handleError(err, file, fileList) {
|
||||||
let readyFiles = fileList.filter(item => item.status === 'success')
|
let readyFiles = fileList.filter(item => item.status === 'success')
|
||||||
if (readyFiles.length === fileList.length ) {
|
if (readyFiles.length === fileList.length) {
|
||||||
this.getFileMetaData(this.issueId);
|
this.getFileMetaData(this.issueId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleDelete(file, index) {
|
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'),
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
dangerouslyUseHTMLString: true,
|
dangerouslyUseHTMLString: true,
|
||||||
callback: (action) => {
|
callback: (action) => {
|
||||||
|
@ -772,10 +792,10 @@ export default {
|
||||||
this.uploadFiles.splice(delIndex, 1);
|
this.uploadFiles.splice(delIndex, 1);
|
||||||
} else {
|
} else {
|
||||||
deleteIssueAttachment(file.id)
|
deleteIssueAttachment(file.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$success(this.$t('commons.delete_success'));
|
this.$success(this.$t('commons.delete_success'));
|
||||||
this.getFileMetaData(this.issueId);
|
this.getFileMetaData(this.issueId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleUnRelate(file, index) {
|
handleUnRelate(file, index) {
|
||||||
|
@ -797,11 +817,11 @@ export default {
|
||||||
let data = {'belongType': 'issue', 'belongId': this.issueId, 'metadataRefIds': this.unRelateFiles};
|
let data = {'belongType': 'issue', 'belongId': this.issueId, 'metadataRefIds': this.unRelateFiles};
|
||||||
this.result.loading = true;
|
this.result.loading = true;
|
||||||
unrelatedAttachment(data)
|
unrelatedAttachment(data)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$success(this.$t('commons.unrelated_success'));
|
this.$success(this.$t('commons.unrelated_success'));
|
||||||
this.result.loading = false;
|
this.result.loading = false;
|
||||||
this.getFileMetaData(this.issueId);
|
this.getFileMetaData(this.issueId);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -827,7 +847,7 @@ export default {
|
||||||
for (let row of rows) {
|
for (let row of rows) {
|
||||||
let rowIndex = this.tableData.findIndex(item => item.name === row.name);
|
let rowIndex = this.tableData.findIndex(item => item.name === row.name);
|
||||||
if (rowIndex >= 0) {
|
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;
|
repeatRecord = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -856,21 +876,23 @@ export default {
|
||||||
let data = {'belongType': 'issue', 'belongId': this.issueId, 'metadataRefIds': metadataRefIds};
|
let data = {'belongType': 'issue', 'belongId': this.issueId, 'metadataRefIds': metadataRefIds};
|
||||||
this.result.loading = true;
|
this.result.loading = true;
|
||||||
relatedAttachment(data)
|
relatedAttachment(data)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$success(this.$t('commons.relate_success'));
|
this.$success(this.$t('commons.relate_success'));
|
||||||
this.result.loading = false;
|
this.result.loading = false;
|
||||||
this.getFileMetaData(this.issueId);
|
this.getFileMetaData(this.issueId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setModuleId(moduleId) {
|
setModuleId(moduleId) {
|
||||||
let data = {id: getUUID(), resourceId: getCurrentProjectID(), moduleId: moduleId,
|
let data = {
|
||||||
projectId: getCurrentProjectID(), fileName: this.dumpFile.name, attachmentId: this.dumpFile.id};
|
id: getUUID(), resourceId: getCurrentProjectID(), moduleId: moduleId,
|
||||||
|
projectId: getCurrentProjectID(), fileName: this.dumpFile.name, attachmentId: this.dumpFile.id
|
||||||
|
};
|
||||||
dumpAttachment(data)
|
dumpAttachment(data)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$success(this.$t("organization.integration.successful_operation"));
|
this.$success(this.$t("organization.integration.successful_operation"));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getFileMetaData(id) {
|
getFileMetaData(id) {
|
||||||
if (this.type === 'edit') {
|
if (this.type === 'edit') {
|
||||||
|
@ -926,7 +948,7 @@ export default {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-input-class{
|
.top-input-class {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue