refactor(系统设置): 优化svg图片预览图的传输模式

This commit is contained in:
song-tianyang 2023-11-20 17:29:47 +08:00 committed by Craftsman
parent 1ecf35b325
commit 3c26e9e432
11 changed files with 59 additions and 42 deletions

View File

@ -6,9 +6,9 @@ public class ModuleConstants {
//没有父类的节点parent_id为NONE //没有父类的节点parent_id为NONE
public static final String ROOT_NODE_PARENT_ID = "NONE"; public static final String ROOT_NODE_PARENT_ID = "NONE";
//默认节点类型 //默认节点类型
public static final String NODE_TYPE_DEFAULT = "module"; public static final String NODE_TYPE_DEFAULT = "MODULE";
//Git节点类型 //Git节点类型
public static final String NODE_TYPE_GIT = "git"; public static final String NODE_TYPE_GIT = "GIT";
//GitHub节点类型 //GitHub节点类型
public static final String NODE_TYPE_GITHUB = "Github"; public static final String NODE_TYPE_GITHUB = "Github";
//Gitee节点类型 //Gitee节点类型

View File

@ -5,7 +5,7 @@
SELECT id, SELECT id,
NAME, NAME,
parent_id AS parentId, parent_id AS parentId,
'module' AS type 'MODULE' AS type
FROM api_debug_module FROM api_debug_module
WHERE protocol = #{protocol} WHERE protocol = #{protocol}
AND create_user = #{userId} AND create_user = #{userId}
@ -64,7 +64,7 @@
SELECT id, SELECT id,
NAME, NAME,
module_id AS parentId, module_id AS parentId,
'api' AS type, 'API' AS type,
method method
FROM api_debug FROM api_debug
WHERE protocol = #{protocol} WHERE protocol = #{protocol}
@ -107,7 +107,7 @@
SELECT id, SELECT id,
NAME, NAME,
parent_id AS parentId, parent_id AS parentId,
'module' AS type 'MODULE' AS type
FROM api_debug_module FROM api_debug_module
WHERE id IN WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")"> <foreach collection="ids" item="id" open="(" separator="," close=")">

View File

@ -53,7 +53,7 @@
SELECT id, SELECT id,
NAME, NAME,
module_id AS parentId, module_id AS parentId,
'api' AS type, 'API' AS type,
method method
FROM api_definition FROM api_definition
<include refid="api_request"/> <include refid="api_request"/>
@ -95,7 +95,7 @@
m.name, m.name,
m.pos, m.pos,
m.project_id, m.project_id,
'module' AS type 'MODULE' AS type
FROM api_definition_module m FROM api_definition_module m
<include refid="module_request"/> <include refid="module_request"/>
ORDER BY pos ORDER BY pos
@ -106,7 +106,7 @@
m.name, m.name,
m.pos, m.pos,
m.project_id, m.project_id,
'module' AS type 'MODULE' AS type
FROM api_definition_module m FROM api_definition_module m
WHERE m.id IN WHERE m.id IN
<foreach collection="ids" item="id" open="(" separator="," close=")"> <foreach collection="ids" item="id" open="(" separator="," close=")">

View File

@ -54,8 +54,6 @@ public class ApiDefinitionModuleService extends ModuleTreeService {
private ExtApiTestCaseMapper extApiTestCaseMapper; private ExtApiTestCaseMapper extApiTestCaseMapper;
@Resource @Resource
private ApiTestCaseService apiTestCaseService; private ApiTestCaseService apiTestCaseService;
@Resource
private ApiTestCaseLogService apiTestCaseLogService;
public List<BaseTreeNode> getTree(ApiModuleRequest request) { public List<BaseTreeNode> getTree(ApiModuleRequest request) {
//接口的树结构是 模块子模块+接口 接口为非delete状态的 //接口的树结构是 模块子模块+接口 接口为非delete状态的

View File

@ -47,9 +47,6 @@ public class ApiTestCaseService {
public static final Long ORDER_STEP = 5000L; public static final Long ORDER_STEP = 5000L;
private static final String MAIN_FOLDER_PROJECT = "project";
private static final String APP_NAME_API_CASE = "apiCase";
public static final String PRIORITY = "Priority"; public static final String PRIORITY = "Priority";
public static final String STATUS = "Status"; public static final String STATUS = "Status";
public static final String TAGS = "Tags"; public static final String TAGS = "Tags";

View File

@ -10,7 +10,7 @@ import java.util.List;
public interface ExtFileModuleMapper { public interface ExtFileModuleMapper {
List<BaseTreeNode> selectBaseByProjectId(@Param("projectId") String projectId, @Param("moduleType") String moduleType); List<BaseTreeNode> selectBaseByProjectId(@Param("projectId") String projectId, @Param("moduleType") String moduleType);
List<BaseTreeNode> selectIdAndParentIdByProjectId(String projectId); List<BaseTreeNode> selectIdAndParentIdByProjectId(@Param("projectId") String projectId, @Param("storage") String storage);
List<String> selectChildrenIdsByParentIds(@Param("ids") List<String> deleteIds); List<String> selectChildrenIdsByParentIds(@Param("ids") List<String> deleteIds);

View File

@ -11,7 +11,14 @@
<select id="selectIdAndParentIdByProjectId" resultType="io.metersphere.system.dto.sdk.BaseTreeNode"> <select id="selectIdAndParentIdByProjectId" resultType="io.metersphere.system.dto.sdk.BaseTreeNode">
SELECT id, parent_id AS parentId SELECT id, parent_id AS parentId
FROM file_module FROM file_module
WHERE project_id = #{0} WHERE project_id = #{projectId}
<if test="storage == 'MINIO'">
AND module_type = 'MODULE'
</if>
<if test="storage == 'GIT'">
AND module_type = 'GIT'
</if>
</select> </select>
<select id="selectIdsByProjectId" resultType="java.lang.String"> <select id="selectIdsByProjectId" resultType="java.lang.String">
SELECT id SELECT id

View File

@ -465,7 +465,7 @@ public class FileMetadataService {
FileManagementQuery pageDTO = new FileManagementQuery(request); FileManagementQuery pageDTO = new FileManagementQuery(request);
pageDTO.setModuleIds(null); pageDTO.setModuleIds(null);
List<ModuleCountDTO> moduleCountDTOList = extFileMetadataMapper.countModuleIdByKeywordAndFileType(pageDTO); List<ModuleCountDTO> moduleCountDTOList = extFileMetadataMapper.countModuleIdByKeywordAndFileType(pageDTO);
Map<String, Long> moduleCountMap = fileModuleService.getModuleCountMap(request.getProjectId(), moduleCountDTOList); Map<String, Long> moduleCountMap = fileModuleService.getModuleCountMap(request.getProjectId(), pageDTO.getStorage(), moduleCountDTOList);
//查出全部文件和我的文件的数量 //查出全部文件和我的文件的数量
FileManagementQuery myFileCountDTO = new FileManagementQuery(); FileManagementQuery myFileCountDTO = new FileManagementQuery();
@ -480,26 +480,27 @@ public class FileMetadataService {
public ResponseEntity<byte[]> downloadPreviewImgById(String id) throws Exception { public ResponseEntity<byte[]> downloadPreviewImgById(String id) throws Exception {
FileMetadata fileMetadata = fileMetadataMapper.selectByPrimaryKey(id); FileMetadata fileMetadata = fileMetadataMapper.selectByPrimaryKey(id);
String previewImgPath = null; byte[] bytes = new byte[]{};
if (StringUtils.equalsIgnoreCase(fileMetadata.getType(), "svg")) {
return this.downloadById(id); MediaType contentType = MediaType.parseMediaType("application/octet-stream");
} else if (TempFileUtils.isImage(fileMetadata.getType())) { if (TempFileUtils.isImage(fileMetadata.getType())) {
if (TempFileUtils.isImgPreviewFileExists(fileMetadata.getId())) { if (StringUtils.equalsIgnoreCase(fileMetadata.getType(), "svg")) {
previewImgPath = TempFileUtils.getPreviewImgFilePath(fileMetadata.getId()); //svg图片不压缩
contentType = MediaType.parseMediaType("image/svg+xml");
bytes = this.getFileByte(fileMetadata);
} else if (TempFileUtils.isImgPreviewFileExists(fileMetadata.getId())) {
//获取压缩过的图片
bytes = TempFileUtils.getFile(TempFileUtils.getPreviewImgFilePath(fileMetadata.getId()));
} else { } else {
previewImgPath = TempFileUtils.catchCompressImgIfNotExists(fileMetadata.getId(), this.getFile(fileMetadata)); //压缩图片并保存在临时文件夹中
bytes = TempFileUtils.getFile(
TempFileUtils.catchCompressImgIfNotExists(fileMetadata.getId(), this.getFile(fileMetadata))
);
} }
} }
byte[] bytes;
if (StringUtils.isNotBlank(previewImgPath)) {
bytes = TempFileUtils.getFile(previewImgPath);
} else {
bytes = new byte[]{};
}
return ResponseEntity.ok() return ResponseEntity.ok()
.contentType(MediaType.parseMediaType("application/octet-stream")) .contentType(contentType)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + this.getFileName(fileMetadata.getId(), fileMetadata.getType()) + "\"") .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + this.getFileName(fileMetadata.getId(), fileMetadata.getType()) + "\"")
.body(bytes); .body(bytes);
} }

View File

@ -54,9 +54,9 @@ public class FileModuleService extends ModuleTreeService implements CleanupProje
return super.buildTreeAndCountResource(fileModuleList, true, Translator.get("default.module")); return super.buildTreeAndCountResource(fileModuleList, true, Translator.get("default.module"));
} }
public List<BaseTreeNode> getTreeOnlyIdsAndResourceCount(String projectId, List<ModuleCountDTO> moduleCountDTOList) { public List<BaseTreeNode> getTreeOnlyIdsAndResourceCount(String projectId, String storage, List<ModuleCountDTO> moduleCountDTOList) {
//节点内容只有Id和parentId //节点内容只有Id和parentId
List<BaseTreeNode> fileModuleList = extFileModuleMapper.selectIdAndParentIdByProjectId(projectId); List<BaseTreeNode> fileModuleList = extFileModuleMapper.selectIdAndParentIdByProjectId(projectId, storage);
return super.buildTreeAndCountResource(fileModuleList, moduleCountDTOList, true, Translator.get("default.module")); return super.buildTreeAndCountResource(fileModuleList, moduleCountDTOList, true, Translator.get("default.module"));
} }
@ -192,10 +192,10 @@ public class FileModuleService extends ModuleTreeService implements CleanupProje
* 查找当前项目下模块每个节点对应的资源统计 * 查找当前项目下模块每个节点对应的资源统计
* *
*/ */
public Map<String, Long> getModuleCountMap(String projectId, List<ModuleCountDTO> moduleCountDTOList) { public Map<String, Long> getModuleCountMap(String projectId, String storage, List<ModuleCountDTO> moduleCountDTOList) {
//构建模块树并计算每个节点下的所有数量包含子节点 //构建模块树并计算每个节点下的所有数量包含子节点
List<BaseTreeNode> treeNodeList = this.getTreeOnlyIdsAndResourceCount(projectId, moduleCountDTOList); List<BaseTreeNode> treeNodeList = this.getTreeOnlyIdsAndResourceCount(projectId, storage, moduleCountDTOList);
//通过广度遍历的方式构建返回值 //通过广度遍历的方式构建返回值
return super.getIdCountMapByBreadth(treeNodeList); return super.getIdCountMapByBreadth(treeNodeList);
} }

View File

@ -57,6 +57,7 @@ public abstract class ModuleTreeService {
int lastSize = 0; int lastSize = 0;
Map<String, BaseTreeNode> baseTreeNodeMap = new HashMap<>(); Map<String, BaseTreeNode> baseTreeNodeMap = new HashMap<>();
while (CollectionUtils.isNotEmpty(traverseList) && traverseList.size() != lastSize) { while (CollectionUtils.isNotEmpty(traverseList) && traverseList.size() != lastSize) {
lastSize = traverseList.size();
List<BaseTreeNode> notMatchedList = new ArrayList<>(); List<BaseTreeNode> notMatchedList = new ArrayList<>();
for (BaseTreeNode treeNode : traverseList) { for (BaseTreeNode treeNode : traverseList) {
if (StringUtils.equalsIgnoreCase(treeNode.getParentId(), ModuleConstants.ROOT_NODE_PARENT_ID)) { if (StringUtils.equalsIgnoreCase(treeNode.getParentId(), ModuleConstants.ROOT_NODE_PARENT_ID)) {
@ -75,11 +76,6 @@ public abstract class ModuleTreeService {
} }
traverseList = notMatchedList; traverseList = notMatchedList;
} }
//剩余的节点没有匹配上直接放到根节点下
traverseList.forEach(treeNode -> {
BaseTreeNode node = new BaseTreeNode(treeNode.getId(), treeNode.getName(), ModuleConstants.NODE_TYPE_DEFAULT, treeNode.getParentId());
baseTreeNodeMap.get(treeNode.getParentId()).addChild(node);
});
return baseTreeNodeList; return baseTreeNodeList;
} }

View File

@ -919,7 +919,13 @@ public class FileManagementControllerTests extends BaseTest {
for (FileInformationResponse fileDTO : fileList) { for (FileInformationResponse fileDTO : fileList) {
MvcResult originalResult = this.downloadFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_ORIGINAL, "admin", fileDTO.getId())); MvcResult originalResult = this.downloadFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_ORIGINAL, "admin", fileDTO.getId()));
Assertions.assertTrue(originalResult.getResponse().getContentAsByteArray().length > 0); Assertions.assertTrue(originalResult.getResponse().getContentAsByteArray().length > 0);
MvcResult compressedResult = this.downloadFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_COMPRESSED, "admin", fileDTO.getId())); MvcResult compressedResult;
if (StringUtils.equalsIgnoreCase(fileDTO.getFileType(), "svg")) {
compressedResult = this.downloadSvgFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_COMPRESSED, "admin", fileDTO.getId()));
} else {
compressedResult = this.downloadFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_COMPRESSED, "admin", fileDTO.getId()));
}
byte[] fileBytes = compressedResult.getResponse().getContentAsByteArray(); byte[] fileBytes = compressedResult.getResponse().getContentAsByteArray();
if (TempFileUtils.isImage(fileDTO.getFileType())) { if (TempFileUtils.isImage(fileDTO.getFileType())) {
if (StringUtils.equals(reUploadFileId, fileDTO.getId())) { if (StringUtils.equals(reUploadFileId, fileDTO.getId())) {
@ -936,7 +942,13 @@ public class FileManagementControllerTests extends BaseTest {
for (FileInformationResponse fileDTO : fileList) { for (FileInformationResponse fileDTO : fileList) {
MvcResult originalResult = this.downloadFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_ORIGINAL, "admin", fileDTO.getId())); MvcResult originalResult = this.downloadFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_ORIGINAL, "admin", fileDTO.getId()));
Assertions.assertTrue(originalResult.getResponse().getContentAsByteArray().length > 0); Assertions.assertTrue(originalResult.getResponse().getContentAsByteArray().length > 0);
MvcResult compressedResult = this.downloadFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_COMPRESSED, "admin", fileDTO.getId()));
MvcResult compressedResult;
if (StringUtils.equalsIgnoreCase(fileDTO.getFileType(), "svg")) {
compressedResult = this.downloadSvgFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_COMPRESSED, "admin", fileDTO.getId()));
} else {
compressedResult = this.downloadFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_COMPRESSED, "admin", fileDTO.getId()));
}
byte[] fileBytes = compressedResult.getResponse().getContentAsByteArray(); byte[] fileBytes = compressedResult.getResponse().getContentAsByteArray();
if (TempFileUtils.isImage(fileDTO.getFileType())) { if (TempFileUtils.isImage(fileDTO.getFileType())) {
if (StringUtils.equals(reUploadFileId, fileDTO.getId())) { if (StringUtils.equals(reUploadFileId, fileDTO.getId())) {
@ -2068,6 +2080,12 @@ public class FileManagementControllerTests extends BaseTest {
.andReturn(); .andReturn();
} }
protected MvcResult downloadSvgFile(String url, Object... uriVariables) throws Exception {
return mockMvc.perform(getRequestBuilder(url, uriVariables))
.andExpect(content().contentType(MediaType.valueOf("image/svg+xml")))
.andExpect(status().isOk()).andReturn();
}
protected MvcResult downloadFile(String url, Object... uriVariables) throws Exception { protected MvcResult downloadFile(String url, Object... uriVariables) throws Exception {
return mockMvc.perform(getRequestBuilder(url, uriVariables)) return mockMvc.perform(getRequestBuilder(url, uriVariables))
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM_VALUE)) .andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM_VALUE))