From 807fd337e77a6645172a0f88635b0c7748f4b78c Mon Sep 17 00:00:00 2001 From: haozq <1611483981@qq.com> Date: Thu, 23 Oct 2025 20:20:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8E=8B=E7=BC=A9=E5=8C=85?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bonus-business/pom.xml | 7 + .../business/service/ZipImageChecker.java | 84 +++++++ .../service/impl/CompressUploaderService.java | 226 ++++++++++++++++++ .../service/impl/ImageCaptionServiceImpl.java | 183 +++++++++++--- .../mapper/business/ImageCaptionMapper.xml | 11 +- .../java/com/bonus/file/minio/MinioUtil.java | 27 ++- .../java/com/bonus/file/vo/UploadFileVo.java | 2 + 7 files changed, 497 insertions(+), 43 deletions(-) create mode 100644 bonus-business/src/main/java/com/bonus/business/service/ZipImageChecker.java create mode 100644 bonus-business/src/main/java/com/bonus/business/service/impl/CompressUploaderService.java diff --git a/bonus-business/pom.xml b/bonus-business/pom.xml index 494fb0c..6d82c27 100644 --- a/bonus-business/pom.xml +++ b/bonus-business/pom.xml @@ -37,6 +37,13 @@ httpclient 4.5.13 + + + org.apache.commons + commons-compress + 1.20 + + \ No newline at end of file diff --git a/bonus-business/src/main/java/com/bonus/business/service/ZipImageChecker.java b/bonus-business/src/main/java/com/bonus/business/service/ZipImageChecker.java new file mode 100644 index 0000000..331cf2c --- /dev/null +++ b/bonus-business/src/main/java/com/bonus/business/service/ZipImageChecker.java @@ -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 IMAGE_EXTENSIONS = Collections.unmodifiableSet( + new HashSet() {{ + 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); + } +} \ No newline at end of file diff --git a/bonus-business/src/main/java/com/bonus/business/service/impl/CompressUploaderService.java b/bonus-business/src/main/java/com/bonus/business/service/impl/CompressUploaderService.java new file mode 100644 index 0000000..3317fc4 --- /dev/null +++ b/bonus-business/src/main/java/com/bonus/business/service/impl/CompressUploaderService.java @@ -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 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 uploadAndExtract(MultipartFile file,String filePath) throws Exception { + // 1. 验证文件 + List 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 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()); + } + } + } +} \ No newline at end of file diff --git a/bonus-business/src/main/java/com/bonus/business/service/impl/ImageCaptionServiceImpl.java b/bonus-business/src/main/java/com/bonus/business/service/impl/ImageCaptionServiceImpl.java index 94b9895..6b5a945 100644 --- a/bonus-business/src/main/java/com/bonus/business/service/impl/ImageCaptionServiceImpl.java +++ b/bonus-business/src/main/java/com/bonus/business/service/impl/ImageCaptionServiceImpl.java @@ -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 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 list= algorithmService.getImageList(fileList,operaName); //更新标记的数量 和未标记的数量,同时更新 标记图片地址 - updateImage(list,vo); + updateImage(list,vo); // 查询数据历史集合 List 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 fileList, UserOperaVo userOperaVo,String operaType) { + public AjaxResult addOperaData(MultipartFile[] multipartFile, AlgorithmVo vo,String userId,String operaName,String createTime, List 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 fileList ,String id,String operaType){ + public AjaxResult ImageMultipartFile(MultipartFile[] multipartFile ,String path,String createTime,String userId,List 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 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 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; + } + + + } diff --git a/bonus-business/src/main/resources/mapper/business/ImageCaptionMapper.xml b/bonus-business/src/main/resources/mapper/business/ImageCaptionMapper.xml index 444e53a..2a6b297 100644 --- a/bonus-business/src/main/resources/mapper/business/ImageCaptionMapper.xml +++ b/bonus-business/src/main/resources/mapper/business/ImageCaptionMapper.xml @@ -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 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 tb_upload_file set is_active=1 @@ -204,6 +204,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and tir.content_image like concat('%',#{operaName},'%') + ORDER BY file.create_time desc - 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 (#{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} ) \ No newline at end of file diff --git a/bonus-file/src/main/java/com/bonus/file/minio/MinioUtil.java b/bonus-file/src/main/java/com/bonus/file/minio/MinioUtil.java index 6382c7f..e02991d 100644 --- a/bonus-file/src/main/java/com/bonus/file/minio/MinioUtil.java +++ b/bonus-file/src/main/java/com/bonus/file/minio/MinioUtil.java @@ -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 天 diff --git a/bonus-file/src/main/java/com/bonus/file/vo/UploadFileVo.java b/bonus-file/src/main/java/com/bonus/file/vo/UploadFileVo.java index 18a7d79..ba1313c 100644 --- a/bonus-file/src/main/java/com/bonus/file/vo/UploadFileVo.java +++ b/bonus-file/src/main/java/com/bonus/file/vo/UploadFileVo.java @@ -7,6 +7,8 @@ public class UploadFileVo { private String operaName; + private String operaId; + private String imageId; /** * 图片名称