refactor(缺陷管理): 富文本图片预览问题
This commit is contained in:
parent
e309ea7261
commit
7791b800a4
|
@ -34,6 +34,8 @@ public class FilterChainUtils {
|
|||
filterChainDefinitionMap.put("/attachment/download/file/**", "anon");
|
||||
//用例评审副文本访问
|
||||
filterChainDefinitionMap.put("/review/functional/case/download/file/**", "anon");
|
||||
//缺陷管理富文本访问
|
||||
filterChainDefinitionMap.put("/bug/attachment/preview/md/**", "anon");
|
||||
|
||||
filterChainDefinitionMap.put("/system/version/current", "anon");
|
||||
|
||||
|
|
|
@ -133,6 +133,7 @@ public class BugAttachmentController {
|
|||
return bugAttachmentService.upgrade(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
// 富文本相关接口
|
||||
@PostMapping("/upload/md/file")
|
||||
@Operation(summary = "缺陷管理-富文本附件-上传")
|
||||
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_BUG_ADD, PermissionConstants.PROJECT_BUG_UPDATE})
|
||||
|
@ -140,11 +141,9 @@ public class BugAttachmentController {
|
|||
return bugAttachmentService.uploadMdFile(file);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/preview/md/compressed")
|
||||
@GetMapping(value = "/preview/md/{projectId}/{fileId}/{compressed}")
|
||||
@Operation(summary = "缺陷管理-富文本缩略图-预览")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ)
|
||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||
public ResponseEntity<byte[]> previewMdImg(@Validated @RequestBody BugFileSourceRequest request) {
|
||||
return bugAttachmentService.downloadOrPreview(request);
|
||||
public ResponseEntity<byte[]> previewMd(@PathVariable String projectId, @PathVariable String fileId, @PathVariable("compressed") boolean compressed) {
|
||||
return bugAttachmentService.previewMd(projectId, fileId, compressed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,10 @@ import io.metersphere.bug.dto.request.*;
|
|||
import io.metersphere.bug.dto.response.BugColumnsOptionDTO;
|
||||
import io.metersphere.bug.dto.response.BugDTO;
|
||||
import io.metersphere.bug.dto.response.BugDetailDTO;
|
||||
import io.metersphere.bug.service.*;
|
||||
import io.metersphere.bug.service.BugLogService;
|
||||
import io.metersphere.bug.service.BugNoticeService;
|
||||
import io.metersphere.bug.service.BugService;
|
||||
import io.metersphere.bug.service.BugSyncService;
|
||||
import io.metersphere.project.dto.ProjectTemplateOptionDTO;
|
||||
import io.metersphere.project.service.ProjectApplicationService;
|
||||
import io.metersphere.project.service.ProjectTemplateService;
|
||||
|
@ -53,8 +56,6 @@ public class BugController {
|
|||
@Resource
|
||||
private BugSyncService bugSyncService;
|
||||
@Resource
|
||||
private BugStatusService bugStatusService;
|
||||
@Resource
|
||||
private ProjectTemplateService projectTemplateService;
|
||||
@Resource
|
||||
private ProjectApplicationService projectApplicationService;
|
||||
|
|
|
@ -261,10 +261,17 @@ public class BugAttachmentService {
|
|||
String fileId = IDGenerator.nextStr();
|
||||
FileRequest fileRequest = new FileRequest();
|
||||
fileRequest.setFileName(file.getOriginalFilename());
|
||||
String systemTempDir = DefaultRepositoryDir.getSystemTempDir();
|
||||
fileRequest.setFolder(systemTempDir + "/" + fileId);
|
||||
fileRequest.setFolder(DefaultRepositoryDir.getSystemTempDir() + "/" + fileId);
|
||||
try {
|
||||
FileCenter.getDefaultRepository().saveFile(file, fileRequest);
|
||||
String fileType = StringUtils.substring(fileName, fileName.lastIndexOf(".") + 1);
|
||||
if (TempFileUtils.isImage(fileType)) {
|
||||
//图片文件自动生成预览图
|
||||
byte[] previewImg = TempFileUtils.compressPic(file.getBytes());
|
||||
fileRequest.setFolder(DefaultRepositoryDir.getSystemTempCompressDir() + "/" + fileId);
|
||||
fileRequest.setStorage(StorageType.MINIO.toString());
|
||||
fileService.upload(previewImg, fileRequest);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.error(e);
|
||||
throw new MSException(e.getMessage());
|
||||
|
@ -625,7 +632,7 @@ public class BugAttachmentService {
|
|||
* @param source 文件来源
|
||||
*/
|
||||
public void transferTmpFile(String bugId, String projectId, List<String> uploadFileIds, String userId, String source) {
|
||||
if (org.apache.commons.collections.CollectionUtils.isEmpty(uploadFileIds)) {
|
||||
if (CollectionUtils.isEmpty(uploadFileIds)) {
|
||||
return;
|
||||
}
|
||||
//过滤已上传过的
|
||||
|
@ -741,4 +748,85 @@ public class BugAttachmentService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ResponseEntity<byte[]> previewMd(String projectId, String fileId, boolean compressed) {
|
||||
byte[] bytes;
|
||||
String fileName;
|
||||
BugLocalAttachmentExample example = new BugLocalAttachmentExample();
|
||||
example.createCriteria().andFileIdEqualTo(fileId);
|
||||
List<BugLocalAttachment> bugAttachments = bugLocalAttachmentMapper.selectByExample(example);
|
||||
if (CollectionUtils.isEmpty(bugAttachments)) {
|
||||
//在临时文件获取
|
||||
fileName = getTempFileNameByFileId(fileId);
|
||||
bytes = getPreviewImg(fileName, fileId, compressed);
|
||||
} else {
|
||||
//在正式目录获取
|
||||
BugLocalAttachment attachment = bugAttachments.get(0);
|
||||
fileName = attachment.getFileName();
|
||||
FileRequest fileRequest = new FileRequest();
|
||||
fileRequest.setFileName(attachment.getFileName());
|
||||
if (compressed) {
|
||||
fileRequest.setFolder(DefaultRepositoryDir.getBugPreviewDir(projectId, attachment.getBugId()) + "/" + attachment.getFileId());
|
||||
} else {
|
||||
fileRequest.setFolder(DefaultRepositoryDir.getBugDir(projectId, attachment.getBugId()) + "/" + attachment.getFileId());
|
||||
}
|
||||
fileRequest.setStorage(StorageType.MINIO.name());
|
||||
try {
|
||||
bytes = fileService.download(fileRequest);
|
||||
} catch (Exception e) {
|
||||
throw new MSException("get file error");
|
||||
}
|
||||
}
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.parseMediaType("application/octet-stream"))
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
|
||||
.body(bytes);
|
||||
}
|
||||
|
||||
public byte[] getPreviewImg(String fileName, String fileId, boolean isCompressed) {
|
||||
String systemTempDir;
|
||||
if (isCompressed) {
|
||||
systemTempDir = DefaultRepositoryDir.getSystemTempCompressDir();
|
||||
} else {
|
||||
systemTempDir = DefaultRepositoryDir.getSystemTempDir();
|
||||
}
|
||||
FileRequest previewRequest = new FileRequest();
|
||||
previewRequest.setFileName(fileName);
|
||||
previewRequest.setStorage(StorageType.MINIO.name());
|
||||
previewRequest.setFolder(systemTempDir + "/" + fileId);
|
||||
byte[] previewImg = null;
|
||||
try {
|
||||
previewImg = fileService.download(previewRequest);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("获取预览图失败:{}", e);
|
||||
}
|
||||
|
||||
if (previewImg == null || previewImg.length == 0) {
|
||||
try {
|
||||
if (isCompressed) {
|
||||
previewImg = this.compressPicWithFileMetadata(fileName, fileId);
|
||||
previewRequest.setFolder(DefaultRepositoryDir.getSystemTempCompressDir() + "/" + fileId);
|
||||
fileService.upload(previewImg, previewRequest);
|
||||
}
|
||||
return previewImg;
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("获取预览图失败:{}", e);
|
||||
}
|
||||
}
|
||||
return previewImg;
|
||||
}
|
||||
|
||||
//获取文件并压缩的方法需要上锁,防止并发超过一定数量时内存溢出
|
||||
private synchronized byte[] compressPicWithFileMetadata(String fileName, String fileId) throws Exception {
|
||||
byte[] fileBytes = this.getFile(fileName, fileId);
|
||||
return TempFileUtils.compressPic(fileBytes);
|
||||
}
|
||||
|
||||
public byte[] getFile(String fileName, String fileId) throws Exception {
|
||||
FileRequest fileRequest = new FileRequest();
|
||||
fileRequest.setFileName(fileName);
|
||||
fileRequest.setFolder(DefaultRepositoryDir.getSystemTempDir() + "/" + fileId);
|
||||
fileRequest.setStorage(StorageType.MINIO.name());
|
||||
return fileService.download(fileRequest);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1264,11 +1264,14 @@ public class BugService {
|
|||
return;
|
||||
}
|
||||
String fileId = IDGenerator.nextStr();
|
||||
// 第三方平台的图片下载命名为平台名称+随机数字
|
||||
String fileName = updateBug.getPlatform() + "-" + IDGenerator.nextNum() + ".jpg";
|
||||
byte[] bytes;
|
||||
try {
|
||||
// upload platform attachment to minio
|
||||
bytes = in.readAllBytes();
|
||||
FileCenter.getDefaultRepository().saveFile(bytes, buildBugFileRequest(updateBug.getProjectId(), updateBug.getId(), fileId, "image.png"));
|
||||
// 第三方平台下载的图片默认不压缩
|
||||
FileCenter.getDefaultRepository().saveFile(bytes, buildBugFileRequest(updateBug.getProjectId(), updateBug.getId(), fileId, fileName));
|
||||
} catch (Exception e) {
|
||||
throw new MSException(e.getMessage());
|
||||
}
|
||||
|
@ -1277,14 +1280,14 @@ public class BugService {
|
|||
localAttachment.setId(IDGenerator.nextStr());
|
||||
localAttachment.setBugId(updateBug.getId());
|
||||
localAttachment.setFileId(fileId);
|
||||
localAttachment.setFileName("image.png");
|
||||
localAttachment.setFileName(fileName);
|
||||
localAttachment.setSize((long) bytes.length);
|
||||
localAttachment.setCreateTime(System.currentTimeMillis());
|
||||
localAttachment.setCreateUser("admin");
|
||||
localAttachment.setSource(BugAttachmentSourceType.RICH_TEXT.name());
|
||||
bugLocalAttachmentMapper.insert(localAttachment);
|
||||
// 替换富文本中的临时URL
|
||||
updateBug.setDescription(updateBug.getDescription().replace("alt=\"" + key + "\"", "src=\"/attachment/download/file/" + updateBug.getProjectId() + "/" + fileId + "/true\""));
|
||||
// 替换富文本中的临时URL为预览URL
|
||||
updateBug.setDescription(updateBug.getDescription().replace("alt=\"" + key + "\"", "src=\"/bug/attachment/preview/md/" + updateBug.getProjectId() + "/" + fileId + "/false\""));
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public class BugAttachmentControllerTests extends BaseTest {
|
|||
public static final String BUG_ATTACHMENT_CHECK_UPDATE = "/bug/attachment/check-update";
|
||||
public static final String BUG_ATTACHMENT_UPDATE = "/bug/attachment/update";
|
||||
public static final String BUG_ATTACHMENT_UPLOAD_MD = "/bug/attachment/upload/md/file";
|
||||
public static final String BUG_ATTACHMENT_PREVIEW_MD = "/bug/attachment/preview/md/compressed";
|
||||
public static final String BUG_ATTACHMENT_PREVIEW_MD = "/bug/attachment/preview/md";
|
||||
|
||||
@Test
|
||||
@Order(0)
|
||||
|
@ -61,12 +61,7 @@ public class BugAttachmentControllerTests extends BaseTest {
|
|||
// Mock minio save file exception
|
||||
MockMultipartFile file = new MockMultipartFile("file", "test.txt", MediaType.APPLICATION_OCTET_STREAM_VALUE, "aa".getBytes());
|
||||
this.requestUploadFile(BUG_ATTACHMENT_UPLOAD_MD, file);
|
||||
BugFileSourceRequest request = new BugFileSourceRequest();
|
||||
request.setBugId("default-attachment-bug-id");
|
||||
request.setProjectId("default-project-for-attachment");
|
||||
request.setAssociated(false);
|
||||
request.setFileId("not-exist-file-id");
|
||||
this.requestPostDownloadFile(BUG_ATTACHMENT_PREVIEW_MD, null, request);
|
||||
this.requestGetDownloadFile(BUG_ATTACHMENT_PREVIEW_MD + "/default-project-for-attachment/not-exist-file-id/true", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -33,6 +33,11 @@ export default mergeConfig(
|
|||
changeOrigin: true,
|
||||
rewrite: (path: string) => path.replace(/^\/front\/attachment/, ''),
|
||||
},
|
||||
'/bug/attachment': {
|
||||
target: 'http://172.16.200.18:8081/',
|
||||
changeOrigin: true,
|
||||
rewrite: (path: string) => path.replace(/^\/front\/bug\/attachment/, ''),
|
||||
},
|
||||
'/plugin/image': {
|
||||
target: 'http://172.16.200.18:8081/',
|
||||
changeOrigin: true,
|
||||
|
|
Loading…
Reference in New Issue