fix(缺陷管理): 复制缺陷同时保存附件
--bug=1036407 --user=宋昌昌 【缺陷管理】复制带附件缺陷,复制报错 https://www.tapd.cn/55049933/s/1470664
This commit is contained in:
parent
56a93a59b6
commit
54c0764f4f
|
@ -82,6 +82,7 @@ not_local_bug_error=非本地缺陷,无法操作
|
||||||
bug_tags_size_large_than=缺陷标签数量超过{0}个
|
bug_tags_size_large_than=缺陷标签数量超过{0}个
|
||||||
third_party_not_config=项目未配置第三方平台
|
third_party_not_config=项目未配置第三方平台
|
||||||
bug_attachment_upload_error=缺陷附件上传失败
|
bug_attachment_upload_error=缺陷附件上传失败
|
||||||
|
bug_attachment_link_error=缺陷附件关联失败
|
||||||
bug_attachment_delete_error=缺陷附件删除失败
|
bug_attachment_delete_error=缺陷附件删除失败
|
||||||
no_bug_select=未勾选缺陷
|
no_bug_select=未勾选缺陷
|
||||||
bug_select_not_found=未查询到勾选的缺陷
|
bug_select_not_found=未查询到勾选的缺陷
|
||||||
|
|
|
@ -82,6 +82,7 @@ bug_tags_size_large_than=Bug size large than {0}
|
||||||
not_local_bug_error=Not local bug, error
|
not_local_bug_error=Not local bug, error
|
||||||
third_party_not_config=The project third-party platform not configured
|
third_party_not_config=The project third-party platform not configured
|
||||||
bug_attachment_upload_error=Bug attachment upload error
|
bug_attachment_upload_error=Bug attachment upload error
|
||||||
|
bug_attachment_link_error=Bug attachment link error
|
||||||
bug_attachment_delete_error=Bug attachment delete error
|
bug_attachment_delete_error=Bug attachment delete error
|
||||||
no_bug_select=No bug selected
|
no_bug_select=No bug selected
|
||||||
bug_select_not_found=Selected bug not found
|
bug_select_not_found=Selected bug not found
|
||||||
|
|
|
@ -82,6 +82,7 @@ not_local_bug_error=非本地缺陷,无法操作
|
||||||
bug_tags_size_large_than=缺陷标签数量超过{0}个
|
bug_tags_size_large_than=缺陷标签数量超过{0}个
|
||||||
third_party_not_config=项目未配置第三方平台
|
third_party_not_config=项目未配置第三方平台
|
||||||
bug_attachment_upload_error=缺陷附件上传失败
|
bug_attachment_upload_error=缺陷附件上传失败
|
||||||
|
bug_attachment_link_error=缺陷附件关联失败
|
||||||
bug_attachment_delete_error=缺陷附件删除失败
|
bug_attachment_delete_error=缺陷附件删除失败
|
||||||
no_bug_select=未勾选缺陷
|
no_bug_select=未勾选缺陷
|
||||||
bug_select_not_found=未查询到勾选的缺陷
|
bug_select_not_found=未查询到勾选的缺陷
|
||||||
|
|
|
@ -82,6 +82,7 @@ not_local_bug_error=非本地缺陷,無法操作
|
||||||
third_party_not_config=項目未配置第三方平台
|
third_party_not_config=項目未配置第三方平台
|
||||||
bug_tags_size_large_than=缺陷标签数量超过{0}个
|
bug_tags_size_large_than=缺陷标签数量超过{0}个
|
||||||
bug_attachment_upload_error=缺陷附件上傳失敗
|
bug_attachment_upload_error=缺陷附件上傳失敗
|
||||||
|
bug_attachment_link_error=缺陷附件關聯失敗
|
||||||
bug_attachment_delete_error=缺陷附件刪除失敗
|
bug_attachment_delete_error=缺陷附件刪除失敗
|
||||||
no_bug_select=未勾選缺陷
|
no_bug_select=未勾選缺陷
|
||||||
bug_select_not_found=未查詢到勾選的缺陷
|
bug_select_not_found=未查詢到勾選的缺陷
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.metersphere.bug.dto.request;
|
package io.metersphere.bug.dto.request;
|
||||||
|
|
||||||
import io.metersphere.bug.dto.response.BugCustomFieldDTO;
|
import io.metersphere.bug.dto.response.BugCustomFieldDTO;
|
||||||
|
import io.metersphere.bug.dto.response.BugFileDTO;
|
||||||
import io.metersphere.validation.groups.Created;
|
import io.metersphere.validation.groups.Created;
|
||||||
import io.metersphere.validation.groups.Updated;
|
import io.metersphere.validation.groups.Updated;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
@ -56,4 +57,7 @@ public class BugEditRequest implements Serializable {
|
||||||
|
|
||||||
@Schema(description = "用例ID")
|
@Schema(description = "用例ID")
|
||||||
private String caseId;
|
private String caseId;
|
||||||
|
|
||||||
|
@Schema(description = "复制的附件")
|
||||||
|
private List<BugFileDTO> copyFiles;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,9 @@ public class BugFileDTO {
|
||||||
@Schema(description = "文件ID")
|
@Schema(description = "文件ID")
|
||||||
private String fileId;
|
private String fileId;
|
||||||
|
|
||||||
|
@Schema(description = "缺陷ID")
|
||||||
|
private String bugId;
|
||||||
|
|
||||||
@Schema(description = "文件名称")
|
@Schema(description = "文件名称")
|
||||||
private String fileName;
|
private String fileName;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import io.metersphere.project.mapper.ProjectMapper;
|
||||||
import io.metersphere.project.service.*;
|
import io.metersphere.project.service.*;
|
||||||
import io.metersphere.sdk.constants.*;
|
import io.metersphere.sdk.constants.*;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
|
import io.metersphere.sdk.file.FileCenter;
|
||||||
import io.metersphere.sdk.file.FileRequest;
|
import io.metersphere.sdk.file.FileRequest;
|
||||||
import io.metersphere.sdk.util.*;
|
import io.metersphere.sdk.util.*;
|
||||||
import io.metersphere.system.domain.CustomFieldOption;
|
import io.metersphere.system.domain.CustomFieldOption;
|
||||||
|
@ -1006,22 +1007,47 @@ public class BugService {
|
||||||
private List<SyncAttachmentToPlatformRequest> uploadAttachment(BugEditRequest request, List<MultipartFile> files, PlatformBugUpdateDTO platformBug,
|
private List<SyncAttachmentToPlatformRequest> uploadAttachment(BugEditRequest request, List<MultipartFile> files, PlatformBugUpdateDTO platformBug,
|
||||||
String currentUser, String platformName, File tempFileDir) {
|
String currentUser, String platformName, File tempFileDir) {
|
||||||
List<SyncAttachmentToPlatformRequest> uploadPlatformAttachments = new ArrayList<>();
|
List<SyncAttachmentToPlatformRequest> uploadPlatformAttachments = new ArrayList<>();
|
||||||
|
// 复制的附件
|
||||||
|
List<BugLocalAttachment> copyFiles = new ArrayList<>();
|
||||||
|
if (CollectionUtils.isNotEmpty(request.getCopyFiles())) {
|
||||||
|
// 本地附件
|
||||||
|
request.getCopyFiles().stream().filter(BugFileDTO::getLocal).forEach(localFile -> {
|
||||||
|
try {
|
||||||
|
BugFileSourceRequest sourceRequest = new BugFileSourceRequest();
|
||||||
|
sourceRequest.setBugId(localFile.getBugId());
|
||||||
|
sourceRequest.setProjectId(request.getProjectId());
|
||||||
|
sourceRequest.setFileId(localFile.getFileId());
|
||||||
|
sourceRequest.setAssociated(false);
|
||||||
|
byte[] bytes = bugAttachmentService.downloadOrPreview(sourceRequest).getBody();
|
||||||
|
if (bytes != null) {
|
||||||
|
BugLocalAttachment localAttachment = buildBugLocalAttachment(request.getId(), localFile.getFileName(), bytes.length, currentUser);
|
||||||
|
copyFiles.add(localAttachment);
|
||||||
|
// 上传文件库
|
||||||
|
FileCenter.getDefaultRepository().saveFile(bytes, buildBugFileRequest(request.getProjectId(), request.getId(), localAttachment.getFileId(), localFile.getFileName()));
|
||||||
|
// 同步新上传的附件至平台
|
||||||
|
if (!StringUtils.equals(platformName, BugPlatform.LOCAL.getName())) {
|
||||||
|
File uploadTmpFile = new File(tempFileDir, Objects.requireNonNull(localFile.getFileName())).toPath().normalize().toFile();
|
||||||
|
FileUtils.writeByteArrayToFile(uploadTmpFile, bytes);
|
||||||
|
uploadPlatformAttachments.add(new SyncAttachmentToPlatformRequest(platformBug.getPlatformBugKey(), uploadTmpFile, SyncAttachmentType.UPLOAD.syncOperateType()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new MSException(Translator.get("bug_attachment_upload_error"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
extBugLocalAttachmentMapper.batchInsert(copyFiles);
|
||||||
|
// 关联的附件, 直接合并, 后续逻辑会处理
|
||||||
|
List<String> copyLinkFileIds = request.getCopyFiles().stream().filter(file -> !file.getLocal()).map(BugFileDTO::getFileId).collect(Collectors.toList());
|
||||||
|
request.setLinkFileIds(ListUtils.union(request.getLinkFileIds(), copyLinkFileIds));
|
||||||
|
}
|
||||||
// 新本地上传的附件
|
// 新本地上传的附件
|
||||||
List<BugLocalAttachment> addFiles = new ArrayList<>();
|
List<BugLocalAttachment> addFiles = new ArrayList<>();
|
||||||
Map<String, MultipartFile> uploadMinioFiles = new HashMap<>(16);
|
Map<String, MultipartFile> uploadMinioFiles = new HashMap<>(16);
|
||||||
if (CollectionUtils.isNotEmpty(files)) {
|
if (CollectionUtils.isNotEmpty(files)) {
|
||||||
files.forEach(file -> {
|
files.forEach(file -> {
|
||||||
BugLocalAttachment bugAttachment = new BugLocalAttachment();
|
BugLocalAttachment localAttachment = buildBugLocalAttachment(request.getId(), file.getOriginalFilename(), file.getSize(), currentUser);
|
||||||
bugAttachment.setId(IDGenerator.nextStr());
|
addFiles.add(localAttachment);
|
||||||
bugAttachment.setBugId(request.getId());
|
uploadMinioFiles.put(localAttachment.getFileId(), file);
|
||||||
bugAttachment.setFileId(IDGenerator.nextStr());
|
|
||||||
bugAttachment.setFileName(file.getOriginalFilename());
|
|
||||||
bugAttachment.setSize(file.getSize());
|
|
||||||
bugAttachment.setSource(BugAttachmentSourceType.ATTACHMENT.name());
|
|
||||||
bugAttachment.setCreateTime(System.currentTimeMillis());
|
|
||||||
bugAttachment.setCreateUser(currentUser);
|
|
||||||
addFiles.add(bugAttachment);
|
|
||||||
uploadMinioFiles.put(bugAttachment.getFileId(), file);
|
|
||||||
});
|
});
|
||||||
extBugLocalAttachmentMapper.batchInsert(addFiles);
|
extBugLocalAttachmentMapper.batchInsert(addFiles);
|
||||||
uploadMinioFiles.forEach((fileId, file) -> {
|
uploadMinioFiles.forEach((fileId, file) -> {
|
||||||
|
@ -1059,7 +1085,7 @@ public class BugService {
|
||||||
FileUtils.writeByteArrayToFile(uploadTmpFile, fileByte);
|
FileUtils.writeByteArrayToFile(uploadTmpFile, fileByte);
|
||||||
uploadPlatformAttachments.add(new SyncAttachmentToPlatformRequest(platformBug.getPlatformBugKey(), uploadTmpFile, SyncAttachmentType.UPLOAD.syncOperateType()));
|
uploadPlatformAttachments.add(new SyncAttachmentToPlatformRequest(platformBug.getPlatformBugKey(), uploadTmpFile, SyncAttachmentType.UPLOAD.syncOperateType()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new MSException(Translator.get("bug_attachment_upload_error"));
|
throw new MSException(Translator.get("bug_attachment_link_error"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1512,4 +1538,25 @@ public class BugService {
|
||||||
throw new MSException(Translator.getWithArgs("bug_tags_size_large_than", String.valueOf(MAX_TAG_SIZE)));
|
throw new MSException(Translator.getWithArgs("bug_tags_size_large_than", String.valueOf(MAX_TAG_SIZE)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建缺陷本地附件
|
||||||
|
* @param bugId 缺陷ID
|
||||||
|
* @param fileName 文件名称
|
||||||
|
* @param size 文件大小
|
||||||
|
* @param currentUser 当前用户
|
||||||
|
* @return 本地附件
|
||||||
|
*/
|
||||||
|
private BugLocalAttachment buildBugLocalAttachment(String bugId, String fileName, long size, String currentUser) {
|
||||||
|
BugLocalAttachment bugAttachment = new BugLocalAttachment();
|
||||||
|
bugAttachment.setId(IDGenerator.nextStr());
|
||||||
|
bugAttachment.setBugId(bugId);
|
||||||
|
bugAttachment.setFileId(IDGenerator.nextStr());
|
||||||
|
bugAttachment.setFileName(fileName);
|
||||||
|
bugAttachment.setSize(size);
|
||||||
|
bugAttachment.setSource(BugAttachmentSourceType.ATTACHMENT.name());
|
||||||
|
bugAttachment.setCreateTime(System.currentTimeMillis());
|
||||||
|
bugAttachment.setCreateUser(currentUser);
|
||||||
|
return bugAttachment;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -278,7 +278,7 @@
|
||||||
inputFileName.value = fileItem.name || '';
|
inputFileName.value = fileItem.name || '';
|
||||||
}
|
}
|
||||||
fileItem.local = true;
|
fileItem.local = true;
|
||||||
emit('change', _fileList);
|
emit('change', innerFileList.value, fileItem);
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// 在 emit 文件上去之后再关闭菜单
|
// 在 emit 文件上去之后再关闭菜单
|
||||||
buttonDropDownVisible.value = false;
|
buttonDropDownVisible.value = false;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<MsCard
|
<MsCard
|
||||||
:special-height="-54"
|
|
||||||
no-content-padding
|
no-content-padding
|
||||||
divider-has-p-x
|
divider-has-p-x
|
||||||
has-breadcrumb
|
has-breadcrumb
|
||||||
|
@ -22,7 +21,7 @@
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<a-form ref="formRef" :model="form" layout="vertical">
|
<a-form ref="formRef" :model="form" layout="vertical">
|
||||||
<div class="flex flex-row" style="height: calc(100vh - 224px)">
|
<div class="flex flex-row">
|
||||||
<div class="left mt-[16px] min-w-[732px] grow pl-[24px]">
|
<div class="left mt-[16px] min-w-[732px] grow pl-[24px]">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
field="title"
|
field="title"
|
||||||
|
@ -467,9 +466,24 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// 过滤出复制的附件
|
||||||
|
const copyFileList = fileList.value.filter((item) => item.isCopyFlag);
|
||||||
|
let copyFiles: { refId: string; fileId: string; local: boolean }[] = [];
|
||||||
|
if (copyFileList.length > 0) {
|
||||||
|
copyFiles = copyFileList.map((file) => {
|
||||||
|
return {
|
||||||
|
refId: file.associateId,
|
||||||
|
fileId: file.uid,
|
||||||
|
local: file.local,
|
||||||
|
bugId: bugId.value as string,
|
||||||
|
fileName: file.name,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
const tmpObj: BugEditFormObject = {
|
const tmpObj: BugEditFormObject = {
|
||||||
...form.value,
|
...form.value,
|
||||||
customFields,
|
customFields,
|
||||||
|
copyFiles,
|
||||||
};
|
};
|
||||||
if (isCopy.value) {
|
if (isCopy.value) {
|
||||||
delete tmpObj.id;
|
delete tmpObj.id;
|
||||||
|
@ -552,6 +566,7 @@
|
||||||
...fileInfo,
|
...fileInfo,
|
||||||
name: fileInfo.fileName,
|
name: fileInfo.fileName,
|
||||||
isUpdateFlag: checkUpdateFileIds.includes(fileInfo.fileId),
|
isUpdateFlag: checkUpdateFileIds.includes(fileInfo.fileId),
|
||||||
|
isCopyFlag: isCopy.value,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.map((fileInfo: any) => {
|
.map((fileInfo: any) => {
|
||||||
|
|
|
@ -20,7 +20,7 @@ export function convertToFileByBug(fileInfo: AssociatedList): MsFileItem {
|
||||||
});
|
});
|
||||||
Object.defineProperty(file, 'size', { value: fileInfo.fileSize });
|
Object.defineProperty(file, 'size', { value: fileInfo.fileSize });
|
||||||
Object.defineProperty(file, 'type', { value: type });
|
Object.defineProperty(file, 'type', { value: type });
|
||||||
const { fileId, local, isUpdateFlag, refId, createUserName, createTime } = fileInfo;
|
const { fileId, local, isUpdateFlag, isCopyFlag, refId, createUserName, createTime } = fileInfo;
|
||||||
return {
|
return {
|
||||||
enable: fileInfo.enable || false,
|
enable: fileInfo.enable || false,
|
||||||
file,
|
file,
|
||||||
|
@ -32,6 +32,7 @@ export function convertToFileByBug(fileInfo: AssociatedList): MsFileItem {
|
||||||
local,
|
local,
|
||||||
deleteContent: !local ? 'caseManagement.featureCase.cancelLink' : '',
|
deleteContent: !local ? 'caseManagement.featureCase.cancelLink' : '',
|
||||||
isUpdateFlag,
|
isUpdateFlag,
|
||||||
|
isCopyFlag,
|
||||||
associateId: refId,
|
associateId: refId,
|
||||||
createUserName,
|
createUserName,
|
||||||
uploadedTime: createTime,
|
uploadedTime: createTime,
|
||||||
|
|
Loading…
Reference in New Issue