feat: 完成Nacos配置优化和WebSocket集成
主要更新: 1. 统一所有微服务端口配置(19000-19008) 2. 为所有服务创建本地/测试/生产三套环境配置 3. 配置Nacos认证密码(本地:Peanut2817*#, 测试/生产:EmotionMuseum2025) 4. 优化网关路由配置,支持负载均衡和WebSocket 5. 新增emotion-websocket模块,支持实时聊天 6. 前端集成WebSocket,替代HTTP轮询 7. 添加配置验证和管理工具脚本 技术特性: - 完整的环境隔离和服务发现 - WebSocket实时通信支持 - 负载均衡路由配置 - 跨域和安全配置 - 自动重连和心跳检测
This commit is contained in:
@@ -0,0 +1,305 @@
|
||||
2025-07-16T08:59:01.762+08:00 WARN 36358 --- [Thread-1] c.a.n.common.http.HttpClientBeanHolder : [HttpClientBeanHolder] Start destroying common HttpClient
|
||||
2025-07-16T08:59:01.762+08:00 WARN 36358 --- [Thread-7] c.a.nacos.common.notify.NotifyCenter : [NotifyCenter] Start destroying Publisher
|
||||
2025-07-16T08:59:01.864+08:00 WARN 36358 --- [Thread-7] c.a.nacos.common.notify.NotifyCenter : [NotifyCenter] Destruction of the end
|
||||
2025-07-16T08:59:01.871+08:00 WARN 36358 --- [Thread-1] c.a.n.common.http.HttpClientBeanHolder : [HttpClientBeanHolder] Destruction of the end
|
||||
2025-07-16T08:59:02.053+08:00 INFO 36358 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
|
||||
2025-07-16T08:59:02.060+08:00 INFO 36358 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
|
||||
2025-07-16T08:59:19.149+08:00 WARN 15828 --- [main] c.a.nacos.client.logging.NacosLogging : Load Logback Configuration of Nacos fail, message: Could not initialize Logback Nacos logging from classpath:nacos-logback.xml
|
||||
2025-07-16T08:59:19.178+08:00 INFO 15828 --- [main] c.a.n.c.c.impl.LocalConfigInfoProcessor : LOCAL_SNAPSHOT_PATH:/Users/huazhongmin/nacos/config
|
||||
2025-07-16T08:59:19.182+08:00 INFO 15828 --- [main] com.alibaba.nacos.common.remote.client : [RpcClientFactory] create a new rpc client of f264096d-5a79-4318-9f7b-d1a3577abfef_config-0
|
||||
2025-07-16T08:59:19.203+08:00 INFO 15828 --- [main] com.alibaba.nacos.common.remote.client : [f264096d-5a79-4318-9f7b-d1a3577abfef_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda/0x000000012f2dc260
|
||||
2025-07-16T08:59:19.204+08:00 INFO 15828 --- [main] com.alibaba.nacos.common.remote.client : [f264096d-5a79-4318-9f7b-d1a3577abfef_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda/0x000000012f2dc670
|
||||
2025-07-16T08:59:19.204+08:00 INFO 15828 --- [main] com.alibaba.nacos.common.remote.client : [f264096d-5a79-4318-9f7b-d1a3577abfef_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1
|
||||
2025-07-16T08:59:19.204+08:00 INFO 15828 --- [main] com.alibaba.nacos.common.remote.client : [f264096d-5a79-4318-9f7b-d1a3577abfef_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2
|
||||
2025-07-16T08:59:19.218+08:00 INFO 15828 --- [main] com.alibaba.nacos.common.remote.client : [f264096d-5a79-4318-9f7b-d1a3577abfef_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848}
|
||||
2025-07-16T08:59:19.263+08:00 INFO 15828 --- [main] c.a.n.c.remote.client.grpc.GrpcClient : grpc client connection server:127.0.0.1 ip,serverPort:9848,grpcTslConfig:{"sslProvider":"OPENSSL","enableTls":false,"mutualAuthEnable":false,"trustAll":false}
|
||||
2025-07-16T08:59:19.932+08:00 INFO 15828 --- [main] com.alibaba.nacos.common.remote.client : [f264096d-5a79-4318-9f7b-d1a3577abfef_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1752627559740_127.0.0.1_61370
|
||||
2025-07-16T08:59:19.933+08:00 INFO 15828 --- [com.alibaba.nacos.client.remote.worker] com.alibaba.nacos.common.remote.client : [f264096d-5a79-4318-9f7b-d1a3577abfef_config-0] Notify connected event to listeners.
|
||||
2025-07-16T08:59:19.933+08:00 INFO 15828 --- [com.alibaba.nacos.client.remote.worker] c.a.n.client.config.impl.ClientWorker : [f264096d-5a79-4318-9f7b-d1a3577abfef_config-0] Connected,notify listen context...
|
||||
2025-07-16T08:59:19.933+08:00 INFO 15828 --- [main] com.alibaba.nacos.common.remote.client : [f264096d-5a79-4318-9f7b-d1a3577abfef_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler
|
||||
2025-07-16T08:59:19.934+08:00 INFO 15828 --- [main] com.alibaba.nacos.common.remote.client : [f264096d-5a79-4318-9f7b-d1a3577abfef_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda/0x000000012f43f118
|
||||
2025-07-16T08:59:19.978+08:00 INFO 15828 --- [main] c.a.nacos.client.config.impl.Limiter : limitTime:5.0
|
||||
2025-07-16T08:59:20.036+08:00 WARN 15828 --- [main] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[emotion-user] & group[DEFAULT_GROUP]
|
||||
2025-07-16T08:59:20.042+08:00 WARN 15828 --- [main] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[emotion-user.properties] & group[DEFAULT_GROUP]
|
||||
2025-07-16T08:59:20.051+08:00 WARN 15828 --- [main] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[emotion-user-local.properties] & group[DEFAULT_GROUP]
|
||||
2025-07-16T08:59:20.052+08:00 INFO 15828 --- [main] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-emotion-user-local.properties,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-emotion-user.properties,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-emotion-user,DEFAULT_GROUP'}]
|
||||
2025-07-16T08:59:20.079+08:00 WARN 15828 --- [main] c.a.nacos.client.logging.NacosLogging : Load Logback Configuration of Nacos fail, message: Could not initialize Logback Nacos logging from classpath:nacos-logback.xml
|
||||
2025-07-16T08:59:20.080+08:00 INFO 15828 --- [main] com.emotionmuseum.user.UserApplication : The following 1 profile is active: "local"
|
||||
2025-07-16T08:59:21.224+08:00 INFO 15828 --- [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
|
||||
2025-07-16T08:59:21.229+08:00 INFO 15828 --- [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
|
||||
2025-07-16T08:59:21.266+08:00 INFO 15828 --- [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 Redis repository interfaces.
|
||||
2025-07-16T08:59:21.689+08:00 INFO 15828 --- [main] o.s.cloud.context.scope.GenericScope : BeanFactory id=2c694ed0-114c-30e6-aed7-dcee6bca36f0
|
||||
2025-07-16T08:59:22.421+08:00 INFO 15828 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 19001 (http)
|
||||
2025-07-16T08:59:22.451+08:00 INFO 15828 --- [main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
|
||||
2025-07-16T08:59:22.452+08:00 INFO 15828 --- [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.5]
|
||||
2025-07-16T08:59:22.557+08:00 INFO 15828 --- [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
|
||||
2025-07-16T08:59:22.558+08:00 INFO 15828 --- [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2449 ms
|
||||
2025-07-16T08:59:23.525+08:00 INFO 15828 --- [main] c.e.common.config.SnowflakeConfig : 使用MAC地址生成的机器ID: 669
|
||||
2025-07-16T08:59:23.527+08:00 INFO 15828 --- [main] c.e.common.config.SnowflakeConfig : 雪花算法配置完成,使用机器ID: 669
|
||||
2025-07-16T08:59:23.527+08:00 INFO 15828 --- [main] c.e.common.util.SnowflakeIdGenerator : 雪花算法ID生成器初始化完成,机器ID: 669
|
||||
2025-07-16T08:59:24.050+08:00 DEBUG 15828 --- [main] c.e.u.security.JwtAuthenticationFilter : Filter 'jwtAuthenticationFilter' configured for use
|
||||
2025-07-16T08:59:24.054+08:00 DEBUG 15828 --- [main] o.s.w.f.ServerHttpObservationFilter : Filter 'serverHttpObservationFilter' configured for use
|
||||
2025-07-16T08:59:24.740+08:00 DEBUG 15828 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : 19 mappings in 'requestMappingHandlerMapping'
|
||||
2025-07-16T08:59:24.773+08:00 DEBUG 15828 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Patterns [/webjars/**, /**] in 'resourceHandlerMapping'
|
||||
2025-07-16T08:59:25.010+08:00 INFO 15828 --- [main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 3 endpoint(s) beneath base path '/actuator'
|
||||
2025-07-16T08:59:25.104+08:00 INFO 15828 --- [main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@6993c8df, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@57545c3f, org.springframework.security.web.context.SecurityContextHolderFilter@64920dc2, org.springframework.security.web.header.HeaderWriterFilter@794366a5, org.springframework.web.filter.CorsFilter@326e0b8e, org.springframework.security.web.authentication.logout.LogoutFilter@30839e44, com.emotionmuseum.user.security.JwtAuthenticationFilter@434514d8, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@493ac8d3, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@13dbed9e, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@36baa049, org.springframework.security.web.session.SessionManagementFilter@1ee47d9e, org.springframework.security.web.access.ExceptionTranslationFilter@3f36e8d1, org.springframework.security.web.access.intercept.AuthorizationFilter@7978e022]
|
||||
2025-07-16T08:59:25.230+08:00 DEBUG 15828 --- [main] s.w.s.m.m.a.RequestMappingHandlerAdapter : ControllerAdvice beans: 0 @ModelAttribute, 0 @InitBinder, 1 RequestBodyAdvice, 1 ResponseBodyAdvice
|
||||
2025-07-16T08:59:25.275+08:00 DEBUG 15828 --- [main] .m.m.a.ExceptionHandlerExceptionResolver : ControllerAdvice beans: 0 @ExceptionHandler, 1 ResponseBodyAdvice
|
||||
2025-07-16T08:59:25.597+08:00 INFO 15828 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 19001 (http) with context path ''
|
||||
2025-07-16T08:59:25.626+08:00 INFO 15828 --- [main] com.emotionmuseum.user.UserApplication : Started UserApplication in 7.738 seconds (process running for 8.451)
|
||||
2025-07-16T08:59:57.321+08:00 INFO 15828 --- [http-nio-19001-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
|
||||
2025-07-16T08:59:57.322+08:00 INFO 15828 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
|
||||
2025-07-16T08:59:57.322+08:00 DEBUG 15828 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
|
||||
2025-07-16T08:59:57.322+08:00 DEBUG 15828 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected AcceptHeaderLocaleResolver
|
||||
2025-07-16T08:59:57.322+08:00 DEBUG 15828 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected FixedThemeResolver
|
||||
2025-07-16T08:59:57.323+08:00 DEBUG 15828 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator@35e7e45f
|
||||
2025-07-16T08:59:57.323+08:00 DEBUG 15828 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.support.SessionFlashMapManager@5dfd939f
|
||||
2025-07-16T08:59:57.323+08:00 DEBUG 15828 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
|
||||
2025-07-16T08:59:57.324+08:00 INFO 15828 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
|
||||
2025-07-16T08:59:57.373+08:00 DEBUG 15828 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : GET "/actuator/health", parameters={}
|
||||
2025-07-16T08:59:57.404+08:00 INFO 15828 --- [http-nio-19001-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
|
||||
2025-07-16T08:59:57.629+08:00 INFO 15828 --- [http-nio-19001-exec-1] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@4cf3c80b
|
||||
2025-07-16T08:59:57.633+08:00 INFO 15828 --- [http-nio-19001-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
|
||||
2025-07-16T08:59:58.042+08:00 DEBUG 15828 --- [http-nio-19001-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/vnd.spring-boot.actuator.v3+json', given [*/*] and supported [application/vnd.spring-boot.actuator.v3+json, application/vnd.spring-boot.actuator.v2+json, application/json]
|
||||
2025-07-16T08:59:58.052+08:00 DEBUG 15828 --- [http-nio-19001-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [org.springframework.boot.actuate.health.SystemHealth@1ec7b554]
|
||||
2025-07-16T08:59:58.069+08:00 DEBUG 15828 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK
|
||||
2025-07-16T09:01:08.310+08:00 DEBUG 15828 --- [http-nio-19001-exec-3] o.s.web.servlet.DispatcherServlet : GET "/actuator/health", parameters={}
|
||||
2025-07-16T09:01:08.316+08:00 DEBUG 15828 --- [http-nio-19001-exec-3] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/vnd.spring-boot.actuator.v3+json', given [*/*] and supported [application/vnd.spring-boot.actuator.v3+json, application/vnd.spring-boot.actuator.v2+json, application/json]
|
||||
2025-07-16T09:01:08.316+08:00 DEBUG 15828 --- [http-nio-19001-exec-3] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [org.springframework.boot.actuate.health.SystemHealth@6fbe5cda]
|
||||
2025-07-16T09:01:08.317+08:00 DEBUG 15828 --- [http-nio-19001-exec-3] o.s.web.servlet.DispatcherServlet : Completed 200 OK
|
||||
2025-07-16T09:03:03.679+08:00 WARN 15828 --- [Thread-7] c.a.nacos.common.notify.NotifyCenter : [NotifyCenter] Start destroying Publisher
|
||||
2025-07-16T09:03:03.679+08:00 WARN 15828 --- [Thread-1] c.a.n.common.http.HttpClientBeanHolder : [HttpClientBeanHolder] Start destroying common HttpClient
|
||||
2025-07-16T09:03:03.680+08:00 WARN 15828 --- [Thread-7] c.a.nacos.common.notify.NotifyCenter : [NotifyCenter] Destruction of the end
|
||||
2025-07-16T09:03:03.680+08:00 WARN 15828 --- [Thread-1] c.a.n.common.http.HttpClientBeanHolder : [HttpClientBeanHolder] Destruction of the end
|
||||
2025-07-16T09:03:03.697+08:00 INFO 15828 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
|
||||
2025-07-16T09:03:03.705+08:00 INFO 15828 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
|
||||
2025-07-16T09:03:19.624+08:00 WARN 19784 --- [main] c.a.nacos.client.logging.NacosLogging : Load Logback Configuration of Nacos fail, message: Could not initialize Logback Nacos logging from classpath:nacos-logback.xml
|
||||
2025-07-16T09:03:19.652+08:00 INFO 19784 --- [main] c.a.n.c.c.impl.LocalConfigInfoProcessor : LOCAL_SNAPSHOT_PATH:/Users/huazhongmin/nacos/config
|
||||
2025-07-16T09:03:19.656+08:00 INFO 19784 --- [main] com.alibaba.nacos.common.remote.client : [RpcClientFactory] create a new rpc client of 745c3cf4-7cb2-4ac6-a11a-86fd37de7293_config-0
|
||||
2025-07-16T09:03:19.675+08:00 INFO 19784 --- [main] com.alibaba.nacos.common.remote.client : [745c3cf4-7cb2-4ac6-a11a-86fd37de7293_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda/0x000000013d2dc530
|
||||
2025-07-16T09:03:19.676+08:00 INFO 19784 --- [main] com.alibaba.nacos.common.remote.client : [745c3cf4-7cb2-4ac6-a11a-86fd37de7293_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda/0x000000013d2dc940
|
||||
2025-07-16T09:03:19.676+08:00 INFO 19784 --- [main] com.alibaba.nacos.common.remote.client : [745c3cf4-7cb2-4ac6-a11a-86fd37de7293_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1
|
||||
2025-07-16T09:03:19.677+08:00 INFO 19784 --- [main] com.alibaba.nacos.common.remote.client : [745c3cf4-7cb2-4ac6-a11a-86fd37de7293_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2
|
||||
2025-07-16T09:03:19.689+08:00 INFO 19784 --- [main] com.alibaba.nacos.common.remote.client : [745c3cf4-7cb2-4ac6-a11a-86fd37de7293_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848}
|
||||
2025-07-16T09:03:19.748+08:00 INFO 19784 --- [main] c.a.n.c.remote.client.grpc.GrpcClient : grpc client connection server:127.0.0.1 ip,serverPort:9848,grpcTslConfig:{"sslProvider":"OPENSSL","enableTls":false,"mutualAuthEnable":false,"trustAll":false}
|
||||
2025-07-16T09:03:20.358+08:00 INFO 19784 --- [main] com.alibaba.nacos.common.remote.client : [745c3cf4-7cb2-4ac6-a11a-86fd37de7293_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1752627800162_127.0.0.1_62095
|
||||
2025-07-16T09:03:20.358+08:00 INFO 19784 --- [com.alibaba.nacos.client.remote.worker] com.alibaba.nacos.common.remote.client : [745c3cf4-7cb2-4ac6-a11a-86fd37de7293_config-0] Notify connected event to listeners.
|
||||
2025-07-16T09:03:20.359+08:00 INFO 19784 --- [com.alibaba.nacos.client.remote.worker] c.a.n.client.config.impl.ClientWorker : [745c3cf4-7cb2-4ac6-a11a-86fd37de7293_config-0] Connected,notify listen context...
|
||||
2025-07-16T09:03:20.359+08:00 INFO 19784 --- [main] com.alibaba.nacos.common.remote.client : [745c3cf4-7cb2-4ac6-a11a-86fd37de7293_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler
|
||||
2025-07-16T09:03:20.359+08:00 INFO 19784 --- [main] com.alibaba.nacos.common.remote.client : [745c3cf4-7cb2-4ac6-a11a-86fd37de7293_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda/0x000000013d43f118
|
||||
2025-07-16T09:03:20.394+08:00 INFO 19784 --- [main] c.a.nacos.client.config.impl.Limiter : limitTime:5.0
|
||||
2025-07-16T09:03:20.411+08:00 WARN 19784 --- [main] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[emotion-user] & group[DEFAULT_GROUP]
|
||||
2025-07-16T09:03:20.417+08:00 WARN 19784 --- [main] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[emotion-user.properties] & group[DEFAULT_GROUP]
|
||||
2025-07-16T09:03:20.422+08:00 WARN 19784 --- [main] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[emotion-user-local.properties] & group[DEFAULT_GROUP]
|
||||
2025-07-16T09:03:20.423+08:00 INFO 19784 --- [main] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-emotion-user-local.properties,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-emotion-user.properties,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-emotion-user,DEFAULT_GROUP'}]
|
||||
2025-07-16T09:03:20.445+08:00 WARN 19784 --- [main] c.a.nacos.client.logging.NacosLogging : Load Logback Configuration of Nacos fail, message: Could not initialize Logback Nacos logging from classpath:nacos-logback.xml
|
||||
2025-07-16T09:03:20.446+08:00 INFO 19784 --- [main] com.emotionmuseum.user.UserApplication : The following 1 profile is active: "local"
|
||||
2025-07-16T09:03:21.462+08:00 INFO 19784 --- [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
|
||||
2025-07-16T09:03:21.466+08:00 INFO 19784 --- [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
|
||||
2025-07-16T09:03:21.498+08:00 INFO 19784 --- [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces.
|
||||
2025-07-16T09:03:21.895+08:00 INFO 19784 --- [main] o.s.cloud.context.scope.GenericScope : BeanFactory id=2c694ed0-114c-30e6-aed7-dcee6bca36f0
|
||||
2025-07-16T09:03:22.569+08:00 INFO 19784 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 19001 (http)
|
||||
2025-07-16T09:03:22.584+08:00 INFO 19784 --- [main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
|
||||
2025-07-16T09:03:22.585+08:00 INFO 19784 --- [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.5]
|
||||
2025-07-16T09:03:22.681+08:00 INFO 19784 --- [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
|
||||
2025-07-16T09:03:22.682+08:00 INFO 19784 --- [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2214 ms
|
||||
2025-07-16T09:03:23.440+08:00 INFO 19784 --- [main] c.e.common.config.SnowflakeConfig : 使用MAC地址生成的机器ID: 669
|
||||
2025-07-16T09:03:23.440+08:00 INFO 19784 --- [main] c.e.common.config.SnowflakeConfig : 雪花算法配置完成,使用机器ID: 669
|
||||
2025-07-16T09:03:23.440+08:00 INFO 19784 --- [main] c.e.common.util.SnowflakeIdGenerator : 雪花算法ID生成器初始化完成,机器ID: 669
|
||||
2025-07-16T09:03:24.033+08:00 DEBUG 19784 --- [main] c.e.u.security.JwtAuthenticationFilter : Filter 'jwtAuthenticationFilter' configured for use
|
||||
2025-07-16T09:03:24.037+08:00 DEBUG 19784 --- [main] o.s.w.f.ServerHttpObservationFilter : Filter 'serverHttpObservationFilter' configured for use
|
||||
2025-07-16T09:03:24.837+08:00 DEBUG 19784 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : 19 mappings in 'requestMappingHandlerMapping'
|
||||
2025-07-16T09:03:24.878+08:00 DEBUG 19784 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Patterns [/webjars/**, /**] in 'resourceHandlerMapping'
|
||||
2025-07-16T09:03:25.069+08:00 INFO 19784 --- [main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 3 endpoint(s) beneath base path '/actuator'
|
||||
2025-07-16T09:03:25.128+08:00 INFO 19784 --- [main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@6993c8df, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@57545c3f, org.springframework.security.web.context.SecurityContextHolderFilter@64920dc2, org.springframework.security.web.header.HeaderWriterFilter@794366a5, org.springframework.web.filter.CorsFilter@326e0b8e, org.springframework.security.web.authentication.logout.LogoutFilter@30839e44, com.emotionmuseum.user.security.JwtAuthenticationFilter@434514d8, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@493ac8d3, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@13dbed9e, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@36baa049, org.springframework.security.web.session.SessionManagementFilter@1ee47d9e, org.springframework.security.web.access.ExceptionTranslationFilter@3f36e8d1, org.springframework.security.web.access.intercept.AuthorizationFilter@7978e022]
|
||||
2025-07-16T09:03:25.229+08:00 DEBUG 19784 --- [main] s.w.s.m.m.a.RequestMappingHandlerAdapter : ControllerAdvice beans: 0 @ModelAttribute, 0 @InitBinder, 1 RequestBodyAdvice, 1 ResponseBodyAdvice
|
||||
2025-07-16T09:03:25.268+08:00 DEBUG 19784 --- [main] .m.m.a.ExceptionHandlerExceptionResolver : ControllerAdvice beans: 0 @ExceptionHandler, 1 ResponseBodyAdvice
|
||||
2025-07-16T09:03:25.658+08:00 INFO 19784 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 19001 (http) with context path ''
|
||||
2025-07-16T09:03:25.689+08:00 INFO 19784 --- [main] com.emotionmuseum.user.UserApplication : Started UserApplication in 7.27 seconds (process running for 7.838)
|
||||
2025-07-16T09:03:57.442+08:00 INFO 19784 --- [http-nio-19001-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
|
||||
2025-07-16T09:03:57.443+08:00 INFO 19784 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
|
||||
2025-07-16T09:03:57.443+08:00 DEBUG 19784 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
|
||||
2025-07-16T09:03:57.443+08:00 DEBUG 19784 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected AcceptHeaderLocaleResolver
|
||||
2025-07-16T09:03:57.443+08:00 DEBUG 19784 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected FixedThemeResolver
|
||||
2025-07-16T09:03:57.444+08:00 DEBUG 19784 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator@5e240cb6
|
||||
2025-07-16T09:03:57.444+08:00 DEBUG 19784 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.support.SessionFlashMapManager@2e21a5d9
|
||||
2025-07-16T09:03:57.445+08:00 DEBUG 19784 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
|
||||
2025-07-16T09:03:57.445+08:00 INFO 19784 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
|
||||
2025-07-16T09:03:57.509+08:00 DEBUG 19784 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : GET "/actuator/health", parameters={}
|
||||
2025-07-16T09:03:57.546+08:00 INFO 19784 --- [http-nio-19001-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
|
||||
2025-07-16T09:03:57.793+08:00 INFO 19784 --- [http-nio-19001-exec-1] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@1703fbc9
|
||||
2025-07-16T09:03:57.797+08:00 INFO 19784 --- [http-nio-19001-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
|
||||
2025-07-16T09:03:58.405+08:00 DEBUG 19784 --- [http-nio-19001-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/vnd.spring-boot.actuator.v3+json', given [*/*] and supported [application/vnd.spring-boot.actuator.v3+json, application/vnd.spring-boot.actuator.v2+json, application/json]
|
||||
2025-07-16T09:03:58.416+08:00 DEBUG 19784 --- [http-nio-19001-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [org.springframework.boot.actuate.health.SystemHealth@178369bf]
|
||||
2025-07-16T09:03:58.433+08:00 DEBUG 19784 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK
|
||||
2025-07-16T09:04:12.530+08:00 DEBUG 19784 --- [http-nio-19001-exec-3] o.s.web.servlet.DispatcherServlet : GET "/actuator/health", parameters={}
|
||||
2025-07-16T09:04:12.544+08:00 DEBUG 19784 --- [http-nio-19001-exec-3] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/vnd.spring-boot.actuator.v3+json', given [*/*] and supported [application/vnd.spring-boot.actuator.v3+json, application/vnd.spring-boot.actuator.v2+json, application/json]
|
||||
2025-07-16T09:04:12.545+08:00 DEBUG 19784 --- [http-nio-19001-exec-3] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [org.springframework.boot.actuate.health.SystemHealth@159e4af4]
|
||||
2025-07-16T09:04:12.545+08:00 DEBUG 19784 --- [http-nio-19001-exec-3] o.s.web.servlet.DispatcherServlet : Completed 200 OK
|
||||
2025-07-16T09:04:22.221+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.223+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.224+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.224+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.225+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.225+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.226+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.226+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.227+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.227+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.228+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.228+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.229+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
|
||||
2025-07-16T09:04:22.237+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.237+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.238+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.238+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.238+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.239+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.239+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.239+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.240+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.240+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.240+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.241+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.241+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.242+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error", parameters={}
|
||||
2025-07-16T09:04:22.242+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
|
||||
2025-07-16T09:04:22.245+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json]
|
||||
2025-07-16T09:04:22.245+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Wed Jul 16 09:04:22 CST 2025, status=403, error=Forbidden, path=/user/actuator/health}]
|
||||
2025-07-16T09:04:22.249+08:00 DEBUG 19784 --- [http-nio-19001-exec-5] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 403
|
||||
2025-07-16T09:45:38.808+08:00 WARN 56575 --- [restartedMain] c.a.nacos.client.logging.NacosLogging : Load Logback Configuration of Nacos fail, message: Could not initialize Logback Nacos logging from classpath:nacos-logback.xml
|
||||
2025-07-16T09:45:38.828+08:00 INFO 56575 --- [restartedMain] c.a.n.c.c.impl.LocalConfigInfoProcessor : LOCAL_SNAPSHOT_PATH:/Users/huazhongmin/nacos/config
|
||||
2025-07-16T09:45:38.832+08:00 INFO 56575 --- [restartedMain] com.alibaba.nacos.common.remote.client : [RpcClientFactory] create a new rpc client of ecde1dfa-90a6-49ad-97db-0a748b10d78c_config-0
|
||||
2025-07-16T09:45:38.850+08:00 INFO 56575 --- [restartedMain] com.alibaba.nacos.common.remote.client : [ecde1dfa-90a6-49ad-97db-0a748b10d78c_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda/0x00000001273239b8
|
||||
2025-07-16T09:45:38.850+08:00 INFO 56575 --- [restartedMain] com.alibaba.nacos.common.remote.client : [ecde1dfa-90a6-49ad-97db-0a748b10d78c_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda/0x0000000127323de8
|
||||
2025-07-16T09:45:38.851+08:00 INFO 56575 --- [restartedMain] com.alibaba.nacos.common.remote.client : [ecde1dfa-90a6-49ad-97db-0a748b10d78c_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1
|
||||
2025-07-16T09:45:38.851+08:00 INFO 56575 --- [restartedMain] com.alibaba.nacos.common.remote.client : [ecde1dfa-90a6-49ad-97db-0a748b10d78c_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2
|
||||
2025-07-16T09:45:38.857+08:00 INFO 56575 --- [restartedMain] com.alibaba.nacos.common.remote.client : [ecde1dfa-90a6-49ad-97db-0a748b10d78c_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848}
|
||||
2025-07-16T09:45:38.890+08:00 INFO 56575 --- [restartedMain] c.a.n.c.remote.client.grpc.GrpcClient : grpc client connection server:127.0.0.1 ip,serverPort:9848,grpcTslConfig:{"sslProvider":"OPENSSL","enableTls":false,"mutualAuthEnable":false,"trustAll":false}
|
||||
2025-07-16T09:45:39.587+08:00 INFO 56575 --- [restartedMain] com.alibaba.nacos.common.remote.client : [ecde1dfa-90a6-49ad-97db-0a748b10d78c_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1752630339357_127.0.0.1_52952
|
||||
2025-07-16T09:45:39.589+08:00 INFO 56575 --- [restartedMain] com.alibaba.nacos.common.remote.client : [ecde1dfa-90a6-49ad-97db-0a748b10d78c_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler
|
||||
2025-07-16T09:45:39.589+08:00 INFO 56575 --- [com.alibaba.nacos.client.remote.worker] com.alibaba.nacos.common.remote.client : [ecde1dfa-90a6-49ad-97db-0a748b10d78c_config-0] Notify connected event to listeners.
|
||||
2025-07-16T09:45:39.589+08:00 INFO 56575 --- [com.alibaba.nacos.client.remote.worker] c.a.n.client.config.impl.ClientWorker : [ecde1dfa-90a6-49ad-97db-0a748b10d78c_config-0] Connected,notify listen context...
|
||||
2025-07-16T09:45:39.590+08:00 INFO 56575 --- [restartedMain] com.alibaba.nacos.common.remote.client : [ecde1dfa-90a6-49ad-97db-0a748b10d78c_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda/0x000000012748f730
|
||||
2025-07-16T09:45:39.641+08:00 INFO 56575 --- [restartedMain] c.a.nacos.client.config.impl.Limiter : limitTime:5.0
|
||||
2025-07-16T09:45:39.679+08:00 WARN 56575 --- [restartedMain] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[emotion-user] & group[DEFAULT_GROUP]
|
||||
2025-07-16T09:45:39.684+08:00 WARN 56575 --- [restartedMain] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[emotion-user.properties] & group[DEFAULT_GROUP]
|
||||
2025-07-16T09:45:39.691+08:00 WARN 56575 --- [restartedMain] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[emotion-user-local.properties] & group[DEFAULT_GROUP]
|
||||
2025-07-16T09:45:39.691+08:00 INFO 56575 --- [restartedMain] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-emotion-user-local.properties,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-emotion-user.properties,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-emotion-user,DEFAULT_GROUP'}]
|
||||
2025-07-16T09:45:39.707+08:00 WARN 56575 --- [restartedMain] c.a.nacos.client.logging.NacosLogging : Load Logback Configuration of Nacos fail, message: Could not initialize Logback Nacos logging from classpath:nacos-logback.xml
|
||||
2025-07-16T09:45:39.707+08:00 INFO 56575 --- [restartedMain] com.emotionmuseum.user.UserApplication : The following 1 profile is active: "local"
|
||||
2025-07-16T09:45:40.656+08:00 INFO 56575 --- [restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
|
||||
2025-07-16T09:45:40.660+08:00 INFO 56575 --- [restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
|
||||
2025-07-16T09:45:40.691+08:00 INFO 56575 --- [restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 13 ms. Found 0 Redis repository interfaces.
|
||||
2025-07-16T09:45:40.909+08:00 INFO 56575 --- [restartedMain] o.s.cloud.context.scope.GenericScope : BeanFactory id=46ac2086-60cb-34f0-84ae-496767f2402a
|
||||
2025-07-16T09:45:41.566+08:00 INFO 56575 --- [restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 19001 (http)
|
||||
2025-07-16T09:45:41.578+08:00 INFO 56575 --- [restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
|
||||
2025-07-16T09:45:41.578+08:00 INFO 56575 --- [restartedMain] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.5]
|
||||
2025-07-16T09:45:41.632+08:00 INFO 56575 --- [restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
|
||||
2025-07-16T09:45:41.633+08:00 INFO 56575 --- [restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1902 ms
|
||||
2025-07-16T09:45:42.183+08:00 INFO 56575 --- [restartedMain] c.e.common.config.SnowflakeConfig : 使用MAC地址生成的机器ID: 217
|
||||
2025-07-16T09:45:42.183+08:00 INFO 56575 --- [restartedMain] c.e.common.config.SnowflakeConfig : 雪花算法配置完成,使用机器ID: 217
|
||||
2025-07-16T09:45:42.183+08:00 INFO 56575 --- [restartedMain] c.e.common.util.SnowflakeIdGenerator : 雪花算法ID生成器初始化完成,机器ID: 217
|
||||
2025-07-16T09:45:42.424+08:00 DEBUG 56575 --- [restartedMain] c.e.u.security.JwtAuthenticationFilter : Filter 'jwtAuthenticationFilter' configured for use
|
||||
2025-07-16T09:45:42.426+08:00 DEBUG 56575 --- [restartedMain] o.s.w.f.ServerHttpObservationFilter : Filter 'serverHttpObservationFilter' configured for use
|
||||
2025-07-16T09:45:43.011+08:00 DEBUG 56575 --- [restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : 19 mappings in 'requestMappingHandlerMapping'
|
||||
2025-07-16T09:45:43.044+08:00 DEBUG 56575 --- [restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Patterns [/webjars/**, /**] in 'resourceHandlerMapping'
|
||||
2025-07-16T09:45:43.167+08:00 INFO 56575 --- [restartedMain] o.s.b.a.e.web.EndpointLinksResolver : Exposing 3 endpoint(s) beneath base path '/actuator'
|
||||
2025-07-16T09:45:43.225+08:00 INFO 56575 --- [restartedMain] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@6197bfc3, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@19b14e61, org.springframework.security.web.context.SecurityContextHolderFilter@4c11c4d5, org.springframework.security.web.header.HeaderWriterFilter@467455d6, org.springframework.web.filter.CorsFilter@390f1c1, org.springframework.security.web.authentication.logout.LogoutFilter@335ca7f9, com.emotionmuseum.user.security.JwtAuthenticationFilter@32d98a3b, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@76defa49, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@52afd65a, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@1624e51e, org.springframework.security.web.session.SessionManagementFilter@3aee12aa, org.springframework.security.web.access.ExceptionTranslationFilter@1c7422d0, org.springframework.security.web.access.intercept.AuthorizationFilter@6503bbb3]
|
||||
2025-07-16T09:45:43.297+08:00 DEBUG 56575 --- [restartedMain] s.w.s.m.m.a.RequestMappingHandlerAdapter : ControllerAdvice beans: 0 @ModelAttribute, 0 @InitBinder, 1 RequestBodyAdvice, 1 ResponseBodyAdvice
|
||||
2025-07-16T09:45:43.336+08:00 DEBUG 56575 --- [restartedMain] .m.m.a.ExceptionHandlerExceptionResolver : ControllerAdvice beans: 0 @ExceptionHandler, 1 ResponseBodyAdvice
|
||||
2025-07-16T09:45:43.536+08:00 INFO 56575 --- [restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
|
||||
2025-07-16T09:45:43.600+08:00 WARN 56575 --- [restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
|
||||
2025-07-16T09:45:43.618+08:00 INFO 56575 --- [restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
|
||||
2025-07-16T09:45:43.732+08:00 INFO 56575 --- [restartedMain] .s.b.a.l.ConditionEvaluationReportLogger :
|
||||
|
||||
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
|
||||
2025-07-16T09:45:43.749+08:00 ERROR 56575 --- [restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
|
||||
|
||||
***************************
|
||||
APPLICATION FAILED TO START
|
||||
***************************
|
||||
|
||||
Description:
|
||||
|
||||
Web server failed to start. Port 19001 was already in use.
|
||||
|
||||
Action:
|
||||
|
||||
Identify and stop the process that's listening on port 19001 or configure this application to listen on another port.
|
||||
|
||||
2025-07-16T09:46:36.096+08:00 WARN 56575 --- [Thread-10] c.a.nacos.common.notify.NotifyCenter : [NotifyCenter] Start destroying Publisher
|
||||
2025-07-16T09:46:36.096+08:00 WARN 56575 --- [Thread-4] c.a.n.common.http.HttpClientBeanHolder : [HttpClientBeanHolder] Start destroying common HttpClient
|
||||
2025-07-16T09:46:36.096+08:00 WARN 56575 --- [Thread-10] c.a.nacos.common.notify.NotifyCenter : [NotifyCenter] Destruction of the end
|
||||
2025-07-16T09:46:48.938+08:00 WARN 19784 --- [Thread-7] c.a.nacos.common.notify.NotifyCenter : [NotifyCenter] Start destroying Publisher
|
||||
2025-07-16T09:46:48.938+08:00 WARN 19784 --- [Thread-1] c.a.n.common.http.HttpClientBeanHolder : [HttpClientBeanHolder] Start destroying common HttpClient
|
||||
2025-07-16T09:46:48.964+08:00 WARN 19784 --- [Thread-7] c.a.nacos.common.notify.NotifyCenter : [NotifyCenter] Destruction of the end
|
||||
2025-07-16T09:46:48.973+08:00 WARN 19784 --- [Thread-1] c.a.n.common.http.HttpClientBeanHolder : [HttpClientBeanHolder] Destruction of the end
|
||||
2025-07-16T09:46:49.141+08:00 INFO 19784 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
|
||||
2025-07-16T09:46:49.151+08:00 INFO 19784 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
|
||||
2025-07-16T09:48:19.128+08:00 WARN 59407 --- [restartedMain] c.a.nacos.client.logging.NacosLogging : Load Logback Configuration of Nacos fail, message: Could not initialize Logback Nacos logging from classpath:nacos-logback.xml
|
||||
2025-07-16T09:48:19.155+08:00 INFO 59407 --- [restartedMain] c.a.n.c.c.impl.LocalConfigInfoProcessor : LOCAL_SNAPSHOT_PATH:/Users/huazhongmin/nacos/config
|
||||
2025-07-16T09:48:19.158+08:00 INFO 59407 --- [restartedMain] com.alibaba.nacos.common.remote.client : [RpcClientFactory] create a new rpc client of 55011ce6-21c3-4e3d-aef7-8b1bc89c6930_config-0
|
||||
2025-07-16T09:48:19.177+08:00 INFO 59407 --- [restartedMain] com.alibaba.nacos.common.remote.client : [55011ce6-21c3-4e3d-aef7-8b1bc89c6930_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda/0x00000001283221c0
|
||||
2025-07-16T09:48:19.177+08:00 INFO 59407 --- [restartedMain] com.alibaba.nacos.common.remote.client : [55011ce6-21c3-4e3d-aef7-8b1bc89c6930_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda/0x00000001283225f0
|
||||
2025-07-16T09:48:19.177+08:00 INFO 59407 --- [restartedMain] com.alibaba.nacos.common.remote.client : [55011ce6-21c3-4e3d-aef7-8b1bc89c6930_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1
|
||||
2025-07-16T09:48:19.177+08:00 INFO 59407 --- [restartedMain] com.alibaba.nacos.common.remote.client : [55011ce6-21c3-4e3d-aef7-8b1bc89c6930_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2
|
||||
2025-07-16T09:48:19.183+08:00 INFO 59407 --- [restartedMain] com.alibaba.nacos.common.remote.client : [55011ce6-21c3-4e3d-aef7-8b1bc89c6930_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848}
|
||||
2025-07-16T09:48:19.215+08:00 INFO 59407 --- [restartedMain] c.a.n.c.remote.client.grpc.GrpcClient : grpc client connection server:127.0.0.1 ip,serverPort:9848,grpcTslConfig:{"sslProvider":"OPENSSL","enableTls":false,"mutualAuthEnable":false,"trustAll":false}
|
||||
2025-07-16T09:48:19.832+08:00 INFO 59407 --- [restartedMain] com.alibaba.nacos.common.remote.client : [55011ce6-21c3-4e3d-aef7-8b1bc89c6930_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1752630499650_127.0.0.1_53418
|
||||
2025-07-16T09:48:19.832+08:00 INFO 59407 --- [com.alibaba.nacos.client.remote.worker] com.alibaba.nacos.common.remote.client : [55011ce6-21c3-4e3d-aef7-8b1bc89c6930_config-0] Notify connected event to listeners.
|
||||
2025-07-16T09:48:19.832+08:00 INFO 59407 --- [restartedMain] com.alibaba.nacos.common.remote.client : [55011ce6-21c3-4e3d-aef7-8b1bc89c6930_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler
|
||||
2025-07-16T09:48:19.832+08:00 INFO 59407 --- [com.alibaba.nacos.client.remote.worker] c.a.n.client.config.impl.ClientWorker : [55011ce6-21c3-4e3d-aef7-8b1bc89c6930_config-0] Connected,notify listen context...
|
||||
2025-07-16T09:48:19.833+08:00 INFO 59407 --- [restartedMain] com.alibaba.nacos.common.remote.client : [55011ce6-21c3-4e3d-aef7-8b1bc89c6930_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda/0x000000012848b618
|
||||
2025-07-16T09:48:19.871+08:00 INFO 59407 --- [restartedMain] c.a.nacos.client.config.impl.Limiter : limitTime:5.0
|
||||
2025-07-16T09:48:19.889+08:00 WARN 59407 --- [restartedMain] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[emotion-user] & group[DEFAULT_GROUP]
|
||||
2025-07-16T09:48:19.895+08:00 WARN 59407 --- [restartedMain] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[emotion-user.properties] & group[DEFAULT_GROUP]
|
||||
2025-07-16T09:48:19.899+08:00 WARN 59407 --- [restartedMain] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[emotion-user-local.properties] & group[DEFAULT_GROUP]
|
||||
2025-07-16T09:48:19.900+08:00 INFO 59407 --- [restartedMain] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-emotion-user-local.properties,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-emotion-user.properties,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-emotion-user,DEFAULT_GROUP'}]
|
||||
2025-07-16T09:48:19.918+08:00 WARN 59407 --- [restartedMain] c.a.nacos.client.logging.NacosLogging : Load Logback Configuration of Nacos fail, message: Could not initialize Logback Nacos logging from classpath:nacos-logback.xml
|
||||
2025-07-16T09:48:19.919+08:00 INFO 59407 --- [restartedMain] com.emotionmuseum.user.UserApplication : The following 1 profile is active: "local"
|
||||
2025-07-16T09:48:20.767+08:00 INFO 59407 --- [restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
|
||||
2025-07-16T09:48:20.771+08:00 INFO 59407 --- [restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
|
||||
2025-07-16T09:48:20.797+08:00 INFO 59407 --- [restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 11 ms. Found 0 Redis repository interfaces.
|
||||
2025-07-16T09:48:21.020+08:00 INFO 59407 --- [restartedMain] o.s.cloud.context.scope.GenericScope : BeanFactory id=46ac2086-60cb-34f0-84ae-496767f2402a
|
||||
2025-07-16T09:48:21.786+08:00 INFO 59407 --- [restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 19001 (http)
|
||||
2025-07-16T09:48:21.797+08:00 INFO 59407 --- [restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
|
||||
2025-07-16T09:48:21.798+08:00 INFO 59407 --- [restartedMain] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.5]
|
||||
2025-07-16T09:48:21.851+08:00 INFO 59407 --- [restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
|
||||
2025-07-16T09:48:21.851+08:00 INFO 59407 --- [restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1904 ms
|
||||
2025-07-16T09:48:22.859+08:00 INFO 59407 --- [restartedMain] c.e.common.config.SnowflakeConfig : 使用MAC地址生成的机器ID: 652
|
||||
2025-07-16T09:48:22.860+08:00 INFO 59407 --- [restartedMain] c.e.common.config.SnowflakeConfig : 雪花算法配置完成,使用机器ID: 652
|
||||
2025-07-16T09:48:22.860+08:00 INFO 59407 --- [restartedMain] c.e.common.util.SnowflakeIdGenerator : 雪花算法ID生成器初始化完成,机器ID: 652
|
||||
2025-07-16T09:48:23.723+08:00 DEBUG 59407 --- [restartedMain] c.e.u.security.JwtAuthenticationFilter : Filter 'jwtAuthenticationFilter' configured for use
|
||||
2025-07-16T09:48:23.726+08:00 DEBUG 59407 --- [restartedMain] o.s.w.f.ServerHttpObservationFilter : Filter 'serverHttpObservationFilter' configured for use
|
||||
2025-07-16T09:48:24.530+08:00 DEBUG 59407 --- [restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : 19 mappings in 'requestMappingHandlerMapping'
|
||||
2025-07-16T09:48:24.598+08:00 DEBUG 59407 --- [restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Patterns [/webjars/**, /**] in 'resourceHandlerMapping'
|
||||
2025-07-16T09:48:24.845+08:00 INFO 59407 --- [restartedMain] o.s.b.a.e.web.EndpointLinksResolver : Exposing 3 endpoint(s) beneath base path '/actuator'
|
||||
2025-07-16T09:48:24.941+08:00 INFO 59407 --- [restartedMain] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@45cfcad, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@c053d77, org.springframework.security.web.context.SecurityContextHolderFilter@45f2ef0, org.springframework.security.web.header.HeaderWriterFilter@6ae52284, org.springframework.web.filter.CorsFilter@78f6eda5, org.springframework.security.web.authentication.logout.LogoutFilter@333894cb, com.emotionmuseum.user.security.JwtAuthenticationFilter@5e26f22e, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@75d7738, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6c5ba2aa, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@4dfa0a5, org.springframework.security.web.session.SessionManagementFilter@5d5c7ca2, org.springframework.security.web.access.ExceptionTranslationFilter@25061101, org.springframework.security.web.access.intercept.AuthorizationFilter@14938851]
|
||||
2025-07-16T09:48:25.117+08:00 DEBUG 59407 --- [restartedMain] s.w.s.m.m.a.RequestMappingHandlerAdapter : ControllerAdvice beans: 0 @ModelAttribute, 0 @InitBinder, 1 RequestBodyAdvice, 1 ResponseBodyAdvice
|
||||
2025-07-16T09:48:25.165+08:00 DEBUG 59407 --- [restartedMain] .m.m.a.ExceptionHandlerExceptionResolver : ControllerAdvice beans: 0 @ExceptionHandler, 1 ResponseBodyAdvice
|
||||
2025-07-16T09:48:25.472+08:00 INFO 59407 --- [restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
|
||||
2025-07-16T09:48:25.568+08:00 INFO 59407 --- [restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 19001 (http) with context path ''
|
||||
2025-07-16T09:48:25.592+08:00 INFO 59407 --- [restartedMain] com.emotionmuseum.user.UserApplication : Started UserApplication in 7.306 seconds (process running for 7.799)
|
||||
2025-07-16T09:49:18.783+08:00 INFO 59407 --- [http-nio-19001-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
|
||||
2025-07-16T09:49:18.783+08:00 INFO 59407 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
|
||||
2025-07-16T09:49:18.783+08:00 DEBUG 59407 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
|
||||
2025-07-16T09:49:18.783+08:00 DEBUG 59407 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected AcceptHeaderLocaleResolver
|
||||
2025-07-16T09:49:18.783+08:00 DEBUG 59407 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected FixedThemeResolver
|
||||
2025-07-16T09:49:18.785+08:00 DEBUG 59407 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator@10bf8750
|
||||
2025-07-16T09:49:18.785+08:00 DEBUG 59407 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.support.SessionFlashMapManager@a8815ac
|
||||
2025-07-16T09:49:18.785+08:00 DEBUG 59407 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
|
||||
2025-07-16T09:49:18.786+08:00 INFO 59407 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 3 ms
|
||||
2025-07-16T09:49:18.845+08:00 DEBUG 59407 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : GET "/actuator/health", parameters={}
|
||||
2025-07-16T09:49:18.877+08:00 INFO 59407 --- [http-nio-19001-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
|
||||
2025-07-16T09:49:19.066+08:00 INFO 59407 --- [http-nio-19001-exec-1] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@22c2045e
|
||||
2025-07-16T09:49:19.069+08:00 INFO 59407 --- [http-nio-19001-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
|
||||
2025-07-16T09:49:19.516+08:00 DEBUG 59407 --- [http-nio-19001-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/vnd.spring-boot.actuator.v3+json', given [*/*] and supported [application/vnd.spring-boot.actuator.v3+json, application/vnd.spring-boot.actuator.v2+json, application/json]
|
||||
2025-07-16T09:49:19.525+08:00 DEBUG 59407 --- [http-nio-19001-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [org.springframework.boot.actuate.health.SystemHealth@5e85c0c]
|
||||
2025-07-16T09:49:19.539+08:00 DEBUG 59407 --- [http-nio-19001-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK
|
||||
2025-07-16T09:49:31.721+08:00 WARN 59407 --- [Thread-4] c.a.n.common.http.HttpClientBeanHolder : [HttpClientBeanHolder] Start destroying common HttpClient
|
||||
2025-07-16T09:49:31.721+08:00 WARN 59407 --- [Thread-10] c.a.nacos.common.notify.NotifyCenter : [NotifyCenter] Start destroying Publisher
|
||||
2025-07-16T09:49:31.721+08:00 WARN 59407 --- [Thread-10] c.a.nacos.common.notify.NotifyCenter : [NotifyCenter] Destruction of the end
|
||||
2025-07-16T09:49:31.722+08:00 WARN 59407 --- [Thread-4] c.a.n.common.http.HttpClientBeanHolder : [HttpClientBeanHolder] Destruction of the end
|
||||
2025-07-16T09:49:31.740+08:00 INFO 59407 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
|
||||
2025-07-16T09:49:31.746+08:00 INFO 59407 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
|
||||
Binary file not shown.
+53
@@ -0,0 +1,53 @@
|
||||
package com.emotionmuseum.user.config;
|
||||
|
||||
import com.emotionmuseum.user.security.UserDetailsServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
/**
|
||||
* 认证配置类
|
||||
* 独立的认证配置,避免循环依赖
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class AuthenticationConfig {
|
||||
|
||||
private final UserDetailsServiceImpl userDetailsService;
|
||||
|
||||
/**
|
||||
* 密码编码器
|
||||
*/
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 认证提供者
|
||||
*/
|
||||
@Bean
|
||||
public AuthenticationProvider authenticationProvider() {
|
||||
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
|
||||
authProvider.setUserDetailsService(userDetailsService);
|
||||
authProvider.setPasswordEncoder(passwordEncoder());
|
||||
return authProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* 认证管理器
|
||||
*/
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
||||
return config.getAuthenticationManager();
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ public class CaptchaConfig {
|
||||
public Captcha arithmeticCaptcha() {
|
||||
ArithmeticCaptcha captcha = new ArithmeticCaptcha(130, 48);
|
||||
captcha.setLen(2); // 几位数运算,默认是两位
|
||||
captcha.getArithmeticString(); // 获取运算的公式:3+2=?
|
||||
return captcha;
|
||||
}
|
||||
|
||||
|
||||
+8
-34
@@ -3,19 +3,17 @@ package com.emotionmuseum.user.config;
|
||||
import com.emotionmuseum.user.security.JwtAuthenticationFilter;
|
||||
import com.emotionmuseum.user.security.UserDetailsServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
@@ -37,35 +35,10 @@ import java.util.Collections;
|
||||
@RequiredArgsConstructor
|
||||
public class SecurityConfig {
|
||||
|
||||
private final UserDetailsServiceImpl userDetailsService;
|
||||
private final JwtAuthenticationFilter jwtAuthenticationFilter;
|
||||
private final ApplicationContext applicationContext;
|
||||
private final AuthenticationProvider authenticationProvider;
|
||||
|
||||
/**
|
||||
* 密码编码器
|
||||
*/
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 认证提供者
|
||||
*/
|
||||
@Bean
|
||||
public AuthenticationProvider authenticationProvider() {
|
||||
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
|
||||
authProvider.setUserDetailsService(userDetailsService);
|
||||
authProvider.setPasswordEncoder(passwordEncoder());
|
||||
return authProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* 认证管理器
|
||||
*/
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
||||
return config.getAuthenticationManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* CORS配置
|
||||
@@ -126,10 +99,11 @@ public class SecurityConfig {
|
||||
.anyRequest().authenticated())
|
||||
|
||||
// 配置认证提供者
|
||||
.authenticationProvider(authenticationProvider())
|
||||
.authenticationProvider(authenticationProvider)
|
||||
|
||||
// 添加JWT过滤器
|
||||
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
.addFilterBefore(applicationContext.getBean(JwtAuthenticationFilter.class),
|
||||
UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
package com.emotionmuseum.user.controller;
|
||||
|
||||
import com.emotionmuseum.common.result.Result;
|
||||
import com.emotionmuseum.user.dto.CaptchaResponse;
|
||||
import com.emotionmuseum.user.dto.SliderCaptchaResponse;
|
||||
import com.emotionmuseum.user.dto.SliderCaptchaVerifyRequest;
|
||||
import com.emotionmuseum.user.service.CaptchaService;
|
||||
import com.emotionmuseum.user.service.SliderCaptchaService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 验证码控制器
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/captcha")
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "验证码管理", description = "验证码生成和验证接口")
|
||||
public class CaptchaController {
|
||||
|
||||
private final CaptchaService captchaService;
|
||||
private final SliderCaptchaService sliderCaptchaService;
|
||||
|
||||
@Operation(summary = "生成验证码")
|
||||
@GetMapping("/generate")
|
||||
public Result<CaptchaResponse> generateCaptcha(
|
||||
@Parameter(description = "验证码类型", example = "arithmetic") @RequestParam(defaultValue = "arithmetic") String type) {
|
||||
log.info("生成验证码请求,类型: {}", type);
|
||||
CaptchaResponse response = captchaService.generateCaptcha(type);
|
||||
return Result.success(response);
|
||||
}
|
||||
|
||||
@Operation(summary = "验证验证码")
|
||||
@PostMapping("/verify")
|
||||
public Result<Boolean> verifyCaptcha(
|
||||
@Parameter(description = "验证码ID") @RequestParam String captchaId,
|
||||
@Parameter(description = "验证码") @RequestParam String captcha) {
|
||||
log.info("验证验证码请求,ID: {}", captchaId);
|
||||
boolean isValid = captchaService.verifyCaptcha(captchaId, captcha);
|
||||
return Result.success(isValid);
|
||||
}
|
||||
|
||||
@Operation(summary = "生成滑块验证码")
|
||||
@GetMapping("/slider/generate")
|
||||
public Result<SliderCaptchaResponse> generateSliderCaptcha() {
|
||||
log.info("生成滑块验证码请求");
|
||||
SliderCaptchaResponse response = sliderCaptchaService.generateSliderCaptcha();
|
||||
return Result.success(response);
|
||||
}
|
||||
|
||||
@Operation(summary = "验证滑块验证码")
|
||||
@PostMapping("/slider/verify")
|
||||
public Result<Boolean> verifySliderCaptcha(@RequestBody SliderCaptchaVerifyRequest request) {
|
||||
log.info("验证滑块验证码请求,ID: {}", request.getCaptchaId());
|
||||
boolean isValid = sliderCaptchaService.verifySliderCaptcha(request);
|
||||
return Result.success(isValid);
|
||||
}
|
||||
}
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
package com.emotionmuseum.user.controller;
|
||||
|
||||
import com.emotionmuseum.common.result.Result;
|
||||
import com.emotionmuseum.user.dto.OAuthLoginRequest;
|
||||
import com.emotionmuseum.user.service.OAuthService;
|
||||
import com.emotionmuseum.user.vo.LoginResponse;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
/**
|
||||
* 第三方登录控制器
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/oauth")
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "第三方登录", description = "微信、QQ等第三方登录接口")
|
||||
public class OAuthController {
|
||||
|
||||
private final OAuthService oauthService;
|
||||
|
||||
@Operation(summary = "获取第三方登录授权URL")
|
||||
@GetMapping("/auth-url/{platform}")
|
||||
public Result<String> getAuthUrl(
|
||||
@Parameter(description = "平台类型", example = "wechat")
|
||||
@PathVariable String platform) {
|
||||
log.info("获取第三方登录授权URL: {}", platform);
|
||||
String authUrl = oauthService.getAuthUrl(platform);
|
||||
return Result.success(authUrl);
|
||||
}
|
||||
|
||||
@Operation(summary = "第三方登录")
|
||||
@PostMapping("/login")
|
||||
public Result<LoginResponse> oauthLogin(@Valid @RequestBody OAuthLoginRequest request) {
|
||||
log.info("第三方登录请求: {}", request.getPlatform());
|
||||
LoginResponse response = oauthService.oauthLogin(request);
|
||||
return Result.success(response);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取第三方用户信息")
|
||||
@GetMapping("/user-info/{platform}")
|
||||
public Result<Object> getOAuthUserInfo(
|
||||
@Parameter(description = "平台类型") @PathVariable String platform,
|
||||
@Parameter(description = "授权码") @RequestParam String code,
|
||||
@Parameter(description = "状态码") @RequestParam(required = false) String state) {
|
||||
log.info("获取第三方用户信息: {}", platform);
|
||||
Object userInfo = oauthService.getOAuthUserInfo(platform, code, state);
|
||||
return Result.success(userInfo);
|
||||
}
|
||||
}
|
||||
+1
-62
@@ -1,11 +1,8 @@
|
||||
package com.emotionmuseum.user.controller;
|
||||
|
||||
import com.emotionmuseum.common.result.Result;
|
||||
import com.emotionmuseum.user.dto.LoginRequest;
|
||||
import com.emotionmuseum.user.dto.RegisterRequest;
|
||||
import com.emotionmuseum.user.dto.UserUpdateRequest;
|
||||
import com.emotionmuseum.user.service.UserService;
|
||||
import com.emotionmuseum.user.vo.LoginResponse;
|
||||
import com.emotionmuseum.user.vo.UserInfoResponse;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -28,36 +25,11 @@ import jakarta.validation.Valid;
|
||||
@RequestMapping("/user")
|
||||
@RequiredArgsConstructor
|
||||
@Validated
|
||||
@Tag(name = "用户管理", description = "用户注册、登录、信息管理")
|
||||
@Tag(name = "用户管理", description = "用户信息管理")
|
||||
public class UserController {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
@Operation(summary = "用户注册")
|
||||
@PostMapping("/register")
|
||||
public Result<UserInfoResponse> register(@Valid @RequestBody RegisterRequest request) {
|
||||
log.info("用户注册请求: {}", request.getAccount());
|
||||
UserInfoResponse response = userService.register(request);
|
||||
return Result.success("注册成功", response);
|
||||
}
|
||||
|
||||
@Operation(summary = "用户登录")
|
||||
@PostMapping("/login")
|
||||
public Result<LoginResponse> login(@Valid @RequestBody LoginRequest request) {
|
||||
log.info("用户登录请求: {}", request.getAccount());
|
||||
LoginResponse response = userService.login(request);
|
||||
return Result.success("登录成功", response);
|
||||
}
|
||||
|
||||
@Operation(summary = "刷新Token")
|
||||
@PostMapping("/refresh")
|
||||
public Result<LoginResponse> refreshToken(
|
||||
@Parameter(description = "刷新Token") @RequestParam String refreshToken) {
|
||||
log.info("刷新Token请求");
|
||||
LoginResponse response = userService.refreshToken(refreshToken);
|
||||
return Result.success("Token刷新成功", response);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取用户信息")
|
||||
@GetMapping("/info/{userId}")
|
||||
public Result<UserInfoResponse> getUserInfo(
|
||||
@@ -77,30 +49,6 @@ public class UserController {
|
||||
return Result.success("更新成功", response);
|
||||
}
|
||||
|
||||
@Operation(summary = "检查账号是否存在")
|
||||
@GetMapping("/check/account")
|
||||
public Result<Boolean> checkAccount(
|
||||
@Parameter(description = "账号") @RequestParam String account) {
|
||||
boolean exists = userService.existsByAccount(account);
|
||||
return Result.success(exists);
|
||||
}
|
||||
|
||||
@Operation(summary = "检查邮箱是否存在")
|
||||
@GetMapping("/check/email")
|
||||
public Result<Boolean> checkEmail(
|
||||
@Parameter(description = "邮箱") @RequestParam String email) {
|
||||
boolean exists = userService.existsByEmail(email);
|
||||
return Result.success(exists);
|
||||
}
|
||||
|
||||
@Operation(summary = "检查手机号是否存在")
|
||||
@GetMapping("/check/phone")
|
||||
public Result<Boolean> checkPhone(
|
||||
@Parameter(description = "手机号") @RequestParam String phone) {
|
||||
boolean exists = userService.existsByPhone(phone);
|
||||
return Result.success(exists);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新最后活跃时间")
|
||||
@PostMapping("/active/{userId}")
|
||||
public Result<Void> updateLastActiveTime(
|
||||
@@ -108,13 +56,4 @@ public class UserController {
|
||||
userService.updateLastActiveTime(userId);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "用户登出")
|
||||
@PostMapping("/logout/{userId}")
|
||||
public Result<Void> logout(
|
||||
@Parameter(description = "用户ID") @PathVariable String userId) {
|
||||
log.info("用户登出请求: {}", userId);
|
||||
userService.logout(userId);
|
||||
return Result.success();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.emotionmuseum.user.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 验证码响应
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "验证码响应")
|
||||
public class CaptchaResponse {
|
||||
|
||||
@Schema(description = "验证码ID")
|
||||
private String captchaId;
|
||||
|
||||
@Schema(description = "验证码图片Base64")
|
||||
private String captchaImage;
|
||||
|
||||
@Schema(description = "验证码类型", example = "arithmetic")
|
||||
private String captchaType;
|
||||
|
||||
@Schema(description = "过期时间(秒)", example = "300")
|
||||
private Long expireTime;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.emotionmuseum.user.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 用户登录请求
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-12
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "用户登录请求")
|
||||
public class LoginRequest {
|
||||
|
||||
@Schema(description = "账号(支持账号/邮箱/手机号)", example = "test_user")
|
||||
@NotBlank(message = "账号不能为空")
|
||||
private String account;
|
||||
|
||||
@Schema(description = "密码", example = "123456")
|
||||
@NotBlank(message = "密码不能为空")
|
||||
private String password;
|
||||
|
||||
@Schema(description = "验证码ID", example = "captcha_123")
|
||||
@NotBlank(message = "验证码ID不能为空")
|
||||
private String captchaId;
|
||||
|
||||
@Schema(description = "验证码", example = "1234")
|
||||
@NotBlank(message = "验证码不能为空")
|
||||
private String captcha;
|
||||
|
||||
@Schema(description = "记住我", example = "false")
|
||||
private Boolean rememberMe = false;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.emotionmuseum.user.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 第三方登录请求
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "第三方登录请求")
|
||||
public class OAuthLoginRequest {
|
||||
|
||||
@Schema(description = "第三方平台类型", example = "wechat")
|
||||
@NotBlank(message = "平台类型不能为空")
|
||||
private String platform;
|
||||
|
||||
@Schema(description = "授权码", example = "auth_code_123")
|
||||
@NotBlank(message = "授权码不能为空")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "状态码", example = "state_123")
|
||||
private String state;
|
||||
|
||||
@Schema(description = "验证码ID", example = "captcha_123")
|
||||
@NotBlank(message = "验证码ID不能为空")
|
||||
private String captchaId;
|
||||
|
||||
@Schema(description = "验证码", example = "1234")
|
||||
@NotBlank(message = "验证码不能为空")
|
||||
private String captcha;
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package com.emotionmuseum.user.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 用户注册请求
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-12
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "用户注册请求")
|
||||
public class RegisterRequest {
|
||||
|
||||
@Schema(description = "账号", example = "test_user")
|
||||
@NotBlank(message = "账号不能为空")
|
||||
@Size(min = 4, max = 20, message = "账号长度必须在4-20位之间")
|
||||
@Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "账号只能包含字母、数字和下划线")
|
||||
private String account;
|
||||
|
||||
@Schema(description = "密码", example = "123456")
|
||||
@NotBlank(message = "密码不能为空")
|
||||
@Size(min = 6, max = 20, message = "密码长度必须在6-20位之间")
|
||||
private String password;
|
||||
|
||||
@Schema(description = "确认密码", example = "123456")
|
||||
@NotBlank(message = "确认密码不能为空")
|
||||
private String confirmPassword;
|
||||
|
||||
@Schema(description = "验证码ID", example = "captcha_123")
|
||||
@NotBlank(message = "验证码ID不能为空")
|
||||
private String captchaId;
|
||||
|
||||
@Schema(description = "验证码", example = "1234")
|
||||
@NotBlank(message = "验证码不能为空")
|
||||
private String captcha;
|
||||
|
||||
@Schema(description = "用户名", example = "测试用户")
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
@Size(min = 2, max = 20, message = "用户名长度必须在2-20位之间")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "邮箱", example = "test@example.com")
|
||||
@NotBlank(message = "邮箱不能为空")
|
||||
@Email(message = "邮箱格式不正确")
|
||||
private String email;
|
||||
|
||||
@Schema(description = "手机号", example = "13800138000")
|
||||
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
|
||||
private String phone;
|
||||
|
||||
@Schema(description = "昵称", example = "小测试")
|
||||
@NotBlank(message = "昵称不能为空")
|
||||
@Size(min = 1, max = 20, message = "昵称长度必须在1-20位之间")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "生日", example = "1990-01-01")
|
||||
private LocalDate birthDate;
|
||||
|
||||
@Schema(description = "所在地", example = "北京市")
|
||||
@Size(max = 50, message = "所在地长度不能超过50位")
|
||||
private String location;
|
||||
|
||||
@Schema(description = "个人简介", example = "这是一个测试用户")
|
||||
@Size(max = 200, message = "个人简介长度不能超过200位")
|
||||
private String bio;
|
||||
|
||||
/**
|
||||
* 验证密码一致性
|
||||
*/
|
||||
public boolean isPasswordMatch() {
|
||||
return password != null && password.equals(confirmPassword);
|
||||
}
|
||||
}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
package com.emotionmuseum.user.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 滑块验证码响应
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "滑块验证码响应")
|
||||
public class SliderCaptchaResponse {
|
||||
|
||||
@Schema(description = "验证码ID")
|
||||
private String captchaId;
|
||||
|
||||
@Schema(description = "背景图片Base64")
|
||||
private String backgroundImage;
|
||||
|
||||
@Schema(description = "滑块图片Base64")
|
||||
private String sliderImage;
|
||||
|
||||
@Schema(description = "滑块X坐标")
|
||||
private Integer sliderX;
|
||||
|
||||
@Schema(description = "滑块Y坐标")
|
||||
private Integer sliderY;
|
||||
|
||||
@Schema(description = "过期时间(秒)")
|
||||
private Long expireTime;
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
package com.emotionmuseum.user.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 滑块验证码验证请求
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "滑块验证码验证请求")
|
||||
public class SliderCaptchaVerifyRequest {
|
||||
|
||||
@Schema(description = "验证码ID")
|
||||
@NotBlank(message = "验证码ID不能为空")
|
||||
private String captchaId;
|
||||
|
||||
@Schema(description = "滑块X坐标")
|
||||
@NotNull(message = "滑块X坐标不能为空")
|
||||
private Integer x;
|
||||
|
||||
@Schema(description = "滑块Y坐标")
|
||||
@NotNull(message = "滑块Y坐标不能为空")
|
||||
private Integer y;
|
||||
|
||||
@Schema(description = "滑动轨迹")
|
||||
private String track;
|
||||
}
|
||||
@@ -14,30 +14,6 @@ import org.apache.ibatis.annotations.Param;
|
||||
@Mapper
|
||||
public interface UserMapper extends BaseMapper<User> {
|
||||
|
||||
/**
|
||||
* 根据账号查询用户
|
||||
*
|
||||
* @param account 账号
|
||||
* @return 用户信息
|
||||
*/
|
||||
User selectByAccount(@Param("account") String account);
|
||||
|
||||
/**
|
||||
* 根据邮箱查询用户
|
||||
*
|
||||
* @param email 邮箱
|
||||
* @return 用户信息
|
||||
*/
|
||||
User selectByEmail(@Param("email") String email);
|
||||
|
||||
/**
|
||||
* 根据手机号查询用户
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @return 用户信息
|
||||
*/
|
||||
User selectByPhone(@Param("phone") String phone);
|
||||
|
||||
/**
|
||||
* 更新最后活跃时间
|
||||
*
|
||||
|
||||
+2
@@ -8,6 +8,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@@ -32,6 +33,7 @@ import java.util.concurrent.TimeUnit;
|
||||
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
private final JwtUtil jwtUtil;
|
||||
@Lazy
|
||||
private final UserDetailsService userDetailsService;
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
|
||||
+2
@@ -4,6 +4,7 @@ import com.emotionmuseum.user.entity.User;
|
||||
import com.emotionmuseum.user.service.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
@@ -25,6 +26,7 @@ import java.util.Collections;
|
||||
@RequiredArgsConstructor
|
||||
public class UserDetailsServiceImpl implements UserDetailsService {
|
||||
|
||||
@Lazy
|
||||
private final UserService userService;
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.emotionmuseum.user.service;
|
||||
|
||||
import com.emotionmuseum.user.dto.CaptchaResponse;
|
||||
|
||||
/**
|
||||
* 验证码服务接口
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
public interface CaptchaService {
|
||||
|
||||
/**
|
||||
* 生成验证码
|
||||
*
|
||||
* @param type 验证码类型 (arithmetic, chinese, gif, spec)
|
||||
* @return 验证码响应
|
||||
*/
|
||||
CaptchaResponse generateCaptcha(String type);
|
||||
|
||||
/**
|
||||
* 验证验证码
|
||||
*
|
||||
* @param captchaId 验证码ID
|
||||
* @param captcha 用户输入的验证码
|
||||
* @return 是否验证成功
|
||||
*/
|
||||
boolean verifyCaptcha(String captchaId, String captcha);
|
||||
|
||||
/**
|
||||
* 删除验证码
|
||||
*
|
||||
* @param captchaId 验证码ID
|
||||
*/
|
||||
void removeCaptcha(String captchaId);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package com.emotionmuseum.user.service;
|
||||
|
||||
import com.emotionmuseum.user.dto.OAuthLoginRequest;
|
||||
import com.emotionmuseum.user.vo.LoginResponse;
|
||||
|
||||
/**
|
||||
* 第三方登录服务接口
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
public interface OAuthService {
|
||||
|
||||
/**
|
||||
* 获取第三方登录授权URL
|
||||
*
|
||||
* @param platform 平台类型 (wechat, qq, wechat-mp)
|
||||
* @return 授权URL
|
||||
*/
|
||||
String getAuthUrl(String platform);
|
||||
|
||||
/**
|
||||
* 第三方登录
|
||||
*
|
||||
* @param request 第三方登录请求
|
||||
* @return 登录响应
|
||||
*/
|
||||
LoginResponse oauthLogin(OAuthLoginRequest request);
|
||||
|
||||
/**
|
||||
* 获取第三方用户信息
|
||||
*
|
||||
* @param platform 平台类型
|
||||
* @param code 授权码
|
||||
* @param state 状态码
|
||||
* @return 用户信息
|
||||
*/
|
||||
Object getOAuthUserInfo(String platform, String code, String state);
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
package com.emotionmuseum.user.service;
|
||||
|
||||
import com.emotionmuseum.user.dto.SliderCaptchaResponse;
|
||||
import com.emotionmuseum.user.dto.SliderCaptchaVerifyRequest;
|
||||
|
||||
/**
|
||||
* 滑块验证码服务接口
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
public interface SliderCaptchaService {
|
||||
|
||||
/**
|
||||
* 生成滑块验证码
|
||||
*
|
||||
* @return 滑块验证码响应
|
||||
*/
|
||||
SliderCaptchaResponse generateSliderCaptcha();
|
||||
|
||||
/**
|
||||
* 验证滑块验证码
|
||||
*
|
||||
* @param request 验证请求
|
||||
* @return 是否验证成功
|
||||
*/
|
||||
boolean verifySliderCaptcha(SliderCaptchaVerifyRequest request);
|
||||
|
||||
/**
|
||||
* 删除滑块验证码
|
||||
*
|
||||
* @param captchaId 验证码ID
|
||||
*/
|
||||
void removeSliderCaptcha(String captchaId);
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
package com.emotionmuseum.user.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.emotionmuseum.user.dto.LoginRequest;
|
||||
import com.emotionmuseum.user.dto.RegisterRequest;
|
||||
import com.emotionmuseum.user.dto.UserUpdateRequest;
|
||||
import com.emotionmuseum.user.entity.User;
|
||||
import com.emotionmuseum.user.vo.LoginResponse;
|
||||
import com.emotionmuseum.user.vo.UserInfoResponse;
|
||||
|
||||
/**
|
||||
@@ -16,30 +13,6 @@ import com.emotionmuseum.user.vo.UserInfoResponse;
|
||||
*/
|
||||
public interface UserService extends IService<User> {
|
||||
|
||||
/**
|
||||
* 用户注册
|
||||
*
|
||||
* @param request 注册请求
|
||||
* @return 用户信息
|
||||
*/
|
||||
UserInfoResponse register(RegisterRequest request);
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
*
|
||||
* @param request 登录请求
|
||||
* @return 登录响应
|
||||
*/
|
||||
LoginResponse login(LoginRequest request);
|
||||
|
||||
/**
|
||||
* 刷新Token
|
||||
*
|
||||
* @param refreshToken 刷新Token
|
||||
* @return 登录响应
|
||||
*/
|
||||
LoginResponse refreshToken(String refreshToken);
|
||||
|
||||
/**
|
||||
* 根据用户ID获取用户信息
|
||||
*
|
||||
@@ -57,49 +30,10 @@ public interface UserService extends IService<User> {
|
||||
*/
|
||||
UserInfoResponse updateUserInfo(String userId, UserUpdateRequest request);
|
||||
|
||||
/**
|
||||
* 检查账号是否存在
|
||||
*
|
||||
* @param account 账号
|
||||
* @return 是否存在
|
||||
*/
|
||||
boolean existsByAccount(String account);
|
||||
|
||||
/**
|
||||
* 检查邮箱是否存在
|
||||
*
|
||||
* @param email 邮箱
|
||||
* @return 是否存在
|
||||
*/
|
||||
boolean existsByEmail(String email);
|
||||
|
||||
/**
|
||||
* 检查手机号是否存在
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @return 是否存在
|
||||
*/
|
||||
boolean existsByPhone(String phone);
|
||||
|
||||
/**
|
||||
* 更新最后活跃时间
|
||||
*
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
void updateLastActiveTime(String userId);
|
||||
|
||||
/**
|
||||
* 用户登出
|
||||
*
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
void logout(String userId);
|
||||
|
||||
/**
|
||||
* 根据第三方平台ID查找用户
|
||||
*
|
||||
* @param thirdPartyId 第三方平台ID
|
||||
* @return 用户信息
|
||||
*/
|
||||
User findByThirdPartyId(String thirdPartyId);
|
||||
}
|
||||
|
||||
-119
@@ -1,119 +0,0 @@
|
||||
package com.emotionmuseum.user.service.impl;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.emotionmuseum.user.dto.CaptchaResponse;
|
||||
import com.emotionmuseum.user.dto.SliderCaptchaResponse;
|
||||
import com.emotionmuseum.user.dto.SliderCaptchaVerifyRequest;
|
||||
import com.emotionmuseum.user.service.CaptchaService;
|
||||
import com.emotionmuseum.user.service.SliderCaptchaService;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 验证码服务实现
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CaptchaServiceImpl implements CaptchaService {
|
||||
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
private static final String CAPTCHA_KEY_PREFIX = "captcha:";
|
||||
private static final long CAPTCHA_EXPIRE_TIME = 300; // 5分钟
|
||||
|
||||
@Override
|
||||
public CaptchaResponse generateCaptcha(String type) {
|
||||
try {
|
||||
// 根据类型获取验证码Bean
|
||||
String beanName = getBeanNameByType(type);
|
||||
Captcha captcha = (Captcha) applicationContext.getBean(beanName);
|
||||
|
||||
// 生成验证码
|
||||
String captchaId = IdUtil.simpleUUID();
|
||||
String captchaText = captcha.text();
|
||||
String captchaImage = captcha.toBase64();
|
||||
|
||||
// 存储到Redis
|
||||
String redisKey = CAPTCHA_KEY_PREFIX + captchaId;
|
||||
redisTemplate.opsForValue().set(redisKey, captchaText.toLowerCase(), CAPTCHA_EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
|
||||
log.debug("生成验证码成功,ID: {}, 内容: {}", captchaId, captchaText);
|
||||
|
||||
return new CaptchaResponse(captchaId, captchaImage, type, CAPTCHA_EXPIRE_TIME);
|
||||
} catch (Exception e) {
|
||||
log.error("生成验证码失败: {}", e.getMessage());
|
||||
throw new RuntimeException("生成验证码失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyCaptcha(String captchaId, String captcha) {
|
||||
if (StrUtil.isBlank(captchaId) || StrUtil.isBlank(captcha)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
String redisKey = CAPTCHA_KEY_PREFIX + captchaId;
|
||||
String storedCaptcha = (String) redisTemplate.opsForValue().get(redisKey);
|
||||
|
||||
if (StrUtil.isBlank(storedCaptcha)) {
|
||||
log.warn("验证码已过期或不存在,ID: {}", captchaId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 验证码不区分大小写
|
||||
boolean isValid = storedCaptcha.equalsIgnoreCase(captcha.trim());
|
||||
|
||||
if (isValid) {
|
||||
// 验证成功后删除验证码
|
||||
redisTemplate.delete(redisKey);
|
||||
log.debug("验证码验证成功,ID: {}", captchaId);
|
||||
} else {
|
||||
log.warn("验证码验证失败,ID: {}, 期望: {}, 实际: {}", captchaId, storedCaptcha, captcha);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
} catch (Exception e) {
|
||||
log.error("验证验证码失败: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCaptcha(String captchaId) {
|
||||
if (StrUtil.isNotBlank(captchaId)) {
|
||||
String redisKey = CAPTCHA_KEY_PREFIX + captchaId;
|
||||
redisTemplate.delete(redisKey);
|
||||
log.debug("删除验证码,ID: {}", captchaId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据类型获取Bean名称
|
||||
*/
|
||||
private String getBeanNameByType(String type) {
|
||||
String defaultType = StrUtil.blankToDefault(type, "spec");
|
||||
switch (defaultType) {
|
||||
case "arithmetic":
|
||||
return "arithmeticCaptcha";
|
||||
case "chinese":
|
||||
return "chineseCaptcha";
|
||||
case "gif":
|
||||
return "gifCaptcha";
|
||||
default:
|
||||
return "specCaptcha";
|
||||
}
|
||||
}
|
||||
}
|
||||
-182
@@ -1,182 +0,0 @@
|
||||
package com.emotionmuseum.user.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.emotionmuseum.common.result.ResultCode;
|
||||
import com.emotionmuseum.common.util.JwtUtil;
|
||||
import com.emotionmuseum.user.dto.OAuthLoginRequest;
|
||||
import com.emotionmuseum.user.entity.User;
|
||||
import com.emotionmuseum.user.service.CaptchaService;
|
||||
import com.emotionmuseum.user.service.OAuthService;
|
||||
import com.emotionmuseum.user.service.UserService;
|
||||
import com.emotionmuseum.user.vo.LoginResponse;
|
||||
import com.emotionmuseum.user.vo.UserInfoResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhyd.oauth.model.AuthCallback;
|
||||
import me.zhyd.oauth.model.AuthResponse;
|
||||
import me.zhyd.oauth.model.AuthUser;
|
||||
import me.zhyd.oauth.request.AuthQqRequest;
|
||||
import me.zhyd.oauth.request.AuthRequest;
|
||||
import me.zhyd.oauth.request.AuthWeChatMpRequest;
|
||||
import me.zhyd.oauth.request.AuthWeChatOpenRequest;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 第三方登录服务实现
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class OAuthServiceImpl implements OAuthService {
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
private final CaptchaService captchaService;
|
||||
private final UserService userService;
|
||||
private final JwtUtil jwtUtil;
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
private static final String REDIS_TOKEN_KEY_PREFIX = "auth:token:";
|
||||
|
||||
@Override
|
||||
public String getAuthUrl(String platform) {
|
||||
try {
|
||||
AuthRequest authRequest = getAuthRequest(platform);
|
||||
return authRequest.authorize();
|
||||
} catch (Exception e) {
|
||||
log.error("获取第三方登录授权URL失败: {}", e.getMessage());
|
||||
throw new RuntimeException("获取授权URL失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginResponse oauthLogin(OAuthLoginRequest request) {
|
||||
// 验证验证码
|
||||
if (!captchaService.verifyCaptcha(request.getCaptchaId(), request.getCaptcha())) {
|
||||
throw new RuntimeException(ResultCode.CAPTCHA_ERROR.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取第三方用户信息
|
||||
AuthUser authUser = (AuthUser) getOAuthUserInfo(request.getPlatform(), request.getCode(),
|
||||
request.getState());
|
||||
|
||||
if (authUser == null) {
|
||||
throw new RuntimeException("获取第三方用户信息失败");
|
||||
}
|
||||
|
||||
// 查找或创建用户
|
||||
User user = findOrCreateUser(authUser, request.getPlatform());
|
||||
|
||||
// 生成Token
|
||||
String accessToken = jwtUtil.generateToken(user.getId(), user.getUsername());
|
||||
String refreshToken = jwtUtil.generateRefreshToken(user.getId(), user.getUsername());
|
||||
|
||||
// 将token存储到Redis中
|
||||
String redisKey = REDIS_TOKEN_KEY_PREFIX + user.getId();
|
||||
redisTemplate.opsForValue().set(redisKey, accessToken, 24, TimeUnit.HOURS);
|
||||
|
||||
// 更新最后活跃时间
|
||||
userService.updateLastActiveTime(user.getId());
|
||||
|
||||
// 构建响应
|
||||
LoginResponse response = new LoginResponse();
|
||||
response.setAccessToken(accessToken);
|
||||
response.setRefreshToken(refreshToken);
|
||||
response.setExpiresIn(86400L); // 24小时
|
||||
response.setUserInfo(convertToUserInfoResponse(user));
|
||||
response.setLoginTime(LocalDateTime.now());
|
||||
|
||||
log.info("第三方登录成功: {} - {}", request.getPlatform(), user.getId());
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
log.error("第三方登录失败: {}", e.getMessage());
|
||||
throw new RuntimeException("第三方登录失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOAuthUserInfo(String platform, String code, String state) {
|
||||
try {
|
||||
AuthRequest authRequest = getAuthRequest(platform);
|
||||
AuthCallback callback = AuthCallback.builder()
|
||||
.code(code)
|
||||
.state(state)
|
||||
.build();
|
||||
|
||||
AuthResponse<AuthUser> response = authRequest.login(callback);
|
||||
|
||||
if (response.ok()) {
|
||||
return response.getData();
|
||||
} else {
|
||||
log.error("第三方登录失败: {}", response.getMsg());
|
||||
throw new RuntimeException("第三方登录失败: " + response.getMsg());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取第三方用户信息失败: {}", e.getMessage());
|
||||
throw new RuntimeException("获取第三方用户信息失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据平台类型获取AuthRequest
|
||||
*/
|
||||
private AuthRequest getAuthRequest(String platform) {
|
||||
switch (platform.toLowerCase()) {
|
||||
case "wechat":
|
||||
return applicationContext.getBean(AuthWeChatOpenRequest.class);
|
||||
case "wechat-mp":
|
||||
return applicationContext.getBean(AuthWeChatMpRequest.class);
|
||||
case "qq":
|
||||
return applicationContext.getBean(AuthQqRequest.class);
|
||||
default:
|
||||
throw new RuntimeException("不支持的第三方平台: " + platform);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找或创建用户
|
||||
*/
|
||||
private User findOrCreateUser(AuthUser authUser, String platform) {
|
||||
// 根据第三方平台ID查找用户
|
||||
String thirdPartyId = platform + "_" + authUser.getUuid();
|
||||
User existingUser = userService.findByThirdPartyId(thirdPartyId);
|
||||
|
||||
if (existingUser != null) {
|
||||
return existingUser;
|
||||
}
|
||||
|
||||
// 创建新用户
|
||||
User newUser = new User();
|
||||
newUser.setUsername(authUser.getNickname());
|
||||
newUser.setNickname(authUser.getNickname());
|
||||
newUser.setAvatar(authUser.getAvatar());
|
||||
newUser.setEmail(authUser.getEmail());
|
||||
newUser.setThirdPartyId(thirdPartyId);
|
||||
newUser.setThirdPartyType(platform);
|
||||
newUser.setStatus(1); // 启用状态
|
||||
|
||||
// 保存用户
|
||||
userService.save(newUser);
|
||||
|
||||
log.info("创建第三方登录用户: {} - {}", platform, newUser.getId());
|
||||
return newUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为用户信息响应
|
||||
*/
|
||||
private UserInfoResponse convertToUserInfoResponse(User user) {
|
||||
UserInfoResponse response = new UserInfoResponse();
|
||||
BeanUtils.copyProperties(user, response);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
-210
@@ -1,210 +0,0 @@
|
||||
package com.emotionmuseum.user.service.impl;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.emotionmuseum.user.dto.SliderCaptchaResponse;
|
||||
import com.emotionmuseum.user.dto.SliderCaptchaVerifyRequest;
|
||||
import com.emotionmuseum.user.service.SliderCaptchaService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 滑块验证码服务实现
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-15
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SliderCaptchaServiceImpl implements SliderCaptchaService {
|
||||
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
private static final String SLIDER_CAPTCHA_KEY_PREFIX = "slider_captcha:";
|
||||
private static final long SLIDER_CAPTCHA_EXPIRE_TIME = 300; // 5分钟
|
||||
private static final int BACKGROUND_WIDTH = 300;
|
||||
private static final int BACKGROUND_HEIGHT = 150;
|
||||
private static final int SLIDER_WIDTH = 60;
|
||||
private static final int SLIDER_HEIGHT = 60;
|
||||
private static final int TOLERANCE = 5; // 容错范围
|
||||
|
||||
@Override
|
||||
public SliderCaptchaResponse generateSliderCaptcha() {
|
||||
try {
|
||||
String captchaId = IdUtil.simpleUUID();
|
||||
|
||||
// 生成随机位置
|
||||
Random random = new Random();
|
||||
int sliderX = random.nextInt(BACKGROUND_WIDTH - SLIDER_WIDTH - 50) + 50;
|
||||
int sliderY = random.nextInt(BACKGROUND_HEIGHT - SLIDER_HEIGHT - 20) + 20;
|
||||
|
||||
// 生成背景图片
|
||||
BufferedImage backgroundImage = generateBackgroundImage(sliderX, sliderY);
|
||||
String backgroundBase64 = imageToBase64(backgroundImage);
|
||||
|
||||
// 生成滑块图片
|
||||
BufferedImage sliderImage = generateSliderImage();
|
||||
String sliderBase64 = imageToBase64(sliderImage);
|
||||
|
||||
// 存储到Redis
|
||||
String redisKey = SLIDER_CAPTCHA_KEY_PREFIX + captchaId;
|
||||
SliderCaptchaData data = new SliderCaptchaData(sliderX, sliderY);
|
||||
redisTemplate.opsForValue().set(redisKey, data, SLIDER_CAPTCHA_EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
|
||||
log.debug("生成滑块验证码成功,ID: {}, 位置: ({}, {})", captchaId, sliderX, sliderY);
|
||||
|
||||
return new SliderCaptchaResponse(captchaId, backgroundBase64, sliderBase64, 0, sliderY, SLIDER_CAPTCHA_EXPIRE_TIME);
|
||||
} catch (Exception e) {
|
||||
log.error("生成滑块验证码失败: {}", e.getMessage());
|
||||
throw new RuntimeException("生成滑块验证码失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifySliderCaptcha(SliderCaptchaVerifyRequest request) {
|
||||
if (StrUtil.isBlank(request.getCaptchaId()) || request.getX() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
String redisKey = SLIDER_CAPTCHA_KEY_PREFIX + request.getCaptchaId();
|
||||
SliderCaptchaData data = (SliderCaptchaData) redisTemplate.opsForValue().get(redisKey);
|
||||
|
||||
if (data == null) {
|
||||
log.warn("滑块验证码已过期或不存在,ID: {}", request.getCaptchaId());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 验证X坐标是否在容错范围内
|
||||
boolean isValid = Math.abs(data.getSliderX() - request.getX()) <= TOLERANCE;
|
||||
|
||||
if (isValid) {
|
||||
// 验证成功后删除验证码
|
||||
redisTemplate.delete(redisKey);
|
||||
log.debug("滑块验证码验证成功,ID: {}", request.getCaptchaId());
|
||||
} else {
|
||||
log.warn("滑块验证码验证失败,ID: {}, 期望X: {}, 实际X: {}",
|
||||
request.getCaptchaId(), data.getSliderX(), request.getX());
|
||||
}
|
||||
|
||||
return isValid;
|
||||
} catch (Exception e) {
|
||||
log.error("验证滑块验证码失败: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSliderCaptcha(String captchaId) {
|
||||
if (StrUtil.isNotBlank(captchaId)) {
|
||||
String redisKey = SLIDER_CAPTCHA_KEY_PREFIX + captchaId;
|
||||
redisTemplate.delete(redisKey);
|
||||
log.debug("删除滑块验证码,ID: {}", captchaId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成背景图片
|
||||
*/
|
||||
private BufferedImage generateBackgroundImage(int sliderX, int sliderY) {
|
||||
BufferedImage image = new BufferedImage(BACKGROUND_WIDTH, BACKGROUND_HEIGHT, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g2d = image.createGraphics();
|
||||
|
||||
// 设置抗锯齿
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
// 绘制渐变背景
|
||||
GradientPaint gradient = new GradientPaint(0, 0, new Color(135, 206, 250),
|
||||
BACKGROUND_WIDTH, BACKGROUND_HEIGHT, new Color(70, 130, 180));
|
||||
g2d.setPaint(gradient);
|
||||
g2d.fillRect(0, 0, BACKGROUND_WIDTH, BACKGROUND_HEIGHT);
|
||||
|
||||
// 绘制一些装饰性图形
|
||||
Random random = new Random();
|
||||
g2d.setColor(new Color(255, 255, 255, 100));
|
||||
for (int i = 0; i < 20; i++) {
|
||||
int x = random.nextInt(BACKGROUND_WIDTH);
|
||||
int y = random.nextInt(BACKGROUND_HEIGHT);
|
||||
int size = random.nextInt(20) + 5;
|
||||
g2d.fillOval(x, y, size, size);
|
||||
}
|
||||
|
||||
// 绘制滑块缺口
|
||||
g2d.setColor(new Color(0, 0, 0, 150));
|
||||
g2d.fillRoundRect(sliderX, sliderY, SLIDER_WIDTH, SLIDER_HEIGHT, 10, 10);
|
||||
|
||||
g2d.dispose();
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成滑块图片
|
||||
*/
|
||||
private BufferedImage generateSliderImage() {
|
||||
BufferedImage image = new BufferedImage(SLIDER_WIDTH, SLIDER_HEIGHT, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = image.createGraphics();
|
||||
|
||||
// 设置抗锯齿
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
// 绘制滑块
|
||||
g2d.setColor(new Color(70, 130, 180));
|
||||
g2d.fillRoundRect(0, 0, SLIDER_WIDTH, SLIDER_HEIGHT, 10, 10);
|
||||
|
||||
// 绘制边框
|
||||
g2d.setColor(new Color(255, 255, 255));
|
||||
g2d.setStroke(new BasicStroke(2));
|
||||
g2d.drawRoundRect(1, 1, SLIDER_WIDTH - 2, SLIDER_HEIGHT - 2, 10, 10);
|
||||
|
||||
// 绘制箭头
|
||||
g2d.setColor(Color.WHITE);
|
||||
int[] xPoints = {SLIDER_WIDTH/2 - 8, SLIDER_WIDTH/2 + 8, SLIDER_WIDTH/2};
|
||||
int[] yPoints = {SLIDER_HEIGHT/2, SLIDER_HEIGHT/2, SLIDER_HEIGHT/2 - 8};
|
||||
g2d.fillPolygon(xPoints, yPoints, 3);
|
||||
|
||||
g2d.dispose();
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片转Base64
|
||||
*/
|
||||
private String imageToBase64(BufferedImage image) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(image, "PNG", baos);
|
||||
byte[] bytes = baos.toByteArray();
|
||||
return "data:image/png;base64," + Base64.getEncoder().encodeToString(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 滑块验证码数据
|
||||
*/
|
||||
public static class SliderCaptchaData {
|
||||
private int sliderX;
|
||||
private int sliderY;
|
||||
|
||||
public SliderCaptchaData() {}
|
||||
|
||||
public SliderCaptchaData(int sliderX, int sliderY) {
|
||||
this.sliderX = sliderX;
|
||||
this.sliderY = sliderY;
|
||||
}
|
||||
|
||||
public int getSliderX() { return sliderX; }
|
||||
public void setSliderX(int sliderX) { this.sliderX = sliderX; }
|
||||
public int getSliderY() { return sliderY; }
|
||||
public void setSliderY(int sliderY) { this.sliderY = sliderY; }
|
||||
}
|
||||
}
|
||||
+2
-239
@@ -1,30 +1,17 @@
|
||||
package com.emotionmuseum.user.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.emotionmuseum.common.result.ResultCode;
|
||||
import com.emotionmuseum.common.util.JwtUtil;
|
||||
import com.emotionmuseum.user.dto.LoginRequest;
|
||||
import com.emotionmuseum.user.dto.RegisterRequest;
|
||||
import com.emotionmuseum.user.dto.UserUpdateRequest;
|
||||
import com.emotionmuseum.user.entity.User;
|
||||
import com.emotionmuseum.user.mapper.UserMapper;
|
||||
import com.emotionmuseum.user.service.UserService;
|
||||
import com.emotionmuseum.user.vo.LoginResponse;
|
||||
import com.emotionmuseum.user.vo.UserInfoResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import com.emotionmuseum.user.service.CaptchaService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 用户服务实现类
|
||||
*
|
||||
@@ -36,156 +23,11 @@ import java.time.LocalDateTime;
|
||||
@RequiredArgsConstructor
|
||||
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
|
||||
|
||||
private final JwtUtil jwtUtil;
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final CaptchaService captchaService;
|
||||
|
||||
private static final String REDIS_TOKEN_KEY_PREFIX = "auth:token:";
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public UserInfoResponse register(RegisterRequest request) {
|
||||
// 验证验证码
|
||||
if (!captchaService.verifyCaptcha(request.getCaptchaId(), request.getCaptcha())) {
|
||||
throw new RuntimeException(ResultCode.CAPTCHA_ERROR.getMessage());
|
||||
}
|
||||
|
||||
// 验证密码一致性
|
||||
if (!request.isPasswordMatch()) {
|
||||
throw new RuntimeException(ResultCode.PARAM_VALIDATION_ERROR.getMessage() + ": 两次密码不一致");
|
||||
}
|
||||
|
||||
// 检查账号是否存在
|
||||
if (existsByAccount(request.getAccount())) {
|
||||
throw new RuntimeException(ResultCode.ACCOUNT_ALREADY_EXISTS.getMessage());
|
||||
}
|
||||
|
||||
// 检查邮箱是否存在
|
||||
if (existsByEmail(request.getEmail())) {
|
||||
throw new RuntimeException(ResultCode.EMAIL_ALREADY_EXISTS.getMessage());
|
||||
}
|
||||
|
||||
// 检查手机号是否存在
|
||||
if (StrUtil.isNotBlank(request.getPhone()) && existsByPhone(request.getPhone())) {
|
||||
throw new RuntimeException(ResultCode.PHONE_ALREADY_EXISTS.getMessage());
|
||||
}
|
||||
|
||||
// 创建用户
|
||||
User user = new User();
|
||||
BeanUtils.copyProperties(request, user);
|
||||
|
||||
// 加密密码
|
||||
user.setPassword(passwordEncoder.encode(request.getPassword()));
|
||||
|
||||
// 设置默认值
|
||||
user.setMemberLevel("free");
|
||||
user.setTotalDays(0);
|
||||
user.setSelfAwareness(new BigDecimal("50.00"));
|
||||
user.setEmotionalResilience(new BigDecimal("50.00"));
|
||||
user.setActionPower(new BigDecimal("50.00"));
|
||||
user.setEmpathy(new BigDecimal("50.00"));
|
||||
user.setLifeEnthusiasm(new BigDecimal("50.00"));
|
||||
user.setStatus(1);
|
||||
user.setIsVerified(0);
|
||||
user.setLastActiveTime(LocalDateTime.now());
|
||||
|
||||
// 保存用户
|
||||
save(user);
|
||||
|
||||
log.info("用户注册成功: {}", user.getAccount());
|
||||
return convertToUserInfoResponse(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginResponse login(LoginRequest request) {
|
||||
// 验证验证码
|
||||
if (!captchaService.verifyCaptcha(request.getCaptchaId(), request.getCaptcha())) {
|
||||
throw new RuntimeException(ResultCode.CAPTCHA_ERROR.getMessage());
|
||||
}
|
||||
|
||||
// 查找用户(支持账号/邮箱/手机号登录)
|
||||
User user = findUserByAccount(request.getAccount());
|
||||
if (user == null) {
|
||||
throw new RuntimeException(ResultCode.USER_NOT_FOUND.getMessage());
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
|
||||
throw new RuntimeException(ResultCode.INVALID_CREDENTIALS.getMessage());
|
||||
}
|
||||
|
||||
// 检查用户状态
|
||||
if (user.getStatus() == 0) {
|
||||
throw new RuntimeException(ResultCode.USER_DISABLED.getMessage());
|
||||
}
|
||||
|
||||
// 生成Token
|
||||
String accessToken = jwtUtil.generateToken(user.getId(), user.getUsername());
|
||||
String refreshToken = jwtUtil.generateRefreshToken(user.getId(), user.getUsername());
|
||||
|
||||
// 将token存储到Redis中(用于登出和token管理)
|
||||
String redisKey = REDIS_TOKEN_KEY_PREFIX + user.getId();
|
||||
redisTemplate.opsForValue().set(redisKey, accessToken, 24, java.util.concurrent.TimeUnit.HOURS);
|
||||
|
||||
// 更新最后活跃时间
|
||||
updateLastActiveTime(user.getId());
|
||||
|
||||
// 构建响应
|
||||
LoginResponse response = new LoginResponse();
|
||||
response.setAccessToken(accessToken);
|
||||
response.setRefreshToken(refreshToken);
|
||||
response.setExpiresIn(86400L); // 24小时
|
||||
response.setUserInfo(convertToUserInfoResponse(user));
|
||||
response.setLoginTime(LocalDateTime.now());
|
||||
|
||||
log.info("用户登录成功: {}", user.getAccount());
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginResponse refreshToken(String refreshToken) {
|
||||
if (!jwtUtil.validateToken(refreshToken)) {
|
||||
throw new RuntimeException(ResultCode.REFRESH_TOKEN_INVALID.getMessage());
|
||||
}
|
||||
|
||||
String userId = jwtUtil.getUserIdFromToken(refreshToken);
|
||||
String username = jwtUtil.getUsernameFromToken(refreshToken);
|
||||
|
||||
if (StrUtil.isBlank(userId) || StrUtil.isBlank(username)) {
|
||||
throw new RuntimeException(ResultCode.REFRESH_TOKEN_INVALID.getMessage());
|
||||
}
|
||||
|
||||
// 生成新Token
|
||||
String newAccessToken = jwtUtil.generateToken(userId, username);
|
||||
String newRefreshToken = jwtUtil.generateRefreshToken(userId, username);
|
||||
|
||||
// 更新Redis中的token
|
||||
String redisKey = REDIS_TOKEN_KEY_PREFIX + userId;
|
||||
redisTemplate.opsForValue().set(redisKey, newAccessToken, 24, java.util.concurrent.TimeUnit.HOURS);
|
||||
|
||||
// 获取用户信息
|
||||
User user = getById(userId);
|
||||
if (user == null) {
|
||||
throw new RuntimeException(ResultCode.USER_NOT_FOUND.getMessage());
|
||||
}
|
||||
|
||||
// 构建响应
|
||||
LoginResponse response = new LoginResponse();
|
||||
response.setAccessToken(newAccessToken);
|
||||
response.setRefreshToken(newRefreshToken);
|
||||
response.setExpiresIn(86400L);
|
||||
response.setUserInfo(convertToUserInfoResponse(user));
|
||||
response.setLoginTime(LocalDateTime.now());
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserInfoResponse getUserInfo(String userId) {
|
||||
User user = getById(userId);
|
||||
if (user == null) {
|
||||
throw new RuntimeException(ResultCode.USER_NOT_FOUND.getMessage());
|
||||
throw new RuntimeException("用户不存在");
|
||||
}
|
||||
return convertToUserInfoResponse(user);
|
||||
}
|
||||
@@ -195,21 +37,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
public UserInfoResponse updateUserInfo(String userId, UserUpdateRequest request) {
|
||||
User user = getById(userId);
|
||||
if (user == null) {
|
||||
throw new RuntimeException(ResultCode.USER_NOT_FOUND.getMessage());
|
||||
}
|
||||
|
||||
// 检查邮箱是否被其他用户使用
|
||||
if (StrUtil.isNotBlank(request.getEmail()) && !request.getEmail().equals(user.getEmail())) {
|
||||
if (existsByEmail(request.getEmail())) {
|
||||
throw new RuntimeException(ResultCode.EMAIL_ALREADY_EXISTS.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 检查手机号是否被其他用户使用
|
||||
if (StrUtil.isNotBlank(request.getPhone()) && !request.getPhone().equals(user.getPhone())) {
|
||||
if (existsByPhone(request.getPhone())) {
|
||||
throw new RuntimeException(ResultCode.PHONE_ALREADY_EXISTS.getMessage());
|
||||
}
|
||||
throw new RuntimeException("用户不存在");
|
||||
}
|
||||
|
||||
// 更新用户信息
|
||||
@@ -220,76 +48,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
return convertToUserInfoResponse(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsByAccount(String account) {
|
||||
return baseMapper.selectByAccount(account) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsByEmail(String email) {
|
||||
return baseMapper.selectByEmail(email) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsByPhone(String phone) {
|
||||
return StrUtil.isNotBlank(phone) && baseMapper.selectByPhone(phone) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLastActiveTime(String userId) {
|
||||
baseMapper.updateLastActiveTime(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout(String userId) {
|
||||
// 从Redis中删除token
|
||||
String redisKey = REDIS_TOKEN_KEY_PREFIX + userId;
|
||||
redisTemplate.delete(redisKey);
|
||||
log.info("用户登出成功: {}", userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User findByThirdPartyId(String thirdPartyId) {
|
||||
if (StrUtil.isBlank(thirdPartyId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(User::getThirdPartyId, thirdPartyId);
|
||||
queryWrapper.eq(User::getIsDeleted, 0);
|
||||
|
||||
return getOne(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据账号查找用户(支持账号/邮箱/手机号)
|
||||
*/
|
||||
private User findUserByAccount(String account) {
|
||||
// 先按账号查找
|
||||
User user = baseMapper.selectByAccount(account);
|
||||
if (user != null) {
|
||||
return user;
|
||||
}
|
||||
|
||||
// 按邮箱查找
|
||||
if (account.contains("@")) {
|
||||
user = baseMapper.selectByEmail(account);
|
||||
if (user != null) {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
// 按手机号查找
|
||||
if (account.matches("^1[3-9]\\d{9}$")) {
|
||||
user = baseMapper.selectByPhone(account);
|
||||
if (user != null) {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为用户信息响应
|
||||
*/
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.emotionmuseum.user.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 登录响应
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @since 2025-07-12
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "登录响应")
|
||||
public class LoginResponse {
|
||||
|
||||
@Schema(description = "访问Token")
|
||||
private String accessToken;
|
||||
|
||||
@Schema(description = "刷新Token")
|
||||
private String refreshToken;
|
||||
|
||||
@Schema(description = "Token类型", example = "Bearer")
|
||||
private String tokenType = "Bearer";
|
||||
|
||||
@Schema(description = "Token过期时间(秒)", example = "86400")
|
||||
private Long expiresIn;
|
||||
|
||||
@Schema(description = "用户信息")
|
||||
private UserInfoResponse userInfo;
|
||||
|
||||
@Schema(description = "登录时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime loginTime;
|
||||
}
|
||||
@@ -1,102 +1,55 @@
|
||||
server:
|
||||
port: 19001
|
||||
# 本地开发环境配置
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: emotion-user
|
||||
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
namespace:
|
||||
group: DEFAULT_GROUP
|
||||
enabled: true
|
||||
username: nacos
|
||||
password: Peanut2817*#
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
zone: local
|
||||
register-enabled: true
|
||||
ephemeral: true
|
||||
cluster-name: DEFAULT
|
||||
service: ${spring.application.name}
|
||||
weight: 1
|
||||
heart-beat-interval: 5000
|
||||
heart-beat-timeout: 15000
|
||||
ip-delete-timeout: 30000
|
||||
config:
|
||||
server-addr: localhost:8848
|
||||
namespace:
|
||||
group: DEFAULT_GROUP
|
||||
file-extension: yml
|
||||
enabled: false
|
||||
username: nacos
|
||||
password: Peanut2817*#
|
||||
|
||||
# 数据源配置
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/emotion_museum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: 123456
|
||||
|
||||
|
||||
# Redis配置
|
||||
data:
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
password:
|
||||
password:
|
||||
database: 0
|
||||
timeout: 10000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 8
|
||||
max-wait: -1ms
|
||||
max-idle: 8
|
||||
min-idle: 0
|
||||
|
||||
# MyBatis Plus配置
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
logic-delete-field: isDeleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
|
||||
# Nacos配置
|
||||
spring:
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
namespace:
|
||||
group: DEFAULT_GROUP
|
||||
enabled: true
|
||||
register-enabled: true
|
||||
heart-beat-interval: 5000
|
||||
heart-beat-timeout: 15000
|
||||
ip-delete-timeout: 30000
|
||||
config:
|
||||
server-addr: localhost:8848
|
||||
namespace:
|
||||
group: DEFAULT_GROUP
|
||||
file-extension: yml
|
||||
enabled: false
|
||||
|
||||
# JWT配置
|
||||
jwt:
|
||||
secret: emotion-museum-secret-key-2025-local
|
||||
expiration: 86400
|
||||
refresh-expiration: 604800
|
||||
|
||||
# 第三方登录配置
|
||||
oauth:
|
||||
wechat:
|
||||
client-id: ${WECHAT_CLIENT_ID:your_wechat_client_id}
|
||||
client-secret: ${WECHAT_CLIENT_SECRET:your_wechat_client_secret}
|
||||
redirect-uri: ${WECHAT_REDIRECT_URI:http://localhost:19001/oauth/callback/wechat}
|
||||
wechat-mp:
|
||||
client-id: ${WECHAT_MP_CLIENT_ID:your_wechat_mp_client_id}
|
||||
client-secret: ${WECHAT_MP_CLIENT_SECRET:your_wechat_mp_client_secret}
|
||||
redirect-uri: ${WECHAT_MP_REDIRECT_URI:http://localhost:19001/oauth/callback/wechat-mp}
|
||||
qq:
|
||||
client-id: ${QQ_CLIENT_ID:your_qq_client_id}
|
||||
client-secret: ${QQ_CLIENT_SECRET:your_qq_client_secret}
|
||||
redirect-uri: ${QQ_REDIRECT_URI:http://localhost:19001/oauth/callback/qq}
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.emotionmuseum: debug
|
||||
org.springframework.security: debug
|
||||
org.springframework.web: debug
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n"
|
||||
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n"
|
||||
com.baomidou.mybatisplus: debug
|
||||
com.alibaba.nacos: info
|
||||
file:
|
||||
name: logs/emotion-user-local.log
|
||||
|
||||
# 管理端点配置
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# 本地开发环境配置
|
||||
|
||||
spring:
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
namespace:
|
||||
group: DEFAULT_GROUP
|
||||
enabled: true
|
||||
username: nacos
|
||||
password: nacos
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
zone: local
|
||||
register-enabled: true
|
||||
ephemeral: true
|
||||
cluster-name: DEFAULT
|
||||
service: ${spring.application.name}
|
||||
weight: 1
|
||||
heart-beat-interval: 5000
|
||||
heart-beat-timeout: 15000
|
||||
ip-delete-timeout: 30000
|
||||
config:
|
||||
server-addr: localhost:8848
|
||||
namespace:
|
||||
group: DEFAULT_GROUP
|
||||
file-extension: yml
|
||||
enabled: false
|
||||
username: nacos
|
||||
password: nacos
|
||||
|
||||
# 数据源配置
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/emotion_museum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: 123456
|
||||
|
||||
# Redis配置
|
||||
data:
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
password:
|
||||
database: 0
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.emotionmuseum: debug
|
||||
com.baomidou.mybatisplus: debug
|
||||
com.alibaba.nacos: info
|
||||
file:
|
||||
name: logs/emotion-user-local.log
|
||||
@@ -1,75 +1,55 @@
|
||||
server:
|
||||
port: 9001
|
||||
# 生产环境配置
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: emotion-user
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
|
||||
namespace: public
|
||||
server-addr: 47.111.10.27:8848
|
||||
namespace: prod
|
||||
group: DEFAULT_GROUP
|
||||
enabled: true
|
||||
ip: ${SERVER_IP:localhost}
|
||||
username: nacos
|
||||
password: EmotionMuseum2025
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
environment: prod
|
||||
zone: prod
|
||||
register-enabled: true
|
||||
ephemeral: true
|
||||
cluster-name: DEFAULT
|
||||
service: ${spring.application.name}
|
||||
weight: 1
|
||||
heart-beat-interval: 5000
|
||||
heart-beat-timeout: 15000
|
||||
ip-delete-timeout: 30000
|
||||
config:
|
||||
server-addr: 47.111.10.27:8848
|
||||
namespace: prod
|
||||
group: DEFAULT_GROUP
|
||||
file-extension: yml
|
||||
enabled: false
|
||||
username: nacos
|
||||
password: EmotionMuseum2025
|
||||
|
||||
# 数据源配置
|
||||
datasource:
|
||||
url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:emotion_museum}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: ${MYSQL_USERNAME:emotion}
|
||||
password: ${MYSQL_PASSWORD:EmotionDB2024!}
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
hikari:
|
||||
minimum-idle: 5
|
||||
maximum-pool-size: 20
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
url: jdbc:mysql://47.111.10.27:3306/emotion_museum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: EmotionMuseum2025*#
|
||||
|
||||
# Redis配置
|
||||
data:
|
||||
redis:
|
||||
host: ${REDIS_HOST:localhost}
|
||||
port: ${REDIS_PORT:6379}
|
||||
host: 47.111.10.27
|
||||
port: 6379
|
||||
password: EmotionMuseum2025*#
|
||||
database: 0
|
||||
timeout: 3000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 20
|
||||
max-idle: 10
|
||||
min-idle: 5
|
||||
max-wait: 3000ms
|
||||
|
||||
# MyBatis Plus配置
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: input
|
||||
logic-delete-field: is_deleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
mapper-locations: classpath*:mapper/*.xml
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.emotionmuseum: INFO
|
||||
com.baomidou.mybatisplus: DEBUG
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
|
||||
|
||||
# 管理端点
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
com.emotionmuseum: warn
|
||||
com.baomidou.mybatisplus: warn
|
||||
com.alibaba.nacos: error
|
||||
file:
|
||||
name: logs/emotion-user-prod.log
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# 测试环境配置
|
||||
|
||||
spring:
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: 47.111.10.27:8848
|
||||
namespace: test
|
||||
group: DEFAULT_GROUP
|
||||
enabled: true
|
||||
username: nacos
|
||||
password: EmotionMuseum2025
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
zone: test
|
||||
register-enabled: true
|
||||
ephemeral: true
|
||||
cluster-name: DEFAULT
|
||||
service: ${spring.application.name}
|
||||
weight: 1
|
||||
heart-beat-interval: 5000
|
||||
heart-beat-timeout: 15000
|
||||
ip-delete-timeout: 30000
|
||||
config:
|
||||
server-addr: 47.111.10.27:8848
|
||||
namespace: test
|
||||
group: DEFAULT_GROUP
|
||||
file-extension: yml
|
||||
enabled: false
|
||||
username: nacos
|
||||
password: EmotionMuseum2025
|
||||
|
||||
# 数据源配置
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://47.111.10.27:3306/emotion_museum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: EmotionMuseum2025*#
|
||||
|
||||
# Redis配置
|
||||
data:
|
||||
redis:
|
||||
host: 47.111.10.27
|
||||
port: 6379
|
||||
password: EmotionMuseum2025*#
|
||||
database: 0
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.emotionmuseum: info
|
||||
com.baomidou.mybatisplus: info
|
||||
com.alibaba.nacos: warn
|
||||
file:
|
||||
name: logs/emotion-user-test.log
|
||||
@@ -4,40 +4,74 @@ server:
|
||||
spring:
|
||||
application:
|
||||
name: emotion-user
|
||||
|
||||
# 配置文件激活
|
||||
profiles:
|
||||
active: dev
|
||||
active: ${SPRING_PROFILES_ACTIVE:local}
|
||||
|
||||
# 允许Bean覆盖和循环引用
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
allow-circular-references: true
|
||||
|
||||
# 数据源配置
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/emotion_museum?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: 123456
|
||||
url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:emotion_museum}?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: ${MYSQL_USERNAME:root}
|
||||
password: ${MYSQL_PASSWORD:123456}
|
||||
hikari:
|
||||
minimum-idle: 5
|
||||
maximum-pool-size: 20
|
||||
idle-timeout: 600000
|
||||
idle-timeout: 30000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
connection-test-query: SELECT 1
|
||||
|
||||
# Redis配置
|
||||
data:
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
host: ${REDIS_HOST:localhost}
|
||||
port: ${REDIS_PORT:6379}
|
||||
password: ${REDIS_PASSWORD:}
|
||||
database: 0
|
||||
timeout: 3000ms
|
||||
timeout: 10000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 20
|
||||
max-idle: 10
|
||||
min-idle: 5
|
||||
max-wait: 3000ms
|
||||
max-active: 8
|
||||
max-wait: -1ms
|
||||
max-idle: 8
|
||||
min-idle: 0
|
||||
|
||||
# Nacos配置
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
namespace: emotion-dev
|
||||
group: DEFAULT_GROUP
|
||||
enabled: false
|
||||
server-addr: ${NACOS_HOST:localhost}:${NACOS_PORT:8848}
|
||||
namespace: ${NACOS_NAMESPACE:}
|
||||
group: ${NACOS_GROUP:DEFAULT_GROUP}
|
||||
enabled: ${NACOS_DISCOVERY_ENABLED:true}
|
||||
username: ${NACOS_USERNAME:nacos}
|
||||
password: ${NACOS_PASSWORD:nacos}
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
zone: ${NACOS_ZONE:default}
|
||||
register-enabled: true
|
||||
ephemeral: true
|
||||
cluster-name: DEFAULT
|
||||
service: ${spring.application.name}
|
||||
weight: 1
|
||||
heart-beat-interval: 5000
|
||||
heart-beat-timeout: 15000
|
||||
ip-delete-timeout: 30000
|
||||
config:
|
||||
enabled: false
|
||||
server-addr: ${NACOS_HOST:localhost}:${NACOS_PORT:8848}
|
||||
namespace: ${NACOS_NAMESPACE:}
|
||||
group: ${NACOS_GROUP:DEFAULT_GROUP}
|
||||
file-extension: yml
|
||||
enabled: ${NACOS_CONFIG_ENABLED:false}
|
||||
username: ${NACOS_USERNAME:nacos}
|
||||
password: ${NACOS_PASSWORD:nacos}
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
|
||||
@@ -2,18 +2,6 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.emotionmuseum.user.mapper.UserMapper">
|
||||
|
||||
<!-- 根据账号查询用户 -->
|
||||
<select id="selectByAccount" resultType="com.emotionmuseum.user.entity.User"> SELECT * FROM user
|
||||
WHERE account = #{account} AND is_deleted = 0 </select>
|
||||
|
||||
<!-- 根据邮箱查询用户 -->
|
||||
<select id="selectByEmail" resultType="com.emotionmuseum.user.entity.User"> SELECT * FROM user
|
||||
WHERE email = #{email} AND is_deleted = 0 </select>
|
||||
|
||||
<!-- 根据手机号查询用户 -->
|
||||
<select id="selectByPhone" resultType="com.emotionmuseum.user.entity.User"> SELECT * FROM user
|
||||
WHERE phone = #{phone} AND is_deleted = 0 </select>
|
||||
|
||||
<!-- 更新最后活跃时间 -->
|
||||
<update id="updateLastActiveTime"> UPDATE user SET last_active_time = NOW(), update_time = NOW()
|
||||
WHERE id = #{userId} AND is_deleted = 0 </update>
|
||||
|
||||
@@ -1,102 +1,55 @@
|
||||
server:
|
||||
port: 19001
|
||||
# 本地开发环境配置
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: emotion-user
|
||||
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
namespace:
|
||||
group: DEFAULT_GROUP
|
||||
enabled: true
|
||||
username: nacos
|
||||
password: Peanut2817*#
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
zone: local
|
||||
register-enabled: true
|
||||
ephemeral: true
|
||||
cluster-name: DEFAULT
|
||||
service: ${spring.application.name}
|
||||
weight: 1
|
||||
heart-beat-interval: 5000
|
||||
heart-beat-timeout: 15000
|
||||
ip-delete-timeout: 30000
|
||||
config:
|
||||
server-addr: localhost:8848
|
||||
namespace:
|
||||
group: DEFAULT_GROUP
|
||||
file-extension: yml
|
||||
enabled: false
|
||||
username: nacos
|
||||
password: Peanut2817*#
|
||||
|
||||
# 数据源配置
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/emotion_museum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: 123456
|
||||
|
||||
|
||||
# Redis配置
|
||||
data:
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
password:
|
||||
password:
|
||||
database: 0
|
||||
timeout: 10000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 8
|
||||
max-wait: -1ms
|
||||
max-idle: 8
|
||||
min-idle: 0
|
||||
|
||||
# MyBatis Plus配置
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
logic-delete-field: isDeleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
|
||||
# Nacos配置
|
||||
spring:
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
namespace:
|
||||
group: DEFAULT_GROUP
|
||||
enabled: true
|
||||
register-enabled: true
|
||||
heart-beat-interval: 5000
|
||||
heart-beat-timeout: 15000
|
||||
ip-delete-timeout: 30000
|
||||
config:
|
||||
server-addr: localhost:8848
|
||||
namespace:
|
||||
group: DEFAULT_GROUP
|
||||
file-extension: yml
|
||||
enabled: false
|
||||
|
||||
# JWT配置
|
||||
jwt:
|
||||
secret: emotion-museum-secret-key-2025-local
|
||||
expiration: 86400
|
||||
refresh-expiration: 604800
|
||||
|
||||
# 第三方登录配置
|
||||
oauth:
|
||||
wechat:
|
||||
client-id: ${WECHAT_CLIENT_ID:your_wechat_client_id}
|
||||
client-secret: ${WECHAT_CLIENT_SECRET:your_wechat_client_secret}
|
||||
redirect-uri: ${WECHAT_REDIRECT_URI:http://localhost:19001/oauth/callback/wechat}
|
||||
wechat-mp:
|
||||
client-id: ${WECHAT_MP_CLIENT_ID:your_wechat_mp_client_id}
|
||||
client-secret: ${WECHAT_MP_CLIENT_SECRET:your_wechat_mp_client_secret}
|
||||
redirect-uri: ${WECHAT_MP_REDIRECT_URI:http://localhost:19001/oauth/callback/wechat-mp}
|
||||
qq:
|
||||
client-id: ${QQ_CLIENT_ID:your_qq_client_id}
|
||||
client-secret: ${QQ_CLIENT_SECRET:your_qq_client_secret}
|
||||
redirect-uri: ${QQ_REDIRECT_URI:http://localhost:19001/oauth/callback/qq}
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.emotionmuseum: debug
|
||||
org.springframework.security: debug
|
||||
org.springframework.web: debug
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n"
|
||||
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n"
|
||||
com.baomidou.mybatisplus: debug
|
||||
com.alibaba.nacos: info
|
||||
file:
|
||||
name: logs/emotion-user-local.log
|
||||
|
||||
# 管理端点配置
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# 本地开发环境配置
|
||||
|
||||
spring:
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
namespace:
|
||||
group: DEFAULT_GROUP
|
||||
enabled: true
|
||||
username: nacos
|
||||
password: nacos
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
zone: local
|
||||
register-enabled: true
|
||||
ephemeral: true
|
||||
cluster-name: DEFAULT
|
||||
service: ${spring.application.name}
|
||||
weight: 1
|
||||
heart-beat-interval: 5000
|
||||
heart-beat-timeout: 15000
|
||||
ip-delete-timeout: 30000
|
||||
config:
|
||||
server-addr: localhost:8848
|
||||
namespace:
|
||||
group: DEFAULT_GROUP
|
||||
file-extension: yml
|
||||
enabled: false
|
||||
username: nacos
|
||||
password: nacos
|
||||
|
||||
# 数据源配置
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/emotion_museum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: 123456
|
||||
|
||||
# Redis配置
|
||||
data:
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
password:
|
||||
database: 0
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.emotionmuseum: debug
|
||||
com.baomidou.mybatisplus: debug
|
||||
com.alibaba.nacos: info
|
||||
file:
|
||||
name: logs/emotion-user-local.log
|
||||
@@ -1,75 +1,55 @@
|
||||
server:
|
||||
port: 9001
|
||||
# 生产环境配置
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: emotion-user
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
|
||||
namespace: public
|
||||
server-addr: 47.111.10.27:8848
|
||||
namespace: prod
|
||||
group: DEFAULT_GROUP
|
||||
enabled: true
|
||||
ip: ${SERVER_IP:localhost}
|
||||
username: nacos
|
||||
password: EmotionMuseum2025
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
environment: prod
|
||||
zone: prod
|
||||
register-enabled: true
|
||||
ephemeral: true
|
||||
cluster-name: DEFAULT
|
||||
service: ${spring.application.name}
|
||||
weight: 1
|
||||
heart-beat-interval: 5000
|
||||
heart-beat-timeout: 15000
|
||||
ip-delete-timeout: 30000
|
||||
config:
|
||||
server-addr: 47.111.10.27:8848
|
||||
namespace: prod
|
||||
group: DEFAULT_GROUP
|
||||
file-extension: yml
|
||||
enabled: false
|
||||
username: nacos
|
||||
password: EmotionMuseum2025
|
||||
|
||||
# 数据源配置
|
||||
datasource:
|
||||
url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:emotion_museum}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: ${MYSQL_USERNAME:emotion}
|
||||
password: ${MYSQL_PASSWORD:EmotionDB2024!}
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
hikari:
|
||||
minimum-idle: 5
|
||||
maximum-pool-size: 20
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
url: jdbc:mysql://47.111.10.27:3306/emotion_museum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: EmotionMuseum2025*#
|
||||
|
||||
# Redis配置
|
||||
data:
|
||||
redis:
|
||||
host: ${REDIS_HOST:localhost}
|
||||
port: ${REDIS_PORT:6379}
|
||||
host: 47.111.10.27
|
||||
port: 6379
|
||||
password: EmotionMuseum2025*#
|
||||
database: 0
|
||||
timeout: 3000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 20
|
||||
max-idle: 10
|
||||
min-idle: 5
|
||||
max-wait: 3000ms
|
||||
|
||||
# MyBatis Plus配置
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: input
|
||||
logic-delete-field: is_deleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
mapper-locations: classpath*:mapper/*.xml
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.emotionmuseum: INFO
|
||||
com.baomidou.mybatisplus: DEBUG
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
|
||||
|
||||
# 管理端点
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
com.emotionmuseum: warn
|
||||
com.baomidou.mybatisplus: warn
|
||||
com.alibaba.nacos: error
|
||||
file:
|
||||
name: logs/emotion-user-prod.log
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# 测试环境配置
|
||||
|
||||
spring:
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: 47.111.10.27:8848
|
||||
namespace: test
|
||||
group: DEFAULT_GROUP
|
||||
enabled: true
|
||||
username: nacos
|
||||
password: EmotionMuseum2025
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
zone: test
|
||||
register-enabled: true
|
||||
ephemeral: true
|
||||
cluster-name: DEFAULT
|
||||
service: ${spring.application.name}
|
||||
weight: 1
|
||||
heart-beat-interval: 5000
|
||||
heart-beat-timeout: 15000
|
||||
ip-delete-timeout: 30000
|
||||
config:
|
||||
server-addr: 47.111.10.27:8848
|
||||
namespace: test
|
||||
group: DEFAULT_GROUP
|
||||
file-extension: yml
|
||||
enabled: false
|
||||
username: nacos
|
||||
password: EmotionMuseum2025
|
||||
|
||||
# 数据源配置
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://47.111.10.27:3306/emotion_museum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: EmotionMuseum2025*#
|
||||
|
||||
# Redis配置
|
||||
data:
|
||||
redis:
|
||||
host: 47.111.10.27
|
||||
port: 6379
|
||||
password: EmotionMuseum2025*#
|
||||
database: 0
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.emotionmuseum: info
|
||||
com.baomidou.mybatisplus: info
|
||||
com.alibaba.nacos: warn
|
||||
file:
|
||||
name: logs/emotion-user-test.log
|
||||
@@ -4,40 +4,74 @@ server:
|
||||
spring:
|
||||
application:
|
||||
name: emotion-user
|
||||
|
||||
# 配置文件激活
|
||||
profiles:
|
||||
active: dev
|
||||
active: ${SPRING_PROFILES_ACTIVE:local}
|
||||
|
||||
# 允许Bean覆盖和循环引用
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
allow-circular-references: true
|
||||
|
||||
# 数据源配置
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/emotion_museum?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: 123456
|
||||
url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:emotion_museum}?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: ${MYSQL_USERNAME:root}
|
||||
password: ${MYSQL_PASSWORD:123456}
|
||||
hikari:
|
||||
minimum-idle: 5
|
||||
maximum-pool-size: 20
|
||||
idle-timeout: 600000
|
||||
idle-timeout: 30000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
connection-test-query: SELECT 1
|
||||
|
||||
# Redis配置
|
||||
data:
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
host: ${REDIS_HOST:localhost}
|
||||
port: ${REDIS_PORT:6379}
|
||||
password: ${REDIS_PASSWORD:}
|
||||
database: 0
|
||||
timeout: 3000ms
|
||||
timeout: 10000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 20
|
||||
max-idle: 10
|
||||
min-idle: 5
|
||||
max-wait: 3000ms
|
||||
max-active: 8
|
||||
max-wait: -1ms
|
||||
max-idle: 8
|
||||
min-idle: 0
|
||||
|
||||
# Nacos配置
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
namespace: emotion-dev
|
||||
group: DEFAULT_GROUP
|
||||
enabled: false
|
||||
server-addr: ${NACOS_HOST:localhost}:${NACOS_PORT:8848}
|
||||
namespace: ${NACOS_NAMESPACE:}
|
||||
group: ${NACOS_GROUP:DEFAULT_GROUP}
|
||||
enabled: ${NACOS_DISCOVERY_ENABLED:true}
|
||||
username: ${NACOS_USERNAME:nacos}
|
||||
password: ${NACOS_PASSWORD:nacos}
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
zone: ${NACOS_ZONE:default}
|
||||
register-enabled: true
|
||||
ephemeral: true
|
||||
cluster-name: DEFAULT
|
||||
service: ${spring.application.name}
|
||||
weight: 1
|
||||
heart-beat-interval: 5000
|
||||
heart-beat-timeout: 15000
|
||||
ip-delete-timeout: 30000
|
||||
config:
|
||||
enabled: false
|
||||
server-addr: ${NACOS_HOST:localhost}:${NACOS_PORT:8848}
|
||||
namespace: ${NACOS_NAMESPACE:}
|
||||
group: ${NACOS_GROUP:DEFAULT_GROUP}
|
||||
file-extension: yml
|
||||
enabled: ${NACOS_CONFIG_ENABLED:false}
|
||||
username: ${NACOS_USERNAME:nacos}
|
||||
password: ${NACOS_PASSWORD:nacos}
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
|
||||
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
@@ -2,18 +2,6 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.emotionmuseum.user.mapper.UserMapper">
|
||||
|
||||
<!-- 根据账号查询用户 -->
|
||||
<select id="selectByAccount" resultType="com.emotionmuseum.user.entity.User"> SELECT * FROM user
|
||||
WHERE account = #{account} AND is_deleted = 0 </select>
|
||||
|
||||
<!-- 根据邮箱查询用户 -->
|
||||
<select id="selectByEmail" resultType="com.emotionmuseum.user.entity.User"> SELECT * FROM user
|
||||
WHERE email = #{email} AND is_deleted = 0 </select>
|
||||
|
||||
<!-- 根据手机号查询用户 -->
|
||||
<select id="selectByPhone" resultType="com.emotionmuseum.user.entity.User"> SELECT * FROM user
|
||||
WHERE phone = #{phone} AND is_deleted = 0 </select>
|
||||
|
||||
<!-- 更新最后活跃时间 -->
|
||||
<update id="updateLastActiveTime"> UPDATE user SET last_active_time = NOW(), update_time = NOW()
|
||||
WHERE id = #{userId} AND is_deleted = 0 </update>
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
artifactId=emotion-user
|
||||
groupId=com.emotionmuseum
|
||||
version=1.0.0
|
||||
+5
-20
@@ -1,32 +1,17 @@
|
||||
com/emotionmuseum/user/vo/LoginResponse.class
|
||||
com/emotionmuseum/user/security/UserDetailsServiceImpl$SecurityUser.class
|
||||
com/emotionmuseum/user/config/SecurityConfig.class
|
||||
com/emotionmuseum/user/config/RedisConfig.class
|
||||
com/emotionmuseum/user/service/impl/SliderCaptchaServiceImpl.class
|
||||
com/emotionmuseum/user/vo/UserInfoResponse.class
|
||||
com/emotionmuseum/user/config/CaptchaConfig.class
|
||||
com/emotionmuseum/user/config/OAuthConfig.class
|
||||
com/emotionmuseum/user/dto/UserUpdateRequest.class
|
||||
com/emotionmuseum/user/dto/OAuthLoginRequest.class
|
||||
com/emotionmuseum/user/dto/SliderCaptchaResponse.class
|
||||
com/emotionmuseum/user/controller/OAuthController.class
|
||||
com/emotionmuseum/user/UserApplication.class
|
||||
com/emotionmuseum/user/service/impl/OAuthServiceImpl.class
|
||||
com/emotionmuseum/user/dto/SliderCaptchaVerifyRequest.class
|
||||
com/emotionmuseum/user/service/impl/SliderCaptchaServiceImpl$SliderCaptchaData.class
|
||||
com/emotionmuseum/user/controller/UserController.class
|
||||
com/emotionmuseum/user/config/AuthenticationConfig.class
|
||||
com/emotionmuseum/user/service/UserService.class
|
||||
com/emotionmuseum/user/service/impl/CaptchaServiceImpl.class
|
||||
com/emotionmuseum/user/security/JwtAuthenticationFilter.class
|
||||
com/emotionmuseum/user/entity/User.class
|
||||
com/emotionmuseum/user/service/impl/UserServiceImpl.class
|
||||
com/emotionmuseum/user/security/UserDetailsServiceImpl.class
|
||||
com/emotionmuseum/user/dto/CaptchaResponse.class
|
||||
com/emotionmuseum/user/service/CaptchaService.class
|
||||
com/emotionmuseum/user/security/UserDetailsServiceImpl$SecurityUser.class
|
||||
com/emotionmuseum/user/dto/RegisterRequest.class
|
||||
com/emotionmuseum/user/config/CaptchaConfig.class
|
||||
com/emotionmuseum/user/service/OAuthService.class
|
||||
com/emotionmuseum/user/controller/CaptchaController.class
|
||||
com/emotionmuseum/user/dto/LoginRequest.class
|
||||
com/emotionmuseum/user/controller/UserController.class
|
||||
com/emotionmuseum/user/security/JwtAuthenticationFilter.class
|
||||
com/emotionmuseum/user/service/SliderCaptchaService.class
|
||||
com/emotionmuseum/user/vo/UserInfoResponse$GrowthStatsVO.class
|
||||
com/emotionmuseum/user/mapper/UserMapper.class
|
||||
|
||||
+6
-20
@@ -1,29 +1,15 @@
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/config/SecurityConfig.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/vo/LoginResponse.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/dto/RegisterRequest.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/service/impl/CaptchaServiceImpl.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/security/JwtAuthenticationFilter.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/dto/CaptchaResponse.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/service/impl/UserServiceImpl.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/controller/UserController.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/config/CaptchaConfig.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/config/OAuthConfig.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/service/UserService.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/service/OAuthService.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/dto/SliderCaptchaVerifyRequest.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/service/SliderCaptchaService.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/service/impl/OAuthServiceImpl.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/service/impl/SliderCaptchaServiceImpl.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/config/RedisConfig.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/vo/UserInfoResponse.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/dto/UserUpdateRequest.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/entity/User.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/mapper/UserMapper.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/config/AuthenticationConfig.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/security/UserDetailsServiceImpl.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/UserApplication.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/dto/LoginRequest.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/controller/OAuthController.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/dto/OAuthLoginRequest.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/service/impl/UserServiceImpl.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/service/CaptchaService.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/controller/UserController.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/dto/SliderCaptchaResponse.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/config/OAuthConfig.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/config/RedisConfig.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/dto/UserUpdateRequest.java
|
||||
/Users/huazhongmin/peanut/AppleDevelop/EmotionMuseum/backend/emotion-user/src/main/java/com/emotionmuseum/user/controller/CaptchaController.java
|
||||
|
||||
Reference in New Issue
Block a user