From dcb696a94a8015fa62e2b7c66d8e908f04aeb1eb Mon Sep 17 00:00:00 2001 From: Odboy Date: Thu, 17 Jul 2025 22:48:37 +0800 Subject: [PATCH] =?UTF-8?q?feat(system):=20=E4=BC=98=E5=8C=96=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=B8=8A=E4=BC=A0=E5=8A=9F=E8=83=BD=E5=B9=B6=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=89=8D=E7=AB=AF=E4=B8=8A=E4=BC=A0=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改后端文件上传接口,返回上传文件的URL - 新增文件上传前的本地校验逻辑- 实现文件拖拽上传功能 - 添加两个新的前端上传组件:CuteFileUpload 和 CuteFileDragUpload - 更新后端 MinioRepository 类,支持生成预签名 URL --- README.MD | 2 + .../business/CuteFileDragUpload.vue | 69 +++++++++++++++++++ .../components/business/CuteFileUpload.vue | 67 ++++++++++++++++++ .../src/views/system/storage/oss/index.vue | 8 +-- .../SystemOssStorageController.java | 6 +- .../storage/minio/MinioRepository.java | 45 +++++------- .../service/SystemOssStorageService.java | 4 +- .../impl/SystemOssStorageServiceImpl.java | 41 ++++++++++- 8 files changed, 204 insertions(+), 38 deletions(-) create mode 100644 cutejava-front/src/views/components/business/CuteFileDragUpload.vue create mode 100644 cutejava-front/src/views/components/business/CuteFileUpload.vue diff --git a/README.MD b/README.MD index 1696570a..32f9276a 100644 --- a/README.MD +++ b/README.MD @@ -72,6 +72,8 @@ https://github.com/odboy-tianjun/cutejava - CuteDeptTree 部门树 - CuteUserSelect 用户多选框 +- CuteFileUpload 上传文件到OSS, 必须结合Minio使用(上传完成后必须销毁组件) +- CuteFileDragUpload 支持拖拽上传文件到OSS, 必须结合Minio使用(上传完成后必须销毁组件) #### 系统模块 diff --git a/cutejava-front/src/views/components/business/CuteFileDragUpload.vue b/cutejava-front/src/views/components/business/CuteFileDragUpload.vue new file mode 100644 index 00000000..1dbfaba3 --- /dev/null +++ b/cutejava-front/src/views/components/business/CuteFileDragUpload.vue @@ -0,0 +1,69 @@ + + + diff --git a/cutejava-front/src/views/components/business/CuteFileUpload.vue b/cutejava-front/src/views/components/business/CuteFileUpload.vue new file mode 100644 index 00000000..aa5b4b53 --- /dev/null +++ b/cutejava-front/src/views/components/business/CuteFileUpload.vue @@ -0,0 +1,67 @@ + + + diff --git a/cutejava-front/src/views/system/storage/oss/index.vue b/cutejava-front/src/views/system/storage/oss/index.vue index d6504efc..8c635111 100644 --- a/cutejava-front/src/views/system/storage/oss/index.vue +++ b/cutejava-front/src/views/system/storage/oss/index.vue @@ -40,9 +40,6 @@ width="500px" > - - -
添加文件
可上传任意格式文件,且不超过100M
@@ -106,7 +103,7 @@ import DateRangePicker from '@/components/DateRangePicker' import Clipboard from 'clipboard' import { Message } from 'element-ui' -const defaultForm = { id: null, name: '' } +const defaultForm = { id: null } export default { components: { pagination, crudOperation, rrOperation, DateRangePicker }, cruds() { @@ -145,7 +142,6 @@ export default { this.loading = false this.$message.error('上传文件大小不能超过 100MB') } - this.form.name = file.name return isLt2M }, handleSuccess(response, file, fileList) { diff --git a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/controller/SystemOssStorageController.java b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/controller/SystemOssStorageController.java index 48cf44c1..97fa0109 100644 --- a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/controller/SystemOssStorageController.java +++ b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/controller/SystemOssStorageController.java @@ -49,9 +49,9 @@ public class SystemOssStorageController { @ApiOperation("上传文件") @PostMapping(value = "/uploadFile") @PreAuthorize("@el.check('storage:add')") - public ResponseEntity uploadFile(@RequestParam String name, @RequestParam("file") MultipartFile file) { - systemOssStorageService.uploadFile(name, file); - return new ResponseEntity<>(HttpStatus.CREATED); + public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file) { + String fileUrl = systemOssStorageService.uploadFile(file); + return ResponseEntity.ok(fileUrl); } @ApiOperation("多选删除") diff --git a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/framework/storage/minio/MinioRepository.java b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/framework/storage/minio/MinioRepository.java index 90b14486..5f921679 100644 --- a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/framework/storage/minio/MinioRepository.java +++ b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/framework/storage/minio/MinioRepository.java @@ -11,7 +11,6 @@ import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.properties.AppProperties; import cn.odboy.framework.properties.model.OSSConfigModel; import cn.odboy.framework.properties.model.StorageOSSModel; -import cn.odboy.framework.server.core.FileUploadPathHelper; import cn.odboy.system.dal.dataobject.SystemOssStorageTb; import cn.odboy.util.CsDateUtil; import cn.odboy.util.FileUtil; @@ -38,7 +37,6 @@ import java.util.List; public class MinioRepository { private final AppProperties properties; private final MinioClient minioClient; - private final FileUploadPathHelper fileUploadPathHelper; /** * 检查存储bucket是否存在 @@ -114,27 +112,19 @@ public class MinioRepository { /** * 文件上传 * - * @param file 文件 + * @param tempFile 文件 + * @param originalFilename 源文件名 + * @param fileSize 文件大小 + * @param contentType 文件类型 + * @param md5 文件md5 * @return String 上传后的文件名,上传失败返回 null */ - public SystemOssStorageTb upload(MultipartFile file) { - String originalFilename = file.getOriginalFilename(); - if (StrUtil.isBlank(originalFilename)) { - throw new BadRequestException("文件名不能为空"); - } - + public SystemOssStorageTb upload(File tempFile, String originalFilename, long fileSize, String contentType, String md5) { StorageOSSModel ossConfig = properties.getOss(); OSSConfigModel ossMinioConfig = ossConfig.getMinio(); - long fileSize = file.getSize(); - FileUtil.checkSize(ossConfig.getMaxSize(), fileSize); - String contentType = file.getContentType(); - - // 按天分组 - String nowDateStr = CsDateUtil.getNowDateStr(); - File tempFile = FileUtil.upload(file, fileUploadPathHelper.getPath() + nowDateStr + File.separator); - if (tempFile == null) { - throw new BadRequestException("上传失败"); - } + String type = FileTypeUtil.getType(tempFile); + String prefix = FileUtil.getPrefix(tempFile); + String suffix = FileUtil.getSuffix(tempFile); String fileCode = IdUtil.fastSimpleUUID(); String fileName = fileCode + getFileExtension(originalFilename); @@ -148,10 +138,10 @@ public class MinioRepository { systemOssStorageTb.setBucketName(StrUtil.trim(ossMinioConfig.getBucketName())); systemOssStorageTb.setFileName(originalFilename); systemOssStorageTb.setFileSize(fileSize); - systemOssStorageTb.setFileMime(FileTypeUtil.getType(tempFile)); - systemOssStorageTb.setFilePrefix(FileUtil.getPrefix(tempFile)); - systemOssStorageTb.setFileSuffix(FileUtil.getSuffix(tempFile)); - systemOssStorageTb.setFileMd5(FileUtil.getMd5(tempFile)); + systemOssStorageTb.setFileMime(type); + systemOssStorageTb.setFilePrefix(prefix); + systemOssStorageTb.setFileSuffix(suffix); + systemOssStorageTb.setFileMd5(md5); systemOssStorageTb.setFileUrl(fileUrl); systemOssStorageTb.setFileCode(fileCode); systemOssStorageTb.setObjectName(objectName); @@ -276,9 +266,12 @@ public class MinioRepository { return null; } try { - GetPresignedObjectUrlArgs presignedUrlArgs = GetPresignedObjectUrlArgs.builder().bucket(properties.getOss().getMinio().getBucketName()).object(fullFileName).method(Method.GET) - // 设置 URL 过期时间为 1 小时 - .expiry(3600).build(); + GetPresignedObjectUrlArgs presignedUrlArgs = GetPresignedObjectUrlArgs.builder() + .bucket(properties.getOss().getMinio().getBucketName()) + .object(fullFileName) + .method(Method.GET) + // 设置 URL 过期时间为 7 天, 最大 7 天, 别挣扎了 + .expiry(3600 * 24 * 7).build(); String url = minioClient.getPresignedObjectUrl(presignedUrlArgs); log.info("生成预签名 URL 成功,fileName: {}, url: {}", fullFileName, url); return url; diff --git a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/service/SystemOssStorageService.java b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/service/SystemOssStorageService.java index 97c7d312..b9fc3138 100644 --- a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/service/SystemOssStorageService.java +++ b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/service/SystemOssStorageService.java @@ -27,7 +27,9 @@ public interface SystemOssStorageService extends IService { void exportOssStorageExcel(List list, HttpServletResponse response) throws IOException; - void uploadFile(String name, MultipartFile file); + String uploadFile(MultipartFile file); void removeFileByIds(Long[] ids); + + SystemOssStorageTb getByMd5(String md5); } diff --git a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/service/impl/SystemOssStorageServiceImpl.java b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/service/impl/SystemOssStorageServiceImpl.java index 13c1d819..baa2e985 100644 --- a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/service/impl/SystemOssStorageServiceImpl.java +++ b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/service/impl/SystemOssStorageServiceImpl.java @@ -1,14 +1,19 @@ package cn.odboy.system.service.impl; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.StrUtil; import cn.odboy.base.CsResultVo; import cn.odboy.framework.exception.BadRequestException; +import cn.odboy.framework.properties.AppProperties; +import cn.odboy.framework.properties.model.StorageOSSModel; +import cn.odboy.framework.server.core.FileUploadPathHelper; import cn.odboy.system.dal.dataobject.SystemOssStorageTb; import cn.odboy.system.dal.model.SystemOssStorageVo; import cn.odboy.system.dal.model.SystemQueryStorageArgs; import cn.odboy.system.dal.mysql.SystemOssStorageMapper; import cn.odboy.system.framework.storage.minio.MinioRepository; import cn.odboy.system.service.SystemOssStorageService; +import cn.odboy.util.CsDateUtil; import cn.odboy.util.CsPageUtil; import cn.odboy.util.FileUtil; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -20,6 +25,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -38,6 +44,8 @@ import java.util.Map; @RequiredArgsConstructor public class SystemOssStorageServiceImpl extends ServiceImpl implements SystemOssStorageService { private final MinioRepository minioRepository; + private final AppProperties properties; + private final FileUploadPathHelper fileUploadPathHelper; @Override public CsResultVo> queryOssStorage(SystemQueryStorageArgs criteria, Page page) { @@ -77,12 +85,36 @@ public class SystemOssStorageServiceImpl extends ServiceImpl