没报错了
This commit is contained in:
		
							parent
							
								
									acb58cefce
								
							
						
					
					
						commit
						624dacfe12
					
				| @ -0,0 +1,84 @@ | |||||||
|  | 17:48:12.931 [restartedMain] ERROR o.s.b.d.LoggingFailureAnalysisReporter - [report,40] -  | ||||||
|  | 
 | ||||||
|  | *************************** | ||||||
|  | APPLICATION FAILED TO START | ||||||
|  | *************************** | ||||||
|  | 
 | ||||||
|  | Description: | ||||||
|  | 
 | ||||||
|  | Field relationService in com.mmg.service.impl.ResourceServiceImpl required a bean of type 'com.mmg.service.ResourceCategoryService' that could not be found. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Action: | ||||||
|  | 
 | ||||||
|  | Consider defining a bean of type 'com.mmg.service.ResourceCategoryService' in your configuration. | ||||||
|  | 
 | ||||||
|  | 17:50:03.577 [restartedMain] ERROR o.s.b.d.LoggingFailureAnalysisReporter - [report,40] -  | ||||||
|  | 
 | ||||||
|  | *************************** | ||||||
|  | APPLICATION FAILED TO START | ||||||
|  | *************************** | ||||||
|  | 
 | ||||||
|  | Description: | ||||||
|  | 
 | ||||||
|  | Field relationService in com.mmg.service.impl.ResourceServiceImpl required a bean of type 'com.mmg.service.ResourceCategoryService' that could not be found. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Action: | ||||||
|  | 
 | ||||||
|  | Consider defining a bean of type 'com.mmg.service.ResourceCategoryService' in your configuration. | ||||||
|  | 
 | ||||||
