diff --git a/database/SQL_INDEX.md b/database/SQL_INDEX.md index 9833c8d3..86e43433 100644 --- a/database/SQL_INDEX.md +++ b/database/SQL_INDEX.md @@ -5,6 +5,10 @@ - **用于生产一次性导入**:`wuhan_saga_prod_YYYYMMDD.sql`(全库 `mysqldump`,含结构与数据)。 - 导入后**不要**再按顺序重放本目录下历史 `patch_*.sql` / `migration_*.sql`(除非你在维护很老的库且确认缺列)。 +## 附件与 MinIO + +- 图片路径在库中仍为 `/uploads/{分类}/{文件名}`。`upload.storage=minio` 时文件在对象存储桶内键为 `uploads/...`,需把原 `uploads/` 目录同步进桶(见仓库 `docker-compose.minio.yml` 与后端 `application.yml` 中 `minio.*`)。 + ## 日常开发以代码为准的 DDL | 文件 | 用途 | diff --git a/docker-compose.minio.yml b/docker-compose.minio.yml new file mode 100644 index 00000000..36f9f84b --- /dev/null +++ b/docker-compose.minio.yml @@ -0,0 +1,19 @@ +# 本地/内网 MinIO(与 Spring upload.storage=minio 配套) +# 启动:docker compose -f docker-compose.minio.yml up -d +# 控制台:http://127.0.0.1:9001 (默认账号 minioadmin / minioadmin,生产务必修改) + +services: + minio: + image: minio/minio:RELEASE.2024-11-07T00-52-20Z + command: server /data --console-address ":9001" + ports: + - "9000:9000" + - "9001:9001" + environment: + MINIO_ROOT_USER: minioadmin + MINIO_ROOT_PASSWORD: minioadmin + volumes: + - minio-data:/data + +volumes: + minio-data: diff --git a/server/deploy/minio-spring-config.example.yml b/server/deploy/minio-spring-config.example.yml new file mode 100644 index 00000000..b9fe01de --- /dev/null +++ b/server/deploy/minio-spring-config.example.yml @@ -0,0 +1,27 @@ +# Spring Boot 使用 MinIO 时,在「生产配置」里增加或改成以下内容。 +# 不要提交含真实生产密码的副本;交给运维时可另存为服务器上的 application-prod.yml。 +# +# 启动示例:java -jar wuhan-saga-server.jar --spring.profiles.active=prod +# +# 与运维 Docker 中环境变量的对应: +# MINIO_ROOT_USER -> minio.access-key +# MINIO_ROOT_PASSWORD -> minio.secret-key +# endpoint:Spring 所在机器能访问的 MinIO API(9000)。同机 Docker host 网络一般用 http://127.0.0.1:9000 + +# --- 下面粘贴进 application-prod.yml(或通过 Nacos/环境变量等价提供)--- + +spring: + config: + activate: + on-profile: prod + +upload: + storage: minio + path: uploads/ + +minio: + endpoint: http://127.0.0.1:9000 + access-key: klp + secret-key: ruoyi123 + bucket: wuhan-saga + region: us-east-1 diff --git a/server/pom.xml b/server/pom.xml index d0a4bd18..f3a918fd 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -84,6 +84,12 @@ ${hutool.version} + + io.minio + minio + 8.5.13 + + org.projectlombok lombok diff --git a/server/src/main/java/com/wuhansaga/server/WuhanSagaApplication.java b/server/src/main/java/com/wuhansaga/server/WuhanSagaApplication.java index 94c211da..09a7957e 100644 --- a/server/src/main/java/com/wuhansaga/server/WuhanSagaApplication.java +++ b/server/src/main/java/com/wuhansaga/server/WuhanSagaApplication.java @@ -1,5 +1,6 @@ package com.wuhansaga.server; +import com.wuhansaga.server.config.MinioProperties; import com.wuhansaga.server.config.PortalSiteProperties; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; @@ -8,7 +9,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties @SpringBootApplication @MapperScan("com.wuhansaga.server.mapper") -@EnableConfigurationProperties(PortalSiteProperties.class) +@EnableConfigurationProperties({ PortalSiteProperties.class, MinioProperties.class }) public class WuhanSagaApplication { public static void main(String[] args) { diff --git a/server/src/main/java/com/wuhansaga/server/config/MinioProperties.java b/server/src/main/java/com/wuhansaga/server/config/MinioProperties.java new file mode 100644 index 00000000..3ab1adb5 --- /dev/null +++ b/server/src/main/java/com/wuhansaga/server/config/MinioProperties.java @@ -0,0 +1,24 @@ +package com.wuhansaga.server.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * MinIO(S3 兼容)接入;仅在 upload.storage=minio 时使用。 + */ +@ConfigurationProperties(prefix = "minio") +public record MinioProperties( + /** 例:http://127.0.0.1:9000 或 https://minio.example.com(无尾斜杠) */ + String endpoint, + String accessKey, + String secretKey, + /** 桶名,需有读权限;上传会 put 到此桶 */ + String bucket, + /** 区域,MinIO 单机常用 us-east-1 */ + String region +) { + public MinioProperties { + if (region == null || region.isBlank()) { + region = "us-east-1"; + } + } +} diff --git a/server/src/main/java/com/wuhansaga/server/config/WebMvcConfig.java b/server/src/main/java/com/wuhansaga/server/config/WebMvcConfig.java index ef1f0c13..c482ab9a 100644 --- a/server/src/main/java/com/wuhansaga/server/config/WebMvcConfig.java +++ b/server/src/main/java/com/wuhansaga/server/config/WebMvcConfig.java @@ -14,6 +14,9 @@ public class WebMvcConfig implements WebMvcConfigurer { @Value("${upload.path:uploads/}") private String uploadPath; + @Value("${upload.storage:local}") + private String uploadStorage; + @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") @@ -26,6 +29,9 @@ public class WebMvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { + if ("minio".equalsIgnoreCase(uploadStorage)) { + return; + } File dir = new File(uploadPath); if (!dir.isAbsolute()) { dir = new File(System.getProperty("user.dir"), uploadPath); diff --git a/server/src/main/java/com/wuhansaga/server/controller/portal/UploadServeController.java b/server/src/main/java/com/wuhansaga/server/controller/portal/UploadServeController.java new file mode 100644 index 00000000..ab134cbd --- /dev/null +++ b/server/src/main/java/com/wuhansaga/server/controller/portal/UploadServeController.java @@ -0,0 +1,88 @@ +package com.wuhansaga.server.controller.portal; + +import com.wuhansaga.server.storage.UploadStorage; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import jakarta.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; + +/** + * MinIO 模式下由应用流式输出 /uploads/**;对象不存在时回退到 classpath bundled-uploads。 + */ +@RestController +@RequiredArgsConstructor +@ConditionalOnProperty(name = "upload.storage", havingValue = "minio") +public class UploadServeController { + + private final UploadStorage uploadStorage; + private final ResourceLoader resourceLoader; + + @GetMapping("/uploads/**") + public ResponseEntity serve(HttpServletRequest request) + throws IOException { + String rel = requestUriWithoutContext(request); + if (!rel.startsWith("/uploads/")) { + return ResponseEntity.notFound().build(); + } + + Optional fromStore = uploadStorage.open(rel); + if (fromStore.isPresent()) { + UploadStorage.StoredObject o = fromStore.get(); + MediaType mt = MediaType.parseMediaType(o.contentType()); + var body = new org.springframework.core.io.InputStreamResource(o.inputStream()) { + @Override + public long contentLength() { + return o.size(); + } + }; + return ResponseEntity.ok().contentType(mt).contentLength(o.size()).body(body); + } + + String tail = rel.substring("/uploads/".length()); + Resource bundled = resourceLoader.getResource("classpath:/static/bundled-uploads/" + tail); + if (!bundled.exists() || !bundled.isReadable()) { + return ResponseEntity.notFound().build(); + } + InputStream in = bundled.getInputStream(); + long len = bundled.contentLength(); + MediaType mt = MediaType.APPLICATION_OCTET_STREAM; + String name = bundled.getFilename(); + if (name != null && (name.endsWith(".jpg") || name.endsWith(".jpeg"))) { + mt = MediaType.IMAGE_JPEG; + } else if (name != null && name.endsWith(".png")) { + mt = MediaType.IMAGE_PNG; + } else if (name != null && name.endsWith(".gif")) { + mt = MediaType.IMAGE_GIF; + } else if (name != null && name.endsWith(".webp")) { + mt = MediaType.parseMediaType("image/webp"); + } + var body = new org.springframework.core.io.InputStreamResource(in) { + @Override + public long contentLength() { + return len > 0 ? len : -1; + } + }; + if (len > 0) { + return ResponseEntity.ok().contentType(mt).contentLength(len).body(body); + } + return ResponseEntity.ok().contentType(mt).body(body); + } + + private static String requestUriWithoutContext(HttpServletRequest request) { + String uri = request.getRequestURI(); + String cp = request.getContextPath(); + if (cp != null && !cp.isEmpty() && uri.startsWith(cp)) { + return uri.substring(cp.length()); + } + return uri; + } +} diff --git a/server/src/main/java/com/wuhansaga/server/service/MediaLibraryService.java b/server/src/main/java/com/wuhansaga/server/service/MediaLibraryService.java index ddf79d10..e4701500 100644 --- a/server/src/main/java/com/wuhansaga/server/service/MediaLibraryService.java +++ b/server/src/main/java/com/wuhansaga/server/service/MediaLibraryService.java @@ -4,13 +4,11 @@ import com.wuhansaga.server.common.PageQuery; import com.wuhansaga.server.common.PageResult; import com.wuhansaga.server.entity.MediaLibrary; import com.wuhansaga.server.mapper.MediaLibraryMapper; +import com.wuhansaga.server.storage.UploadStorage; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; -import jakarta.annotation.PostConstruct; -import java.io.File; import java.io.IOException; import java.util.List; import java.util.UUID; @@ -20,29 +18,11 @@ import java.util.UUID; public class MediaLibraryService { private final MediaLibraryMapper mediaLibraryMapper; + private final UploadStorage uploadStorage; - @Value("${upload.path}") - private String uploadPath; - - private File uploadDir; - - public MediaLibraryService(MediaLibraryMapper mediaLibraryMapper) { + public MediaLibraryService(MediaLibraryMapper mediaLibraryMapper, UploadStorage uploadStorage) { this.mediaLibraryMapper = mediaLibraryMapper; - } - - @PostConstruct - public void init() { - uploadDir = new File(uploadPath); - if (!uploadDir.isAbsolute()) { - String userDir = System.getProperty("user.dir"); - uploadDir = new File(userDir, uploadPath); - } - if (!uploadDir.exists()) { - boolean created = uploadDir.mkdirs(); - log.info("初始化上传目录: {} => {}", uploadDir.getAbsolutePath(), created); - } else { - log.info("上传目录已存在: {}", uploadDir.getAbsolutePath()); - } + this.uploadStorage = uploadStorage; } public PageResult page(String category, String keyword, PageQuery query) { @@ -63,15 +43,7 @@ public class MediaLibraryService { String newFileName = UUID.randomUUID().toString().replace("-", "") + ext; String relativePath = "/uploads/" + category + "/" + newFileName; - File categoryDir = new File(uploadDir, category); - if (!categoryDir.exists()) { - boolean created = categoryDir.mkdirs(); - log.info("创建分类目录: {} => {}", categoryDir.getAbsolutePath(), created); - } - - File dest = new File(categoryDir, newFileName); - file.transferTo(dest); - log.info("文件已保存: {}", dest.getAbsolutePath()); + uploadStorage.store(file, relativePath); MediaLibrary media = new MediaLibrary(); media.setFilePath(relativePath); diff --git a/server/src/main/java/com/wuhansaga/server/storage/LocalUploadStorage.java b/server/src/main/java/com/wuhansaga/server/storage/LocalUploadStorage.java new file mode 100644 index 00000000..157d6acf --- /dev/null +++ b/server/src/main/java/com/wuhansaga/server/storage/LocalUploadStorage.java @@ -0,0 +1,77 @@ +package com.wuhansaga.server.storage; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import jakarta.annotation.PostConstruct; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.Optional; + +@Slf4j +@Component +@ConditionalOnProperty(name = "upload.storage", havingValue = "local", matchIfMissing = true) +public class LocalUploadStorage implements UploadStorage { + + @Value("${upload.path}") + private String uploadPath; + + private File uploadDir; + + @PostConstruct + public void init() { + uploadDir = new File(uploadPath); + if (!uploadDir.isAbsolute()) { + uploadDir = new File(System.getProperty("user.dir"), uploadPath); + } + if (!uploadDir.exists()) { + boolean created = uploadDir.mkdirs(); + log.info("初始化本地上传目录: {} => {}", uploadDir.getAbsolutePath(), created); + } else { + log.info("本地上传目录已存在: {}", uploadDir.getAbsolutePath()); + } + } + + @Override + public void store(MultipartFile file, String relativePath) throws IOException { + if (relativePath == null || !relativePath.startsWith("/uploads/")) { + throw new IllegalArgumentException("relativePath 须以 /uploads/ 开头: " + relativePath); + } + String withoutPrefix = relativePath.substring("/uploads/".length()); + int slash = withoutPrefix.lastIndexOf('/'); + String category = slash >= 0 ? withoutPrefix.substring(0, slash) : ""; + String fileName = slash >= 0 ? withoutPrefix.substring(slash + 1) : withoutPrefix; + + File categoryDir = category.isEmpty() ? uploadDir : new File(uploadDir, category); + if (!categoryDir.exists()) { + boolean created = categoryDir.mkdirs(); + log.info("创建分类目录: {} => {}", categoryDir.getAbsolutePath(), created); + } + File dest = new File(categoryDir, fileName); + file.transferTo(dest); + log.info("文件已保存(本地): {}", dest.getAbsolutePath()); + } + + @Override + public Optional open(String relativePath) throws IOException { + if (relativePath == null || !relativePath.startsWith("/uploads/")) { + return Optional.empty(); + } + String withoutPrefix = relativePath.substring("/uploads/".length()); + File f = new File(uploadDir, withoutPrefix.replace('/', File.separatorChar)); + if (!f.isFile()) { + return Optional.empty(); + } + String ct = Files.probeContentType(f.toPath()); + if (ct == null) { + ct = "application/octet-stream"; + } + InputStream in = Files.newInputStream(f.toPath()); + return Optional.of(new StoredObject(in, f.length(), ct)); + } +} diff --git a/server/src/main/java/com/wuhansaga/server/storage/MinioUploadStorage.java b/server/src/main/java/com/wuhansaga/server/storage/MinioUploadStorage.java new file mode 100644 index 00000000..180a54b6 --- /dev/null +++ b/server/src/main/java/com/wuhansaga/server/storage/MinioUploadStorage.java @@ -0,0 +1,112 @@ +package com.wuhansaga.server.storage; + +import com.wuhansaga.server.config.MinioProperties; +import io.minio.BucketExistsArgs; +import io.minio.GetObjectArgs; +import io.minio.MakeBucketArgs; +import io.minio.MinioClient; +import io.minio.PutObjectArgs; +import io.minio.StatObjectArgs; +import io.minio.StatObjectResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import jakarta.annotation.PostConstruct; +import java.io.InputStream; +import java.util.Optional; + +@Slf4j +@Component +@ConditionalOnProperty(name = "upload.storage", havingValue = "minio") +public class MinioUploadStorage implements UploadStorage { + + private final MinioProperties props; + private MinioClient client; + + public MinioUploadStorage(MinioProperties props) { + this.props = props; + } + + @PostConstruct + public void init() throws java.io.IOException { + if (props.endpoint() == null || props.endpoint().isBlank()) { + throw new IllegalStateException("minio.endpoint 未配置"); + } + if (props.accessKey() == null || props.secretKey() == null || props.bucket() == null + || props.accessKey().isBlank() || props.secretKey().isBlank() || props.bucket().isBlank()) { + throw new IllegalStateException("minio.access-key、secret-key、bucket 均需配置"); + } + client = MinioClient.builder() + .endpoint(props.endpoint()) + .region(props.region()) + .credentials(props.accessKey(), props.secretKey()) + .build(); + try { + boolean exists = client.bucketExists(BucketExistsArgs.builder().bucket(props.bucket()).build()); + if (!exists) { + client.makeBucket(MakeBucketArgs.builder().bucket(props.bucket()).build()); + log.info("已创建 MinIO 桶: {}", props.bucket()); + } else { + log.info("MinIO 桶已存在: {}", props.bucket()); + } + } catch (Exception e) { + throw new java.io.IOException("初始化 MinIO 失败: " + e.getMessage(), e); + } + } + + private static String objectName(String relativePath) { + if (relativePath == null || !relativePath.startsWith("/uploads/")) { + throw new IllegalArgumentException("relativePath 须以 /uploads/ 开头: " + relativePath); + } + return relativePath.substring(1); + } + + @Override + public void store(MultipartFile file, String relativePath) throws java.io.IOException { + String name = objectName(relativePath); + String ct = file.getContentType(); + if (ct == null || ct.isBlank()) { + ct = "application/octet-stream"; + } + try (InputStream in = file.getInputStream()) { + client.putObject( + PutObjectArgs.builder() + .bucket(props.bucket()) + .object(name) + .stream(in, file.getSize(), -1) + .contentType(ct) + .build()); + } catch (Exception e) { + throw new java.io.IOException("MinIO 上传失败: " + e.getMessage(), e); + } + log.info("文件已写入 MinIO: {}/{}", props.bucket(), name); + } + + @Override + public Optional open(String relativePath) throws java.io.IOException { + if (relativePath == null || !relativePath.startsWith("/uploads/")) { + return Optional.empty(); + } + String name = objectName(relativePath); + try { + StatObjectResponse stat = client.statObject( + StatObjectArgs.builder().bucket(props.bucket()).object(name).build()); + InputStream in = client.getObject( + GetObjectArgs.builder().bucket(props.bucket()).object(name).build()); + String ct = stat.contentType(); + if (ct == null || ct.isBlank()) { + ct = "application/octet-stream"; + } + return Optional.of(new StoredObject(in, stat.size(), ct)); + } catch (io.minio.errors.ErrorResponseException e) { + if ("NoSuchKey".equals(e.errorResponse().code()) || "NoSuchObject".equals(e.errorResponse().code())) { + return Optional.empty(); + } + throw new java.io.IOException("MinIO 读取失败: " + e.getMessage(), e); + } catch (Exception e) { + throw new java.io.IOException("MinIO 读取失败: " + e.getMessage(), e); + } + } +} diff --git a/server/src/main/java/com/wuhansaga/server/storage/UploadStorage.java b/server/src/main/java/com/wuhansaga/server/storage/UploadStorage.java new file mode 100644 index 00000000..26445c1a --- /dev/null +++ b/server/src/main/java/com/wuhansaga/server/storage/UploadStorage.java @@ -0,0 +1,19 @@ +package com.wuhansaga.server.storage; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; + +/** + * 统一上传存储;相对路径与库存一致,如 /uploads/banner/xxx.jpg + */ +public interface UploadStorage { + + void store(MultipartFile file, String relativePath) throws IOException; + + Optional open(String relativePath) throws IOException; + + record StoredObject(InputStream inputStream, long size, String contentType) {} +} diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml index 838b6190..be64af1e 100644 --- a/server/src/main/resources/application.yml +++ b/server/src/main/resources/application.yml @@ -56,11 +56,21 @@ knife4j: setting: language: zh_cn +# 存储:local=本机 uploads | minio=对象存储,见 server/deploy/minio-spring-config.example.yml upload: + storage: local path: uploads/ allowed-types: image/jpeg,image/png,image/gif,image/webp,image/svg+xml,video/mp4,video/webm max-size: 52428800 +# 仅 upload.storage=minio 时生效;密钥用环境变量注入,勿提交生产明文 +minio: + endpoint: http://127.0.0.1:9000 + access-key: minioadmin + secret-key: minioadmin + bucket: wuhan-saga + region: us-east-1 + # 新闻中心多站点:单部署实例默认站点;扩展编码时改 allowed-site-codes 与库内数据 app: portal: diff --git a/server/target/classes/application.yml b/server/target/classes/application.yml index 838b6190..be64af1e 100644 --- a/server/target/classes/application.yml +++ b/server/target/classes/application.yml @@ -56,11 +56,21 @@ knife4j: setting: language: zh_cn +# 存储:local=本机 uploads | minio=对象存储,见 server/deploy/minio-spring-config.example.yml upload: + storage: local path: uploads/ allowed-types: image/jpeg,image/png,image/gif,image/webp,image/svg+xml,video/mp4,video/webm max-size: 52428800 +# 仅 upload.storage=minio 时生效;密钥用环境变量注入,勿提交生产明文 +minio: + endpoint: http://127.0.0.1:9000 + access-key: minioadmin + secret-key: minioadmin + bucket: wuhan-saga + region: us-east-1 + # 新闻中心多站点:单部署实例默认站点;扩展编码时改 allowed-site-codes 与库内数据 app: portal: diff --git a/server/target/classes/com/wuhansaga/server/WuhanSagaApplication.class b/server/target/classes/com/wuhansaga/server/WuhanSagaApplication.class index 67441d3d..19d133e6 100644 Binary files a/server/target/classes/com/wuhansaga/server/WuhanSagaApplication.class and b/server/target/classes/com/wuhansaga/server/WuhanSagaApplication.class differ diff --git a/server/target/classes/com/wuhansaga/server/config/MinioProperties.class b/server/target/classes/com/wuhansaga/server/config/MinioProperties.class new file mode 100644 index 00000000..8e4569c5 Binary files /dev/null and b/server/target/classes/com/wuhansaga/server/config/MinioProperties.class differ diff --git a/server/target/classes/com/wuhansaga/server/config/PortalSiteProperties.class b/server/target/classes/com/wuhansaga/server/config/PortalSiteProperties.class index 016eaee3..b5e8cf9d 100644 Binary files a/server/target/classes/com/wuhansaga/server/config/PortalSiteProperties.class and b/server/target/classes/com/wuhansaga/server/config/PortalSiteProperties.class differ diff --git a/server/target/classes/com/wuhansaga/server/config/PortalSiteResolver.class b/server/target/classes/com/wuhansaga/server/config/PortalSiteResolver.class index c9129e37..eaee7108 100644 Binary files a/server/target/classes/com/wuhansaga/server/config/PortalSiteResolver.class and b/server/target/classes/com/wuhansaga/server/config/PortalSiteResolver.class differ diff --git a/server/target/classes/com/wuhansaga/server/config/WebMvcConfig.class b/server/target/classes/com/wuhansaga/server/config/WebMvcConfig.class index fdaa3e75..4f18a6ea 100644 Binary files a/server/target/classes/com/wuhansaga/server/config/WebMvcConfig.class and b/server/target/classes/com/wuhansaga/server/config/WebMvcConfig.class differ diff --git a/server/target/classes/com/wuhansaga/server/constant/SiteCodes.class b/server/target/classes/com/wuhansaga/server/constant/SiteCodes.class index 1f331a17..e003ff80 100644 Binary files a/server/target/classes/com/wuhansaga/server/constant/SiteCodes.class and b/server/target/classes/com/wuhansaga/server/constant/SiteCodes.class differ diff --git a/server/target/classes/com/wuhansaga/server/controller/admin/AdminNewsController.class b/server/target/classes/com/wuhansaga/server/controller/admin/AdminNewsController.class index 2ba8543e..4260f6b8 100644 Binary files a/server/target/classes/com/wuhansaga/server/controller/admin/AdminNewsController.class and b/server/target/classes/com/wuhansaga/server/controller/admin/AdminNewsController.class differ diff --git a/server/target/classes/com/wuhansaga/server/controller/admin/AdminProductLineController.class b/server/target/classes/com/wuhansaga/server/controller/admin/AdminProductLineController.class index 27b79356..4954035d 100644 Binary files a/server/target/classes/com/wuhansaga/server/controller/admin/AdminProductLineController.class and b/server/target/classes/com/wuhansaga/server/controller/admin/AdminProductLineController.class differ diff --git a/server/target/classes/com/wuhansaga/server/controller/portal/PortalNewsController.class b/server/target/classes/com/wuhansaga/server/controller/portal/PortalNewsController.class index d2accee0..26c39ea4 100644 Binary files a/server/target/classes/com/wuhansaga/server/controller/portal/PortalNewsController.class and b/server/target/classes/com/wuhansaga/server/controller/portal/PortalNewsController.class differ diff --git a/server/target/classes/com/wuhansaga/server/controller/portal/PortalProductController.class b/server/target/classes/com/wuhansaga/server/controller/portal/PortalProductController.class index f3fe82e0..c9a5f397 100644 Binary files a/server/target/classes/com/wuhansaga/server/controller/portal/PortalProductController.class and b/server/target/classes/com/wuhansaga/server/controller/portal/PortalProductController.class differ diff --git a/server/target/classes/com/wuhansaga/server/controller/portal/UploadServeController$1.class b/server/target/classes/com/wuhansaga/server/controller/portal/UploadServeController$1.class new file mode 100644 index 00000000..19ee0831 Binary files /dev/null and b/server/target/classes/com/wuhansaga/server/controller/portal/UploadServeController$1.class differ diff --git a/server/target/classes/com/wuhansaga/server/controller/portal/UploadServeController$2.class b/server/target/classes/com/wuhansaga/server/controller/portal/UploadServeController$2.class new file mode 100644 index 00000000..0cf42869 Binary files /dev/null and b/server/target/classes/com/wuhansaga/server/controller/portal/UploadServeController$2.class differ diff --git a/server/target/classes/com/wuhansaga/server/controller/portal/UploadServeController.class b/server/target/classes/com/wuhansaga/server/controller/portal/UploadServeController.class new file mode 100644 index 00000000..61f40d53 Binary files /dev/null and b/server/target/classes/com/wuhansaga/server/controller/portal/UploadServeController.class differ diff --git a/server/target/classes/com/wuhansaga/server/entity/MediaLibrary.class b/server/target/classes/com/wuhansaga/server/entity/MediaLibrary.class index 8fb2772e..7ba4dc54 100644 Binary files a/server/target/classes/com/wuhansaga/server/entity/MediaLibrary.class and b/server/target/classes/com/wuhansaga/server/entity/MediaLibrary.class differ diff --git a/server/target/classes/com/wuhansaga/server/entity/News.class b/server/target/classes/com/wuhansaga/server/entity/News.class index af0abdcc..16a122d5 100644 Binary files a/server/target/classes/com/wuhansaga/server/entity/News.class and b/server/target/classes/com/wuhansaga/server/entity/News.class differ diff --git a/server/target/classes/com/wuhansaga/server/entity/NewsCategory.class b/server/target/classes/com/wuhansaga/server/entity/NewsCategory.class index 00ee26b7..2062066a 100644 Binary files a/server/target/classes/com/wuhansaga/server/entity/NewsCategory.class and b/server/target/classes/com/wuhansaga/server/entity/NewsCategory.class differ diff --git a/server/target/classes/com/wuhansaga/server/entity/ProductCategory.class b/server/target/classes/com/wuhansaga/server/entity/ProductCategory.class index f7b39202..18f2692c 100644 Binary files a/server/target/classes/com/wuhansaga/server/entity/ProductCategory.class and b/server/target/classes/com/wuhansaga/server/entity/ProductCategory.class differ diff --git a/server/target/classes/com/wuhansaga/server/entity/ProductLine.class b/server/target/classes/com/wuhansaga/server/entity/ProductLine.class index b893108f..479065c3 100644 Binary files a/server/target/classes/com/wuhansaga/server/entity/ProductLine.class and b/server/target/classes/com/wuhansaga/server/entity/ProductLine.class differ diff --git a/server/target/classes/com/wuhansaga/server/entity/SingleEquipment.class b/server/target/classes/com/wuhansaga/server/entity/SingleEquipment.class index 81f48732..9214ad43 100644 Binary files a/server/target/classes/com/wuhansaga/server/entity/SingleEquipment.class and b/server/target/classes/com/wuhansaga/server/entity/SingleEquipment.class differ diff --git a/server/target/classes/com/wuhansaga/server/entity/SparePart.class b/server/target/classes/com/wuhansaga/server/entity/SparePart.class index 7e114c4a..3b163198 100644 Binary files a/server/target/classes/com/wuhansaga/server/entity/SparePart.class and b/server/target/classes/com/wuhansaga/server/entity/SparePart.class differ diff --git a/server/target/classes/com/wuhansaga/server/mapper/NewsCategoryMapper.class b/server/target/classes/com/wuhansaga/server/mapper/NewsCategoryMapper.class index bf5b04ab..780730f2 100644 Binary files a/server/target/classes/com/wuhansaga/server/mapper/NewsCategoryMapper.class and b/server/target/classes/com/wuhansaga/server/mapper/NewsCategoryMapper.class differ diff --git a/server/target/classes/com/wuhansaga/server/mapper/NewsMapper.class b/server/target/classes/com/wuhansaga/server/mapper/NewsMapper.class index e808518d..2108c7ca 100644 Binary files a/server/target/classes/com/wuhansaga/server/mapper/NewsMapper.class and b/server/target/classes/com/wuhansaga/server/mapper/NewsMapper.class differ diff --git a/server/target/classes/com/wuhansaga/server/mapper/ProductCategoryMapper.class b/server/target/classes/com/wuhansaga/server/mapper/ProductCategoryMapper.class index fad989a8..fa83f437 100644 Binary files a/server/target/classes/com/wuhansaga/server/mapper/ProductCategoryMapper.class and b/server/target/classes/com/wuhansaga/server/mapper/ProductCategoryMapper.class differ diff --git a/server/target/classes/com/wuhansaga/server/mapper/ProductLineEquipmentMapper.class b/server/target/classes/com/wuhansaga/server/mapper/ProductLineEquipmentMapper.class index 83813a9c..73662ba3 100644 Binary files a/server/target/classes/com/wuhansaga/server/mapper/ProductLineEquipmentMapper.class and b/server/target/classes/com/wuhansaga/server/mapper/ProductLineEquipmentMapper.class differ diff --git a/server/target/classes/com/wuhansaga/server/mapper/SingleEquipmentMapper.class b/server/target/classes/com/wuhansaga/server/mapper/SingleEquipmentMapper.class index 8a43999c..d391a110 100644 Binary files a/server/target/classes/com/wuhansaga/server/mapper/SingleEquipmentMapper.class and b/server/target/classes/com/wuhansaga/server/mapper/SingleEquipmentMapper.class differ diff --git a/server/target/classes/com/wuhansaga/server/service/BannerService.class b/server/target/classes/com/wuhansaga/server/service/BannerService.class index 7eb3ebd5..08654da1 100644 Binary files a/server/target/classes/com/wuhansaga/server/service/BannerService.class and b/server/target/classes/com/wuhansaga/server/service/BannerService.class differ diff --git a/server/target/classes/com/wuhansaga/server/service/MediaLibraryService.class b/server/target/classes/com/wuhansaga/server/service/MediaLibraryService.class index c1a06642..9d05baea 100644 Binary files a/server/target/classes/com/wuhansaga/server/service/MediaLibraryService.class and b/server/target/classes/com/wuhansaga/server/service/MediaLibraryService.class differ diff --git a/server/target/classes/com/wuhansaga/server/service/NewsCategoryService.class b/server/target/classes/com/wuhansaga/server/service/NewsCategoryService.class index 2931e821..59ec1f5e 100644 Binary files a/server/target/classes/com/wuhansaga/server/service/NewsCategoryService.class and b/server/target/classes/com/wuhansaga/server/service/NewsCategoryService.class differ diff --git a/server/target/classes/com/wuhansaga/server/service/NewsService.class b/server/target/classes/com/wuhansaga/server/service/NewsService.class index b84ff8cb..c61a0c92 100644 Binary files a/server/target/classes/com/wuhansaga/server/service/NewsService.class and b/server/target/classes/com/wuhansaga/server/service/NewsService.class differ diff --git a/server/target/classes/com/wuhansaga/server/service/ProductCategoryService.class b/server/target/classes/com/wuhansaga/server/service/ProductCategoryService.class index 527fbefc..b313ecbd 100644 Binary files a/server/target/classes/com/wuhansaga/server/service/ProductCategoryService.class and b/server/target/classes/com/wuhansaga/server/service/ProductCategoryService.class differ diff --git a/server/target/classes/com/wuhansaga/server/service/ProductLineService.class b/server/target/classes/com/wuhansaga/server/service/ProductLineService.class index 65e2b022..6469f8ca 100644 Binary files a/server/target/classes/com/wuhansaga/server/service/ProductLineService.class and b/server/target/classes/com/wuhansaga/server/service/ProductLineService.class differ diff --git a/server/target/classes/com/wuhansaga/server/storage/LocalUploadStorage.class b/server/target/classes/com/wuhansaga/server/storage/LocalUploadStorage.class new file mode 100644 index 00000000..eee84b43 Binary files /dev/null and b/server/target/classes/com/wuhansaga/server/storage/LocalUploadStorage.class differ diff --git a/server/target/classes/com/wuhansaga/server/storage/MinioUploadStorage.class b/server/target/classes/com/wuhansaga/server/storage/MinioUploadStorage.class new file mode 100644 index 00000000..13a71187 Binary files /dev/null and b/server/target/classes/com/wuhansaga/server/storage/MinioUploadStorage.class differ diff --git a/server/target/classes/com/wuhansaga/server/storage/UploadStorage$StoredObject.class b/server/target/classes/com/wuhansaga/server/storage/UploadStorage$StoredObject.class new file mode 100644 index 00000000..a0506d22 Binary files /dev/null and b/server/target/classes/com/wuhansaga/server/storage/UploadStorage$StoredObject.class differ diff --git a/server/target/classes/com/wuhansaga/server/storage/UploadStorage.class b/server/target/classes/com/wuhansaga/server/storage/UploadStorage.class new file mode 100644 index 00000000..a4f5d590 Binary files /dev/null and b/server/target/classes/com/wuhansaga/server/storage/UploadStorage.class differ diff --git a/server/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/server/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst index bfd4da2c..c6e297ee 100644 --- a/server/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ b/server/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -7,10 +7,12 @@ com\wuhansaga\server\mapper\SingleEquipmentMapper.class com\wuhansaga\server\mapper\ProductCategoryMapper.class com\wuhansaga\server\service\WorkshopService.class com\wuhansaga\server\controller\portal\PortalCaseController.class +com\wuhansaga\server\config\MinioProperties.class com\wuhansaga\server\service\CompanyInfoService.class com\wuhansaga\server\controller\admin\AdminBannerController.class com\wuhansaga\server\controller\admin\AdminCaseController.class com\wuhansaga\server\mapper\MediaLibraryMapper.class +com\wuhansaga\server\controller\portal\UploadServeController$1.class com\wuhansaga\server\common\PageQuery.class com\wuhansaga\server\entity\MediaLibrary.class com\wuhansaga\server\controller\portal\PortalWorkshopController.class @@ -23,11 +25,15 @@ com\wuhansaga\server\service\MediaLibraryService.class com\wuhansaga\server\mapper\CaseMediaMapper.class com\wuhansaga\server\config\OpenApiConfig.class com\wuhansaga\server\mapper\CompanyInfoMapper.class +com\wuhansaga\server\controller\portal\UploadServeController.class com\wuhansaga\server\entity\CaseMedia.class com\wuhansaga\server\controller\admin\AdminAuthController.class com\wuhansaga\server\entity\ProductMedia.class +com\wuhansaga\server\controller\portal\UploadServeController$2.class com\wuhansaga\server\mapper\SysUserMapper.class +com\wuhansaga\server\storage\UploadStorage$StoredObject.class com\wuhansaga\server\mapper\AboutMapper.class +com\wuhansaga\server\storage\LocalUploadStorage.class com\wuhansaga\server\controller\admin\AdminProductCategoryController.class com\wuhansaga\server\controller\portal\PortalProductController.class com\wuhansaga\server\common\GlobalExceptionHandler.class @@ -48,6 +54,7 @@ com\wuhansaga\server\controller\admin\AdminCompanyController.class com\wuhansaga\server\entity\SysUser.class com\wuhansaga\server\service\AboutService.class com\wuhansaga\server\mapper\CaseStudyMapper.class +com\wuhansaga\server\storage\UploadStorage.class com\wuhansaga\server\config\WebMvcConfig.class com\wuhansaga\server\entity\News.class com\wuhansaga\server\common\PageResult.class @@ -79,6 +86,7 @@ com\wuhansaga\server\controller\admin\AdminWorkshopController.class com\wuhansaga\server\mapper\CaseCategoryMapper.class com\wuhansaga\server\entity\Banner.class com\wuhansaga\server\entity\ProductCategory.class +com\wuhansaga\server\storage\MinioUploadStorage.class com\wuhansaga\server\entity\Contact.class com\wuhansaga\server\config\SaTokenConfig.class com\wuhansaga\server\entity\SparePart.class diff --git a/server/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/server/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst index db7fbce4..d75e8b1c 100644 --- a/server/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ b/server/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -3,6 +3,7 @@ D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\common\PageQuery.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\common\PageResult.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\common\R.java +D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\config\MinioProperties.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\config\OpenApiConfig.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\config\PortalSiteProperties.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\config\PortalSiteResolver.java @@ -31,6 +32,7 @@ D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\controller\portal\PortalProductController.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\controller\portal\PortalTechnologyController.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\controller\portal\PortalWorkshopController.java +D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\controller\portal\UploadServeController.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\entity\About.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\entity\Banner.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\entity\CaseCategory.java @@ -83,4 +85,7 @@ D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\service\SingleEquipmentService.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\service\SparePartService.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\service\WorkshopService.java +D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\storage\LocalUploadStorage.java +D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\storage\MinioUploadStorage.java +D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\storage\UploadStorage.java D:\DeXun_workspace\projects\wuhan-saga-official-website\server\src\main\java\com\wuhansaga\server\WuhanSagaApplication.java