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("/attachment/download/file/**", "anon");
|
||||||
//用例评审副文本访问
|
//用例评审副文本访问
|
||||||
filterChainDefinitionMap.put("/review/functional/case/download/file/**", "anon");
|
filterChainDefinitionMap.put("/review/functional/case/download/file/**", "anon");
|
||||||
|
//缺陷管理富文本访问
|
||||||
|
filterChainDefinitionMap.put("/bug/attachment/preview/md/**", "anon");
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/system/version/current", "anon");
|
filterChainDefinitionMap.put("/system/version/current", "anon");
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,7 @@ public class BugAttachmentController {
|
||||||
return bugAttachmentService.upgrade(request, SessionUtils.getUserId());
|
return bugAttachmentService.upgrade(request, SessionUtils.getUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 富文本相关接口
|
||||||
@PostMapping("/upload/md/file")
|
@PostMapping("/upload/md/file")
|
||||||
@Operation(summary = "缺陷管理-富文本附件-上传")
|
@Operation(summary = "缺陷管理-富文本附件-上传")
|
||||||
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_BUG_ADD, PermissionConstants.PROJECT_BUG_UPDATE})
|
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_BUG_ADD, PermissionConstants.PROJECT_BUG_UPDATE})
|
||||||
|
@ -140,11 +141,9 @@ public class BugAttachmentController {
|
||||||
return bugAttachmentService.uploadMdFile(file);
|
return bugAttachmentService.uploadMdFile(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/preview/md/compressed")
|
@GetMapping(value = "/preview/md/{projectId}/{fileId}/{compressed}")
|
||||||
@Operation(summary = "缺陷管理-富文本缩略图-预览")
|
@Operation(summary = "缺陷管理-富文本缩略图-预览")
|
||||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ)
|
public ResponseEntity<byte[]> previewMd(@PathVariable String projectId, @PathVariable String fileId, @PathVariable("compressed") boolean compressed) {
|
||||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
return bugAttachmentService.previewMd(projectId, fileId, compressed);
|
||||||
public ResponseEntity<byte[]> previewMdImg(@Validated @RequestBody BugFileSourceRequest request) {
|
|
||||||
return bugAttachmentService.downloadOrPreview(request);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,10 @@ import io.metersphere.bug.dto.request.*;
|
||||||
import io.metersphere.bug.dto.response.BugColumnsOptionDTO;
|
import io.metersphere.bug.dto.response.BugColumnsOptionDTO;
|
||||||
import io.metersphere.bug.dto.response.BugDTO;
|
import io.metersphere.bug.dto.response.BugDTO;
|
||||||
import io.metersphere.bug.dto.response.BugDetailDTO;
|
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.dto.ProjectTemplateOptionDTO;
|
||||||
import io.metersphere.project.service.ProjectApplicationService;
|
import io.metersphere.project.service.ProjectApplicationService;
|
||||||
import io.metersphere.project.service.ProjectTemplateService;
|
import io.metersphere.project.service.ProjectTemplateService;
|
||||||
|
@ -53,8 +56,6 @@ public class BugController {
|
||||||
@Resource
|
@Resource
|
||||||
private BugSyncService bugSyncService;
|
private BugSyncService bugSyncService;
|
||||||
@Resource
|
@Resource
|
||||||
private BugStatusService bugStatusService;
|
|
||||||
@Resource
|
|
||||||
private ProjectTemplateService projectTemplateService;
|
private ProjectTemplateService projectTemplateService;
|
||||||
@Resource
|
@Resource
|
||||||
private ProjectApplicationService projectApplicationService;
|
private ProjectApplicationService projectApplicationService;
|
||||||
|
|
|
@ -261,10 +261,17 @@ public class BugAttachmentService {
|
||||||
String fileId = IDGenerator.nextStr();
|
String fileId = IDGenerator.nextStr();
|
||||||
FileRequest fileRequest = new FileRequest();
|
FileRequest fileRequest = new FileRequest();
|
||||||
fileRequest.setFileName(file.getOriginalFilename());
|
fileRequest.setFileName(file.getOriginalFilename());
|
||||||
String systemTempDir = DefaultRepositoryDir.getSystemTempDir();
|
fileRequest.setFolder(DefaultRepositoryDir.getSystemTempDir() + "/" + fileId);
|
||||||
fileRequest.setFolder(systemTempDir + "/" + fileId);
|
|
||||||
try {
|
try {
|
||||||
FileCenter.getDefaultRepository().saveFile(file, fileRequest);
|
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) {
|
} catch (Exception e) {
|
||||||
LogUtils.error(e);
|
LogUtils.error(e);
|
||||||
throw new MSException(e.getMessage());
|
throw new MSException(e.getMessage());
|
||||||
|
@ -625,7 +632,7 @@ public class BugAttachmentService {
|
||||||
* @param source 文件来源
|
* @param source 文件来源
|
||||||
*/
|
*/
|
||||||
public void transferTmpFile(String bugId, String projectId, List<String> uploadFileIds, String userId, String 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;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
String fileId = IDGenerator.nextStr();
|
String fileId = IDGenerator.nextStr();
|
||||||
|
// 第三方平台的图片下载命名为平台名称+随机数字
|
||||||
|
String fileName = updateBug.getPlatform() + "-" + IDGenerator.nextNum() + ".jpg";
|
||||||
byte[] bytes;
|
byte[] bytes;
|
||||||
try {
|
try {
|
||||||
// upload platform attachment to minio
|
// upload platform attachment to minio
|
||||||
bytes = in.readAllBytes();
|
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) {
|
} catch (Exception e) {
|
||||||
throw new MSException(e.getMessage());
|
throw new MSException(e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -1277,14 +1280,14 @@ public class BugService {
|
||||||
localAttachment.setId(IDGenerator.nextStr());
|
localAttachment.setId(IDGenerator.nextStr());
|
||||||
localAttachment.setBugId(updateBug.getId());
|
localAttachment.setBugId(updateBug.getId());
|
||||||
localAttachment.setFileId(fileId);
|
localAttachment.setFileId(fileId);
|
||||||
localAttachment.setFileName("image.png");
|
localAttachment.setFileName(fileName);
|
||||||
localAttachment.setSize((long) bytes.length);
|
localAttachment.setSize((long) bytes.length);
|
||||||
localAttachment.setCreateTime(System.currentTimeMillis());
|
localAttachment.setCreateTime(System.currentTimeMillis());
|
||||||
localAttachment.setCreateUser("admin");
|
localAttachment.setCreateUser("admin");
|
||||||
localAttachment.setSource(BugAttachmentSourceType.RICH_TEXT.name());
|
localAttachment.setSource(BugAttachmentSourceType.RICH_TEXT.name());
|
||||||
bugLocalAttachmentMapper.insert(localAttachment);
|
bugLocalAttachmentMapper.insert(localAttachment);
|
||||||
// 替换富文本中的临时URL
|
// 替换富文本中的临时URL为预览URL
|
||||||
updateBug.setDescription(updateBug.getDescription().replace("alt=\"" + key + "\"", "src=\"/attachment/download/file/" + updateBug.getProjectId() + "/" + fileId + "/true\""));
|
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_CHECK_UPDATE = "/bug/attachment/check-update";
|
||||||
public static final String BUG_ATTACHMENT_UPDATE = "/bug/attachment/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_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
|
@Test
|
||||||
@Order(0)
|
@Order(0)
|
||||||
|
@ -61,12 +61,7 @@ public class BugAttachmentControllerTests extends BaseTest {
|
||||||
// Mock minio save file exception
|
// Mock minio save file exception
|
||||||
MockMultipartFile file = new MockMultipartFile("file", "test.txt", MediaType.APPLICATION_OCTET_STREAM_VALUE, "aa".getBytes());
|
MockMultipartFile file = new MockMultipartFile("file", "test.txt", MediaType.APPLICATION_OCTET_STREAM_VALUE, "aa".getBytes());
|
||||||
this.requestUploadFile(BUG_ATTACHMENT_UPLOAD_MD, file);
|
this.requestUploadFile(BUG_ATTACHMENT_UPLOAD_MD, file);
|
||||||
BugFileSourceRequest request = new BugFileSourceRequest();
|
this.requestGetDownloadFile(BUG_ATTACHMENT_PREVIEW_MD + "/default-project-for-attachment/not-exist-file-id/true", null);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -33,6 +33,11 @@ export default mergeConfig(
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path: string) => path.replace(/^\/front\/attachment/, ''),
|
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': {
|
'/plugin/image': {
|
||||||
target: 'http://172.16.200.18:8081/',
|
target: 'http://172.16.200.18:8081/',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
|
|
Loading…
Reference in New Issue