|  | 18:00:57.930 [http-nio-9090-exec-2] ERROR c.m.c.MinioController - [initMultiPartUpload,106] - ³õʼ»¯·ÖƬÉÏ´«Ê§°Ü | ||||||
|  | java.lang.IllegalArgumentException: Access key cannot be null. | ||||||
|  | 	at com.amazonaws.auth.BasicAWSCredentials.<init>(BasicAWSCredentials.java:37) | ||||||
|  | 	at com.mmg.utils.S3Util.getClient(S3Util.java:59) | ||||||
|  | 	at com.mmg.utils.S3Util.uploadId(S3Util.java:98) | ||||||
|  | 	at com.mmg.controller.MinioController.initMultiPartUpload(MinioController.java:90) | ||||||
|  | 	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) | ||||||
|  | 	at java.base/java.lang.reflect.Method.invoke(Method.java:578) | ||||||
|  | 	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) | ||||||
|  | 	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) | ||||||
|  | 	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) | ||||||
|  | 	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) | ||||||
|  | 	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) | ||||||
|  | 	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) | ||||||
|  | 	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1080) | ||||||
|  | 	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:973) | ||||||
|  | 	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) | ||||||
|  | 	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) | ||||||
|  | 	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:731) | ||||||
|  | 	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) | ||||||
|  | 	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814) | ||||||
|  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223) | ||||||
|  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) | ||||||
|  | 	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) | ||||||
|  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) | ||||||
|  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) | ||||||
|  | 	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) | ||||||
|  | 	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) | ||||||
|  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) | ||||||
|  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) | ||||||
|  | 	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) | ||||||
|  | 	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) | ||||||
|  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) | ||||||
|  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) | ||||||
|  | 	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) | ||||||
|  | 	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) | ||||||
|  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) | ||||||
|  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) | ||||||
|  | 	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) | ||||||
|  | 	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) | ||||||
|  | 	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) | ||||||
|  | 	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119) | ||||||
|  | 	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) | ||||||
|  | 	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) | ||||||
|  | 	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) | ||||||
|  | 	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400) | ||||||
|  | 	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) | ||||||
|  | 	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:859) | ||||||
|  | 	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1734) | ||||||
|  | 	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) | ||||||
|  | 	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) | ||||||
|  | 	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) | ||||||
|  | 	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) | ||||||
|  | 	at java.base/java.lang.Thread.run(Thread.java:1623) | ||||||
| @ -97,3 +97,116 @@ | |||||||
| 15:20:03.249 [http-nio-9090-exec-3] INFO  c.m.utils.MinioUtils - [getUploadObjectUrl,64] - tip message: 通过 <20b919730ee383d47e4c008f11652b02.jpg-image> 开始单文件上传<minio> | 15:20:03.249 [http-nio-9090-exec-3] INFO  c.m.utils.MinioUtils - [getUploadObjectUrl,64] - tip message: 通过 <20b919730ee383d47e4c008f11652b02.jpg-image> 开始单文件上传<minio> | ||||||
| 15:20:03.253 [http-nio-9090-exec-3] INFO  c.m.utils.MinioUtils - [getUploadObjectUrl,74] - 预签名完成:http://47.103.114.59:9000/image/20b919730ee383d47e4c008f11652b02.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=olive%2F20241213%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20241213T072003Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=c53c0fc6753a7c55e09b0536ac6141a907018141886e910e68d3b64c513ed1a6 | 15:20:03.253 [http-nio-9090-exec-3] INFO  c.m.utils.MinioUtils - [getUploadObjectUrl,74] - 预签名完成:http://47.103.114.59:9000/image/20b919730ee383d47e4c008f11652b02.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=olive%2F20241213%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20241213T072003Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=c53c0fc6753a7c55e09b0536ac6141a907018141886e910e68d3b64c513ed1a6 | ||||||
| 15:20:03.253 [http-nio-9090-exec-3] INFO  c.m.utils.MinioUtils - [getUploadObjectUrl,75] - tip message: 单个文件上传、成功 | 15:20:03.253 [http-nio-9090-exec-3] INFO  c.m.utils.MinioUtils - [getUploadObjectUrl,75] - tip message: 单个文件上传、成功 | ||||||
|  | 17:41:29.203 [SpringApplicationShutdownHook] INFO  c.z.h.HikariDataSource - [close,350] - HikariPool-1 - Shutdown initiated... | ||||||
|  | 17:41:29.207 [SpringApplicationShutdownHook] INFO  c.z.h.HikariDataSource - [close,352] - HikariPool-1 - Shutdown completed. | ||||||
|  | 17:48:11.753 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 8.0.0.Final | ||||||
|  | 17:48:11.771 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarting,51] - Starting MinioUploadFileApplication using Java 20.0.2.1 with PID 135148 (F:\Project\tutorial_repo\minio-admin\target\classes started by Administrator in F:\Project\tutorial_repo\minio-admin) | ||||||
|  | 17:48:11.772 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStartupProfileInfo,630] - No active profile set, falling back to 1 default profile: "default" | ||||||
|  | 17:48:12.707 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9090"] | ||||||
|  | 17:48:12.708 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] | ||||||
|  | 17:48:12.708 [restartedMain] INFO  o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/10.1.5] | ||||||
|  | 17:48:12.740 [restartedMain] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext | ||||||
|  | 17:48:12.911 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Stopping service [Tomcat] | ||||||
|  | 17:50:02.517 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 8.0.0.Final | ||||||
|  | 17:50:02.530 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarting,51] - Starting MinioUploadFileApplication using Java 20.0.2.1 with PID 124000 (F:\Project\tutorial_repo\minio-admin\target\classes started by Administrator in F:\Project\tutorial_repo\minio-admin) | ||||||
|  | 17:50:02.531 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStartupProfileInfo,630] - No active profile set, falling back to 1 default profile: "default" | ||||||
|  | 17:50:03.311 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9090"] | ||||||
|  | 17:50:03.312 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] | ||||||
|  | 17:50:03.313 [restartedMain] INFO  o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/10.1.5] | ||||||
|  | 17:50:03.359 [restartedMain] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext | ||||||
|  | 17:50:03.558 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Stopping service [Tomcat] | ||||||
|  | 17:51:31.914 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 8.0.0.Final | ||||||
|  | 17:51:31.928 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarting,51] - Starting MinioUploadFileApplication using Java 20.0.2.1 with PID 135100 (F:\Project\tutorial_repo\minio-admin\target\classes started by Administrator in F:\Project\tutorial_repo\minio-admin) | ||||||
|  | 17:51:31.929 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStartupProfileInfo,630] - No active profile set, falling back to 1 default profile: "default" | ||||||
|  | 17:51:32.727 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9090"] | ||||||
|  | 17:51:32.727 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] | ||||||
|  | 17:51:32.727 [restartedMain] INFO  o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/10.1.5] | ||||||
|  | 17:51:32.768 [restartedMain] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext | ||||||
|  | 17:51:33.483 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9090"] | ||||||
|  | 17:51:33.505 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarted,57] - Started MinioUploadFileApplication in 1.759 seconds (process running for 2.231) | ||||||
|  | 17:51:49.537 [http-nio-9090-exec-1] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' | ||||||
|  | 17:59:17.459 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 8.0.0.Final | ||||||
|  | 17:59:17.478 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarting,51] - Starting MinioUploadFileApplication using Java 20.0.2.1 with PID 133680 (F:\Project\tutorial_repo\minio-admin\target\classes started by Administrator in F:\Project\tutorial_repo\minio-admin) | ||||||
|  | 17:59:17.480 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStartupProfileInfo,630] - No active profile set, falling back to 1 default profile: "default" | ||||||
|  | 17:59:18.595 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9090"] | ||||||
|  | 17:59:18.596 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] | ||||||
|  | 17:59:18.596 [restartedMain] INFO  o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/10.1.5] | ||||||
|  | 17:59:18.636 [restartedMain] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext | ||||||
|  | 17:59:19.482 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9090"] | ||||||
|  | 17:59:19.517 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarted,57] - Started MinioUploadFileApplication in 2.289 seconds (process running for 2.888) | ||||||
|  | 18:00:01.217 [http-nio-9090-exec-6] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' | ||||||
|  | 18:00:36.955 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 8.0.0.Final | ||||||
|  | 18:00:36.971 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarting,51] - Starting MinioUploadFileApplication using Java 20.0.2.1 with PID 124016 (F:\Project\tutorial_repo\minio-admin\target\classes started by Administrator in F:\Project\tutorial_repo\minio-admin) | ||||||
|  | 18:00:36.972 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStartupProfileInfo,630] - No active profile set, falling back to 1 default profile: "default" | ||||||
|  | 18:00:37.959 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:00:37.960 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] | ||||||
|  | 18:00:37.960 [restartedMain] INFO  o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/10.1.5] | ||||||
|  | 18:00:38.011 [restartedMain] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext | ||||||
|  | 18:00:38.813 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:00:38.840 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarted,57] - Started MinioUploadFileApplication in 2.175 seconds (process running for 2.807) | ||||||
|  | 18:00:57.595 [http-nio-9090-exec-1] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' | ||||||
|  | 18:00:57.654 [http-nio-9090-exec-1] INFO  c.z.h.HikariDataSource - [getConnection,110] - HikariPool-1 - Starting... | ||||||
|  | 18:00:57.847 [http-nio-9090-exec-1] INFO  c.z.h.p.HikariPool - [checkFailFast,565] - HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@7d397f49 | ||||||
|  | 18:00:57.848 [http-nio-9090-exec-1] INFO  c.z.h.HikariDataSource - [getConnection,123] - HikariPool-1 - Start completed. | ||||||
|  | 18:08:07.136 [SpringApplicationShutdownHook] INFO  c.z.h.HikariDataSource - [close,350] - HikariPool-1 - Shutdown initiated... | ||||||
|  | 18:08:07.138 [SpringApplicationShutdownHook] INFO  c.z.h.HikariDataSource - [close,352] - HikariPool-1 - Shutdown completed. | ||||||
|  | 18:08:13.108 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 8.0.0.Final | ||||||
|  | 18:08:13.123 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarting,51] - Starting MinioUploadFileApplication using Java 20.0.2.1 with PID 129352 (F:\Project\tutorial_repo\minio-admin\target\classes started by Administrator in F:\Project\tutorial_repo\minio-admin) | ||||||
|  | 18:08:13.123 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStartupProfileInfo,630] - No active profile set, falling back to 1 default profile: "default" | ||||||
|  | 18:08:13.832 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:08:13.833 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] | ||||||
|  | 18:08:13.833 [restartedMain] INFO  o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/10.1.5] | ||||||
|  | 18:08:13.866 [restartedMain] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext | ||||||
|  | 18:08:14.350 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:08:14.368 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarted,57] - Started MinioUploadFileApplication in 1.414 seconds (process running for 1.867) | ||||||
|  | 18:08:45.514 [http-nio-9090-exec-1] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' | ||||||
|  | 18:17:19.097 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 8.0.0.Final | ||||||
|  | 18:17:19.111 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarting,51] - Starting MinioUploadFileApplication using Java 20.0.2.1 with PID 134044 (F:\Project\tutorial_repo\minio-admin\target\classes started by Administrator in F:\Project\tutorial_repo\minio-admin) | ||||||
|  | 18:17:19.112 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStartupProfileInfo,630] - No active profile set, falling back to 1 default profile: "default" | ||||||
|  | 18:17:20.068 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:17:20.068 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] | ||||||
|  | 18:17:20.068 [restartedMain] INFO  o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/10.1.5] | ||||||
|  | 18:17:20.133 [restartedMain] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext | ||||||
|  | 18:17:20.854 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:17:20.870 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarted,57] - Started MinioUploadFileApplication in 2.005 seconds (process running for 2.953) | ||||||
|  | 18:27:28.415 [http-nio-9090-exec-1] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' | ||||||
|  | 18:33:58.150 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 8.0.0.Final | ||||||
|  | 18:33:58.163 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarting,51] - Starting MinioUploadFileApplication using Java 20.0.2.1 with PID 2836 (F:\Project\tutorial_repo\minio-admin\target\classes started by Administrator in F:\Project\tutorial_repo\minio-admin) | ||||||
|  | 18:33:58.164 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStartupProfileInfo,630] - No active profile set, falling back to 1 default profile: "default" | ||||||
|  | 18:33:58.897 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:33:58.897 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] | ||||||
|  | 18:33:58.897 [restartedMain] INFO  o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/10.1.5] | ||||||
|  | 18:33:58.936 [restartedMain] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext | ||||||
|  | 18:33:59.444 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:33:59.459 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarted,57] - Started MinioUploadFileApplication in 1.467 seconds (process running for 1.96) | ||||||
|  | 18:34:11.712 [http-nio-9090-exec-1] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' | ||||||
|  | 18:35:54.452 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 8.0.0.Final | ||||||
|  | 18:35:54.467 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarting,51] - Starting MinioUploadFileApplication using Java 20.0.2.1 with PID 134524 (F:\Project\tutorial_repo\minio-admin\target\classes started by Administrator in F:\Project\tutorial_repo\minio-admin) | ||||||
|  | 18:35:54.467 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStartupProfileInfo,630] - No active profile set, falling back to 1 default profile: "default" | ||||||
|  | 18:35:55.200 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:35:55.201 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] | ||||||
|  | 18:35:55.201 [restartedMain] INFO  o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/10.1.5] | ||||||
|  | 18:35:55.238 [restartedMain] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext | ||||||
|  | 18:35:55.754 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:35:55.773 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarted,57] - Started MinioUploadFileApplication in 1.485 seconds (process running for 2.018) | ||||||
|  | 18:43:33.044 [http-nio-9090-exec-1] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' | ||||||
|  | 18:44:29.614 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 8.0.0.Final | ||||||
|  | 18:44:29.630 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarting,51] - Starting MinioUploadFileApplication using Java 20.0.2.1 with PID 119900 (F:\Project\tutorial_repo\minio-admin\target\classes started by Administrator in F:\Project\tutorial_repo\minio-admin) | ||||||
|  | 18:44:29.631 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStartupProfileInfo,630] - No active profile set, falling back to 1 default profile: "default" | ||||||
|  | 18:44:30.555 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:44:30.556 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] | ||||||
|  | 18:44:30.556 [restartedMain] INFO  o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/10.1.5] | ||||||
|  | 18:44:30.599 [restartedMain] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext | ||||||
|  | 18:44:31.241 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:44:31.260 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarted,57] - Started MinioUploadFileApplication in 1.898 seconds (process running for 2.479) | ||||||
|  | 18:44:38.626 [http-nio-9090-exec-2] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' | ||||||
|  | 18:51:29.695 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 8.0.0.Final | ||||||
|  | 18:51:29.711 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarting,51] - Starting MinioUploadFileApplication using Java 20.0.2.1 with PID 118064 (F:\Project\tutorial_repo\minio-admin\target\classes started by Administrator in F:\Project\tutorial_repo\minio-admin) | ||||||
|  | 18:51:29.712 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStartupProfileInfo,630] - No active profile set, falling back to 1 default profile: "default" | ||||||
|  | 18:51:30.440 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:51:30.441 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] | ||||||
|  | 18:51:30.441 [restartedMain] INFO  o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/10.1.5] | ||||||
|  | 18:51:30.479 [restartedMain] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext | ||||||
|  | 18:51:30.993 [restartedMain] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9090"] | ||||||
|  | 18:51:31.013 [restartedMain] INFO  c.m.MinioUploadFileApplication - [logStarted,57] - Started MinioUploadFileApplication in 1.488 seconds (process running for 2.024) | ||||||
|  | 18:51:38.918 [http-nio-9090-exec-1] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' | ||||||
|  | |||||||
| @ -2,8 +2,11 @@ package com.mmg; | |||||||
| 
 | 
 | ||||||
