From 4d70e622d2f1786c2ef25fa732bbcec599fe8b14 Mon Sep 17 00:00:00 2001 From: chenhj <1263187585@qq.com> Date: 星期五, 30 五月 2025 14:39:56 +0800 Subject: [PATCH] mino修改 --- ruoyi-common/src/main/java/com/ruoyi/basic/service/StorageBlobService.java | 35 +++ ruoyi-common/src/main/java/com/ruoyi/basic/service/impl/StorageBlobServiceImpl.java | 105 +++++++++ ruoyi-common/src/main/java/com/ruoyi/basic/entity/dto/StorageBlobDTO.java | 9 ruoyi-common/src/main/java/com/ruoyi/basic/service/impl/StorageAttachmentServiceImpl.java | 92 ++++++++ ruoyi-admin/src/main/resources/application.yml.example | 9 ruoyi-common/src/main/java/com/ruoyi/basic/mapper/StorageBlobMapper.java | 18 + ruoyi-common/src/main/java/com/ruoyi/common/constant/StorageAttachmentConstants.java | 17 + ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java | 15 + ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MinioUtils.java | 14 + ruoyi-admin/src/main/resources/db/beforeSql/postgresql/beforeSQL__sys.sql | 4 ruoyi-common/src/main/java/com/ruoyi/basic/mapper/StorageAttachmentMapper.java | 18 + ruoyi-common/src/main/resources/mapper/StorageBlobMapper.xml | 22 ++ ruoyi-common/src/main/resources/mapper/StorageAttachmentMapper.xml | 22 ++ ruoyi-common/src/main/resources/db/migration/postgresql/V20250525003447__create_table_storage_attachment.sql | 22 +- ruoyi-common/src/main/java/com/ruoyi/basic/entity/StorageBlob.java | 65 +++++ ruoyi-common/src/main/resources/db/migration/postgresql/V20250525003427__create_table_storage_blob.sql | 18 + ruoyi-common/src/main/java/com/ruoyi/common/handler/MyMetaObjectHandler.java | 43 +++ ruoyi-admin/src/main/java/com/ruoyi/PlusCodeGenerator.java | 6 ruoyi-common/src/main/java/com/ruoyi/basic/entity/StorageAttachment.java | 73 ++++++ ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml | 10 ruoyi-common/src/main/java/com/ruoyi/basic/service/StorageAttachmentService.java | 43 +++ 21 files changed, 631 insertions(+), 29 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/PlusCodeGenerator.java b/ruoyi-admin/src/main/java/com/ruoyi/PlusCodeGenerator.java index 196735f..5ec4f02 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/PlusCodeGenerator.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/PlusCodeGenerator.java @@ -38,8 +38,8 @@ public static void main(String[] args) { String projectPath = System.getProperty("user.dir"); // 鑾峰彇椤圭洰鏍硅矾寰� - String path = "basic-server"; // 妯″潡鍚嶇О - String table = "test"; // 琛ㄥ悕锛屽涓〃閫楀彿闅斿紑 + String path = "ruoyi-common"; // 妯″潡鍚嶇О + String table = "storage_attachment"; // 琛ㄥ悕锛屽涓〃閫楀彿闅斿紑 // 浠g爜杈撳嚭璺緞閰嶇疆 String outputBasePath = Paths.get(projectPath, path, "src", "main", "java").toString(); @@ -48,7 +48,7 @@ // 浠g爜鐢熸垚鏍稿績閰嶇疆 FastAutoGenerator.create(DB_URL, DB_USERNAME, DB_PASSWORD) .globalConfig(builder -> { - builder.author("ruoyi") // 浣滆�呬俊鎭� + builder.author("chen") // 浣滆�呬俊鎭� .outputDir(outputBasePath) // 浠g爜杈撳嚭鐩綍 .dateType(DateType.ONLY_DATE) // 鏃ユ湡绫诲瀷 .commentDate("yyyy-MM-dd") // 娉ㄩ噴鏃ユ湡鏍煎紡 diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java index b7fad0c..31fc707 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java @@ -2,6 +2,9 @@ import java.util.ArrayList; import java.util.List; + +import com.ruoyi.basic.service.StorageBlobService; +import com.ruoyi.common.core.domain.R; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; @@ -36,6 +39,9 @@ private ServerConfig serverConfig; private static final String FILE_DELIMETER = ","; + + @Autowired + private StorageBlobService storageBlobService; /** * 閫氱敤涓嬭浇璇锋眰 @@ -133,6 +139,15 @@ } /** + * minio閫氱敤涓婁紶璇锋眰锛堝涓級 + */ + @PostMapping("/minioUploads") + public R minioUploadFiles(List<MultipartFile> files, String bucketName) throws Exception + { + return R.ok(storageBlobService.updateStorageBlobs(files, bucketName)); + } + + /** * 鏈湴璧勬簮閫氱敤涓嬭浇 */ @GetMapping("/download/resource") diff --git a/ruoyi-admin/src/main/resources/application.yml.example b/ruoyi-admin/src/main/resources/application.yml.example index a173945..4ebf163 100644 --- a/ruoyi-admin/src/main/resources/application.yml.example +++ b/ruoyi-admin/src/main/resources/application.yml.example @@ -1,3 +1,12 @@ +minio: + endpoint: lunor.cn + port: 9000 + secure: false + accessKey: admin + secretKey: Admin123! + preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂 + default-bucket: ruoyi # 榛樿瀛樺偍妗� + # 椤圭洰鐩稿叧閰嶇疆 ruoyi: # 鍚嶇О diff --git a/ruoyi-admin/src/main/resources/db/beforeSql/postgresql/beforeSQL__sys.sql b/ruoyi-admin/src/main/resources/db/beforeSql/postgresql/beforeSQL__sys.sql index af37cc5..b7274a3 100644 --- a/ruoyi-admin/src/main/resources/db/beforeSql/postgresql/beforeSQL__sys.sql +++ b/ruoyi-admin/src/main/resources/db/beforeSql/postgresql/beforeSQL__sys.sql @@ -227,8 +227,8 @@ component VARCHAR(255) DEFAULT NULL, query VARCHAR(255) DEFAULT NULL, route_name VARCHAR(50) DEFAULT '', - is_frame INTEGER DEFAULT 1, - is_cache INTEGER DEFAULT 0, + is_frame VARCHAR(10) DEFAULT 1, + is_cache VARCHAR(10) DEFAULT 0, menu_type CHAR(1) DEFAULT '', visible CHAR(1) DEFAULT '0', status CHAR(1) DEFAULT '0', diff --git a/ruoyi-common/src/main/java/com/ruoyi/basic/entity/StorageAttachment.java b/ruoyi-common/src/main/java/com/ruoyi/basic/entity/StorageAttachment.java new file mode 100644 index 0000000..dddde62 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/basic/entity/StorageAttachment.java @@ -0,0 +1,73 @@ +package com.ruoyi.basic.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.basic.entity.dto.StorageBlobDTO; +import lombok.Data; +import com.ruoyi.common.core.domain.BaseEntity; + +import java.io.Serializable; +import java.util.Date; + +/** + * 閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭� 瀹炰綋绫� + * + * @author ruoyi + * @date 2025-05-29 + */ +@Data +@TableName("storage_attachment") +public class StorageAttachment implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** 鍒涘缓鏃堕棿 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + /** 鏇存柊鏃堕棿 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + /** + * 閫昏緫鍒犻櫎 + */ + @TableField(value = "deleted") + private Long deleted; + /** + * 鍏宠仈鐨勮褰曠被鍨� + */ + @TableField(value = "record_type") + private Long recordType; + /** + * 鍏宠仈鐨勮褰昳d + */ + @TableField(value = "record_id") + private Long recordId; + /** + * 绫诲瀷鍚嶇О, 濡�: file, avatar (鍖哄垎鍚屼竴鏉¤褰曚笉鍚岀被鍨嬬殑闄勪欢) + */ + @TableField(value = "name") + private String name; + /** + * 鍏宠仈storage_blob璁板綍id + */ + @TableField(value = "storage_blob_id") + private Long storageBlobId; + + private StorageBlobDTO storageBlobDTO; + + public StorageAttachment(String fileType, Long recordType, Long recordId) { + this.name = fileType; + this.recordType = recordType; + this.recordId = recordId; + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/basic/entity/StorageBlob.java b/ruoyi-common/src/main/java/com/ruoyi/basic/entity/StorageBlob.java new file mode 100644 index 0000000..e793031 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/basic/entity/StorageBlob.java @@ -0,0 +1,65 @@ +package com.ruoyi.basic.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import com.ruoyi.common.core.domain.BaseEntity; + +import java.io.Serializable; +import java.util.Date; + +/** + * 閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭� 瀹炰綋绫� + * + * @author ruoyi + * @date 2025-05-29 + */ +@Data +@TableName("storage_blob") +public class StorageBlob implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** 鍒涘缓鏃堕棿 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") +// @TableField(fill = FieldFill.INSERT) + private Date createTime; + + /** + * 璧勬簮id + */ + @TableField(value = "key") + private String key; + /** + * 璧勬簮绫诲瀷锛屼緥濡侸PG鍥剧墖鐨勮祫婧愮被鍨嬩负image/jpg + */ + @TableField(value = "content_type") + private String contentType; + /** + * 鍘熸枃浠跺悕 + */ + @TableField(value = "original_filename") + private String originalFilename; + + /** + * 瀛樺偍妗朵腑 + */ + @TableField(value = "bucket_filename") + private String bucketFilename; + /** + * 瀛樺偍妗跺悕 + */ + @TableField(value = "bucket_name") + private String bucketName; + /** + * 璧勬簮灏哄(瀛楄妭) + */ + @TableField(value = "byte_size") + private Long byteSize; +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/basic/entity/dto/StorageBlobDTO.java b/ruoyi-common/src/main/java/com/ruoyi/basic/entity/dto/StorageBlobDTO.java new file mode 100644 index 0000000..2ab3d2c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/basic/entity/dto/StorageBlobDTO.java @@ -0,0 +1,9 @@ +package com.ruoyi.basic.entity.dto; + +import com.ruoyi.basic.entity.StorageBlob; +import lombok.Data; + +@Data +public class StorageBlobDTO extends StorageBlob { + private String url; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/basic/mapper/StorageAttachmentMapper.java b/ruoyi-common/src/main/java/com/ruoyi/basic/mapper/StorageAttachmentMapper.java new file mode 100644 index 0000000..9216656 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/basic/mapper/StorageAttachmentMapper.java @@ -0,0 +1,18 @@ +package com.ruoyi.basic.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.basic.entity.StorageAttachment; +import org.apache.ibatis.annotations.Mapper; + +/** + * <p> + * 閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭� Mapper 鎺ュ彛 + * </p> + * + * @author ruoyi + * @since 2025-05-29 + */ +@Mapper +public interface StorageAttachmentMapper extends BaseMapper<StorageAttachment> { + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/basic/mapper/StorageBlobMapper.java b/ruoyi-common/src/main/java/com/ruoyi/basic/mapper/StorageBlobMapper.java new file mode 100644 index 0000000..a832c80 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/basic/mapper/StorageBlobMapper.java @@ -0,0 +1,18 @@ +package com.ruoyi.basic.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.basic.entity.StorageBlob; +import org.apache.ibatis.annotations.Mapper; + +/** + * <p> + * 閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭� Mapper 鎺ュ彛 + * </p> + * + * @author ruoyi + * @since 2025-05-29 + */ +@Mapper +public interface StorageBlobMapper extends BaseMapper<StorageBlob> { + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/basic/service/StorageAttachmentService.java b/ruoyi-common/src/main/java/com/ruoyi/basic/service/StorageAttachmentService.java new file mode 100644 index 0000000..bcf9d31 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/basic/service/StorageAttachmentService.java @@ -0,0 +1,43 @@ +package com.ruoyi.basic.service; + +import com.ruoyi.basic.entity.StorageAttachment; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.constant.StorageAttachmentConstants; +import com.ruoyi.common.enums.StorageAttachmentRecordType; + +import java.util.List; + +/** + * <p> + * 閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭� 鏈嶅姟绫� + * </p> + * + * @author ruoyi + * @since 2025-05-29 + */ +public interface StorageAttachmentService extends IService<StorageAttachment> { + /** + * 鏌ヨ閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭� + * @param recordId 鍏宠仈璁板綍id + * @param recordType 鍏宠仈璁板綍绫诲瀷 + * @param fileType 鏂囦欢绫诲瀷 + * @return 鏂囦欢淇℃伅鍒楄〃 + */ + List<StorageAttachment> selectStorageAttachments(Long recordId, StorageAttachmentRecordType recordType, StorageAttachmentConstants fileType); + + /** + * 淇濆瓨閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭� + * @param attachments 鏂囦欢淇℃伅鍒楄〃 + * @param recordId 绠$悊璁板綍id + * @param recordType 鍏宠仈璁板綍绫诲瀷 + * @param fileType 鏂囦欢绫诲瀷 + */ + public void saveStorageAttachment(List<StorageAttachment> attachments, Long recordId, StorageAttachmentRecordType recordType, StorageAttachmentConstants fileType); + + /** + * 鍒犻櫎閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭� + * @param storageAttachment 鏂囦欢淇℃伅 + * @return 鍒犻櫎缁撴灉 + */ + public int deleteStorageAttachment(StorageAttachment storageAttachment); +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/basic/service/StorageBlobService.java b/ruoyi-common/src/main/java/com/ruoyi/basic/service/StorageBlobService.java new file mode 100644 index 0000000..b242c26 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/basic/service/StorageBlobService.java @@ -0,0 +1,35 @@ +package com.ruoyi.basic.service; + +import com.ruoyi.basic.entity.StorageAttachment; +import com.ruoyi.basic.entity.StorageBlob; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.basic.entity.dto.StorageBlobDTO; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + * <p> + * 閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭� 鏈嶅姟绫� + * </p> + * + * @author ruoyi + * @since 2025-05-29 + */ +public interface StorageBlobService extends IService<StorageBlob> { + + /** + * 鏂囦欢涓婁紶鎺ュ彛 + * @param files 鏂囦欢淇℃伅 + * @param bucketName 瀛樺偍妗跺悕绉� + * @return 涓婁紶缁撴灉 + */ + List<StorageBlobDTO> updateStorageBlobs(List<MultipartFile> files, String bucketName); + + /** + * 鎵归噺鍒犻櫎鏂囦欢 + * @param attachment + * @return + */ + public int deleteStorageBlobs(StorageAttachment attachment); +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/basic/service/impl/StorageAttachmentServiceImpl.java b/ruoyi-common/src/main/java/com/ruoyi/basic/service/impl/StorageAttachmentServiceImpl.java new file mode 100644 index 0000000..d4e87bf --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/basic/service/impl/StorageAttachmentServiceImpl.java @@ -0,0 +1,92 @@ +package com.ruoyi.basic.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.basic.entity.StorageAttachment; +import com.ruoyi.basic.entity.StorageBlob; +import com.ruoyi.basic.entity.dto.StorageBlobDTO; +import com.ruoyi.basic.mapper.StorageAttachmentMapper; +import com.ruoyi.basic.mapper.StorageBlobMapper; +import com.ruoyi.basic.service.StorageAttachmentService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.basic.service.StorageBlobService; +import com.ruoyi.common.constant.StorageAttachmentConstants; +import com.ruoyi.common.enums.StorageAttachmentRecordType; +import com.ruoyi.common.utils.file.MinioUtils; +import io.minio.MinioClient; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +/** + * <p> + * 閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭� 鏈嶅姟瀹炵幇绫� + * </p> + * + * @author ruoyi + * @since 2025-05-29 + */ +@Service +@RequiredArgsConstructor +public class StorageAttachmentServiceImpl extends ServiceImpl<StorageAttachmentMapper, StorageAttachment> implements StorageAttachmentService { + @Autowired + private StorageBlobMapper storageBlobMapper; + + @Autowired + private StorageAttachmentMapper storageAttachmentMapper; + + @Autowired + private StorageBlobService storageBlobService; + + @Autowired + private MinioUtils minioUtils; + + @Override + public List<StorageAttachment> selectStorageAttachments(Long recordId, StorageAttachmentRecordType recordType, StorageAttachmentConstants fileType) { + List<StorageAttachment> storageAttachments = storageAttachmentMapper.selectList(new LambdaQueryWrapper<StorageAttachment>() + .eq(StorageAttachment::getRecordId, recordId) + .eq(StorageAttachment::getRecordType, recordType.ordinal()) + .eq(StorageAttachment::getName, fileType.toString())); + if (storageAttachments != null) { + for (StorageAttachment storageAttachment : storageAttachments) { + StorageBlob storageBlob = storageBlobMapper.selectById(storageAttachment.getStorageBlobId()); + StorageBlobDTO storageBlobDTO = new StorageBlobDTO(); + BeanUtils.copyProperties(storageBlob, storageBlobDTO); + storageBlobDTO.setUrl(minioUtils.getPreviewUrl(storageBlob.getBucketName(), storageBlob.getBucketName(), true)); + storageAttachment.setStorageBlobDTO(storageBlobDTO); + } + } + + return storageAttachments; + } + + @Override + public void saveStorageAttachment(List<StorageAttachment> attachments, Long recordId, StorageAttachmentRecordType recordType, StorageAttachmentConstants fileType) { + // 鍒犻櫎鏃у浘 + deleteStorageAttachment(new StorageAttachment(fileType.toString(), (long) recordType.ordinal(), recordId)); + for (StorageAttachment attachment : attachments) { + // 鑾峰彇鍏宠仈璁板綍 + StorageBlob storageBlob = attachment.getStorageBlobDTO(); + attachment.setName(fileType.toString()); + attachment.setRecordType((long) recordType.ordinal()); + attachment.setRecordId(recordId); + attachment.setStorageBlobId(storageBlob.getId()); + storageAttachmentMapper.insert(attachment); + } + + } + + @Override + public int deleteStorageAttachment(StorageAttachment storageAttachment) { + // 鍏堝垹闄ゆ槑缁嗚〃 + storageBlobService.deleteStorageBlobs(storageAttachment); + + + return storageAttachmentMapper.delete(new LambdaQueryWrapper<StorageAttachment>() + .eq(StorageAttachment::getRecordId, storageAttachment.getRecordId()) + .eq(StorageAttachment::getRecordType, storageAttachment.getRecordType()) + .eq(StorageAttachment::getName, storageAttachment.getName())); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/basic/service/impl/StorageBlobServiceImpl.java b/ruoyi-common/src/main/java/com/ruoyi/basic/service/impl/StorageBlobServiceImpl.java new file mode 100644 index 0000000..dc7acff --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/basic/service/impl/StorageBlobServiceImpl.java @@ -0,0 +1,105 @@ +package com.ruoyi.basic.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.basic.entity.StorageAttachment; +import com.ruoyi.basic.entity.StorageBlob; +import com.ruoyi.basic.entity.dto.StorageBlobDTO; +import com.ruoyi.basic.mapper.StorageAttachmentMapper; +import com.ruoyi.basic.mapper.StorageBlobMapper; +import com.ruoyi.basic.service.StorageBlobService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.config.MinioConfig; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.MinioResult; +import com.ruoyi.common.exception.file.InvalidExtensionException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.MinioUtils; +import com.ruoyi.common.utils.uuid.IdUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import lombok.RequiredArgsConstructor; +import org.springframework.web.multipart.MultipartFile; + +import java.util.ArrayList; +import java.util.List; + +/** + * <p> + * 閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭� 鏈嶅姟瀹炵幇绫� + * </p> + * + * @author ruoyi + * @since 2025-05-29 + */ +@Service +@RequiredArgsConstructor +public class StorageBlobServiceImpl extends ServiceImpl<StorageBlobMapper, StorageBlob> implements StorageBlobService { + @Autowired + private StorageAttachmentMapper storageAttachmentMapper; + + @Autowired + private StorageBlobMapper storageBlobMapper; + + @Autowired + private MinioUtils minioUtils; + + @Override + public List<StorageBlobDTO> updateStorageBlobs(List<MultipartFile> files, String bucketName) { + + // 鑻ユ病浼犲叆bucketName锛屽垯浣跨敤榛樿bucketName + if (StringUtils.isEmpty(bucketName)) { + bucketName = minioUtils.getDefaultBucket(); + } + + List<StorageBlobDTO> storageBlobDTOs = new ArrayList<>(); + for (MultipartFile file : files) { + try { + MinioResult res = minioUtils.upload(bucketName, file, false); + StorageBlobDTO dto = new StorageBlobDTO(); + dto.setContentType(file.getContentType()); + dto.setBucketFilename(res.getBucketFileName()); + dto.setOriginalFilename(res.getOriginalName()); + dto.setByteSize(file.getSize()); + dto.setKey(IdUtils.simpleUUID()); + dto.setBucketName(bucketName); + dto.setCreateTime(DateUtils.getNowDate()); + dto.setUrl(minioUtils.getPreviewUrl(res.getBucketFileName(), bucketName, false)); + // 鎻掑叆鏁版嵁搴� + storageBlobMapper.insert(dto); + + storageBlobDTOs.add(dto); + } catch (InvalidExtensionException e) { + throw new RuntimeException("minio鏂囦欢涓婁紶寮傚父锛�" + e); + } + } + + + return storageBlobDTOs; + } + + @Override + public int deleteStorageBlobs(StorageAttachment attachment) { + List<StorageAttachment> attachments = storageAttachmentMapper.selectList(new LambdaQueryWrapper<StorageAttachment>() + .eq(StorageAttachment::getRecordId, attachment.getRecordId()) + .eq(StorageAttachment::getRecordType, attachment.getRecordType()) + .eq(StorageAttachment::getName, attachment.getName())); + List<Long> ids = attachments.stream().map(StorageAttachment::getStorageBlobId).toList(); + List<StorageBlob> storageBlobs = storageBlobMapper.selectList(new LambdaQueryWrapper<StorageBlob>() + .in(StorageBlob::getId, ids)); + if (!storageBlobs.isEmpty()) { + for (StorageBlob storageBlob : storageBlobs) { + // 绉婚櫎妗跺唴鏂囦欢 + minioUtils.removeObjectsResult(storageBlob.getBucketName(), storageBlob.getBucketName()); + } + } + + if (!ids.isEmpty()) { + return storageBlobMapper.delete(new QueryWrapper<StorageBlob>().lambda().in(StorageBlob::getId, ids)); + } + + return 0; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/StorageAttachmentConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/StorageAttachmentConstants.java new file mode 100644 index 0000000..1bc8123 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/StorageAttachmentConstants.java @@ -0,0 +1,17 @@ +package com.ruoyi.common.constant; + +/** + * 闄勪欢甯搁噺 + */ +public class StorageAttachmentConstants { + + /** + * 鏂囦欢 + */ + public static final String StorageAttachmentFile = "file"; + + /** + * 鍥剧墖 + */ + public static final String StorageAttachmentImage = "image"; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/handler/MyMetaObjectHandler.java b/ruoyi-common/src/main/java/com/ruoyi/common/handler/MyMetaObjectHandler.java new file mode 100644 index 0000000..46811dd --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/handler/MyMetaObjectHandler.java @@ -0,0 +1,43 @@ +package com.ruoyi.common.handler; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; + +/** + * @Author: zhangxy + * @Date: 2020-08-05 14:40 + */ +@Component +public class MyMetaObjectHandler implements MetaObjectHandler { + + + @Override + public void insertFill(MetaObject metaObject) { + this.setFieldValByName("createTime", LocalDateTime.now(), metaObject); + this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject); + // 寮�绾跨▼锛屽彇涓嶅埌user + try { +// SysUser currentUser = SecurityUtils.getLoginUser(); +// if (currentUser != null) { +// this.setFieldValByName("createUser", currentUser.getUsername(), metaObject); +// this.setFieldValByName("updateUser", currentUser.getUsername(), metaObject); +// } + } catch (Exception e) { + } + } + + @Override + public void updateFill(MetaObject metaObject) { + this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject); + try { +// ZttUser currentUser = SecurityUtils.getUser(); +// if (currentUser != null) { +// this.setFieldValByName("updateUser", currentUser.getUsername(), metaObject); +// } + } catch (Exception e) { + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MinioUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MinioUtils.java index de6ad5f..4b87a2e 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MinioUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MinioUtils.java @@ -9,6 +9,7 @@ import io.minio.http.Method; import io.minio.messages.DeleteError; import io.minio.messages.DeleteObject; +import lombok.Getter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -34,6 +35,16 @@ @Value("${minio.preview-expiry}") private Integer previewExpiry; + + /** + * -- GETTER -- + * 鑾峰彇榛樿瀛樺偍妗跺悕绉� + * + * @return + */ + @Getter + @Value("${minio.default-bucket}") + private String defaultBucket; /** * 鍒ゆ柇瀛樺偍妗舵槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯鍒涘缓 @@ -161,7 +172,7 @@ .build() ); } catch (Exception e) { - throw new UtilException("MinioUtils锛氫笂浼犳枃浠跺伐鍏风被寮傚父"); + throw new UtilException("MinioUtils锛氫笂浼犳枃浠跺伐鍏风被寮傚父:" + e); } MinioResult minioResult = new MinioResult(); minioResult.setBucketFileName(bucketFilePath); @@ -291,4 +302,5 @@ } return null; } + } diff --git a/ruoyi-common/src/main/resources/db/migration/postgresql/V20250525003427__create_table_storage_blob.sql b/ruoyi-common/src/main/resources/db/migration/postgresql/V20250525003427__create_table_storage_blob.sql index 05cf963..d1ad350 100644 --- a/ruoyi-common/src/main/resources/db/migration/postgresql/V20250525003427__create_table_storage_blob.sql +++ b/ruoyi-common/src/main/resources/db/migration/postgresql/V20250525003427__create_table_storage_blob.sql @@ -2,12 +2,14 @@ CREATE TABLE storage_blob ( - id bigserial PRIMARY KEY, - created_at timestamp default now() NOT NULL, - key varchar(150) DEFAULT '' NOT NULL, - content_type varchar(100) DEFAULT '' NOT NULL, - filename varchar(255) DEFAULT '' NOT NULL, - byte_size bigint DEFAULT 0 NOT NULL, + id bigserial PRIMARY KEY, + create_time timestamp default now() NOT NULL, + key varchar(150) DEFAULT '' NOT NULL, + content_type varchar(100) DEFAULT '' NOT NULL, + original_filename varchar(255) DEFAULT '' NOT NULL, + bucket_filename varchar(255) DEFAULT '' NOT NULL, + bucket_name varchar(255) DEFAULT '' NOT NULL, + byte_size bigint DEFAULT 0 NOT NULL, UNIQUE (key) ); @@ -15,6 +17,8 @@ COMMENT ON COLUMN storage_blob.key IS '璧勬簮id'; COMMENT ON COLUMN storage_blob.content_type IS '璧勬簮绫诲瀷锛屼緥濡侸PG鍥剧墖鐨勮祫婧愮被鍨嬩负image/jpg'; -COMMENT ON COLUMN storage_blob.filename IS '鏂囦欢鍚�'; +COMMENT ON COLUMN storage_blob.original_filename IS '鍘熸枃浠跺悕绉�'; +COMMENT ON COLUMN storage_blob.bucket_filename IS '瀛樺偍妗朵腑鏂囦欢鍚�'; +COMMENT ON COLUMN storage_blob.bucket_name IS '瀛樺偍妗跺悕'; COMMENT ON COLUMN storage_blob.byte_size IS '璧勬簮灏哄(瀛楄妭)'; diff --git a/ruoyi-common/src/main/resources/db/migration/postgresql/V20250525003447__create_table_storage_attachment.sql b/ruoyi-common/src/main/resources/db/migration/postgresql/V20250525003447__create_table_storage_attachment.sql index d743faa..98a73de 100644 --- a/ruoyi-common/src/main/resources/db/migration/postgresql/V20250525003447__create_table_storage_attachment.sql +++ b/ruoyi-common/src/main/resources/db/migration/postgresql/V20250525003447__create_table_storage_attachment.sql @@ -2,24 +2,24 @@ -- 闄勪欢琛� -- ---------------------------- drop table if exists storage_attachment; -CREATE TABLE storage_attachments +CREATE TABLE storage_attachment ( id bigserial PRIMARY KEY, - created_at timestamp default now() NOT NULL, - updated_at timestamp default now() NOT NULL, - deleted_at bigint DEFAULT 0 NOT NULL, + create_time timestamp default now() NOT NULL, + update_time timestamp default now() NOT NULL, + deleted bigint DEFAULT 0 NOT NULL, record_type smallint DEFAULT 0 NOT NULL, record_id bigint DEFAULT 0 NOT NULL, name varchar(100) DEFAULT '' NOT NULL, storage_blob_id bigint DEFAULT 0 NOT NULL ); -COMMENT ON TABLE storage_attachments IS '閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭�'; +COMMENT ON TABLE storage_attachment IS '閫氱敤鏂囦欢涓婁紶鐨勯檮浠朵俊鎭�'; -COMMENT ON COLUMN storage_attachments.record_type IS '鍏宠仈鐨勮褰曠被鍨�'; -COMMENT ON COLUMN storage_attachments.record_id IS '鍏宠仈鐨勮褰昳d'; -COMMENT ON COLUMN storage_attachments.name IS '鍚嶇О, 濡�: file, avatar (鍖哄垎鍚屼竴鏉¤褰曚笉鍚岀被鍨嬬殑闄勪欢)'; -COMMENT ON COLUMN storage_attachments.storage_blob_id IS '鍏宠仈storage_blob璁板綍id'; +COMMENT ON COLUMN storage_attachment.record_type IS '鍏宠仈鐨勮褰曠被鍨�'; +COMMENT ON COLUMN storage_attachment.record_id IS '鍏宠仈鐨勮褰昳d'; +COMMENT ON COLUMN storage_attachment.name IS '鍚嶇О, 濡�: file, avatar (鍖哄垎鍚屼竴鏉¤褰曚笉鍚岀被鍨嬬殑闄勪欢)'; +COMMENT ON COLUMN storage_attachment.storage_blob_id IS '鍏宠仈storage_blob璁板綍id'; -CREATE INDEX idx_storage_attachments_on_record - ON storage_attachments (record_type, record_id); \ No newline at end of file +CREATE INDEX idx_storage_attachment_on_record + ON storage_attachment (record_type, record_id); \ No newline at end of file diff --git a/ruoyi-common/src/main/resources/mapper/StorageAttachmentMapper.xml b/ruoyi-common/src/main/resources/mapper/StorageAttachmentMapper.xml new file mode 100644 index 0000000..60830e9 --- /dev/null +++ b/ruoyi-common/src/main/resources/mapper/StorageAttachmentMapper.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.basic.mapper.StorageAttachmentMapper"> + + <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 --> + <resultMap id="BaseResultMap" type="com.ruoyi.basic.entity.StorageAttachment"> + <id column="id" property="id" /> + <result column="create_time" property="createTime" /> + <result column="update_time" property="updateTime" /> + <result column="deleted" property="deleted" /> + <result column="record_type" property="recordType" /> + <result column="record_id" property="recordId" /> + <result column="name" property="name" /> + <result column="storage_blob_id" property="storageBlobId" /> + </resultMap> + + <!-- 閫氱敤鏌ヨ缁撴灉鍒� --> + <sql id="Base_Column_List"> + id, create_time, update_time, deleted, record_type, record_id, name, storage_blob_id + </sql> + +</mapper> \ No newline at end of file diff --git a/ruoyi-common/src/main/resources/mapper/StorageBlobMapper.xml b/ruoyi-common/src/main/resources/mapper/StorageBlobMapper.xml new file mode 100644 index 0000000..eace5ea --- /dev/null +++ b/ruoyi-common/src/main/resources/mapper/StorageBlobMapper.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.basic.mapper.StorageBlobMapper"> + + <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 --> + <resultMap id="BaseResultMap" type="com.ruoyi.basic.entity.StorageBlob"> + <id column="id" property="id" /> + <result column="create_time" property="createTime" /> + <result column="key" property="key" /> + <result column="content_type" property="contentType" /> + <result column="original_filename" property="originalFilename" /> + <result column="bucket_filename" property="bucketFilename" /> + <result column="bucket_name" property="bucketName" /> + <result column="byte_size" property="byteSize" /> + </resultMap> + + <!-- 閫氱敤鏌ヨ缁撴灉鍒� --> + <sql id="Base_Column_List"> + id, create_time, key, content_type, original_filename,bucket_filename,bucket_name, byte_size + </sql> + +</mapper> \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml index d576174..353a345 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -50,13 +50,13 @@ </select> <select id="selectMenuTreeAll" resultMap="SysMenuResult"> - select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m."query", m.route_name, m.visible, m.status, COALESCE(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time - from sys_menu m where m.menu_type in ('M', 'C') and m.status = 0 + select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.query, m.route_name, m.visible, m.status, COALESCE(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time + from sys_menu m where m.menu_type in ('M', 'C') and m.status = '0' order by m.parent_id, m.order_num </select> <select id="selectMenuListByUserId" parameterType="SysMenu" resultMap="SysMenuResult"> - select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m."query", m.route_name, m.visible, m.status, COALESCE(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time + select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.query, m.route_name, m.visible, m.status, COALESCE(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time from sys_menu m left join sys_role_menu rm on m.menu_id = rm.menu_id left join sys_user_role ur on rm.role_id = ur.role_id @@ -75,13 +75,13 @@ </select> <select id="selectMenuTreeByUserId" parameterType="Long" resultMap="SysMenuResult"> - select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m."query", m.route_name, m.visible, m.status, COALESCE(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time + select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.query, m.route_name, m.visible, m.status, COALESCE(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time from sys_menu m left join sys_role_menu rm on m.menu_id = rm.menu_id left join sys_user_role ur on rm.role_id = ur.role_id left join sys_role ro on ur.role_id = ro.role_id left join sys_user u on ur.user_id = u.user_id - where u.user_id = #{userId} and m.menu_type in ('M', 'C') and m.status = 0 AND ro.status = 0 + where u.user_id = #{userId} and m.menu_type in ('M', 'C') and m.status = '0' AND ro.status = '0' order by m.parent_id, m.order_num </select> -- Gitblit v1.9.3