添加压缩包上传
This commit is contained in:
parent
4e15ae287b
commit
807fd337e7
|
|
@ -37,6 +37,13 @@
|
|||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.13</version> <!-- 使用最新版本 -->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.20</version> <!-- 使用最新的版本 -->
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package com.bonus.business.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class ZipImageChecker {
|
||||
|
||||
// 支持的图片扩展名(JDK 1.8用Collections.unmodifiableSet替代Set.of())
|
||||
private static final Set<String> IMAGE_EXTENSIONS = Collections.unmodifiableSet(
|
||||
new HashSet<String>() {{
|
||||
add("jpg");
|
||||
add("jpeg");
|
||||
add("png");
|
||||
add("gif");
|
||||
add("bmp");
|
||||
add("webp");
|
||||
add("avif");
|
||||
add("svg");
|
||||
}}
|
||||
);
|
||||
|
||||
/**
|
||||
* 检查ZIP压缩包中是否包含图片文件(适配JDK 1.8)
|
||||
* @param zipInputStream ZIP文件输入流
|
||||
* @param charset 压缩包文件名编码(如GBK、UTF-8,根据实际情况传入)
|
||||
* @return 存在图片返回true,否则返回false
|
||||
*/
|
||||
public boolean hasImageInZip(InputStream zipInputStream, String charset) {
|
||||
// 使用Apache Commons Compress的ZipArchiveInputStream,支持JDK 1.8和指定编码
|
||||
try (ZipArchiveInputStream zis = new ZipArchiveInputStream(zipInputStream, charset, false)) {
|
||||
ZipArchiveEntry entry;
|
||||
while ((entry = zis.getNextZipEntry()) != null) {
|
||||
// 跳过目录,只处理文件
|
||||
if (entry.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String entryName = entry.getName();
|
||||
// 检查是否为图片
|
||||
if (!isImage(entryName)) {
|
||||
return true; // 找到第一个图片即返回
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("解析ZIP文件失败:" + e.getMessage(), e);
|
||||
}
|
||||
// 遍历完所有条目未找到图片
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件名是否为图片(处理大小写和常见扩展名)
|
||||
*/
|
||||
private boolean isImage(String fileName) {
|
||||
if (fileName == null || fileName.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 提取扩展名(忽略大小写)
|
||||
int lastDotIndex = fileName.lastIndexOf('.');
|
||||
if (lastDotIndex == -1) { // 无扩展名的文件不是图片
|
||||
return false;
|
||||
}
|
||||
|
||||
String extension = fileName.substring(lastDotIndex + 1).toLowerCase();
|
||||
return IMAGE_EXTENSIONS.contains(extension);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
package com.bonus.business.service.impl;
|
||||
|
||||
import com.bonus.common.utils.DateUtils;
|
||||
import com.bonus.common.utils.StringUtils;
|
||||
import com.bonus.file.config.SysFile;
|
||||
import com.bonus.file.minio.MinioUtil;
|
||||
import io.minio.UploadObjectArgs;
|
||||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.ArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
@Service
|
||||
public class CompressUploaderService {
|
||||
|
||||
|
||||
@Autowired
|
||||
private MinioUtil minioUtil;
|
||||
// 支持的压缩格式扩展名
|
||||
private static final List<String> SUPPORTED_EXTENSIONS = Arrays.asList(
|
||||
".zip", ".tar", ".tar.gz", ".tgz", ".tar.bz2", ".tbz2"
|
||||
);
|
||||
|
||||
|
||||
|
||||
// 临时目录(基于系统临时目录,自动清理)
|
||||
private final String tempBaseDir = System.getProperty("java.io.tmpdir") + "/minio_compress_temp/";
|
||||
|
||||
|
||||
/**
|
||||
* 主流程:接收压缩包 -> 验证格式 -> 保存临时文件 -> 解压 -> 上传MinIO -> 清理临时文件
|
||||
* @param file 上传的压缩包(MultipartFile)
|
||||
*/
|
||||
public List<SysFile> uploadAndExtract(MultipartFile file,String filePath) throws Exception {
|
||||
// 1. 验证文件
|
||||
List<SysFile> sysFiles = new ArrayList<>();
|
||||
String fileName = file.getOriginalFilename();
|
||||
if (fileName == null || !isSupportedCompressFile(fileName)) {
|
||||
throw new IllegalArgumentException("不支持的压缩格式,仅支持:" + SUPPORTED_EXTENSIONS);
|
||||
}
|
||||
|
||||
// 2. 保存上传的压缩包到临时文件
|
||||
File tempCompressFile = saveToTempFile(file);
|
||||
// 3. 创建唯一临时解压目录(避免并发冲突)
|
||||
File unzipDir = createTempExtractDir();
|
||||
try {
|
||||
// 4. 根据文件类型解压
|
||||
extractFile(tempCompressFile, unzipDir);
|
||||
// 6. 上传解压后的内容到MinIO(保留目录结构)
|
||||
uploadDirToMinIO(unzipDir,filePath,sysFiles);
|
||||
} finally {
|
||||
// 7. 强制清理临时文件(无论成功失败)
|
||||
cleanTempFiles(tempCompressFile, unzipDir);
|
||||
}
|
||||
return sysFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证是否为支持的压缩文件
|
||||
*/
|
||||
private boolean isSupportedCompressFile(String fileName) {
|
||||
return SUPPORTED_EXTENSIONS.stream().anyMatch(ext -> fileName.toLowerCase().endsWith(ext));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将MultipartFile保存到临时文件
|
||||
*/
|
||||
private File saveToTempFile(MultipartFile file) throws IOException {
|
||||
// 创建临时目录(如不存在)
|
||||
File tempDir = new File(tempBaseDir + "upload/");
|
||||
if (!tempDir.exists()) {
|
||||
tempDir.mkdirs();
|
||||
}
|
||||
// 生成临时文件名(原文件名+时间戳,避免重复)
|
||||
String tempFileName = System.currentTimeMillis() + "_" + Objects.requireNonNull(file.getOriginalFilename());
|
||||
File tempFile = new File(tempDir, tempFileName);
|
||||
file.transferTo(tempFile);
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建唯一的临时解压目录
|
||||
*/
|
||||
private File createTempExtractDir() throws IOException {
|
||||
String dirName = "extract_" + System.currentTimeMillis() + "_" + System.nanoTime();
|
||||
File dir = new File(tempBaseDir + dirName);
|
||||
if (!dir.mkdirs()) {
|
||||
throw new IOException("创建临时解压目录失败:" + dir.getAbsolutePath());
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件类型选择对应的解压方式
|
||||
*/
|
||||
private void extractFile(File compressFile, File destDir) throws IOException {
|
||||
String fileName = compressFile.getName().toLowerCase();
|
||||
try (InputStream fis = new FileInputStream(compressFile)) {
|
||||
ArchiveInputStream ais = createArchiveInputStream(fis, fileName);
|
||||
|
||||
ArchiveEntry entry;
|
||||
while ((entry = ais.getNextEntry()) != null) {
|
||||
// 跳过空条目
|
||||
if (!ais.canReadEntryData(entry)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
File entryFile = new File(destDir, entry.getName());
|
||||
// 处理目录条目
|
||||
if (entry.isDirectory()) {
|
||||
if (!entryFile.mkdirs() && !entryFile.exists()) {
|
||||
throw new IOException("创建目录失败:" + entryFile.getAbsolutePath());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 确保父目录存在
|
||||
File parentDir = entryFile.getParentFile();
|
||||
if (!parentDir.exists() && !parentDir.mkdirs()) {
|
||||
throw new IOException("创建父目录失败:" + parentDir.getAbsolutePath());
|
||||
}
|
||||
|
||||
// 写入文件内容
|
||||
try (OutputStream os = Files.newOutputStream(entryFile.toPath())) {
|
||||
byte[] buffer = new byte[1024 * 8];
|
||||
int len;
|
||||
while ((len = ais.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件扩展名创建对应的归档输入流(处理ZIP/TAR系列)
|
||||
*/
|
||||
private ArchiveInputStream createArchiveInputStream(InputStream fis, String fileName) throws IOException {
|
||||
if (fileName.endsWith(".zip")) {
|
||||
return new ZipArchiveInputStream(fis);
|
||||
} else if (fileName.endsWith(".tar")) {
|
||||
return new TarArchiveInputStream(fis);
|
||||
} else if (fileName.endsWith(".tar.gz") || fileName.endsWith(".tgz")) {
|
||||
// 先解GZip,再解Tar
|
||||
return new TarArchiveInputStream(new GzipCompressorInputStream(fis));
|
||||
} else if (fileName.endsWith(".tar.bz2") || fileName.endsWith(".tbz2")) {
|
||||
// 先解BZip2,再解Tar
|
||||
return new TarArchiveInputStream(new BZip2CompressorInputStream(fis));
|
||||
} else {
|
||||
throw new UnsupportedOperationException("不支持的压缩格式:" + fileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 递归上传目录到MinIO(保留目录结构)
|
||||
*/
|
||||
private void uploadDirToMinIO(File dir,String path,List<SysFile> list) throws Exception {
|
||||
File[] files = dir.listFiles();
|
||||
if (files == null) {
|
||||
return; // 空目录或非目录
|
||||
}
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
// 目录需要在路径末尾加"/",保持MinIO目录结构
|
||||
uploadDirToMinIO(file,path,list);
|
||||
} else {
|
||||
|
||||
String originFileName=file.getName();
|
||||
String suffix= StringUtils.substringAfterLast(originFileName, ".");
|
||||
String uuid = StringUtils.randomUUID();
|
||||
String folderPath= path+uuid+"."+suffix;
|
||||
long sizeInBytes = file.length();
|
||||
// 转换为可读格式(如KB/MB)
|
||||
String humanReadableSize = convertToHumanReadable(sizeInBytes);
|
||||
//上传到minio
|
||||
SysFile sysFile=minioUtil.uploadFile(file,folderPath);
|
||||
sysFile.setName(uuid+"."+suffix);
|
||||
sysFile.setOriginName(originFileName);
|
||||
sysFile.setFileSize(humanReadableSize);
|
||||
sysFile.setId(StringUtils.randomUUID());
|
||||
// 上传文件到MinIO
|
||||
list.add(sysFile);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// 辅助方法:字节转可读格式
|
||||
private String convertToHumanReadable(long bytes) {
|
||||
if (bytes < 1024) return bytes + " B";
|
||||
else if (bytes < 1024 * 1024) return String.format("%.2f KB", bytes / 1024.0);
|
||||
else return String.format("%.2f MB", bytes / (1024 * 1024.0));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理临时文件/目录
|
||||
*/
|
||||
private void cleanTempFiles(File... files) {
|
||||
for (File file : files) {
|
||||
try {
|
||||
if (file.isDirectory()) {
|
||||
FileUtils.deleteDirectory(file); // 递归删除目录
|
||||
} else {
|
||||
FileUtils.deleteQuietly(file); // 安静删除文件(失败不抛异常)
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("清理临时文件失败:" + file.getAbsolutePath() + ",原因:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ package com.bonus.business.service.impl;
|
|||
|
||||
import com.bonus.business.domain.AlgorithmVo;
|
||||
import com.bonus.business.domain.ImageRecognize;
|
||||
import com.bonus.business.service.ZipImageChecker;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.file.vo.UploadFileVo;
|
||||
import com.bonus.business.domain.UserOperaVo;
|
||||
import com.bonus.business.mapper.ImageCaptionMapper;
|
||||
|
|
@ -12,15 +14,17 @@ import com.bonus.common.utils.SecurityUtils;
|
|||
import com.bonus.common.utils.StringUtils;
|
||||
import com.bonus.file.config.SysFile;
|
||||
import com.bonus.file.minio.MinioUtil;
|
||||
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
|
||||
import io.minio.MinioClient;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.PushBuilder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
|
@ -47,6 +51,11 @@ public class ImageCaptionServiceImpl implements ImageCaptionService {
|
|||
|
||||
|
||||
public final static String PG_TYPE="2";
|
||||
|
||||
String[] compressedExtensions = { ".zip", ".tar", ".tar.gz", ".tgz", ".tar.bz2", ".tbz2"};
|
||||
|
||||
String[] images = {".jpg", ".png", ".jpeg"};
|
||||
|
||||
/**
|
||||
* 图像上传接口
|
||||
* @param multipartFile
|
||||
|
|
@ -63,19 +72,24 @@ public class ImageCaptionServiceImpl implements ImageCaptionService {
|
|||
if(StringUtils.isEmpty(vo.getParam())){
|
||||
return AjaxResult.error("请至少选择一个算法!");
|
||||
}
|
||||
String userId= "1";
|
||||
// String userId= SecurityUtils.getUserId().toString();
|
||||
|
||||
AjaxResult result0= isZip(multipartFile,vo);
|
||||
if(result0.isError()){
|
||||
return result0;
|
||||
}
|
||||
String userId="1";
|
||||
// String userId= SecurityUtils.getUserId().toString();
|
||||
String operaName=vo.getParam();
|
||||
//操作日期
|
||||
List<SysFile> fileList=new ArrayList<>();
|
||||
UserOperaVo userOperaVo=new UserOperaVo(userId,operaName,createTime,BJ_TYPE);
|
||||
AjaxResult result= addOperaData(multipartFile,vo,userId,operaName,createTime,fileList,userOperaVo,BJ_TYPE);
|
||||
AjaxResult result= addOperaData(multipartFile,vo,userId,operaName,createTime,fileList,userOperaVo,BJ_TYPE, (Boolean) result0.get("data"));
|
||||
if(result.isError()){
|
||||
return result;
|
||||
}
|
||||
List<ImageRecognize> list= algorithmService.getImageList(fileList,operaName);
|
||||
//更新标记的数量 和未标记的数量,同时更新 标记图片地址
|
||||
updateImage(list,vo);
|
||||
updateImage(list,vo);
|
||||
// 查询数据历史集合
|
||||
List<UserOperaVo> hisImageList=getUploadFileList(userOperaVo);
|
||||
return AjaxResult.success(hisImageList);
|
||||
|
|
@ -99,13 +113,18 @@ public class ImageCaptionServiceImpl implements ImageCaptionService {
|
|||
if(multipartFile == null || multipartFile.length == 0){
|
||||
return AjaxResult.error("请上传图片");
|
||||
}
|
||||
// String userId= SecurityUtils.getUserId().toString();
|
||||
String userId="1";
|
||||
String operaName=DateUtils.getDate();
|
||||
|
||||
AjaxResult result0= isZip(multipartFile,vo);
|
||||
if(result0.isError()){
|
||||
return result0;
|
||||
}
|
||||
|
||||
String userId= SecurityUtils.getUserId().toString();
|
||||
String operaName=DateUtils.getDate();
|
||||
//操作日期
|
||||
//文件路径
|
||||
UserOperaVo userOperaVo=new UserOperaVo(userId,operaName,createTime,PG_TYPE);
|
||||
AjaxResult result= addOperaData(multipartFile,vo,userId,operaName,createTime,fileList,userOperaVo,PG_TYPE);
|
||||
AjaxResult result= addOperaData(multipartFile,vo,userId,operaName,createTime,fileList,userOperaVo,PG_TYPE, (Boolean) result0.get("data"));
|
||||
if(result.isError()){
|
||||
return result;
|
||||
}
|
||||
|
|
@ -126,6 +145,47 @@ public class ImageCaptionServiceImpl implements ImageCaptionService {
|
|||
return AjaxResult.error("操作失败");
|
||||
}
|
||||
|
||||
public AjaxResult isZip(MultipartFile[] multipartFile, AlgorithmVo vo) {
|
||||
boolean isZip = false;
|
||||
if(multipartFile.length==1) {
|
||||
MultipartFile file = multipartFile[0];
|
||||
String fileName = file.getOriginalFilename();
|
||||
if (StringUtils.isNotEmpty(fileName)) {
|
||||
for (String extension : compressedExtensions) {
|
||||
if (fileName.toLowerCase().endsWith(extension)) {
|
||||
isZip =true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//压缩包 获取压缩包里面文件路径
|
||||
if(isZip){
|
||||
try (InputStream is = multipartFile[0].getInputStream()) {
|
||||
ZipImageChecker checker = new ZipImageChecker();
|
||||
boolean isImage= checker.hasImageInZip(is,"GBK");
|
||||
if(isImage){
|
||||
return AjaxResult.error("压缩包里面不能包含非图片文件!");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("获取ZIP文件输入流失败", e);
|
||||
}
|
||||
|
||||
}else{
|
||||
//检查上传是否只能是图片
|
||||
for (MultipartFile file : multipartFile) {
|
||||
// 非压缩包上传
|
||||
String fileName = file.getOriginalFilename();
|
||||
boolean isImage = isImage(fileName);
|
||||
if (isImage) {
|
||||
return AjaxResult.error("附件只能上传图片!");
|
||||
}
|
||||
}
|
||||
}
|
||||
return AjaxResult.success(isZip);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加记录数据
|
||||
* @param multipartFile
|
||||
|
|
@ -136,7 +196,7 @@ public class ImageCaptionServiceImpl implements ImageCaptionService {
|
|||
* @param operaType
|
||||
* @return
|
||||
*/
|
||||
public AjaxResult addOperaData(MultipartFile[] multipartFile, AlgorithmVo vo,String userId,String operaName,String createTime, List<SysFile> fileList, UserOperaVo userOperaVo,String operaType) {
|
||||
public AjaxResult addOperaData(MultipartFile[] multipartFile, AlgorithmVo vo,String userId,String operaName,String createTime, List<SysFile> fileList, UserOperaVo userOperaVo,String operaType,boolean isZip) {
|
||||
try{
|
||||
//文件路径
|
||||
String path="image/"+year+"/"+month+"/"+day+"/";
|
||||
|
|
@ -154,7 +214,7 @@ public class ImageCaptionServiceImpl implements ImageCaptionService {
|
|||
if(addedAlgorithmNum==null || addedAlgorithmNum==0){
|
||||
return AjaxResult.error("操作记录添加失败!");
|
||||
}else{
|
||||
AjaxResult result=ImageMultipartFile(multipartFile,path,createTime,userId,fileList,vo.getId(),operaType);
|
||||
AjaxResult result=ImageMultipartFile(multipartFile,path,createTime,userId,fileList,vo.getId(),operaType,isZip);
|
||||
if(result.isError()){
|
||||
return result;
|
||||
}
|
||||
|
|
@ -222,7 +282,8 @@ public class ImageCaptionServiceImpl implements ImageCaptionService {
|
|||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private CompressUploaderService compressUploaderService;
|
||||
/**
|
||||
* 文件处理类
|
||||
* @param multipartFile
|
||||
|
|
@ -234,25 +295,36 @@ public class ImageCaptionServiceImpl implements ImageCaptionService {
|
|||
* @param operaType
|
||||
* @return
|
||||
*/
|
||||
public AjaxResult ImageMultipartFile(MultipartFile[] multipartFile ,String path,String createTime,String userId,List<SysFile> fileList ,String id,String operaType){
|
||||
public AjaxResult ImageMultipartFile(MultipartFile[] multipartFile ,String path,String createTime,String userId,List<SysFile> fileList ,String id,String operaType,boolean isZip){
|
||||
try{
|
||||
for (MultipartFile file : multipartFile) {
|
||||
String originFileName = file.getOriginalFilename();
|
||||
String suffix=StringUtils.substringAfterLast(originFileName, ".");
|
||||
String uuid = StringUtils.randomUUID();
|
||||
String folderPath= path+uuid+"."+suffix;
|
||||
// 获取文件大小(字节)
|
||||
long sizeInBytes = file.getSize();
|
||||
// 转换为可读格式(如KB/MB)
|
||||
String humanReadableSize = convertToHumanReadable(sizeInBytes);
|
||||
SysFile sysFile=minioUtil.uploadFile(file,folderPath);
|
||||
sysFile.setName(uuid+"."+suffix);
|
||||
SysFile.addSource(sysFile,userId,originFileName,humanReadableSize);
|
||||
fileList.add(sysFile);
|
||||
if(isZip){
|
||||
List<SysFile> list=compressUploaderService.uploadAndExtract(multipartFile[0],path);
|
||||
for (SysFile sysFile : list) {
|
||||
sysFile.setCreateUser(userId);
|
||||
fileList.add(sysFile);
|
||||
}
|
||||
}else{
|
||||
for (MultipartFile file : multipartFile) {
|
||||
String originFileName = file.getOriginalFilename();
|
||||
String suffix=StringUtils.substringAfterLast(originFileName, ".");
|
||||
String uuid = StringUtils.randomUUID();
|
||||
String folderPath= path+uuid+"."+suffix;
|
||||
// 获取文件大小(字节)
|
||||
long sizeInBytes = file.getSize();
|
||||
// 转换为可读格式(如KB/MB)
|
||||
String humanReadableSize = convertToHumanReadable(sizeInBytes);
|
||||
SysFile sysFile=minioUtil.uploadFile(file,folderPath);
|
||||
sysFile.setName(uuid+"."+suffix);
|
||||
SysFile.addSource(sysFile,userId,originFileName,humanReadableSize);
|
||||
fileList.add(sysFile);
|
||||
}
|
||||
}
|
||||
if(fileList.size()!=multipartFile.length){
|
||||
return AjaxResult.error("文件上传失败!");
|
||||
if(!isZip){
|
||||
if(fileList.size()!=multipartFile.length){
|
||||
return AjaxResult.error("文件上传失败!");
|
||||
}
|
||||
}
|
||||
|
||||
if(PG_TYPE.equals(operaType)){
|
||||
mapper.addSureLoadImage(fileList,id,createTime,operaType);
|
||||
}
|
||||
|
|
@ -265,6 +337,13 @@ public class ImageCaptionServiceImpl implements ImageCaptionService {
|
|||
}
|
||||
|
||||
|
||||
public AjaxResult uploadZip(){
|
||||
|
||||
|
||||
return AjaxResult.error("文件上传失败!");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询 图片数据结婚
|
||||
* @param vo
|
||||
|
|
@ -320,12 +399,11 @@ public class ImageCaptionServiceImpl implements ImageCaptionService {
|
|||
List<UploadFileVo> fileList=mapper.getFileList(vo);
|
||||
//添加图片到标记
|
||||
mapper.addSureFile(fileList);
|
||||
|
||||
|
||||
return AjaxResult.success("操作成功");
|
||||
}catch (Exception e){
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
return AjaxResult.success("操作成功");
|
||||
return AjaxResult.error("操作失败");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -414,4 +492,43 @@ public class ImageCaptionServiceImpl implements ImageCaptionService {
|
|||
else return String.format("%.2f MB", bytes / (1024 * 1024.0));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断压缩包里面是不是图片
|
||||
* @param zipFile
|
||||
* @return
|
||||
*/
|
||||
public boolean isImage(MultipartFile zipFile){
|
||||
try (InputStream inputStream = zipFile.getInputStream();
|
||||
ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
|
||||
ZipEntry zipEntry;
|
||||
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
|
||||
boolean isImage = isImage( zipEntry.getName());
|
||||
if(isImage){
|
||||
return isImage;
|
||||
}
|
||||
zipInputStream.closeEntry(); // 关闭当前条目,准备下一个条目
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件后缀是不是图片
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
public boolean isImage(String fileName){
|
||||
for (String extension : images) {
|
||||
if (fileName.toLowerCase().endsWith(extension)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
update tb_upload_file set bj_file_path=#{imagePath} where id=#{imageId}
|
||||
</update>
|
||||
<update id="updateAlgorithmSure">
|
||||
update tb_algorithm set is_sure=#{isSure}, sure_user=#{userId} where oper_id=#{id}
|
||||
update tb_algorithm set is_sure=#{isSure}, sure_user=#{userId} where id=#{id}
|
||||
</update>
|
||||
<update id="updateImage">
|
||||
update tb_upload_file set is_active=1
|
||||
|
|
@ -204,6 +204,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="operaName!=null and operaName!=''">
|
||||
and tir.content_image like concat('%',#{operaName},'%')
|
||||
</if>
|
||||
ORDER BY file.create_time desc
|
||||
</select>
|
||||
<select id="getFileList" resultType="com.bonus.file.vo.UploadFileVo">
|
||||
select file.id imageId,
|
||||
|
|
@ -220,20 +221,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
file. file_size fileSize,
|
||||
file.create_user createUser
|
||||
from tb_upload_file file
|
||||
left join tb_algorithm ta on ta.id=file.algorithm_id
|
||||
left join tb_algorithm ta on ta.id=file.algorithm_id
|
||||
WHERE file.is_active=0
|
||||
and ta.oper_id=#{id}
|
||||
and ta.id=#{id}
|
||||
|
||||
</select>
|
||||
|
||||
<insert id="addSureFile">
|
||||
insert into tb_sure_file(
|
||||
replace into tb_sure_file(
|
||||
id, algorithm_id,original_name,file_path,bucket_name,
|
||||
file_name,is_active,create_time,file_type,bj_file_path,file_size,create_user
|
||||
) values
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
(#{item.imageId}, #{item.algorithmId},#{item.originalName},#{item.filePath},#{item.bucketName},
|
||||
#{item.fileName},#{item.isActive},#{item.createTime},#{item.fileType},#{item.bjFilePath},#{item.fileSize},#{item.createUser} )
|
||||
#{item.fileName},#{item.isActive},now(),#{item.fileType},#{item.bjFilePath},#{item.fileSize},#{item.createUser} )
|
||||
</foreach>
|
||||
</insert>
|
||||
</mapper>
|
||||
|
|
@ -91,6 +91,19 @@ public class MinioUtil {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public SysFile uploadFile(File file, String folderPath) throws Exception {
|
||||
minioClient.uploadObject(UploadObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.object(folderPath)
|
||||
.filename(file.getAbsolutePath())
|
||||
.build());
|
||||
return SysFile.builder()
|
||||
.name(file.getName())
|
||||
.bucketName(minioConfig.getBucketName())
|
||||
.url(folderPath).build();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 上传文件到指定存储桶
|
||||
|
|
@ -456,10 +469,10 @@ public class MinioUtil {
|
|||
* @param
|
||||
* @return
|
||||
*/
|
||||
public ObjectWriteResponse uploadImage(String bucketName, String imageBase64, String path) {
|
||||
public SysFile uploadImage(String bucketName, String imageBase64, String path) {
|
||||
if (!StringUtils.isEmpty(imageBase64)) {
|
||||
InputStream in = base64ToInputStream(imageBase64);
|
||||
return uploadFile(bucketName, path, in);
|
||||
return uploadFile( path, in);
|
||||
|
||||
}
|
||||
return null;
|
||||
|
|
@ -478,14 +491,18 @@ public class MinioUtil {
|
|||
/**
|
||||
* 通过流上传文件
|
||||
*
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 文件对象
|
||||
* @param inputStream 文件流
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows(Exception.class)
|
||||
public ObjectWriteResponse uploadFile(String bucketName, String objectName, InputStream inputStream) {
|
||||
return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(inputStream, inputStream.available(), -1).build());
|
||||
public SysFile uploadFile(String objectName, InputStream inputStream) {
|
||||
minioClient.putObject(PutObjectArgs.builder().bucket(minioConfig.getBucketName()).object(objectName).stream(inputStream, inputStream.available(), -1).build());
|
||||
return SysFile.builder()
|
||||
.bucketName(minioConfig.getBucketName())
|
||||
.url(objectName).build();
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* 获取文件的临时访问 URL,默认过期时间为 7 天
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ public class UploadFileVo {
|
|||
|
||||
private String operaName;
|
||||
|
||||
private String operaId;
|
||||
|
||||
private String imageId;
|
||||
/**
|
||||
* 图片名称
|
||||
|
|
|
|||
Reference in New Issue