diff --git a/pom.xml b/pom.xml
index f14fffc..771ee66 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,8 +63,12 @@
hutool-all
5.8.26
-
-
+
+
+ io.minio
+ minio
+ 8.5.17
+
diff --git a/src/main/java/com/huangge1199/picture/config/MinioConfig.java b/src/main/java/com/huangge1199/picture/config/MinioConfig.java
new file mode 100644
index 0000000..c462342
--- /dev/null
+++ b/src/main/java/com/huangge1199/picture/config/MinioConfig.java
@@ -0,0 +1,37 @@
+package com.huangge1199.picture.config;
+
+import org.springframework.context.annotation.Configuration;
+import io.minio.MinioClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * MinioConfig
+ *
+ * @author huangge1199
+ * @since 2025/7/25 10:38:38
+ */
+@Configuration
+public class MinioConfig {
+
+ // 从配置文件中获取Minio的endpoint
+ @Value("${minio.endpoint}")
+ private String endpoint;
+
+ // 从配置文件中获取Minio的accessKey
+ @Value("${minio.access-key}")
+ private String accessKey;
+
+ // 从配置文件中获取Minio的secretKey
+ @Value("${minio.secret-key}")
+ private String secretKey;
+
+ // 创建MinioClient的Bean
+ @Bean
+ public MinioClient minioClient() {
+ return MinioClient.builder()
+ .endpoint(endpoint)
+ .credentials(accessKey, secretKey)
+ .build();
+ }
+}
diff --git a/src/main/java/com/huangge1199/picture/controller/FileController.java b/src/main/java/com/huangge1199/picture/controller/FileController.java
new file mode 100644
index 0000000..bee5384
--- /dev/null
+++ b/src/main/java/com/huangge1199/picture/controller/FileController.java
@@ -0,0 +1,54 @@
+package com.huangge1199.picture.controller;
+
+import com.huangge1199.picture.common.R;
+import com.huangge1199.picture.service.FileService;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+
+/**
+ * 文件
+ *
+ * @author huangge1199
+ * @since 2025/7/25 10:51:38
+ */
+@RestController
+@RequestMapping("/file")
+public class FileController {
+
+ @Resource
+ private FileService fileService;
+
+ /**
+ * 文件上传
+ * @param file 文件
+ * @return 文件上传地址
+ */
+ @PostMapping("/upload")
+ public R uploadFile(@RequestParam("file") MultipartFile file) {
+ try {
+ String url = fileService.uploadFile(file);
+ return R.ok(url);
+ } catch (Exception e) {
+ return R.fail("上传失败: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 文件删除
+ * @param fileUrl 文件的URL
+ * @return 操作结果
+ */
+ @DeleteMapping
+ public R> deleteFile(@RequestParam String fileUrl) {
+ try {
+ fileService.deleteFile(fileUrl);
+ return R.ok("文件删除成功");
+ } catch (Exception e) {
+ return R.fail("删除失败: " + e.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/com/huangge1199/picture/service/FileService.java b/src/main/java/com/huangge1199/picture/service/FileService.java
new file mode 100644
index 0000000..0af44ec
--- /dev/null
+++ b/src/main/java/com/huangge1199/picture/service/FileService.java
@@ -0,0 +1,15 @@
+package com.huangge1199.picture.service;
+
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * FileService
+ *
+ * @author huangge1199
+ * @since 2025/7/25 10:52:55
+ */
+public interface FileService {
+ String uploadFile(MultipartFile file) throws Exception;
+
+ void deleteFile(String fileUrl) throws Exception;
+}
diff --git a/src/main/java/com/huangge1199/picture/service/impl/FileServiceImpl.java b/src/main/java/com/huangge1199/picture/service/impl/FileServiceImpl.java
new file mode 100644
index 0000000..53def60
--- /dev/null
+++ b/src/main/java/com/huangge1199/picture/service/impl/FileServiceImpl.java
@@ -0,0 +1,40 @@
+package com.huangge1199.picture.service.impl;
+
+import com.huangge1199.picture.service.FileService;
+import com.huangge1199.picture.utils.MinioUtil;
+import org.springframework.stereotype.Service;
+import io.minio.MinioClient;
+import io.minio.PutObjectArgs;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.util.UUID;
+
+/**
+ * FileServiceImpl
+ *
+ * @author huangge1199
+ * @since 2025/7/25 10:53:09
+ */
+@Service
+public class FileServiceImpl implements FileService {
+
+ @Resource
+ private MinioUtil minioUtil;
+
+ @Override
+ public String uploadFile(MultipartFile file) throws Exception {
+
+ // 生成唯一文件名
+ String originalFilename = file.getOriginalFilename();
+ String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
+
+ return minioUtil.upload(file.getInputStream(),fileExtension,file.getContentType());
+ }
+
+ @Override
+ public void deleteFile(String fileUrl) throws Exception {
+ minioUtil.deleteFile(fileUrl);
+ }
+}
diff --git a/src/main/java/com/huangge1199/picture/utils/MinioUtil.java b/src/main/java/com/huangge1199/picture/utils/MinioUtil.java
new file mode 100644
index 0000000..9262a97
--- /dev/null
+++ b/src/main/java/com/huangge1199/picture/utils/MinioUtil.java
@@ -0,0 +1,74 @@
+package com.huangge1199.picture.utils;
+
+import io.minio.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.InputStream;
+import java.util.UUID;
+
+/**
+ * MinioUtil
+ *
+ * @author huangge1199
+ * @since 2025/7/25 10:45:58
+ */
+@Component
+@Slf4j
+public class MinioUtil {
+
+ @Resource
+ private MinioClient minioClient;
+
+ @Value("${minio.bucket}")
+ private String bucketName;
+
+ @Value("${minio.endpoint}")
+ private String endpoint;
+
+ /**
+ * 上传文件到 MinIO 并返回访问地址
+ *
+ * @param inputStream 文件流
+ * @param originalFilename 原始文件名
+ * @param contentType 文件类型(如 image/jpeg)
+ * @return 公网访问地址
+ */
+ public String upload(InputStream inputStream, String originalFilename, String contentType) throws Exception {
+ // 生成文件名
+ String fileName = UUID.randomUUID() + "_" + originalFilename;
+
+ // 上传文件到 MinIO
+ minioClient.putObject(PutObjectArgs.builder()
+ .bucket(bucketName)
+ .object(fileName)
+ .stream(inputStream, inputStream.available(), -1)
+ .contentType(contentType)
+ .build());
+
+ // 拼接访问地址(取决于 MinIO 是否配置了静态资源网关)
+ return String.format("%s/%s/%s", endpoint, bucketName, fileName);
+ }
+
+ /**
+ * 删除 Minio 中的文件
+ *
+ * @param fileUrl 文件的URL(需要从中提取文件名)
+ */
+ public void deleteFile(String fileUrl) throws Exception {
+ String fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
+ try {
+ minioClient.removeObject(
+ RemoveObjectArgs.builder()
+ .bucket(bucketName)
+ .object(fileName)
+ .build());
+ log.info("文件删除成功: {}", fileName);
+ } catch (Exception e) {
+ log.error("文件删除失败: {}", fileName, e);
+ throw new RuntimeException("文件删除失败: " + e.getMessage());
+ }
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 5852379..5b11252 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -8,9 +8,11 @@ spring:
# 数据库配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://192.168.188.2:3306/long-picture
- username: root
- password: huangge1199
+ url: jdbc:mysql://ip:端口/数据库名
+ username: 数据库用户名
+ password: 数据库密码
+ profiles:
+ active: local
mybatis-plus:
configuration:
map-underscore-to-camel-case: false