|
@@ -5,25 +5,23 @@ import com.jzg.commons.core.base.BaseController;
|
|
|
import com.jzg.commons.core.page.HttpResult;
|
|
import com.jzg.commons.core.page.HttpResult;
|
|
|
import com.jzg.commons.entity.po.SysUploadFiles;
|
|
import com.jzg.commons.entity.po.SysUploadFiles;
|
|
|
import com.jzg.commons.exception.SystemException;
|
|
import com.jzg.commons.exception.SystemException;
|
|
|
-import com.jzg.commons.request.RequestSingleParam;
|
|
|
|
|
import com.jzg.commons.util.FileUtils;
|
|
import com.jzg.commons.util.FileUtils;
|
|
|
|
|
+import com.jzg.commons.util.ImageUtil;
|
|
|
import com.jzg.commons.util.MinioUtils;
|
|
import com.jzg.commons.util.MinioUtils;
|
|
|
import com.jzg.commons.util.idgen.IdGenerate;
|
|
import com.jzg.commons.util.idgen.IdGenerate;
|
|
|
import com.jzg.mapper.SysUploadFilesMapper;
|
|
import com.jzg.mapper.SysUploadFilesMapper;
|
|
|
import io.minio.*;
|
|
import io.minio.*;
|
|
|
import io.swagger.v3.oas.annotations.Operation;
|
|
import io.swagger.v3.oas.annotations.Operation;
|
|
|
|
|
+import org.jetbrains.annotations.NotNull;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
|
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
|
import java.io.InputStream;
|
|
import java.io.InputStream;
|
|
|
-import java.net.MalformedURLException;
|
|
|
|
|
-import java.net.URI;
|
|
|
|
|
-import java.net.URL;
|
|
|
|
|
-import java.net.URLConnection;
|
|
|
|
|
-import java.net.URLEncoder;
|
|
|
|
|
|
|
+import java.net.*;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.charset.StandardCharsets;
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
|
|
|
|
@@ -47,24 +45,60 @@ public class FileUploadController extends BaseController {
|
|
|
private String bucketName;
|
|
private String bucketName;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 文件上传接口
|
|
|
|
|
+ * 支持图片自动压缩:上传图片时先判断类型,若是图片则进行尺寸和质量压缩后再上传
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param file 上传的文件
|
|
|
|
|
+ * @return 上传结果,包含文件信息和下载链接
|
|
|
|
|
+ */
|
|
|
@PostMapping("/upload")
|
|
@PostMapping("/upload")
|
|
|
- @Operation(summary = "文件上传接口", description = "文件上传接口")
|
|
|
|
|
|
|
+ @Operation(summary = "文件上传接口", description = "文件上传接口,图片自动压缩")
|
|
|
public HttpResult uploadFile(@RequestParam("file") MultipartFile file) {
|
|
public HttpResult uploadFile(@RequestParam("file") MultipartFile file) {
|
|
|
System.out.printf("调用文件上传接口");
|
|
System.out.printf("调用文件上传接口");
|
|
|
try {
|
|
try {
|
|
|
// 获取文件原始名称和扩展名
|
|
// 获取文件原始名称和扩展名
|
|
|
String originalFileName = file.getOriginalFilename();
|
|
String originalFileName = file.getOriginalFilename();
|
|
|
String extension = getFileExtension(originalFileName);
|
|
String extension = getFileExtension(originalFileName);
|
|
|
- // MD5,ETag
|
|
|
|
|
- String fileMd5 = FileUtils.getFileMD5(file);
|
|
|
|
|
- String objectName = generateObjectName(originalFileName, fileMd5, extension);
|
|
|
|
|
- String fileEtag = FileUtils.getFileETag(file);
|
|
|
|
|
- // 查找文件是否已经存在于MinIO
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 判断是否为图片文件,若是则进行压缩
|
|
|
|
|
+ // 双重校验:通过 Content-Type 和文件扩展名判断
|
|
|
|
|
+ byte[] compressedBytes = null;
|
|
|
|
|
+ if (ImageUtil.isImage(file.getContentType()) || ImageUtil.isImageExtension(extension)) {
|
|
|
|
|
+ compressedBytes = ImageUtil.compressImage(file);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 根据是否压缩成功,计算文件的 MD5 和 ETag
|
|
|
|
|
+ // 注意:MD5/ETag 必须基于最终上传的文件内容计算,确保与 MinIO 存储一致
|
|
|
|
|
+ String fileMd5;
|
|
|
|
|
+ String fileEtag;
|
|
|
|
|
+ String objectName;
|
|
|
|
|
+
|
|
|
|
|
+ if (compressedBytes != null && compressedBytes.length > 0) {
|
|
|
|
|
+ // 使用压缩后的字节数组计算哈希值
|
|
|
|
|
+ fileMd5 = FileUtils.getFileMD5(compressedBytes);
|
|
|
|
|
+ fileEtag = FileUtils.getFileETag(compressedBytes);
|
|
|
|
|
+ objectName = generateObjectName(originalFileName, fileMd5, extension);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 使用原始文件计算哈希值(非图片或压缩失败时回退)
|
|
|
|
|
+ fileMd5 = FileUtils.getFileMD5(file);
|
|
|
|
|
+ fileEtag = FileUtils.getFileETag(file);
|
|
|
|
|
+ objectName = generateObjectName(originalFileName, fileMd5, extension);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// if (isFileExistsInMinIo(objectName, fileEtag)) {
|
|
// if (isFileExistsInMinIo(objectName, fileEtag)) {
|
|
|
// return HttpResult.ok(getFileFromDatabase(fileEtag,objectName, extension));
|
|
// return HttpResult.ok(getFileFromDatabase(fileEtag,objectName, extension));
|
|
|
// }
|
|
// }
|
|
|
- //如果文件不存在,执行上传操作
|
|
|
|
|
- SysUploadFiles sysUploadFiles = uploadFileToMinIo(file, objectName, fileEtag, extension);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 根据是否压缩成功,选择对应的上传方式
|
|
|
|
|
+ SysUploadFiles sysUploadFiles;
|
|
|
|
|
+ if (compressedBytes != null && compressedBytes.length > 0) {
|
|
|
|
|
+ // 上传压缩后的图片字节数组
|
|
|
|
|
+ sysUploadFiles = uploadFileToMinIo(compressedBytes, objectName, fileEtag, extension, file.getContentType());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 上传原始文件(非图片或压缩失败时回退)
|
|
|
|
|
+ sysUploadFiles = uploadFileToMinIo(file, objectName, fileEtag, extension);
|
|
|
|
|
+ }
|
|
|
return HttpResult.ok(sysUploadFiles);
|
|
return HttpResult.ok(sysUploadFiles);
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
@@ -87,8 +121,7 @@ public class FileUploadController extends BaseController {
|
|
|
String contentType = connection.getContentType();
|
|
String contentType = connection.getContentType();
|
|
|
String extension = "";
|
|
String extension = "";
|
|
|
|
|
|
|
|
- if(contentType.contains("application/pdf") || contentType.contains("text/html"))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (contentType.contains("application/pdf") || contentType.contains("text/html")) {
|
|
|
extension = ".pdf";
|
|
extension = ".pdf";
|
|
|
}
|
|
}
|
|
|
try (InputStream inputStream = connection.getInputStream()) {
|
|
try (InputStream inputStream = connection.getInputStream()) {
|
|
@@ -96,7 +129,7 @@ public class FileUploadController extends BaseController {
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
throw new RuntimeException(e);
|
|
throw new RuntimeException(e);
|
|
|
}
|
|
}
|
|
|
- }catch (MalformedURLException e){
|
|
|
|
|
|
|
+ } catch (MalformedURLException e) {
|
|
|
throw new RuntimeException("url格式错误");
|
|
throw new RuntimeException("url格式错误");
|
|
|
} catch (IOException e) {
|
|
} catch (IOException e) {
|
|
|
throw new SystemException("url错误");
|
|
throw new SystemException("url错误");
|
|
@@ -169,7 +202,7 @@ public class FileUploadController extends BaseController {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private SysUploadFiles getFileFromDatabase(String fileEtag,String fileName,String fileType) {
|
|
|
|
|
|
|
+ private SysUploadFiles getFileFromDatabase(String fileEtag, String fileName, String fileType) {
|
|
|
SysUploadFiles sysUploadFiles = sysUploadFilesMapper.selectOne(
|
|
SysUploadFiles sysUploadFiles = sysUploadFilesMapper.selectOne(
|
|
|
new LambdaQueryWrapper<SysUploadFiles>().eq(SysUploadFiles::getEtag, fileEtag));
|
|
new LambdaQueryWrapper<SysUploadFiles>().eq(SysUploadFiles::getEtag, fileEtag));
|
|
|
|
|
|
|
@@ -182,11 +215,11 @@ public class FileUploadController extends BaseController {
|
|
|
sysUploadFiles.setEtag(fileEtag);
|
|
sysUploadFiles.setEtag(fileEtag);
|
|
|
sysUploadFiles.setCreateTime(LocalDateTime.now());
|
|
sysUploadFiles.setCreateTime(LocalDateTime.now());
|
|
|
sysUploadFiles.setCreateBy(getUserName());
|
|
sysUploadFiles.setCreateBy(getUserName());
|
|
|
- StatObjectResponse fileContent = MinioUtils.getFileStatusInfo(bucketName,fileName);
|
|
|
|
|
|
|
+ StatObjectResponse fileContent = MinioUtils.getFileStatusInfo(bucketName, fileName);
|
|
|
sysUploadFiles.setFileSize(fileContent.size() + "");
|
|
sysUploadFiles.setFileSize(fileContent.size() + "");
|
|
|
sysUploadFilesMapper.insert(sysUploadFiles);
|
|
sysUploadFilesMapper.insert(sysUploadFiles);
|
|
|
}
|
|
}
|
|
|
- sysUploadFiles.setDownloadUrl(MinioUtils.getPresignedObjectUrl(bucketName,fileName));
|
|
|
|
|
|
|
+ sysUploadFiles.setDownloadUrl(MinioUtils.getPresignedObjectUrl(bucketName, fileName));
|
|
|
return sysUploadFiles;
|
|
return sysUploadFiles;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -200,18 +233,19 @@ public class FileUploadController extends BaseController {
|
|
|
.contentType(file.getContentType())
|
|
.contentType(file.getContentType())
|
|
|
.build());
|
|
.build());
|
|
|
|
|
|
|
|
- SysUploadFiles sysUploadFiles = new SysUploadFiles();
|
|
|
|
|
- sysUploadFiles.setId(IdGenerate.nextId());
|
|
|
|
|
- sysUploadFiles.setFileName(objectName);
|
|
|
|
|
- sysUploadFiles.setFileType(extension.substring(1));
|
|
|
|
|
- StatObjectResponse fileContent = MinioUtils.getFileStatusInfo(bucketName,objectName);
|
|
|
|
|
- sysUploadFiles.setFileSize(fileContent.size() + "");
|
|
|
|
|
- sysUploadFiles.setBucketName(bucketName);
|
|
|
|
|
- sysUploadFiles.setEtag(objectWriteResponse.etag());
|
|
|
|
|
- sysUploadFiles.setCreateTime(LocalDateTime.now());
|
|
|
|
|
- sysUploadFiles.setDownloadUrl(MinioUtils.getPresignedObjectUrl(bucketName,objectName));
|
|
|
|
|
- sysUploadFilesMapper.insert(sysUploadFiles);
|
|
|
|
|
- return sysUploadFiles;
|
|
|
|
|
|
|
+ return insertSysUploadFiles(objectName, extension, objectWriteResponse);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private SysUploadFiles uploadFileToMinIo(byte[] fileBytes, String objectName, String fileEtag, String extension, String contentType) throws Exception {
|
|
|
|
|
+ InputStream fileInputStream = new ByteArrayInputStream(fileBytes);
|
|
|
|
|
+ ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs.builder()
|
|
|
|
|
+ .bucket(bucketName)
|
|
|
|
|
+ .object(objectName)
|
|
|
|
|
+ .stream(fileInputStream, fileBytes.length, -1)
|
|
|
|
|
+ .contentType(contentType)
|
|
|
|
|
+ .build());
|
|
|
|
|
+
|
|
|
|
|
+ return insertSysUploadFiles(objectName, extension, objectWriteResponse);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -224,16 +258,21 @@ public class FileUploadController extends BaseController {
|
|
|
.contentType(contentType)
|
|
.contentType(contentType)
|
|
|
.build());
|
|
.build());
|
|
|
|
|
|
|
|
|
|
+ return insertSysUploadFiles(objectName, extension, objectWriteResponse);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @NotNull
|
|
|
|
|
+ private SysUploadFiles insertSysUploadFiles(String objectName, String extension, ObjectWriteResponse objectWriteResponse) {
|
|
|
SysUploadFiles sysUploadFiles = new SysUploadFiles();
|
|
SysUploadFiles sysUploadFiles = new SysUploadFiles();
|
|
|
sysUploadFiles.setId(IdGenerate.nextId());
|
|
sysUploadFiles.setId(IdGenerate.nextId());
|
|
|
sysUploadFiles.setFileName(objectName);
|
|
sysUploadFiles.setFileName(objectName);
|
|
|
sysUploadFiles.setFileType(extension.substring(1));
|
|
sysUploadFiles.setFileType(extension.substring(1));
|
|
|
- StatObjectResponse fileContent = MinioUtils.getFileStatusInfo(bucketName,objectName);
|
|
|
|
|
|
|
+ StatObjectResponse fileContent = MinioUtils.getFileStatusInfo(bucketName, objectName);
|
|
|
sysUploadFiles.setFileSize(fileContent.size() + "");
|
|
sysUploadFiles.setFileSize(fileContent.size() + "");
|
|
|
sysUploadFiles.setBucketName(bucketName);
|
|
sysUploadFiles.setBucketName(bucketName);
|
|
|
sysUploadFiles.setEtag(objectWriteResponse.etag());
|
|
sysUploadFiles.setEtag(objectWriteResponse.etag());
|
|
|
sysUploadFiles.setCreateTime(LocalDateTime.now());
|
|
sysUploadFiles.setCreateTime(LocalDateTime.now());
|
|
|
- sysUploadFiles.setDownloadUrl(MinioUtils.getPresignedObjectUrl(bucketName,objectName));
|
|
|
|
|
|
|
+ sysUploadFiles.setDownloadUrl(MinioUtils.getPresignedObjectUrl(bucketName, objectName));
|
|
|
sysUploadFilesMapper.insert(sysUploadFiles);
|
|
sysUploadFilesMapper.insert(sysUploadFiles);
|
|
|
return sysUploadFiles;
|
|
return sysUploadFiles;
|
|
|
}
|
|
}
|