| import org.springframework.boot.SpringApplication; | import org.springframework.boot.SpringApplication; | ||||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
|  | import org.springframework.context.annotation.ComponentScan; | ||||||
|  | 
 | ||||||
|  | @SpringBootApplication(scanBasePackages = "com.mmg") | ||||||
|  | @ComponentScan(basePackages = "com.mmg.config") | ||||||
| 
 | 
 | ||||||
| @SpringBootApplication |  | ||||||
| public class MinioUploadFileApplication { | public class MinioUploadFileApplication { | ||||||
|     public static void main(String[] args) { |     public static void main(String[] args) { | ||||||
|         SpringApplication.run(MinioUploadFileApplication.class, args); |         SpringApplication.run(MinioUploadFileApplication.class, args); | ||||||
|  | |||||||
| @ -1,131 +0,0 @@ | |||||||
| package com.mmg.controller; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| import com.mmg.model.vo.FileUploadInfo; |  | ||||||
| import com.mmg.service.UploadService; |  | ||||||
| import com.mmg.utils.MinioUtils; |  | ||||||
| import com.mmg.utils.R; |  | ||||||
| import com.mmg.utils.RedisUtil; |  | ||||||
| import com.mmg.utils.RespEnum; |  | ||||||
| import jakarta.annotation.Resource; |  | ||||||
| import lombok.extern.slf4j.Slf4j; |  | ||||||
| import org.springframework.util.StringUtils; |  | ||||||
| import org.springframework.web.bind.annotation.*; |  | ||||||
| import org.springframework.web.multipart.MultipartFile; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * minio上传流程 |  | ||||||
|  * <p> |  | ||||||
|  * 1.检查数据库中是否存在上传文件 |  | ||||||
|  * <p> |  | ||||||
|  * 2.根据文件信息初始化,获取分片预签名url地址,前端根据url地址上传文件 |  | ||||||
|  * <p> |  | ||||||
|  * 3.上传完成后,将分片上传的文件进行合并 |  | ||||||
|  * <p> |  | ||||||
|  * 4.保存文件信息到数据库 |  | ||||||
|  */ |  | ||||||
| @RestController |  | ||||||
| @Slf4j |  | ||||||
| @RequestMapping("upload") |  | ||||||
| public class FileMinioController { |  | ||||||
| 
 |  | ||||||
|     @Resource |  | ||||||
|     private UploadService uploadService; |  | ||||||
| 
 |  | ||||||
|     @Resource |  | ||||||
|     private RedisUtil redisUtil; |  | ||||||
| 
 |  | ||||||
|     @Resource |  | ||||||
|     private MinioUtils minioUtils; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @param fileMD5 文件md5 |  | ||||||
|      * @return {@link R } |  | ||||||
|      * @description 获取上传文件 |  | ||||||
|      * @author LGY |  | ||||||
|      * @date 2023/04/26 16:00 |  | ||||||
|      */ |  | ||||||
|     @GetMapping("/getUploadingFile/{fileMD5}") |  | ||||||
|     public R getUploadingFile(@PathVariable String fileMD5) { |  | ||||||
|         try { |  | ||||||
|             if (StringUtils.isEmpty(fileMD5)) { |  | ||||||
|                 return R.error(); |  | ||||||
|             } |  | ||||||
|             FileUploadInfo fileUploadInfo = (FileUploadInfo) redisUtil.get(fileMD5); |  | ||||||
|             if (fileUploadInfo != null) { |  | ||||||
|                 // 查询上传后的分片数据 |  | ||||||
|                 fileUploadInfo.setChunkUploadedList(minioUtils.getChunkByFileMD5(fileUploadInfo.getFileName(), fileUploadInfo.getUploadId(), fileUploadInfo.getFileType())); |  | ||||||
|                 return R.ok().setData(fileUploadInfo); |  | ||||||
|             } |  | ||||||
|             return R.error(); |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             return R.error(e.getMessage()); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 校验文件是否存在 |  | ||||||
|      * |  | ||||||
|      * @param md5 String |  | ||||||
|      * @return ResponseResult<Object> |  | ||||||
|      */ |  | ||||||
|     @GetMapping("/multipart/check") |  | ||||||
|     public R checkFileUploadedByMd5(@RequestParam("md5") String md5) { |  | ||||||
|         log.info("REST: 通过查询 <{}> 文件是否存在、是否进行断点续传", md5); |  | ||||||
|         if (StringUtils.isEmpty(md5)) { |  | ||||||
|             log.error("查询文件是否存在、入参无效"); |  | ||||||
|             return R.error(RespEnum.ACCESS_PARAMETER_INVALID); |  | ||||||
|         } |  | ||||||
|         return uploadService.getByFileMD5(md5); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 分片初始化 |  | ||||||
|      * |  | ||||||
|      * @param fileUploadInfo 文件信息 |  | ||||||
|      * @return ResponseResult<Object> |  | ||||||
|      */ |  | ||||||
|     @PostMapping("/multipart/init") |  | ||||||
|     public R initMultiPartUpload(@RequestBody FileUploadInfo fileUploadInfo) { |  | ||||||
|         log.info("REST: 通过 <{}> 初始化上传任务", fileUploadInfo); |  | ||||||
|         return R.ok().setData(uploadService.initMultiPartUpload(fileUploadInfo)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 完成上传 |  | ||||||
|      * |  | ||||||
|      * @param fileUploadInfo 文件信息 |  | ||||||
|      * @return ResponseResult<Object> |  | ||||||
|      */ |  | ||||||
|     @PostMapping("/multipart/merge") |  | ||||||
|     public R completeMultiPartUpload(@RequestBody FileUploadInfo fileUploadInfo) { |  | ||||||
|         log.info("REST: 通过 {} 合并上传任务", fileUploadInfo); |  | ||||||
|         //合并文件 |  | ||||||
|         String url = uploadService.mergeMultipartUpload(fileUploadInfo); |  | ||||||
|         //获取上传文件地址 |  | ||||||
|         if (!StringUtils.isEmpty(url)) { |  | ||||||
|             return R.ok().setData(url); |  | ||||||
|         } |  | ||||||
|         return R.error(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @PostMapping("/multipart/uploadScreenshot") |  | ||||||
|     public R uploaduploadScreenshot(@RequestPart("photos") MultipartFile[] photos, |  | ||||||
|                                     @RequestParam("buckName") String buckName) { |  | ||||||
|         log.info("REST: 上传文件信息 <{}> ", photos); |  | ||||||
| 
 |  | ||||||
|         for (MultipartFile photo : photos) { |  | ||||||
|             if (!photo.isEmpty()) { |  | ||||||
|                 uploadService.upload(photo, buckName); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return R.ok(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     @RequestMapping("/createBucket") |  | ||||||
|     public void createBucket(@RequestParam("bucketName") String bucketName) { |  | ||||||
|         String bucket = minioUtils.createBucket(bucketName); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -0,0 +1,233 @@ | |||||||
|  | package com.mmg.controller; | ||||||
|  | 
 | ||||||
|  | import com.mmg.model.dto.FileUploadInfo; | ||||||
|  | import com.mmg.model.po.Resource; | ||||||
|  | import com.mmg.service.AppConfigService; | ||||||
|  | import com.mmg.service.ResourceCategoryService; | ||||||
|  | import com.mmg.service.ResourceService; | ||||||
|  | import com.mmg.service.UploadService; | ||||||
|  | import com.mmg.utils.R; | ||||||
|  | import com.mmg.utils.S3Util; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  | import org.apache.commons.codec.digest.DigestUtils; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.web.bind.annotation.*; | ||||||
|  | import org.springframework.web.multipart.MultipartFile; | ||||||
|  | 
 | ||||||
|  | import java.util.*; | ||||||
|  | 
 | ||||||
|  | @RestController | ||||||
|  | @RequestMapping("/upload") | ||||||
|  | @CrossOrigin(origins = "*") | ||||||
|  | @Slf4j | ||||||
|  | public class MinioController { | ||||||
|  | 
 | ||||||
|  |     private final UploadService uploadService; | ||||||
|  |     private final ResourceService resourceService; | ||||||
|  |     private final AppConfigService appConfigService; | ||||||
|  |     private final ResourceCategoryService resourceCategoryService; | ||||||
|  |     private final S3Util s3Util; | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     public MinioController(UploadService uploadService, | ||||||
|  |                            ResourceService resourceService, | ||||||
|  |                            AppConfigService appConfigService, | ||||||
|  |                            ResourceCategoryService resourceCategoryService, | ||||||
|  |                            S3Util s3Util) { | ||||||
|  |         this.uploadService = uploadService; | ||||||
|  |         this.resourceService = resourceService; | ||||||
|  |         this.appConfigService = appConfigService; | ||||||
|  |         this.resourceCategoryService = resourceCategoryService; | ||||||
|  |         this.s3Util = s3Util; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 获取上传中的文件信息 | ||||||
|  |      * | ||||||
|  |      * @param fileMD5 文件的 MD5 值 | ||||||
|  |      * @return 响应结果 | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/getUploadingFile/{fileMD5}") | ||||||
|  |     public R getUploadingFile(@PathVariable String fileMD5) { | ||||||
|  |         try { | ||||||
|  |             Resource resource = resourceService.getByMd5(fileMD5); | ||||||
|  |             if (resource != null) { | ||||||
|  |                 return R.ok().put("file", resource); | ||||||
|  |             } else { | ||||||
|  |                 return R.error("文件不存在"); | ||||||
|  |             } | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             log.error("获取上传文件失败", e); | ||||||
|  |             return R.error("获取上传文件失败"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 校验文件是否已经上传 | ||||||
|  |      * | ||||||
|  |      * @param md5 文件的 MD5 值 | ||||||
|  |      * @return 响应结果 | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/multipart/check") | ||||||
|  |     public R checkFileUploadedByMd5(@RequestParam("md5") String md5) { | ||||||
|  |         log.error("进入check"); | ||||||
|  |         try { | ||||||
|  |             boolean exists = resourceService.existsByMd5(md5); | ||||||
|  |             return R.ok().put("exists", exists); | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             log.error("校验文件是否已上传失败", e); | ||||||
|  |             return R.error("校验文件是否已上传失败"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 初始化分片上传 | ||||||
|  |      * | ||||||
|  |      * @param fileUploadInfo 文件上传信息 | ||||||
|  |      * @return 响应结果 | ||||||
|  |      */ | ||||||
|  |     @PostMapping("/multipart/init") | ||||||
|  |     public R initMultiPartUpload(@RequestBody FileUploadInfo fileUploadInfo) { | ||||||
|  |         try { | ||||||
|  |             String uploadId = s3Util.uploadId(fileUploadInfo.getSavePath()); | ||||||
|  |             // 假设每个分片大小为 5MB,计算分片数量 | ||||||
|  |             int partSize = 5 * 1024 * 1024; // 5MB | ||||||
|  |             int partCount = (int) Math.ceil((double) fileUploadInfo.getSize() / partSize); | ||||||
|  |             List<String> preSignedUrls = new ArrayList<>(); | ||||||
|  |             for (int partNumber = 1; partNumber <= partCount; partNumber++) { | ||||||
|  |                 String preSignedUrl = s3Util.generatePartUploadPreSignUrl( | ||||||
|  |                         fileUploadInfo.getSavePath(), String.valueOf(partNumber), uploadId); | ||||||
|  |                 preSignedUrls.add(preSignedUrl); | ||||||
|  |             } | ||||||
|  |             Map<String, Object> response = new HashMap<>(); | ||||||
|  |             response.put("uploadId", uploadId); | ||||||
|  |             response.put("preSignedUrls", preSignedUrls); | ||||||
|  |             response.put("partCount", partCount); | ||||||
|  |             return R.ok().put("data", response); | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             log.error("初始化分片上传失败", e); | ||||||
|  |             return R.error("初始化分片上传失败"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 完成分片上传 | ||||||
|  |      * | ||||||
|  |      * @param fileUploadInfo 文件上传信息 | ||||||
|  |      * @return 响应结果 | ||||||
|  |      */ | ||||||
|  |     @PostMapping("/multipart/merge") | ||||||
|  |     public R completeMultiPartUpload(@RequestBody FileUploadInfo fileUploadInfo) { | ||||||
|  |         try { | ||||||
|  |             String fileUrl = s3Util.merge(fileUploadInfo.getSavePath(), fileUploadInfo.getUploadId()); | ||||||
|  | 
 | ||||||
|  |             // 生成文件MD5 | ||||||
|  |             String fileMD5 = DigestUtils.md5Hex(fileUrl); // 根据实际情况生成MD5值 | ||||||
|  | 
 | ||||||
|  |             // 保存文件信息到数据库 | ||||||
|  |             Resource resource = resourceService.create( | ||||||
|  |                     fileUploadInfo.getAdminId(), | ||||||
|  |                     fileUploadInfo.getCategoryIds(), | ||||||
|  |                     fileUploadInfo.getResourceType(), | ||||||
|  |                     fileUploadInfo.getOriginalName(), | ||||||
|  |                     fileUploadInfo.getExtension(), | ||||||
|  |                     fileUploadInfo.getSize(), | ||||||
|  |                     "minio", | ||||||
|  |                     UUID.randomUUID().toString(), | ||||||
|  |                     fileUploadInfo.getSavePath(), | ||||||
|  |                     fileUrl | ||||||
|  |             ); | ||||||
|  | 
 | ||||||
|  |             // 更新MD5值 | ||||||
|  |             resource.setMd5(fileMD5); | ||||||
|  |             resourceService.updateById(resource); | ||||||
|  | 
 | ||||||
|  |             return R.ok().put("url", fileUrl).put("resource", resource); | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             log.error("完成分片上传失败", e); | ||||||
|  |             return R.error("完成分片上传失败"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 上传截图 | ||||||
|  |      * | ||||||
|  |      * @param photos     上传的截图文件数组 | ||||||
|  |      * @param bucketName Bucket 名称 | ||||||
|  |      * @return 响应结果 | ||||||
|  |      */ | ||||||
|  |     @PostMapping("/multipart/uploadScreenshot") | ||||||
|  |     public R uploadUploadScreenshot(@RequestPart("photos") MultipartFile[] photos, | ||||||
|  |                                     @RequestParam("bucketName") String bucketName) { | ||||||
|  |         try { | ||||||
|  |             List<Map<String, String>> uploadedFiles = new ArrayList<>(); | ||||||
|  |             for (MultipartFile photo : photos) { | ||||||
|  |                 String fileName = UUID.randomUUID().toString() + "_" + photo.getOriginalFilename(); | ||||||
|  |                 String savePath = bucketName + "/" + fileName; | ||||||
|  |                 String url = s3Util.saveFile(photo, savePath, photo.getContentType()); | ||||||
|  | 
 | ||||||
|  |                 // 生成文件 MD5 | ||||||
|  |                 String fileMD5 = DigestUtils.md5Hex(photo.getBytes()); | ||||||
|  | 
 | ||||||
|  |                 // 保存文件信息到数据库 | ||||||
|  |                 Resource resource = resourceService.create( | ||||||
|  |                         null, // 如果有 adminId,请传递 | ||||||
|  |                         null, // 如果有 categoryIds,请传递 | ||||||
|  |                         "image", | ||||||
|  |                         photo.getOriginalFilename(), | ||||||
|  |                         getFileExtension(photo.getOriginalFilename()), | ||||||
|  |                         photo.getSize(), | ||||||
|  |                         "minio", | ||||||
|  |                         UUID.randomUUID().toString(), | ||||||
|  |                         savePath, | ||||||
|  |                         url | ||||||
|  |                 ); | ||||||
|  |                 resource.setMd5(fileMD5); | ||||||
|  |                 resourceService.updateById(resource); | ||||||
|  | 
 | ||||||
|  |                 Map<String, String> fileInfo = new HashMap<>(); | ||||||
|  |                 fileInfo.put("url", url); | ||||||
|  |                 fileInfo.put("filename", photo.getOriginalFilename()); | ||||||
|  |                 uploadedFiles.add(fileInfo); | ||||||
|  |             } | ||||||
|  |             return R.ok().put("files", uploadedFiles); | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             log.error("上传截图失败", e); | ||||||
|  |             return R.error("上传截图失败"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 创建 Bucket | ||||||
|  |      * | ||||||
|  |      * @param bucketName Bucket 名称 | ||||||
|  |      * @return 响应结果 | ||||||
|  |      */ | ||||||
|  |     @PostMapping("/createBucket") | ||||||
|  |     public R createBucket(@RequestParam("bucketName") String bucketName) { | ||||||
|  |         try { | ||||||
|  |             if (!s3Util.getClient().doesBucketExistV2(bucketName)) { | ||||||
|  |                 s3Util.getClient().createBucket(bucketName); | ||||||
|  |                 return R.ok("Bucket 创建成功"); | ||||||
|  |             } else { | ||||||
|  |                 return R.error("Bucket 已存在"); | ||||||
|  |             } | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             log.error("创建 Bucket 失败", e); | ||||||
|  |             return R.error("创建 Bucket 失败"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 获取文件扩展名 | ||||||
|  |      * | ||||||
|  |      * @param filename 文件名 | ||||||
|  |      * @return 扩展名 | ||||||
|  |      */ | ||||||
|  |     private String getFileExtension(String filename) { | ||||||
|  |         if (filename == null || filename.lastIndexOf(".") == -1) { | ||||||
|  |             return ""; | ||||||
|  |         } | ||||||
|  |         return filename.substring(filename.lastIndexOf(".") + 1); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,15 +1,9 @@ | |||||||
| package com.mmg.model.vo; | package com.mmg.model.dto; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| import jakarta.validation.constraints.NotBlank; |  | ||||||
| import jakarta.validation.constraints.NotNull; |  | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| import lombok.experimental.Accessors; |  | ||||||
| 
 |  | ||||||
| import java.util.List; |  | ||||||
| 
 | 
 | ||||||
| @Data | @Data | ||||||
| public class UploadFileInfo { | public class FileUploadInfo { | ||||||
|     private String originalName; |     private String originalName; | ||||||
|     private String extension; |     private String extension; | ||||||
|     private long size; |     private long size; | ||||||
| @ -17,5 +11,7 @@ public class UploadFileInfo { | |||||||
|     private String resourceType; |     private String resourceType; | ||||||
|     private String savePath; |     private String savePath; | ||||||
|     private String url; |     private String url; | ||||||
|  |     private Integer adminId; // 添加管理员ID | ||||||
|  |     private String categoryIds; // 添加分类ID | ||||||
|  |     private String uploadId; // 添加上传ID用于分片上传 | ||||||
| } | } | ||||||
| 
 |  | ||||||
| @ -49,6 +49,7 @@ public class Resource implements Serializable { | |||||||
| 
 | 
 | ||||||
|     /** URL地址 */ |     /** URL地址 */ | ||||||
|     private String url; |     private String url; | ||||||
|  |     private String md5; | ||||||
| 
 | 
 | ||||||
|     /** */ |     /** */ | ||||||
|     @JsonProperty("created_at") |     @JsonProperty("created_at") | ||||||
| @ -61,6 +62,7 @@ public class Resource implements Serializable { | |||||||
|     /** 隐藏[0:否,1:是] */ |     /** 隐藏[0:否,1:是] */ | ||||||
|     @JsonIgnore private Integer isHidden; |     @JsonIgnore private Integer isHidden; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|     @TableField(exist = false) |     @TableField(exist = false) | ||||||
|     private static final long serialVersionUID = 1L; |     private static final long serialVersionUID = 1L; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ import org.springframework.stereotype.Service; | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @Service | 
 | ||||||
| public interface ResourceCategoryService extends IService<ResourceCategory> { | public interface ResourceCategoryService extends IService<ResourceCategory> { | ||||||
|     void rebuild(Integer resourceId, List<Integer> categoryIds); |     void rebuild(Integer resourceId, List<Integer> categoryIds); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ import org.springframework.stereotype.Service; | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @Service | 
 | ||||||
| public interface ResourceService extends IService<Resource> { | public interface ResourceService extends IService<Resource> { | ||||||
| 
 | 
 | ||||||
|     PaginationResult<Resource> paginate(int page, int size, ResourcePaginateFilter filter); |     PaginationResult<Resource> paginate(int page, int size, ResourcePaginateFilter filter); | ||||||
| @ -47,4 +47,10 @@ public interface ResourceService extends IService<Resource> { | |||||||
|     List<Integer> categoryIds(Integer resourceId); |     List<Integer> categoryIds(Integer resourceId); | ||||||
| 
 | 
 | ||||||
|     Integer total(List<String> types); |     Integer total(List<String> types); | ||||||
|  | 
 | ||||||
|  |     // 新增方法:根据 MD5 查询资源 | ||||||
|  |     Resource getByMd5(String md5); | ||||||
|  | 
 | ||||||
|  |     // 新增方法:检查 MD5 是否存在 | ||||||
|  |     boolean existsByMd5(String md5); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,18 +1,18 @@ | |||||||
| 
 | 
 | ||||||
| package com.mmg.service; | package com.mmg.service; | ||||||
| 
 | 
 | ||||||
|  | import com.mmg.model.dto.FileUploadInfo; | ||||||
| import com.mmg.model.po.Resource; | import com.mmg.model.po.Resource; | ||||||
| import com.mmg.model.vo.UploadFileInfo; |  | ||||||
| import org.springframework.web.multipart.MultipartFile; | import org.springframework.web.multipart.MultipartFile; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| public interface UploadService { | public interface UploadService { | ||||||
| 
 | 
 | ||||||
|     UploadFileInfo upload(MultipartFile file, String dir) throws Exception; |     FileUploadInfo upload(MultipartFile file, String dir) throws Exception; | ||||||
| 
 | 
 | ||||||
|     Resource storeMinio(Integer adminId, MultipartFile file, String categoryIds) |     Resource storeMinio(Integer adminId, MultipartFile file, String categoryIds) | ||||||
|             throws Exception; |             throws Exception; | ||||||
|     UploadFileInfo uploadTmp(MultipartFile file, String dir) throws Exception; |     FileUploadInfo uploadTmp(MultipartFile file, String dir) throws Exception; | ||||||
| 
 | 
 | ||||||
|     Resource storeMinioTmp(Integer adminId, MultipartFile file, String categoryIds) |     Resource storeMinioTmp(Integer adminId, MultipartFile file, String categoryIds) | ||||||
|             throws Exception; |             throws Exception; | ||||||
|  | |||||||
| @ -24,7 +24,7 @@ import org.springframework.stereotype.Service; | |||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| 
 | @Service | ||||||
| public class ResourceCategoryServiceImpl | public class ResourceCategoryServiceImpl | ||||||
|         extends ServiceImpl<ResourceCategoryMapper, ResourceCategory> |         extends ServiceImpl<ResourceCategoryMapper, ResourceCategory> | ||||||
|         implements ResourceCategoryService { |         implements ResourceCategoryService { | ||||||
|  | |||||||
| @ -17,6 +17,7 @@ package com.mmg.service.impl; | |||||||
| 
 | 
 | ||||||
| import com.amazonaws.services.kms.model.NotFoundException; | import com.amazonaws.services.kms.model.NotFoundException; | ||||||
| 
 | 
 | ||||||
|  | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||||||
| import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||||||
| import com.mmg.mapper.ResourceMapper; | import com.mmg.mapper.ResourceMapper; | ||||||
| 
 | 
 | ||||||
| @ -194,4 +195,18 @@ public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> | |||||||
|     public Integer total(List<String> types) { |     public Integer total(List<String> types) { | ||||||
|         return Math.toIntExact(count(query().getWrapper().in("type", types).eq("is_hidden", 0))); |         return Math.toIntExact(count(query().getWrapper().in("type", types).eq("is_hidden", 0))); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public Resource getByMd5(String md5) { | ||||||
|  |         QueryWrapper<Resource> queryWrapper = new QueryWrapper<>(); | ||||||
|  |         queryWrapper.eq("md5", md5); | ||||||
|  |         return this.getOne(queryWrapper); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean existsByMd5(String md5) { | ||||||
|  |         QueryWrapper<Resource> queryWrapper = new QueryWrapper<>(); | ||||||
|  |         queryWrapper.eq("md5", md5); | ||||||
|  |         return this.count(queryWrapper) > 0; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -16,10 +16,11 @@ | |||||||
| package com.mmg.service.impl; | package com.mmg.service.impl; | ||||||
| 
 | 
 | ||||||
| import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||||||
|  | import com.mmg.mapper.ResourceVideoMapper; | ||||||
|  | import com.mmg.model.po.ResourceVideo; | ||||||
|  | import com.mmg.service.ResourceVideoService; | ||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
| import xyz.playedu.resource.domain.ResourceVideo; | 
 | ||||||
| import xyz.playedu.resource.mapper.ResourceVideoMapper; |  | ||||||
| import xyz.playedu.resource.service.ResourceVideoService; |  | ||||||
| 
 | 
 | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Date; | import java.util.Date; | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ package com.mmg.service.impl; | |||||||
| import com.mmg.config.S3Config; | import com.mmg.config.S3Config; | ||||||
| import com.mmg.constant.BackendConstant; | import com.mmg.constant.BackendConstant; | ||||||
| import com.mmg.model.po.Resource; | import com.mmg.model.po.Resource; | ||||||
| import com.mmg.model.vo.UploadFileInfo; | import com.mmg.model.dto.FileUploadInfo; | ||||||
| import com.mmg.service.AppConfigService; | import com.mmg.service.AppConfigService; | ||||||
| import com.mmg.service.ResourceService; | import com.mmg.service.ResourceService; | ||||||
| import com.mmg.service.UploadService; | import com.mmg.service.UploadService; | ||||||
| @ -16,8 +16,6 @@ import org.springframework.beans.factory.annotation.Autowired; | |||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
| import org.springframework.web.multipart.MultipartFile; | import org.springframework.web.multipart.MultipartFile; | ||||||
| 
 | 
 | ||||||
| import java.util.Date; |  | ||||||
| 
 |  | ||||||
| @Service | @Service | ||||||
| @Slf4j | @Slf4j | ||||||
| public class UploadServiceImpl implements UploadService { | public class UploadServiceImpl implements UploadService { | ||||||
| @ -30,7 +28,7 @@ public class UploadServiceImpl implements UploadService { | |||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     @SneakyThrows |     @SneakyThrows | ||||||
|     public UploadFileInfo upload(MultipartFile file, String dir) { |     public FileUploadInfo upload(MultipartFile file, String dir) { | ||||||
|         if (file == null || file.isEmpty() || file.getOriginalFilename() == null) { |         if (file == null || file.isEmpty() || file.getOriginalFilename() == null) { | ||||||
|             throw new Exception("请上传文件"); |             throw new Exception("请上传文件"); | ||||||
|         } |         } | ||||||
| @ -38,7 +36,7 @@ public class UploadServiceImpl implements UploadService { | |||||||
|         // 上传上来的文件名名 |         // 上传上来的文件名名 | ||||||
|         String filename = file.getOriginalFilename(); |         String filename = file.getOriginalFilename(); | ||||||
| 
 | 
 | ||||||
|         UploadFileInfo fileInfo = new UploadFileInfo(); |         FileUploadInfo fileInfo = new FileUploadInfo(); | ||||||
|         // 文件大小 |         // 文件大小 | ||||||
|         fileInfo.setSize(file.getSize()); |         fileInfo.setSize(file.getSize()); | ||||||
|         // 解析扩展名 |         // 解析扩展名 | ||||||
| @ -74,7 +72,7 @@ public class UploadServiceImpl implements UploadService { | |||||||
|     @Override |     @Override | ||||||
|     @SneakyThrows |     @SneakyThrows | ||||||
|     public Resource storeMinio(Integer adminId, MultipartFile file, String categoryIds) { |     public Resource storeMinio(Integer adminId, MultipartFile file, String categoryIds) { | ||||||
|         UploadFileInfo info = upload(file, null); |         FileUploadInfo info = upload(file, null); | ||||||
| 
 | 
 | ||||||
|         return resourceService.create( |         return resourceService.create( | ||||||
|                 adminId, |                 adminId, | ||||||
| @ -132,7 +130,7 @@ public class UploadServiceImpl implements UploadService { | |||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     @SneakyThrows |     @SneakyThrows | ||||||
|     public UploadFileInfo uploadTmp(MultipartFile file, String dir) { |     public FileUploadInfo uploadTmp(MultipartFile file, String dir) { | ||||||
|         if (file == null || file.isEmpty() || file.getOriginalFilename() == null) { |         if (file == null || file.isEmpty() || file.getOriginalFilename() == null) { | ||||||
|             throw new Exception("请上传文件"); |             throw new Exception("请上传文件"); | ||||||
|         } |         } | ||||||
| @ -140,7 +138,7 @@ public class UploadServiceImpl implements UploadService { | |||||||
|         // 上传上来的文件名名 |         // 上传上来的文件名名 | ||||||
|         String filename = file.getOriginalFilename(); |         String filename = file.getOriginalFilename(); | ||||||
| 
 | 
 | ||||||
|         UploadFileInfo fileInfo = new UploadFileInfo(); |         FileUploadInfo fileInfo = new FileUploadInfo(); | ||||||
|         // 文件大小 |         // 文件大小 | ||||||
|         fileInfo.setSize(file.getSize()); |         fileInfo.setSize(file.getSize()); | ||||||
|         // 解析扩展名 |         // 解析扩展名 | ||||||
| @ -186,7 +184,7 @@ public class UploadServiceImpl implements UploadService { | |||||||
|     @Override |     @Override | ||||||
|     @SneakyThrows |     @SneakyThrows | ||||||
|     public Resource storeMinioTmp(Integer adminId, MultipartFile file, String categoryIds) { |     public Resource storeMinioTmp(Integer adminId, MultipartFile file, String categoryIds) { | ||||||
|         UploadFileInfo info = uploadTmp(file, null); |         FileUploadInfo info = uploadTmp(file, null); | ||||||
| 
 | 
 | ||||||
|         return resourceService.create( |         return resourceService.create( | ||||||
|                 adminId, |                 adminId, | ||||||
|  | |||||||
| @ -1,307 +0,0 @@ | |||||||
| package com.mmg.utils; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| import cn.hutool.core.text.CharSequenceUtil; |  | ||||||
| import cn.hutool.core.util.StrUtil; |  | ||||||
| import com.google.common.collect.HashMultimap; |  | ||||||
| import com.mmg.config.CustomMinioClient; |  | ||||||
| import com.mmg.model.vo.FileUploadInfo; |  | ||||||
| import io.minio.*; |  | ||||||
| import io.minio.http.Method; |  | ||||||
| import io.minio.messages.Part; |  | ||||||
| import jakarta.annotation.PostConstruct; |  | ||||||
| import lombok.extern.slf4j.Slf4j; |  | ||||||
| import org.springframework.beans.factory.annotation.Value; |  | ||||||
| import org.springframework.stereotype.Component; |  | ||||||
| import org.springframework.util.StringUtils; |  | ||||||
| import org.springframework.web.multipart.MultipartFile; |  | ||||||
| 
 |  | ||||||
| import java.io.IOException; |  | ||||||
| import java.io.InputStream; |  | ||||||
| import java.util.*; |  | ||||||
| import java.util.concurrent.TimeUnit; |  | ||||||
| import java.util.stream.Collectors; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @Slf4j |  | ||||||
| @Component |  | ||||||
| public class MinioUtils { |  | ||||||
| 
 |  | ||||||
|     @Value(value = "${minio.endpoint}") |  | ||||||
|     private String endpoint; |  | ||||||
|     @Value(value = "${minio.accesskey}") |  | ||||||
|     private String accesskey; |  | ||||||
|     @Value(value = "${minio.secretkey}") |  | ||||||
|     private String secretkey; |  | ||||||
| 
 |  | ||||||
|     @Value(value = "${minio.expiry}") |  | ||||||
|     private Integer expiry; |  | ||||||
| 
 |  | ||||||
|     private CustomMinioClient customMinioClient; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 用spring的自动注入会注入失败 |  | ||||||
|      */ |  | ||||||
|     @PostConstruct |  | ||||||
|     public void init() { |  | ||||||
|         MinioClient minioClient = MinioClient.builder() |  | ||||||
|                 .endpoint(endpoint) |  | ||||||
|                 .credentials(accesskey, secretkey) |  | ||||||
|                 .build(); |  | ||||||
|         customMinioClient = new CustomMinioClient(minioClient); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 单文件签名上传 |  | ||||||
|      * |  | ||||||
|      * @param objectName 文件全路径名称 |  | ||||||
|      * @param bucketName 桶名称 |  | ||||||
|      * @return / |  | ||||||
|      */ |  | ||||||
|     public Map<String, Object> getUploadObjectUrl(String objectName, String bucketName) { |  | ||||||
|         try { |  | ||||||
|             log.info("tip message: 通过 <{}-{}> 开始单文件上传<minio>", objectName, bucketName); |  | ||||||
|             Map<String, Object> resMap = new HashMap(); |  | ||||||
|             List<String> partList = new ArrayList<>(); |  | ||||||
|             String url = customMinioClient.getPresignedObjectUrl( |  | ||||||
|                     GetPresignedObjectUrlArgs.builder() |  | ||||||
|                             .method(Method.PUT) |  | ||||||
|                             .bucket(bucketName) |  | ||||||
|                             .object(objectName) |  | ||||||
|                             .expiry(expiry, TimeUnit.DAYS) |  | ||||||
|                             .build()); |  | ||||||
|             log.info("预签名完成:"+url); |  | ||||||
|             log.info("tip message: 单个文件上传、成功"); |  | ||||||
|             partList.add(url); |  | ||||||
|             resMap.put("uploadId", "SingleFileUpload"); |  | ||||||
|             resMap.put("urlList", partList); |  | ||||||
|             return resMap; |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             log.error("error message: 单个文件上传失败、原因:", e); |  | ||||||
|             // 返回 文件上传失败 |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 初始化分片上传 |  | ||||||
|      * |  | ||||||
|      * @param fileUploadInfo |  | ||||||
|      * @param objectName     文件全路径名称 |  | ||||||
|      * @param chunkNum       分片数量 |  | ||||||
|      * @param contentType    类型,如果类型使用默认流会导致无法预览 |  | ||||||
|      * @param bucketName     桶名称 |  | ||||||
|      * @return Mono<Map < String, Object>> |  | ||||||
|      */ |  | ||||||
|     public Map<String, Object> initMultiPartUpload(FileUploadInfo fileUploadInfo, String objectName, int chunkNum, String contentType, String bucketName) { |  | ||||||
|         log.info("tip message: 通过 <{}-{}-{}-{}> 开始初始化<分片上传>数据", objectName, chunkNum, contentType, bucketName); |  | ||||||
|         Map<String, Object> resMap = new HashMap<>(); |  | ||||||
|         try { |  | ||||||
|             if (CharSequenceUtil.isBlank(contentType)) { |  | ||||||
|                 contentType = "application/octet-stream"; |  | ||||||
|             } |  | ||||||
|             HashMultimap<String, String> headers = HashMultimap.create(); |  | ||||||
| 
 |  | ||||||
|             headers.put("Content-Type", contentType); |  | ||||||
| 
 |  | ||||||
|             //获取uploadId |  | ||||||
|             String uploadId = null; |  | ||||||
|             if (StringUtils.isEmpty(fileUploadInfo.getUploadId())) { |  | ||||||
|                 uploadId = customMinioClient.initMultiPartUpload(bucketName, null, objectName, headers, null); |  | ||||||
|             } else { |  | ||||||
|                 uploadId = fileUploadInfo.getUploadId(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             resMap.put("uploadId", uploadId); |  | ||||||
| 
 |  | ||||||
|             fileUploadInfo.setUploadId(uploadId); |  | ||||||
|             fileUploadInfo.setChunkNum(chunkNum); |  | ||||||
| 
 |  | ||||||
|             List<String> partList = new ArrayList<>(); |  | ||||||
| 
 |  | ||||||
|             Map<String, String> reqParams = new HashMap<>(); |  | ||||||
|             reqParams.put("uploadId", uploadId); |  | ||||||
|             for (int i = 1; i <= chunkNum; i++) { |  | ||||||
|                 reqParams.put("partNumber", String.valueOf(i)); |  | ||||||
|                 String uploadUrl = customMinioClient.getPresignedObjectUrl( |  | ||||||
|                         GetPresignedObjectUrlArgs.builder() |  | ||||||
|                                 .method(Method.PUT) |  | ||||||
|                                 .bucket(bucketName) |  | ||||||
|                                 .object(objectName) |  | ||||||
|                                 .expiry(1, TimeUnit.DAYS) |  | ||||||
|                                 .extraQueryParams(reqParams) |  | ||||||
|                                 .build()); |  | ||||||
|                 partList.add(uploadUrl); |  | ||||||
|             } |  | ||||||
|             log.info("tip message: 文件初始化<分片上传>、成功"); |  | ||||||
|             resMap.put("urlList", partList); |  | ||||||
|             return resMap; |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             log.error("error message: 初始化分片上传失败、原因:", e); |  | ||||||
|             // 返回 文件上传失败 |  | ||||||
|             return R.error(RespEnum.UPLOAD_FILE_FAILED); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 分片上传完后合并 |  | ||||||
|      * |  | ||||||
|      * @param objectName 文件全路径名称 |  | ||||||
|      * @param uploadId   返回的uploadId |  | ||||||
|      * @param bucketName 桶名称 |  | ||||||
|      * @return boolean |  | ||||||
|      */ |  | ||||||
|     public boolean mergeMultipartUpload(String objectName, String uploadId, String bucketName) { |  | ||||||
|         try { |  | ||||||
|             log.info("tip message: 通过 <{}-{}-{}> 合并<分片上传>数据", objectName, uploadId, bucketName); |  | ||||||
|             //目前仅做了最大1000分片 |  | ||||||
|             Part[] parts = new Part[1000]; |  | ||||||
|             // 查询上传后的分片数据 |  | ||||||
|             ListPartsResponse partResult = customMinioClient.listMultipart(bucketName, null, objectName, 1000, 0, uploadId, null, null); |  | ||||||
|             int partNumber = 1; |  | ||||||
|             for (Part part : partResult.result().partList()) { |  | ||||||
|                 parts[partNumber - 1] = new Part(partNumber, part.etag()); |  | ||||||
|                 partNumber++; |  | ||||||
|             } |  | ||||||
|             // 合并分片 |  | ||||||
|             customMinioClient.mergeMultipartUpload(bucketName, null, objectName, uploadId, parts, null, null); |  | ||||||
| 
 |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             log.error("error message: 合并失败、原因:", e); |  | ||||||
|             //TODO删除redis的数据 |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 通过 sha256 获取上传中的分片信息 |  | ||||||
|      * |  | ||||||
|      * @param objectName 文件全路径名称 |  | ||||||
|      * @param uploadId   返回的uploadId |  | ||||||
|      * @param bucketName 桶名称 |  | ||||||
|      * @return Mono<Map < String, Object>> |  | ||||||
|      */ |  | ||||||
|     public List<Integer> getChunkByFileMD5(String objectName, String uploadId, String bucketName) { |  | ||||||
|         log.info("通过 <{}-{}-{}> 查询<minio>上传分片数据", objectName, uploadId, bucketName); |  | ||||||
|         try { |  | ||||||
|             // 查询上传后的分片数据 |  | ||||||
|             ListPartsResponse partResult = customMinioClient.listMultipart(bucketName, null, objectName, 1000, 0, uploadId, null, null); |  | ||||||
|             return partResult.result().partList().stream().map(Part::partNumber).collect(Collectors.toList()); |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             log.error("error message: 查询上传后的分片信息失败、原因:", e); |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 获取文件下载地址 |  | ||||||
|      * |  | ||||||
|      * @param bucketName 桶名称 |  | ||||||
|      * @param fileName   文件名 |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public String getFliePath(String bucketName, String fileName) { |  | ||||||
|         return StrUtil.format("{}/{}/{}", endpoint, bucketName, fileName);//文件访问路径 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 创建一个桶 |  | ||||||
|      * |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public String createBucket(String bucketName) { |  | ||||||
|         try { |  | ||||||
|             BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(bucketName).build(); |  | ||||||
|             //如果桶存在 |  | ||||||
|             if (customMinioClient.bucketExists(bucketExistsArgs)) { |  | ||||||
|                 return bucketName; |  | ||||||
|             } |  | ||||||
|             MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build(); |  | ||||||
|             customMinioClient.makeBucket(makeBucketArgs); |  | ||||||
|             return bucketName; |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             log.error("创建桶失败:{}", e.getMessage()); |  | ||||||
|             throw new RuntimeException(e); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 根据文件类型获取minio桶名称 |  | ||||||
|      * |  | ||||||
|      * @param fileType |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public String getBucketName(String fileType) { |  | ||||||
|         try { |  | ||||||
|             //String bucketName = getProperty(fileType.toLowerCase()); |  | ||||||
| 
 |  | ||||||
|             if (fileType != null && !fileType.equals("")) { |  | ||||||
|                 //判断桶是否存在 |  | ||||||
|                 String bucketName2 = createBucket(fileType.toLowerCase()); |  | ||||||
|                 if (bucketName2 != null && !bucketName2.equals("")) { |  | ||||||
|                     return bucketName2; |  | ||||||
|                 } else { |  | ||||||
|                     return fileType; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|         } catch (Exception e) { |  | ||||||
| 
 |  | ||||||
|             log.error("Error reading bucket name "); |  | ||||||
|         } |  | ||||||
|         return fileType; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 读取配置文件 |  | ||||||
|      * |  | ||||||
|      * @param fileType |  | ||||||
|      * @return |  | ||||||
|      * @throws IOException |  | ||||||
|      */ |  | ||||||
|     private String getProperty(String fileType) throws IOException { |  | ||||||
|         Properties SysLocalPropObject = new Properties(); |  | ||||||
|         //判断桶关系配置文件是否为空 |  | ||||||
|         if (SysLocalPropObject.isEmpty()) { |  | ||||||
|             InputStream is = getClass().getResourceAsStream("/BucketRelation.properties"); |  | ||||||
|             SysLocalPropObject.load(is); |  | ||||||
|             is.close(); |  | ||||||
|         } |  | ||||||
|         return SysLocalPropObject.getProperty("bucket." + fileType); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 文件上传 |  | ||||||
|      * |  | ||||||
|      * @param file 文件 |  | ||||||
|      * @return Boolean |  | ||||||
|      */ |  | ||||||
|     public String upload(MultipartFile file, String bucketName) { |  | ||||||
|         String originalFilename = file.getOriginalFilename(); |  | ||||||
|         if (StringUtils.isEmpty(originalFilename)) { |  | ||||||
|             throw new RuntimeException(); |  | ||||||
|         } |  | ||||||
|         String objectName = file.getName(); |  | ||||||
|         try { |  | ||||||
|             PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(objectName) |  | ||||||
|                     .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build(); |  | ||||||
|             //文件名称相同会覆盖 |  | ||||||
|             customMinioClient.putObject(objectArgs); |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             e.printStackTrace(); |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|         // 查看文件地址 |  | ||||||
|         GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs().builder().bucket(bucketName).object(objectName).method(Method.GET).build(); |  | ||||||
|         String url = null; |  | ||||||
|         try { |  | ||||||
|             url = customMinioClient.getPresignedObjectUrl(build); |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             e.printStackTrace(); |  | ||||||
|         } |  | ||||||
|         return url; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -9,6 +9,8 @@ import com.amazonaws.services.s3.AmazonS3; | |||||||
| import com.amazonaws.services.s3.AmazonS3ClientBuilder; | import com.amazonaws.services.s3.AmazonS3ClientBuilder; | ||||||
| import com.amazonaws.services.s3.model.*; | import com.amazonaws.services.s3.model.*; | ||||||
| import com.mmg.config.S3Config; | import com.mmg.config.S3Config; | ||||||
|  | import com.mmg.service.AppConfigService; | ||||||
|  | import jakarta.annotation.PostConstruct; | ||||||
| import lombok.SneakyThrows; | import lombok.SneakyThrows; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||||
| @ -26,11 +28,15 @@ import java.util.List; | |||||||
| @Component | @Component | ||||||
| public class S3Util { | public class S3Util { | ||||||
| 
 | 
 | ||||||
|     @Autowired |  | ||||||
|     private S3Config defaultConfig; |     private S3Config defaultConfig; | ||||||
| 
 | 
 | ||||||
|     public S3Config getS3Config() { |     @Autowired | ||||||
|         return defaultConfig; |     private AppConfigService appConfigService; | ||||||
|  | 
 | ||||||
|  |     @PostConstruct | ||||||
|  |     public void init() { | ||||||
|  |         this.defaultConfig = appConfigService.getS3Config(); | ||||||
|  |         log.info("S3Config initialized: {}", defaultConfig); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public S3Util(S3Config s3Config) { |     public S3Util(S3Config s3Config) { | ||||||
| @ -51,7 +57,7 @@ public class S3Util { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @SneakyThrows |     @SneakyThrows | ||||||
|     private AmazonS3 getClient() { |     public AmazonS3 getClient() { | ||||||
|         if (defaultConfig == null) { |         if (defaultConfig == null) { | ||||||
|             throw new Exception("存储服务未配置"); |             throw new Exception("存储服务未配置"); | ||||||
|         } |         } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user