diff --git a/jsowell-admin/src/main/java/com/jsowell/web/controller/common/CommonController.java b/jsowell-admin/src/main/java/com/jsowell/web/controller/common/CommonController.java index edf07688c..0eb92a87a 100644 --- a/jsowell-admin/src/main/java/com/jsowell/web/controller/common/CommonController.java +++ b/jsowell-admin/src/main/java/com/jsowell/web/controller/common/CommonController.java @@ -30,114 +30,134 @@ import java.util.List; @RestController @RequestMapping("/common") public class CommonController { - private static final Logger log = LoggerFactory.getLogger(CommonController.class); + private static final Logger log = LoggerFactory.getLogger(CommonController.class); - @Autowired - private ServerConfig serverConfig; + @Autowired + private ServerConfig serverConfig; - private static final String FILE_DELIMETER = ","; + private static final String FILE_DELIMETER = ","; - /** - * 通用下载请求 - * - * @param fileName 文件名称 - * @param delete 是否删除 - */ - @GetMapping("/download") - public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) { - try { - if (!FileUtils.checkAllowDownload(fileName)) { - throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); - } - String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); - String filePath = JsowellConfig.getDownloadPath() + fileName; + /** + * 通用下载请求 + * + * @param fileName 文件名称 + * @param delete 是否删除 + */ + @GetMapping("/download") + public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) { + try { + if (!FileUtils.checkAllowDownload(fileName)) { + throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); + } + String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); + String filePath = JsowellConfig.getDownloadPath() + fileName; - response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); - FileUtils.setAttachmentResponseHeader(response, realFileName); - FileUtils.writeBytes(filePath, response.getOutputStream()); - if (delete) { - FileUtils.deleteFile(filePath); - } - } catch (Exception e) { - log.error("下载文件失败", e); - } - } + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, realFileName); + FileUtils.writeBytes(filePath, response.getOutputStream()); + if (delete) { + FileUtils.deleteFile(filePath); + } + } catch (Exception e) { + log.error("下载文件失败", e); + } + } - /** - * 通用上传请求(单个) - */ - @PostMapping("/upload") - public AjaxResult uploadFile(MultipartFile file) throws Exception { - try { - // 上传文件路径 - String filePath = JsowellConfig.getUploadPath(); - // 上传并返回新文件名称 - String fileName = FileUploadUtils.upload(filePath, file); - String url = serverConfig.getUrl() + fileName; - AjaxResult ajax = AjaxResult.success(); - ajax.put("url", url); - ajax.put("fileName", fileName); - ajax.put("newFileName", FileUtils.getName(fileName)); - ajax.put("originalFilename", file.getOriginalFilename()); - return ajax; - } catch (Exception e) { - return AjaxResult.error(e.getMessage()); - } - } + /** + * 通用上传请求(单个) + */ + @PostMapping("/upload") + public AjaxResult uploadFile(MultipartFile file) throws Exception { + try { + // 上传文件路径 + String filePath = JsowellConfig.getUploadPath(); + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + AjaxResult ajax = AjaxResult.success(); + ajax.put("url", url); + ajax.put("fileName", fileName); + ajax.put("newFileName", FileUtils.getName(fileName)); + ajax.put("originalFilename", file.getOriginalFilename()); + return ajax; + } catch (Exception e) { + return AjaxResult.error(e.getMessage()); + } + } - /** - * 通用上传请求(多个) - */ - @PostMapping("/uploads") - public AjaxResult uploadFiles(List files) throws Exception { - try { - // 上传文件路径 - String filePath = JsowellConfig.getUploadPath(); - List urls = new ArrayList(); - List fileNames = new ArrayList(); - List newFileNames = new ArrayList(); - List originalFilenames = new ArrayList(); - for (MultipartFile file : files) { - // 上传并返回新文件名称 - String fileName = FileUploadUtils.upload(filePath, file); - String url = serverConfig.getUrl() + fileName; - urls.add(url); - fileNames.add(fileName); - newFileNames.add(FileUtils.getName(fileName)); - originalFilenames.add(file.getOriginalFilename()); - } - AjaxResult ajax = AjaxResult.success(); - ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); - ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER)); - ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER)); - ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER)); - return ajax; - } catch (Exception e) { - return AjaxResult.error(e.getMessage()); - } - } + /** + * 通用上传请求(多个) + */ + @PostMapping("/uploads") + public AjaxResult uploadFiles(List files) throws Exception { + try { + // 上传文件路径 + String filePath = JsowellConfig.getUploadPath(); + List urls = new ArrayList(); + List fileNames = new ArrayList(); + List newFileNames = new ArrayList(); + List originalFilenames = new ArrayList(); + for (MultipartFile file : files) { + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + urls.add(url); + fileNames.add(fileName); + newFileNames.add(FileUtils.getName(fileName)); + originalFilenames.add(file.getOriginalFilename()); + } + AjaxResult ajax = AjaxResult.success(); + ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); + ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER)); + ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER)); + ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER)); + return ajax; + } catch (Exception e) { + return AjaxResult.error(e.getMessage()); + } + } - /** - * 本地资源通用下载 - */ - @GetMapping("/download/resource") - public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) - throws Exception { - try { - if (!FileUtils.checkAllowDownload(resource)) { - throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); - } - // 本地资源路径 - String localPath = JsowellConfig.getProfile(); - // 数据库资源地址 - String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); - // 下载名称 - String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); - response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); - FileUtils.setAttachmentResponseHeader(response, downloadName); - FileUtils.writeBytes(downloadPath, response.getOutputStream()); - } catch (Exception e) { - log.error("下载文件失败", e); - } - } + /** + * 本地资源通用下载 + */ + @GetMapping("/download/resource") + public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) + throws Exception { + try { + if (!FileUtils.checkAllowDownload(resource)) { + throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); + } + // 本地资源路径 + String localPath = JsowellConfig.getProfile(); + // 数据库资源地址 + String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); + // 下载名称 + String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, downloadName); + FileUtils.writeBytes(downloadPath, response.getOutputStream()); + } catch (Exception e) { + log.error("下载文件失败", e); + } + } + + + /** + * 自定义 Minio 服务器上传请求 + */ + @PostMapping("/uploadMinio") + public AjaxResult uploadFileMinio(MultipartFile file) throws Exception { + try { + // 上传并返回新文件名称 + String fileName = FileUploadUtils.uploadMinio(file); + AjaxResult ajax = AjaxResult.success(); + ajax.put("url", fileName); + ajax.put("fileName", fileName); + ajax.put("newFileName", FileUtils.getName(fileName)); + ajax.put("originalFilename", file.getOriginalFilename()); + return ajax; + } catch (Exception e) { + return AjaxResult.error(e.getMessage()); + } + } } diff --git a/jsowell-admin/src/main/resources/application-dev.yml b/jsowell-admin/src/main/resources/application-dev.yml index 85ff393bf..9df616ccd 100644 --- a/jsowell-admin/src/main/resources/application-dev.yml +++ b/jsowell-admin/src/main/resources/application-dev.yml @@ -97,6 +97,13 @@ logging: qrcodeurl: prefix: https://api.jsowellcloud.com +# Minio配置 +minio: + url: http://localhost:9000 + accessKey: minioadmin + secretKey: minioadmin + bucketName: jsowell + ########################微信支付参数####################################### #微信商户号 diff --git a/jsowell-common/pom.xml b/jsowell-common/pom.xml index 03605d687..68346046a 100644 --- a/jsowell-common/pom.xml +++ b/jsowell-common/pom.xml @@ -157,6 +157,13 @@ hutool-all + + + io.minio + minio + 8.2.1 + + diff --git a/jsowell-common/src/main/java/com/jsowell/common/config/MinioConfig.java b/jsowell-common/src/main/java/com/jsowell/common/config/MinioConfig.java new file mode 100644 index 000000000..180a37ed0 --- /dev/null +++ b/jsowell-common/src/main/java/com/jsowell/common/config/MinioConfig.java @@ -0,0 +1,83 @@ +package com.jsowell.common.config; + +import io.minio.MinioClient; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +/** + * Minio 配置信息 + * + * @author ruoyi + */ +@Configuration +@ConfigurationProperties(prefix = "minio") +public class MinioConfig +{ + /** + * 服务地址 + */ + private static String url; + + /** + * 用户名 + */ + private static String accessKey; + + /** + * 密码 + */ + private static String secretKey; + + /** + * 存储桶名称 + */ + private static String bucketName; + + public static String getUrl() + { + return url; + } + + public void setUrl(String url) + { + MinioConfig.url = url; + } + + public static String getAccessKey() + { + return accessKey; + } + + public void setAccessKey(String accessKey) + { + MinioConfig.accessKey = accessKey; + } + + public static String getSecretKey() + { + return secretKey; + } + + public void setSecretKey(String secretKey) + { + MinioConfig.secretKey = secretKey; + } + + public static String getBucketName() + { + return bucketName; + } + + public void setBucketName(String bucketName) + { + MinioConfig.bucketName = bucketName; + } + + @Bean + public MinioClient getMinioClient() + { + return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build(); + } +} diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/file/FileUploadUtils.java b/jsowell-common/src/main/java/com/jsowell/common/util/file/FileUploadUtils.java index b5c961e9a..ae6380a7b 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/util/file/FileUploadUtils.java +++ b/jsowell-common/src/main/java/com/jsowell/common/util/file/FileUploadUtils.java @@ -1,6 +1,7 @@ package com.jsowell.common.util.file; import com.jsowell.common.config.JsowellConfig; +import com.jsowell.common.config.MinioConfig; import com.jsowell.common.constant.Constants; import com.jsowell.common.exception.file.FileNameLengthLimitExceededException; import com.jsowell.common.exception.file.FileSizeLimitExceededException; @@ -19,7 +20,7 @@ import java.util.Objects; /** * 文件上传工具类 * - * @author jsowell + * @author ruoyi */ public class FileUploadUtils { /** @@ -33,10 +34,15 @@ public class FileUploadUtils { public static final int DEFAULT_FILE_NAME_LENGTH = 100; /** - * 默认上传的地址 + * 本地默认上传的地址 */ private static String defaultBaseDir = JsowellConfig.getProfile(); + /** + * Minio默认上传的地址 + */ + private static String bucketName = MinioConfig.getBucketName(); + public static void setDefaultBaseDir(String defaultBaseDir) { FileUploadUtils.defaultBaseDir = defaultBaseDir; } @@ -45,6 +51,10 @@ public class FileUploadUtils { return defaultBaseDir; } + public static String getBucketName() { + return bucketName; + } + /** * 以默认配置进行文件上传 * @@ -105,6 +115,53 @@ public class FileUploadUtils { return getPathFileName(baseDir, fileName); } + /** + * 以默认BucketName配置上传到Minio服务器 + * + * @param file 上传的文件 + * @return 文件名称 + * @throws Exception + */ + public static final String uploadMinio(MultipartFile file) throws IOException { + try { + return uploadMinino(getBucketName(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } catch (Exception e) { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 自定义bucketName配置上传到Minio服务器 + * + * @param file 上传的文件 + * @return 文件名称 + * @throws Exception + */ + public static final String uploadMinio(MultipartFile file, String bucketName) throws IOException { + try { + return uploadMinino(bucketName, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } catch (Exception e) { + throw new IOException(e.getMessage(), e); + } + } + + private static final String uploadMinino(String bucketName, MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, + InvalidExtensionException { + int fileNamelength = file.getOriginalFilename().length(); + if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) { + throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); + } + assertAllowed(file, allowedExtension); + try { + String fileName = extractFilename(file); + String pathFileName = MinioUtil.uploadFile(bucketName, fileName, file); + return pathFileName; + } catch (Exception e) { + throw new IOException(e.getMessage(), e); + } + } + /** * 编码文件名 */ @@ -195,4 +252,4 @@ public class FileUploadUtils { } return extension; } -} +} \ No newline at end of file diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/file/MinioUtil.java b/jsowell-common/src/main/java/com/jsowell/common/util/file/MinioUtil.java new file mode 100644 index 000000000..dfe78868b --- /dev/null +++ b/jsowell-common/src/main/java/com/jsowell/common/util/file/MinioUtil.java @@ -0,0 +1,39 @@ +package com.jsowell.common.util.file; + +import com.jsowell.common.util.ServletUtils; +import com.jsowell.common.util.spring.SpringUtils; +import io.minio.GetPresignedObjectUrlArgs; +import io.minio.MinioClient; +import io.minio.PutObjectArgs; +import io.minio.http.Method; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Minio 文件存储工具类 + * + * @author ruoyi + */ +public class MinioUtil { + /** + * 上传文件 + * + * @param bucketName 桶名称 + * @param fileName + * @throws IOException + */ + public static String uploadFile(String bucketName, String fileName, MultipartFile multipartFile) throws IOException { + String url = ""; + MinioClient minioClient = SpringUtils.getBean(MinioClient.class); + try (InputStream inputStream = multipartFile.getInputStream()) { + minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(inputStream, multipartFile.getSize(), -1).contentType(multipartFile.getContentType()).build()); + url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName).method(Method.GET).build()); + url = url.substring(0, url.indexOf('?')); + return ServletUtils.urlDecode(url); + } catch (Exception e) { + throw new IOException(e.getMessage(), e); + } + } +}