From c265d3a19a57736cfc3034b69db22b68fc695a9b Mon Sep 17 00:00:00 2001 From: yyb <1416014977@qq.com> Date: Tue, 15 Apr 2025 14:39:18 +0800 Subject: [PATCH] =?UTF-8?q?stomp=20+=20websocket=20=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 30 +++ .../src/main/resources/bootstrap-prod.yml | 64 +++++ .../src/main/resources/bootstrap-test.yml | 89 +++++++ m2pool-auth/src/main/resources/bootstrap.yml | 158 +---------- .../gateway/M2PoolGatewayApplication.java | 1 + .../config/CustomWebsocketRoutingFilter.java | 247 ++++++++++++++++++ .../src/main/resources/bootstrap-prod.yml | 48 ++++ .../src/main/resources/bootstrap-test.yml | 46 ++++ .../src/main/resources/bootstrap.yml | 99 +------ m2pool-modules/m2pool-chat/pom.xml | 6 + .../com/m2pool/chat/M2ChatApplication.java | 2 +- .../chat/config/WebSocketBrokerConfig.java | 18 +- .../m2pool/chat/config/WebSocketConfig.java | 21 -- .../com/m2pool/chat/constant/Destination.java | 34 +++ .../com/m2pool/chat/constant/MessageType.java | 19 ++ .../com/m2pool/chat/constant/UserType.java | 26 ++ .../chat/constant/WebsocketExceptionCode.java | 10 - .../chat/controller/ChatController.java | 82 ------ .../controller/ChatMessageController.java | 74 ++++++ .../chat/controller/ChatRoomController.java | 41 +++ .../chat/controller/StompController.java | 38 +++ .../com/m2pool/chat/dto/ChatMessageDto.java | 33 +++ .../java/com/m2pool/chat/dto/ChatRoomDto.java | 43 +++ .../m2pool/chat/dto/WebsocketMessageDto.java | 21 +- .../com/m2pool/chat/entity/ChatMessage.java | 22 +- .../chat/entity/ChatMessageHistory.java | 15 ++ .../java/com/m2pool/chat/entity/ChatMsg.java | 60 ----- .../java/com/m2pool/chat/entity/ChatRoom.java | 19 ++ .../m2pool/chat/entity/StompPrincipal.java | 19 ++ .../chat/exception/WebSocketException.java | 7 - .../WebsocketChannelInterceptor.java | 39 ++- .../WebsocketHandshakeInterceptor.java | 25 +- .../com/m2pool/chat/mapper/ChatMapper.java | 20 -- .../chat/mapper/ChatMessageHistoryMapper.java | 22 ++ .../m2pool/chat/mapper/ChatMessageMapper.java | 34 +++ .../m2pool/chat/mapper/ChatRoomMapper.java | 35 +++ .../chat/service/ChatMessageService.java | 42 +++ .../m2pool/chat/service/ChatRoomService.java | 30 +++ .../com/m2pool/chat/service/ChatService.java | 30 --- .../com/m2pool/chat/service/StompService.java | 15 ++ .../m2pool/chat/service/WebSocketServer.java | 169 ------------ .../service/impl/ChatMessageServiceImpl.java | 69 +++++ .../service/impl/ChatRoomServiceImpl.java | 89 +++++++ .../chat/service/impl/ChatServiceImpl.java | 37 --- .../chat/service/impl/StompServiceImpl.java | 97 +++++++ .../java/com/m2pool/chat/task/ChatTask.java | 13 + .../java/com/m2pool/chat/vo/CharRoomVo.java | 15 ++ .../com/m2pool/chat/vo/ChatHistoryVo.java | 14 - .../com/m2pool/chat/vo/UserMessageVo.java | 28 +- .../src/main/resources/bootstrap-prod.yml | 76 ++++++ .../src/main/resources/bootstrap-test.yml | 43 +++ .../src/main/resources/bootstrap.yml | 155 +---------- .../mapper/chat/ChatMessageHistoryMapper.xml | 20 ++ .../mapper/chat/ChatMessageMapper.xml | 29 ++ .../resources/mapper/chat/ChatRoomMapper.xml | 31 +++ .../system/M2PoolSystemApplication.java | 2 + .../src/main/resources/bootstrap-prod.yml | 28 ++ .../src/main/resources/bootstrap-test.yml | 24 ++ .../src/main/resources/bootstrap.yml | 57 +--- 59 files changed, 1729 insertions(+), 951 deletions(-) create mode 100644 .gitignore create mode 100644 m2pool-auth/src/main/resources/bootstrap-prod.yml create mode 100644 m2pool-auth/src/main/resources/bootstrap-test.yml create mode 100644 m2pool-gateway/src/main/java/com/m2pool/gateway/config/CustomWebsocketRoutingFilter.java create mode 100644 m2pool-gateway/src/main/resources/bootstrap-prod.yml create mode 100644 m2pool-gateway/src/main/resources/bootstrap-test.yml delete mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/config/WebSocketConfig.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/Destination.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/MessageType.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/UserType.java delete mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/WebsocketExceptionCode.java delete mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatController.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatMessageController.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatRoomController.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/StompController.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/ChatMessageDto.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/ChatRoomDto.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatMessageHistory.java delete mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatMsg.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatRoom.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/StompPrincipal.java delete mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatMapper.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatMessageHistoryMapper.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatMessageMapper.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatRoomMapper.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatMessageService.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatRoomService.java delete mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatService.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/StompService.java delete mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/WebSocketServer.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatMessageServiceImpl.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatRoomServiceImpl.java delete mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatServiceImpl.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/StompServiceImpl.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/task/ChatTask.java create mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/CharRoomVo.java delete mode 100644 m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/ChatHistoryVo.java create mode 100644 m2pool-modules/m2pool-chat/src/main/resources/bootstrap-prod.yml create mode 100644 m2pool-modules/m2pool-chat/src/main/resources/bootstrap-test.yml create mode 100644 m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatMessageHistoryMapper.xml create mode 100644 m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatMessageMapper.xml create mode 100644 m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatRoomMapper.xml create mode 100644 m2pool-modules/m2pool-system/src/main/resources/bootstrap-prod.yml create mode 100644 m2pool-modules/m2pool-system/src/main/resources/bootstrap-test.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f36fd2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# 忽略 IDE 和编译生成的文件 +.idea/ +target/ +*.iml +*.class + +# 忽略日志文件 +logs/ +*.log + +# 忽略配置文件 +application-local.yml +bootstrap-local.yml + +# 忽略临时文件 +*.tmp +*.bak +*.swp + +# 忽略依赖缓存 +.m2/ +node_modules/ + +# 忽略敏感信息 +.env +credentials.json + +# 忽略系统文件 +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/m2pool-auth/src/main/resources/bootstrap-prod.yml b/m2pool-auth/src/main/resources/bootstrap-prod.yml new file mode 100644 index 0000000..2d51f3e --- /dev/null +++ b/m2pool-auth/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,64 @@ +#Tomcat +server: + port: 9200 + +# Spring +spring: + #邮箱基本配置 + mail: + # 配置在limit_time内,用户可以发送limit次验证码 + limit: 2 这个是我额外的配置,结合邮箱服务用的 + limitTime: 10 这个是我额外的配置 + #配置smtp服务主机地址 + # sina smtp.sina.cn + # aliyun smtp.aliyun.com + # 163 smtp.163.com 端口号465或994 + host: mail.privateemail.com + #发送者邮箱 + username: do.not.reply@m2pool.com + #配置密码,注意不是真正的密码,而是刚刚申请到的授权码 +# password: +# password: M2pool2024@! +# password: axvm-zfgx-cgcg-qhhu + password: M2202401! + + + #端口号 + port: 587 + #默认的邮件编码为UTF-8 + default-encoding: UTF-8 + #其他参数 + properties: + mail: + #配置SSL 加密工厂 + smtp: + ssl: + #本地测试,先放开ssl + enable: false + required: false + #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误 + debug: false + socketFactory: + class: javax.net.ssl.SSLSocketFactory + + application: + # 应用名称 + name: m2pool-auth + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8808 + namespace: m2_prod + group: m2_prod_group + config: + # 配置中心地址 + server-addr: 127.0.0.1:8808 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: m2_prod + group: m2_prod_group + diff --git a/m2pool-auth/src/main/resources/bootstrap-test.yml b/m2pool-auth/src/main/resources/bootstrap-test.yml new file mode 100644 index 0000000..87c5f4b --- /dev/null +++ b/m2pool-auth/src/main/resources/bootstrap-test.yml @@ -0,0 +1,89 @@ +server: + port: 9500 + +# Spring +spring: + #邮箱基本配置 + mail: + # 配置在limit_time内,用户可以发送limit次验证码 + limit: 2 这个是我额外的配置,结合邮箱服务用的 + limitTime: 10 这个是我额外的配置 + #配置smtp服务主机地址 + # sina smtp.sina.cn + # aliyun smtp.aliyun.com + # 163 smtp.163.com 端口号465或994 + host: mail.privateemail.com + #发送者邮箱 + username: do.not.reply@m2pool.com + #配置密码,注意不是真正的密码,而是刚刚申请到的授权码 + # password: + # password: M2202401! + # password: axvm-zfgx-cgcg-qhhu + password: M2202401! + + #端口号 + port: 587 +# port: 465 + #默认的邮件编码为UTF-8 + default-encoding: UTF-8 + #其他参数 + properties: + mail: + #配置SSL 加密工厂 + smtp: + ssl: + #本地测试,先放开ssl + enable: false + required: false + #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误 + debug: false + socketFactory: + class: javax.net.ssl.SSLSocketFactory +# +# host: smtp.qq.com +# #发送者邮箱 +# username: 1328642438@qq.com +# #配置密码,注意不是真正的密码,而是刚刚申请到的授权码 +# # password: +# # password: M2pool2024@! +# # password: axvm-zfgx-cgcg-qhhu +# password: eqrzqxeqzlshhedh +# +# #端口号 +# port: 465 +# #默认的邮件编码为UTF-8 +# default-encoding: UTF-8 +# #其他参数 +# properties: +# mail: +# #配置SSL 加密工厂 +# smtp: +# ssl: +# #本地测试,先放开ssl +# enable: true +# required: true +# #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误 +# debug: false +# socketFactory: +# class: javax.net.ssl.SSLSocketFactory + + application: + # 应用名称 + name: m2pool-auth + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + namespace: m2_test + group: m2_test_group + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: m2_test + group: m2_test_group diff --git a/m2pool-auth/src/main/resources/bootstrap.yml b/m2pool-auth/src/main/resources/bootstrap.yml index ad7b21e..90385b2 100644 --- a/m2pool-auth/src/main/resources/bootstrap.yml +++ b/m2pool-auth/src/main/resources/bootstrap.yml @@ -1,159 +1,3 @@ -#Tomcat -server: - port: 9200 - -# Spring spring: - #邮箱基本配置 - mail: - # 配置在limit_time内,用户可以发送limit次验证码 - limit: 2 这个是我额外的配置,结合邮箱服务用的 - limitTime: 10 这个是我额外的配置 - #配置smtp服务主机地址 - # sina smtp.sina.cn - # aliyun smtp.aliyun.com - # 163 smtp.163.com 端口号465或994 - host: mail.privateemail.com - #发送者邮箱 - username: do.not.reply@m2pool.com - #配置密码,注意不是真正的密码,而是刚刚申请到的授权码 -# password: -# password: M2pool2024@! -# password: axvm-zfgx-cgcg-qhhu - password: M2202401! - - - #端口号 - port: 587 - #默认的邮件编码为UTF-8 - default-encoding: UTF-8 - #其他参数 - properties: - mail: - #配置SSL 加密工厂 - smtp: - ssl: - #本地测试,先放开ssl - enable: false - required: false - #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误 - debug: false - socketFactory: - class: javax.net.ssl.SSLSocketFactory - - application: - # 应用名称 - name: m2pool-auth profiles: - # 环境配置 - active: prod - cloud: - nacos: - discovery: - # 服务注册地址 - server-addr: 127.0.0.1:8808 - namespace: m2_prod - group: m2_prod_group - config: - # 配置中心地址 - server-addr: 127.0.0.1:8808 - # 配置文件格式 - file-extension: yml - # 共享配置 - shared-configs: - - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} - namespace: m2_prod - group: m2_prod_group - -#server: -# port: 9500 -# -## Spring -#spring: -# #邮箱基本配置 -# mail: -# # 配置在limit_time内,用户可以发送limit次验证码 -# limit: 2 这个是我额外的配置,结合邮箱服务用的 -# limitTime: 10 这个是我额外的配置 -# #配置smtp服务主机地址 -# # sina smtp.sina.cn -# # aliyun smtp.aliyun.com -# # 163 smtp.163.com 端口号465或994 -# host: mail.privateemail.com -# #发送者邮箱 -# username: do.not.reply@m2pool.com -# #配置密码,注意不是真正的密码,而是刚刚申请到的授权码 -# # password: -# # password: M2202401! -# # password: axvm-zfgx-cgcg-qhhu -# password: M2202401! -# -# #端口号 -# port: 587 -## port: 465 -# #默认的邮件编码为UTF-8 -# default-encoding: UTF-8 -# #其他参数 -# properties: -# mail: -# #配置SSL 加密工厂 -# smtp: -# ssl: -# #本地测试,先放开ssl -# enable: false -# required: false -# #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误 -# debug: false -# socketFactory: -# class: javax.net.ssl.SSLSocketFactory -## -## host: smtp.qq.com -## #发送者邮箱 -## username: 1328642438@qq.com -## #配置密码,注意不是真正的密码,而是刚刚申请到的授权码 -## # password: -## # password: M2pool2024@! -## # password: axvm-zfgx-cgcg-qhhu -## password: eqrzqxeqzlshhedh -## -## #端口号 -## port: 465 -## #默认的邮件编码为UTF-8 -## default-encoding: UTF-8 -## #其他参数 -## properties: -## mail: -## #配置SSL 加密工厂 -## smtp: -## ssl: -## #本地测试,先放开ssl -## enable: true -## required: true -## #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误 -## debug: false -## socketFactory: -## class: javax.net.ssl.SSLSocketFactory -# -# application: -# # 应用名称 -# name: m2pool-auth -# profiles: -# # 环境配置 -# active: test -# cloud: -# nacos: -# discovery: -# # 服务注册地址 -# server-addr: 127.0.0.1:8808 -# namespace: m2_test -# group: m2_test_group -# config: -# # 配置中心地址 -# server-addr: 127.0.0.1:8808 -# # 配置文件格式 -# file-extension: yml -# # 共享配置 -# shared-configs: -# - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} -# namespace: m2_test -# group: m2_test_group + active: prod \ No newline at end of file diff --git a/m2pool-gateway/src/main/java/com/m2pool/gateway/M2PoolGatewayApplication.java b/m2pool-gateway/src/main/java/com/m2pool/gateway/M2PoolGatewayApplication.java index aab8f92..17f378d 100644 --- a/m2pool-gateway/src/main/java/com/m2pool/gateway/M2PoolGatewayApplication.java +++ b/m2pool-gateway/src/main/java/com/m2pool/gateway/M2PoolGatewayApplication.java @@ -1,5 +1,6 @@ package com.m2pool.gateway; +import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; diff --git a/m2pool-gateway/src/main/java/com/m2pool/gateway/config/CustomWebsocketRoutingFilter.java b/m2pool-gateway/src/main/java/com/m2pool/gateway/config/CustomWebsocketRoutingFilter.java new file mode 100644 index 0000000..3afeeab --- /dev/null +++ b/m2pool-gateway/src/main/java/com/m2pool/gateway/config/CustomWebsocketRoutingFilter.java @@ -0,0 +1,247 @@ +package com.m2pool.gateway.config; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter; +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; +import org.springframework.core.Ordered; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.reactive.socket.CloseStatus; +import org.springframework.web.reactive.socket.WebSocketHandler; +import org.springframework.web.reactive.socket.WebSocketMessage; +import org.springframework.web.reactive.socket.WebSocketSession; +import org.springframework.web.reactive.socket.client.WebSocketClient; +import org.springframework.web.reactive.socket.server.WebSocketService; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.util.UriComponentsBuilder; +import reactor.core.publisher.Mono; + +import java.net.URI; +import java.util.*; + +/** + * 解决gateway网关 websocket关闭异常 问题 + * @author yyb + * @Desc websocket客户端主动断开连接, + * @date 2025/4/14 11:21 + */ +@Component +public class CustomWebsocketRoutingFilter implements GlobalFilter, Ordered { + + public static final String SEC_WEBSOCKET_PROTOCOL = "Sec-WebSocket-Protocol"; + private static final Log log = LogFactory.getLog(CustomWebsocketRoutingFilter.class); + private final WebSocketClient webSocketClient; + private final WebSocketService webSocketService; + private final ObjectProvider> headersFiltersProvider; + private volatile List headersFilters; + + public CustomWebsocketRoutingFilter(WebSocketClient webSocketClient, WebSocketService webSocketService, ObjectProvider> headersFiltersProvider) { + this.webSocketClient = webSocketClient; + this.webSocketService = webSocketService; + this.headersFiltersProvider = headersFiltersProvider; + } + + static String convertHttpToWs(String scheme) { + scheme = scheme.toLowerCase(); + return "http".equals(scheme) ? "ws" : ("https".equals(scheme) ? "wss" : scheme); + } + + @Override + public int getOrder() { + return 2147483645; + } + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + changeSchemeIfIsWebSocketUpgrade(exchange); + URI requestUrl = (URI)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR); + String scheme = requestUrl.getScheme(); + if (!ServerWebExchangeUtils.isAlreadyRouted(exchange) && ("ws".equals(scheme) || "wss".equals(scheme))) { + ServerWebExchangeUtils.setAlreadyRouted(exchange); + HttpHeaders headers = exchange.getRequest().getHeaders(); + HttpHeaders filtered = HttpHeadersFilter.filterRequest(this.getHeadersFilters(), exchange); + List protocols = this.getProtocols(headers); + return this.webSocketService.handleRequest(exchange, new CustomWebsocketRoutingFilter.ProxyWebSocketHandler(requestUrl, this.webSocketClient, filtered, protocols)); + } else { + return chain.filter(exchange); + } + } + + List getProtocols(HttpHeaders headers) { + List protocols = headers.get("Sec-WebSocket-Protocol"); + if (protocols != null) { + ArrayList updatedProtocols = new ArrayList(); + + for(int i = 0; i < ((List)protocols).size(); ++i) { + String protocol = (String)((List)protocols).get(i); + updatedProtocols.addAll(Arrays.asList(StringUtils.tokenizeToStringArray(protocol, ","))); + } + + protocols = updatedProtocols; + } + + return (List)protocols; + } + + List getHeadersFilters() { + if (this.headersFilters == null) { + this.headersFilters = (List)this.headersFiltersProvider.getIfAvailable(ArrayList::new); + this.headersFilters.add((headers, exchange) -> { + HttpHeaders filtered = new HttpHeaders(); + filtered.addAll(headers); + filtered.remove("Host"); + boolean preserveHost = (Boolean)exchange.getAttributeOrDefault(ServerWebExchangeUtils.PRESERVE_HOST_HEADER_ATTRIBUTE, false); + if (preserveHost) { + String host = exchange.getRequest().getHeaders().getFirst("Host"); + filtered.add("Host", host); + } + + return filtered; + }); + this.headersFilters.add((headers, exchange) -> { + HttpHeaders filtered = new HttpHeaders(); + Iterator var3 = headers.entrySet().iterator(); + + while(var3.hasNext()) { + Map.Entry> entry = (Map.Entry)var3.next(); + if (!((String)entry.getKey()).toLowerCase().startsWith("sec-websocket")) { + filtered.addAll((String)entry.getKey(), (List)entry.getValue()); + } + } + + return filtered; + }); + } + + return this.headersFilters; + } + + static void changeSchemeIfIsWebSocketUpgrade(ServerWebExchange exchange) { + URI requestUrl = (URI)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR); + String scheme = requestUrl.getScheme().toLowerCase(); + String upgrade = exchange.getRequest().getHeaders().getUpgrade(); + if ("WebSocket".equalsIgnoreCase(upgrade) && ("http".equals(scheme) || "https".equals(scheme))) { + String wsScheme = convertHttpToWs(scheme); + boolean encoded = ServerWebExchangeUtils.containsEncodedParts(requestUrl); + URI wsRequestUrl = UriComponentsBuilder.fromUri(requestUrl).scheme(wsScheme).build(encoded).toUri(); + exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, wsRequestUrl); + if (log.isTraceEnabled()) { + log.trace("changeSchemeTo:[" + wsRequestUrl + "]"); + } + } + + } + + private static class ProxyWebSocketHandler implements WebSocketHandler { + private final WebSocketClient client; + private final URI url; + private final HttpHeaders headers; + private final List subProtocols; + + ProxyWebSocketHandler(URI url, WebSocketClient client, HttpHeaders headers, List protocols) { + this.client = client; + this.url = url; + this.headers = headers; + if (protocols != null) { + this.subProtocols = protocols; + } else { + this.subProtocols = Collections.emptyList(); + } + + } + + @Override + public List getSubProtocols() { + return this.subProtocols; + } + + @Override + public Mono handle(WebSocketSession session) { + return this.client.execute(this.url, this.headers, new WebSocketHandler() { + + private CloseStatus adaptCloseStatus(CloseStatus closeStatus) { + int code = closeStatus.getCode(); + if (code > 2999 && code < 5000) { + return closeStatus; + } + switch (code) { + case 1000: + return closeStatus; + case 1001: + return closeStatus; + case 1002: + return closeStatus; + case 1003: + return closeStatus; + case 1004: + // Should not be used in a close frame + // RESERVED; + return CloseStatus.PROTOCOL_ERROR; + case 1005: + // Should not be used in a close frame + // return CloseStatus.NO_STATUS_CODE; + return CloseStatus.PROTOCOL_ERROR; + case 1006: + // Should not be used in a close frame + // return CloseStatus.NO_CLOSE_FRAME; + return CloseStatus.PROTOCOL_ERROR; + case 1007: + return closeStatus; + case 1008: + return closeStatus; + case 1009: + return closeStatus; + case 1010: + return closeStatus; + case 1011: + return closeStatus; + case 1012: + // Not in RFC6455 + // return CloseStatus.SERVICE_RESTARTED; + return CloseStatus.PROTOCOL_ERROR; + case 1013: + // Not in RFC6455 + // return CloseStatus.SERVICE_OVERLOAD; + return CloseStatus.PROTOCOL_ERROR; + case 1015: + // Should not be used in a close frame + // return CloseStatus.TLS_HANDSHAKE_FAILURE; + return CloseStatus.PROTOCOL_ERROR; + default: + return CloseStatus.PROTOCOL_ERROR; + } + } + + @Override + public Mono handle(WebSocketSession proxySession) { + Mono serverClose = proxySession.closeStatus().filter(__ -> session.isOpen()) + .map(this::adaptCloseStatus) + .flatMap(session::close); + Mono proxyClose = session.closeStatus().filter(__ -> proxySession.isOpen()) + .map(this::adaptCloseStatus) + .flatMap(proxySession::close); + // Use retain() for Reactor Netty + Mono proxySessionSend = proxySession + .send(session.receive().doOnNext(WebSocketMessage::retain)); + Mono serverSessionSend = session + .send(proxySession.receive().doOnNext(WebSocketMessage::retain)); + // Ensure closeStatus from one propagates to the other + Mono.when(serverClose, proxyClose).subscribe(); + // Complete when both sessions are done + return Mono.zip(proxySessionSend, serverSessionSend).then(); + } + + @Override + public List getSubProtocols() { + return CustomWebsocketRoutingFilter.ProxyWebSocketHandler.this.subProtocols; + } + }); + } + } +} + diff --git a/m2pool-gateway/src/main/resources/bootstrap-prod.yml b/m2pool-gateway/src/main/resources/bootstrap-prod.yml new file mode 100644 index 0000000..1711f83 --- /dev/null +++ b/m2pool-gateway/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,48 @@ +# Tomcat +server: + port: 8201 +# Spring +spring: + application: + # 应用名称 + name: m2pool-gateway + main: + allow-circular-references: true + allow-bean-definition-overriding: true + + cloud: + nacos: + discovery: + server-addr: 127.0.0.1:8808 + namespace: m2_prod + group: m2_prod_group + config: + # 配置中心地址 + server-addr: 127.0.0.1:8808 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: m2_prod + group: m2_prod_group + sentinel: + # 取消控制台懒加载 + eager: true + transport: + # 控制台地址 + dashboard: 127.0.0.1:8718 + # nacos配置持久化 + datasource: + ds1: + nacos: + server-addr: 127.0.0.1:8808 + dataId: sentinel-m2pool-gateway + groupId: m2_prod_group + data-type: json + rule-type: flow + servlet: + multipart: + max-file-size: 2MB + max-request-size: 8MB + diff --git a/m2pool-gateway/src/main/resources/bootstrap-test.yml b/m2pool-gateway/src/main/resources/bootstrap-test.yml new file mode 100644 index 0000000..3ee1a6f --- /dev/null +++ b/m2pool-gateway/src/main/resources/bootstrap-test.yml @@ -0,0 +1,46 @@ +server: + port: 8101 +# Spring +spring: + application: + # 应用名称 + name: m2pool-gateway + main: + allow-circular-references: true + allow-bean-definition-overriding: true + + cloud: + nacos: + discovery: + server-addr: 127.0.0.1:8848 + namespace: m2_test + group: m2_test_group + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: m2_test + group: m2_test_group + sentinel: + # 取消控制台懒加载 + eager: true + transport: + # 控制台地址 + dashboard: 127.0.0.1:8718 + # nacos配置持久化 + datasource: + ds1: + nacos: + server-addr: 127.0.0.1:8848 + dataId: sentinel-m2pool-gateway + groupId: m2_test_group + data-type: json + rule-type: flow + servlet: + multipart: + max-file-size: 2MB + max-request-size: 8MB diff --git a/m2pool-gateway/src/main/resources/bootstrap.yml b/m2pool-gateway/src/main/resources/bootstrap.yml index 32ba790..90385b2 100644 --- a/m2pool-gateway/src/main/resources/bootstrap.yml +++ b/m2pool-gateway/src/main/resources/bootstrap.yml @@ -1,100 +1,3 @@ -# Tomcat -server: - port: 8201 -# Spring spring: - application: - # 应用名称 - name: m2pool-gateway profiles: - # 环境配置 - active: prod - main: - allow-circular-references: true - allow-bean-definition-overriding: true - - cloud: - nacos: - discovery: - server-addr: 127.0.0.1:8808 - namespace: m2_prod - group: m2_prod_group - config: - # 配置中心地址 - server-addr: 127.0.0.1:8808 - # 配置文件格式 - file-extension: yml - # 共享配置 - shared-configs: - - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} - namespace: m2_prod - group: m2_prod_group - sentinel: - # 取消控制台懒加载 - eager: true - transport: - # 控制台地址 - dashboard: 127.0.0.1:8718 - # nacos配置持久化 - datasource: - ds1: - nacos: - server-addr: 127.0.0.1:8808 - dataId: sentinel-m2pool-gateway - groupId: m2_prod_group - data-type: json - rule-type: flow - servlet: - multipart: - max-file-size: 2MB - max-request-size: 8MB - -#server: -# port: 8101 -## Spring -#spring: -# application: -# # 应用名称 -# name: m2pool-gateway -# profiles: -# # 环境配置 -# active: test -# main: -# allow-circular-references: true -# allow-bean-definition-overriding: true -# -# cloud: -# nacos: -# discovery: -# server-addr: 127.0.0.1:8808 -# namespace: m2_test -# group: m2_test_group -# config: -# # 配置中心地址 -# server-addr: 127.0.0.1:8808 -# # 配置文件格式 -# file-extension: yml -# # 共享配置 -# shared-configs: -# - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} -# namespace: m2_test -# group: m2_test_group -# sentinel: -# # 取消控制台懒加载 -# eager: true -# transport: -# # 控制台地址 -# dashboard: 127.0.0.1:8718 -# # nacos配置持久化 -# datasource: -# ds1: -# nacos: -# server-addr: 127.0.0.1:8808 -# dataId: sentinel-m2pool-gateway -# groupId: m2_test_group -# data-type: json -# rule-type: flow -# servlet: -# multipart: -# max-file-size: 2MB -# max-request-size: 8MB + active: prod \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/pom.xml b/m2pool-modules/m2pool-chat/pom.xml index 2dfdc63..b3f6866 100644 --- a/m2pool-modules/m2pool-chat/pom.xml +++ b/m2pool-modules/m2pool-chat/pom.xml @@ -135,6 +135,12 @@ compile + + com.baomidou + mybatis-plus-boot-starter + 3.5.3 + + de.taimos diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/M2ChatApplication.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/M2ChatApplication.java index 02eed4f..484114a 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/M2ChatApplication.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/M2ChatApplication.java @@ -28,7 +28,7 @@ public class M2ChatApplication { public static void main(String[] args) { SpringApplication.run(M2ChatApplication.class,args); - System.out.println("m2pool矿池 开放api微服务启动成功"); + System.out.println("m2pool矿池 聊天室微服务启动成功"); } } diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/config/WebSocketBrokerConfig.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/config/WebSocketBrokerConfig.java index c7be399..bcf111f 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/config/WebSocketBrokerConfig.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/config/WebSocketBrokerConfig.java @@ -1,5 +1,6 @@ package com.m2pool.chat.config; +import com.m2pool.chat.constant.Destination; import com.m2pool.chat.coverter.CommonMessageConvert; import com.m2pool.chat.interceptor.WebsocketChannelInterceptor; import com.m2pool.chat.interceptor.WebsocketHandshakeInterceptor; @@ -30,12 +31,17 @@ public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer { */ @Override public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/chat") + + //sockjs 形式端点 + registry.addEndpoint("/sockjs") .addInterceptors(new WebsocketHandshakeInterceptor()) - //.setHandshakeHandler(webSocketHandshakeHandler) - //允许跨域访问 .setAllowedOrigins("*") .withSockJS(); + + // websocket 形式端点 + registry.addEndpoint("/ws") + .addInterceptors(new WebsocketHandshakeInterceptor()) + .setAllowedOrigins("*"); } /** @@ -46,13 +52,13 @@ public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { - config.enableSimpleBroker("/topic", "/queue") + config.enableSimpleBroker(Destination.TOPIC, Destination.QUEUE) .setHeartbeatValue(new long[] {10000, 10000}) .setTaskScheduler(new DefaultManagedTaskScheduler()); - config.setApplicationDestinationPrefixes("/message"); + config.setApplicationDestinationPrefixes(Destination.SEND_PREFIX); //服务端通知客户端的前缀,可以不设置,默认为user - config.setUserDestinationPrefix("/user"); + config.setUserDestinationPrefix(Destination.USER_PREFIX); } diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/config/WebSocketConfig.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/config/WebSocketConfig.java deleted file mode 100644 index a9918b4..0000000 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/config/WebSocketConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.m2pool.chat.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.socket.server.standard.ServerEndpointExporter; - -import javax.websocket.server.ServerEndpointConfig; - -/** - * @Description TODO - * @Date 2025/2/25 14:43 - * @Author 杜懿 - */ -@Configuration -public class WebSocketConfig { - - @Bean - public ServerEndpointExporter serverEndpointExporter(){ - return new ServerEndpointExporter(); - } -} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/Destination.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/Destination.java new file mode 100644 index 0000000..f2847da --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/Destination.java @@ -0,0 +1,34 @@ +package com.m2pool.chat.constant; + +/** + * @ClassName Destination + * @Description 消息发送目的地 + * @Author yyb + * @Date 2025/4/14 14:54 + */ +public class Destination { + /** + * stomp 默认单对单 发送目的地 + */ + public static final String QUEUE = "/queue"; + + /** + * stomp 默认群发 目的地 + */ + public static final String TOPIC = "/topic"; + + /** + * 前端订阅消息所需前缀。 stomp 默认user前缀。 + */ + public static final String USER_PREFIX = "/user"; + + /** + * stomp 默认发送消息前缀。 + */ + public static final String SEND_PREFIX = "/message"; + + /** + * 游客标识 + */ + public static final String VISITOR_PREFIX = "visitor"; +} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/MessageType.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/MessageType.java new file mode 100644 index 0000000..6aeb207 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/MessageType.java @@ -0,0 +1,19 @@ +package com.m2pool.chat.constant; + +/** + * @ClassName messageType + * @Description 消息类型常量类 + * @Author yyb + * @Date 2025/4/14 14:51 + */ +public class MessageType { + /** + * 文本消息 + */ + public static final Integer TYPE_TEXT = 0; + + /** + * 图片信息 + */ + public static final Integer TYPE_IMAGE = 1; +} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/UserType.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/UserType.java new file mode 100644 index 0000000..eaa7516 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/UserType.java @@ -0,0 +1,26 @@ +package com.m2pool.chat.constant; + +/** + * @ClassName UserType + * @Description TODO + * @Author yyb + * @Date 2025/4/15 11:25 + */ +public class UserType { + /** + * 游客 + */ + public static final Integer TOURIST = 0; + + /** + * 登录用户 + */ + public static final Integer LOGIN_USER = 1; + + + /** + * 客服 + */ + public static final Integer CUSTOMER = 2; + +} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/WebsocketExceptionCode.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/WebsocketExceptionCode.java deleted file mode 100644 index b009200..0000000 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/WebsocketExceptionCode.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.m2pool.chat.constant; - -/** - * @ClassName ExceptionCode - * @Description websocket 异常码 - * @Author yyb - * @Date 2025/4/10 16:37 - */ -public class WebsocketExceptionCode { -} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatController.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatController.java deleted file mode 100644 index e379306..0000000 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatController.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.m2pool.chat.controller; - -import com.m2pool.chat.dto.WebsocketMessageDto; -import com.m2pool.chat.service.ChatService; -import com.m2pool.chat.vo.ChatHistoryVo; -import com.m2pool.chat.vo.UserMessageVo; -import com.m2pool.common.core.utils.StringUtils; -import com.m2pool.common.core.web.Result.AjaxResult; -import com.m2pool.common.core.web.controller.BaseController; -import org.springframework.messaging.handler.annotation.DestinationVariable; -import org.springframework.messaging.handler.annotation.MessageMapping; -import org.springframework.messaging.simp.SimpMessagingTemplate; -import org.springframework.messaging.simp.annotation.SendToUser; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.ResponseBody; - -import javax.annotation.Resource; - -/** - * @Description TODO - * @Date 2025/2/24 15:05 - * @Author 杜懿 - */ -@Controller -public class ChatController extends BaseController { - - @Resource - private ChatService chatService; - - //@Resource - // //private WebSocketServer webSocketServer; - - @GetMapping("/history") - @ResponseBody - public AjaxResult getChatHistory(@RequestBody ChatHistoryVo vo) { - - if(StringUtils.isNull(vo)){ - return AjaxResult.error("请求参数为空"); - } - - String identifier = StringUtils.isNotBlank(vo.getEmail()) ? vo.getEmail() : vo.getBrowserId(); - return chatService.getHistory(identifier); - } - - //spring提供的推送方式 - @Resource - private SimpMessagingTemplate messagingTemplate; - - - /** - * 发送消息到对应的用户 - * @param userId 用户id,消息接受者 - * @param userMessageVo 消息体 - * @return 返回值通过CommonMessageConvert消息转换器转换 - */ - @MessageMapping("/message/{userId}") - @SendToUser("/queue/{userId}") - public WebsocketMessageDto sendMessageToUser(@DestinationVariable String userId, UserMessageVo userMessageVo) { - WebsocketMessageDto websocketMessageDto = new WebsocketMessageDto(); - websocketMessageDto.setType("message"); - websocketMessageDto.setMessage(userMessageVo.getMessage()); - - return websocketMessageDto; - } - - - //TODO 前端打开聊天框,获取用户信息,建立一对一链接 - - - //TODO 用户登录后,保存历史信息到数据库表,分表存储(7天)。 - - - //TODO 用户注销,需删除历史信息 - - - // - - - -} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatMessageController.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatMessageController.java new file mode 100644 index 0000000..6588cb1 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatMessageController.java @@ -0,0 +1,74 @@ +package com.m2pool.chat.controller; + +import com.m2pool.chat.service.ChatMessageService; +import com.m2pool.common.core.web.Result.AjaxResult; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/chat/message") +@Api(tags = "聊天消息相关接口") +public class ChatMessageController { + + @Autowired + private ChatMessageService chatMessageService; + + /** + * 查询7天前的历史记录 + * @return + */ + @GetMapping("/find/history/message") + @ApiOperation(value = "查询7天前的历史记录", notes = "根据ID查询7天前的历史记录") + public AjaxResult findHistoryMessage( + @ApiParam(value = "游标:最后一条消息id", required = true, example = "1") + @RequestParam(defaultValue = "1") Long id, + @ApiParam(value = "分页页码,默认为10条/页", example = "10") + @RequestParam(required = false,defaultValue = "10")Integer pageNum, + @ApiParam(value = "聊天室id", required = true, example = "1") + @RequestParam Long roomId + ) { + return chatMessageService.findHistoryMessage(id,pageNum,roomId); + } + + @GetMapping("/find/recently/message") + @ApiOperation(value = "查询七天内的记录", notes = "根据ID查询七天内的记录") + public AjaxResult findRecentlyMessage( + @ApiParam(value = "游标:最后一条消息id", required = true, example = "1") + @RequestParam(defaultValue = "1") Long id, + @ApiParam(value = "分页页码,默认为10条/页", example = "10") + @RequestParam(required = false,defaultValue = "10")Integer pageNum, + @ApiParam(value = "聊天室id", required = true, example = "1") + @RequestParam Long roomId + ) { + return chatMessageService.findRecentlyMessage(id,pageNum,roomId); + } + + @GetMapping("/delete/message") + @ApiOperation(value = "消息撤回或删除") + public AjaxResult deleteMessage( + @ApiParam(value = "消息id", required = true, example = "1") + @RequestParam(defaultValue = "1") Long id, + @ApiParam(value = "消息类型 0 文本 1 图片", example = "0") + @RequestParam(required = false,defaultValue = "0")Integer type + ) { + return chatMessageService.deleteMessage(id,type); + } + + @GetMapping("/read/message") + @ApiOperation(value = "聊天室消息改已读") + public AjaxResult readMessage( + @ApiParam(value = "聊天室id", required = true, example = "1") + @RequestParam Long roomId) { + return null; + } + + + + +} \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatRoomController.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatRoomController.java new file mode 100644 index 0000000..72162a3 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatRoomController.java @@ -0,0 +1,41 @@ +package com.m2pool.chat.controller; + +import com.m2pool.chat.service.ChatRoomService; +import com.m2pool.chat.vo.CharRoomVo; +import com.m2pool.common.core.web.Result.AjaxResult; +import com.m2pool.common.core.web.page.TableDataInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@Api(tags = "聊天室相关接口") +@RestController +@RequestMapping("/chat/rooms") +public class ChatRoomController { + + @Autowired + private ChatRoomService chatRoomService; + + + @GetMapping("/find/room/list") + @ApiOperation(value = "查询客服人员的聊天室列表") + public TableDataInfo findRoomList() { + return chatRoomService.findRoomList(); + } + + @GetMapping("/find/room/by/userid") + @ApiOperation(value = "根据当前用户邮箱查询聊天室") + public AjaxResult findRoomByUserid(@ApiParam(value = "当前用户聊天对象的userId", example = "1") + @RequestParam(required = false) String email) { + return chatRoomService.findRoomByUserid(email); + } + + + @GetMapping("/update/room") + @ApiOperation(value = "修改room相关信息") + public AjaxResult updateRoom(@RequestBody CharRoomVo charRoomVo) { + return chatRoomService.updateRoom(charRoomVo); + } +} \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/StompController.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/StompController.java new file mode 100644 index 0000000..0aa247c --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/StompController.java @@ -0,0 +1,38 @@ +package com.m2pool.chat.controller; + +import com.m2pool.chat.service.StompService; +import com.m2pool.chat.vo.UserMessageVo; +import com.m2pool.common.core.web.Result.AjaxResult; +import com.m2pool.common.core.web.controller.BaseController; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.messaging.simp.annotation.SendToUser; +import org.springframework.stereotype.Controller; + +import javax.annotation.Resource; + +/** + * @Description TODO + * @Date 2025/2/24 15:05 + * @Author 杜懿 + */ +@Controller +public class StompController extends BaseController { + + + + + @Resource + private StompService stompService; + + /** + * 发送消息到对应的用户 + * @param userMessageVo 消息体 + * @return 返回值通过CommonMessageConvert消息转换器转换 + */ + @MessageMapping("/send/message") + @SendToUser("/queue") + public AjaxResult sendMessageToUser(@Payload UserMessageVo userMessageVo) { + return stompService.sendMessageToUser(userMessageVo); + } +} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/ChatMessageDto.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/ChatMessageDto.java new file mode 100644 index 0000000..9c037b7 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/ChatMessageDto.java @@ -0,0 +1,33 @@ +package com.m2pool.chat.dto; + +import cn.hutool.core.date.DateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @ClassName ChatMessageDto + * @Description 聊天消息返回对象 + * @Author yyb + * @Date 2025/4/14 14:28 + */ + +@ApiModel(description = "聊天消息返回对象") +@Data +public class ChatMessageDto { + + @ApiModelProperty(value = "消息ID", example = "1") + private Long id; + + @ApiModelProperty(value = "消息类型", example = "0 文本 1 图片") + private Integer type; + + @ApiModelProperty(value = "发送者邮箱", example = "54544@qq.com") + private String sendEmail; + + @ApiModelProperty(value = "消息内容", example = "消息内容") + private String content; + + @ApiModelProperty(value = "发送时间", example = "") + private DateTime createTime; +} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/ChatRoomDto.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/ChatRoomDto.java new file mode 100644 index 0000000..7ec957c --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/ChatRoomDto.java @@ -0,0 +1,43 @@ +package com.m2pool.chat.dto; + +import cn.hutool.core.date.DateTime; +import lombok.Data; + +/** + * @ClassName ChatRoomDto + * @Description 客服 聊天室列表返回对象 + * @Author yyb + * @Date 2025/4/14 14:28 + */ +@Data +public class ChatRoomDto { + + /** + * 聊天室id + */ + private Long id; + /** + * 聊天对象id + */ + private String userEmail; + /** + * 聊天室重要程度 + */ + private Integer flag; + + /** + * 未读消息条数 + */ + private Integer unReadNumber; + + + /** + * 用户回复时间 + */ + private DateTime lastUserSendTime; + + /** + * 客服回复时间 + */ + private DateTime lastCustomerSendTime; +} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/WebsocketMessageDto.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/WebsocketMessageDto.java index e9dfa6d..3534892 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/WebsocketMessageDto.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/WebsocketMessageDto.java @@ -10,6 +10,23 @@ import lombok.Data; */ @Data public class WebsocketMessageDto { - private String type; - private String message; + + /** + * 消息id + */ + private Long id; + + /** + * 消息类型 + */ + private Integer type; + + /** + * 消息内容 + */ + private String content; + /** + * 是否是登录用户 + */ + private boolean isLoginUser; } diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatMessage.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatMessage.java index 3c7f254..16de54b 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatMessage.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatMessage.java @@ -1,22 +1,18 @@ package com.m2pool.chat.entity; +import cn.hutool.core.date.DateTime; +import lombok.Builder; import lombok.Data; -import java.util.Date; - -/** - * @Description TODO - * @Date 2025/3/7 15:53 - * @Author 杜懿 - */ +@Builder @Data public class ChatMessage { private Long id; - private String senderType; // USER 0/CUSTOMER_SERVICE 1 - private String senderId; // 邮箱或客服ID - private String receiverId; + private Integer type; + private Integer read; + private String sendEmail; private String content; - private String userIdentifier; // 邮箱或浏览器指纹 - private String browserFingerprint; - private Date createdTime; + private Long roomId; + private DateTime createTime; + private DateTime updateTime; } diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatMessageHistory.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatMessageHistory.java new file mode 100644 index 0000000..297df17 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatMessageHistory.java @@ -0,0 +1,15 @@ +package com.m2pool.chat.entity; + +import cn.hutool.core.date.DateTime; +import lombok.Data; + +@Data +public class ChatMessageHistory { + private Long id; + private Integer type; + private String sendEmail; + private String content; + private Long roomId; + private DateTime createTime; + private DateTime updateTime; +} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatMsg.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatMsg.java deleted file mode 100644 index ef5661b..0000000 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatMsg.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.m2pool.chat.entity; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Data; -import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.Transient; - -import java.util.Date; - -/** - * @Description TODO - * @Date 2025/2/28 18:11 - * @Author 杜懿 - */ -@Data -public class ChatMsg { - @Id - private String id; - - /** - * 创建时间 - */ - @JsonFormat(pattern = "yyyy_MM_dd_HH_mm_ss") - private Date createTime=new Date(); - - /** - * 通信key(sendId_receiveId) - */ - private String msgKey; - - /** - * 通信消息 - */ - private String chatMsg; - - /** - * 发送id - */ - private String sendId; - - /** - * 接收id - */ - private String receiveId; - - /** - * 查看状态 0未看 1已看 - */ - private String readState; - - /** - *1为我 0 为他 - */ - @Transient - private Integer flag; - - @Transient - private String name; - -} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatRoom.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatRoom.java new file mode 100644 index 0000000..62e0d50 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/ChatRoom.java @@ -0,0 +1,19 @@ +package com.m2pool.chat.entity; + +import cn.hutool.core.date.DateTime; +import lombok.Builder; +import lombok.Data; + +@Builder +@Data +public class ChatRoom { + private Long id; + private String userOneEmail; + private String userTwoEmail; + private DateTime lastUserSendTime; + private DateTime lastCustomerSendTime; + private Boolean flag; + private DateTime createTime; + private DateTime updateTime; + private Boolean del; +} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/StompPrincipal.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/StompPrincipal.java new file mode 100644 index 0000000..c6b8804 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/entity/StompPrincipal.java @@ -0,0 +1,19 @@ +package com.m2pool.chat.entity; + +import java.security.Principal; + +/** + * stomp用户身份信息 + */ +public class StompPrincipal implements Principal { + String name; + + public StompPrincipal(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } +} \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/exception/WebSocketException.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/exception/WebSocketException.java index 7690f4a..999538b 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/exception/WebSocketException.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/exception/WebSocketException.java @@ -4,23 +4,16 @@ import com.m2pool.common.core.exception.base.BaseException; public class WebSocketException extends BaseException { - private static String websocket_module = "chat-websocket"; - - - public WebSocketException(String module, String code, Object[] args, String defaultMessage) { super(module, code, args, defaultMessage); - module = websocket_module; } public WebSocketException(String module, String code, Object[] args) { super(module, code, args); - module = websocket_module; } public WebSocketException(String module, String defaultMessage) { super(module, defaultMessage); - module = websocket_module; } public WebSocketException(String code, Object[] args) { diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/interceptor/WebsocketChannelInterceptor.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/interceptor/WebsocketChannelInterceptor.java index 2929583..7118234 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/interceptor/WebsocketChannelInterceptor.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/interceptor/WebsocketChannelInterceptor.java @@ -1,18 +1,26 @@ package com.m2pool.chat.interceptor; +import com.m2pool.chat.entity.StompPrincipal; import org.springframework.lang.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.messaging.simp.stomp.StompCommand; import org.springframework.messaging.simp.stomp.StompHeaderAccessor; import org.springframework.messaging.support.ChannelInterceptor; +import org.springframework.messaging.support.MessageHeaderAccessor; + +import java.util.ArrayList; +import java.util.Map; + +import static com.m2pool.chat.constant.Destination.VISITOR_PREFIX; /** * @ClassName WebsocketChannelInterceptor - * @Description websocket channel 通道拦截器 + * @Description websocket channel 通道拦截器 适用于前端@stomp/stompjs 实现. * @Author yyb * @Date 2025/4/10 15:44 */ @@ -27,26 +35,41 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor { */ @Override public Message preSend(Message message, MessageChannel channel) { + //获取链接建立时的请求头信息 StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message); - - //TODO 前端通过@stomp/stompjs、基于stomp-client+webscoket等插件实现,可以在该方法获取自定义请求头,做一些校验 - if (accessor.getCommand() == StompCommand.CONNECT) { + String visitor = (String) accessor.getSessionAttributes().get(VISITOR_PREFIX); LOGGER.info("------------收到websocket的连接消息"); - } + //获取channel 中的请求头信息 + StompHeaderAccessor mha = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); + Object raw = message.getHeaders().get(SimpMessageHeaderAccessor.NATIVE_HEADERS); + System.out.println("raw:"+raw); + if (raw instanceof Map) { + Object userInfo = ((Map) raw).get("userId"); + // 游客或登录用户 + if (userInfo == null){ + mha.setUser(new StompPrincipal(visitor)); + }else if(userInfo instanceof ArrayList) { + mha.setUser(new StompPrincipal((String) ((ArrayList) userInfo).get(0))); + } + } + } if (accessor.getCommand() == StompCommand.SEND) { - LOGGER.info("------------收到websocket的数据发送消息"); + LOGGER.info("------------websocket send message"); } if (accessor.getCommand() == StompCommand.SUBSCRIBE) { - LOGGER.info("------------收到websocket的订阅消息"); + LOGGER.info("------------websocket subscribe message"); } if (accessor.getCommand() == StompCommand.UNSUBSCRIBE) { - LOGGER.info("------------收到websocket的取消订阅消息"); + LOGGER.info("------------websocket unsubscribe"); } + if (accessor.getCommand() == StompCommand.DISCONNECT){ + LOGGER.info("------------websocket disconnect"); + } return message; } diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/interceptor/WebsocketHandshakeInterceptor.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/interceptor/WebsocketHandshakeInterceptor.java index bdc0c62..568b9aa 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/interceptor/WebsocketHandshakeInterceptor.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/interceptor/WebsocketHandshakeInterceptor.java @@ -9,10 +9,12 @@ import org.springframework.web.socket.server.HandshakeInterceptor; import java.util.Map; +import static com.m2pool.chat.constant.Destination.VISITOR_PREFIX; + /** * @ClassName WebsocketHandshakeInterceptor - * @Description websocket 握手处理器类 + * @Description websocket 握手处理器类 适用于前端原生websocket实现.建立websocket链接时调用 * @Author yyb * @Date 2025/4/10 15:39 */ @@ -20,15 +22,32 @@ public class WebsocketHandshakeInterceptor implements HandshakeInterceptor { private static final Logger LOGGER = LoggerFactory.getLogger(WebsocketHandshakeInterceptor.class); + + + @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception { LOGGER.info("------------------WebsocketHandshakeInterceptor:beforeHandshake"); - //TODO 前端如果是webscoket原生实现, 获取一些自定义请求头,做一些校验 +// 为游客生成一个唯一标识 +// String s = generateVisitorId(request); +// attributes.put(VISITOR_PREFIX, s); +// response.getHeaders().add(VISITOR_PREFIX, s); return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { - LOGGER.info("-----------------WebsocketHandshakeInterceptor:afterHandshake"); + LOGGER.info("------------------WebsocketHandshakeInterceptor:afterHandshake"); + } + + /** + * 生成一个唯一标识 + * @param request + * @return + */ + private String generateVisitorId(ServerHttpRequest request) { + String first = request.getHeaders().getFirst("sec-websocket-key"); + String prefix = VISITOR_PREFIX; + return prefix + first; } } diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatMapper.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatMapper.java deleted file mode 100644 index 7f56ada..0000000 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatMapper.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.m2pool.chat.mapper; - -import com.m2pool.chat.entity.ChatMessage; -import com.m2pool.common.datasource.annotation.Master; -import org.apache.ibatis.annotations.Param; - -import javax.validation.constraints.Pattern; -import java.util.List; - -/** - * @Description 角色数据层 - * @Date 2024/6/12 17:37 - * @Author dy - */ -@Master -public interface ChatMapper { - - public boolean insert(@Param("vo") ChatMessage vo); - -} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatMessageHistoryMapper.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatMessageHistoryMapper.java new file mode 100644 index 0000000..b23635d --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatMessageHistoryMapper.java @@ -0,0 +1,22 @@ +package com.m2pool.chat.mapper; + + +import com.m2pool.chat.dto.ChatMessageDto; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface ChatMessageHistoryMapper { + + /** + * 根据游标查询十条数据 + * @param id + * @param pageNum + * @param roomId + * @return + */ + List findHistoryMessage(@Param("id") Long id,@Param("pageNum") Integer pageNum,@Param("roomId") Long roomId); + +} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatMessageMapper.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatMessageMapper.java new file mode 100644 index 0000000..92d800e --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatMessageMapper.java @@ -0,0 +1,34 @@ +package com.m2pool.chat.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.m2pool.chat.dto.ChatMessageDto; +import com.m2pool.chat.entity.ChatMessage; +import org.apache.ibatis.annotations.MapKey; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface ChatMessageMapper extends BaseMapper { + + /** + * 根据游标查询十条数据 + * @param id + * @param pageNum + * @param roomId + * @return + */ + List findRecentlyMessage(@Param("id") Long id,@Param("pageNum") Integer pageNum,@Param("roomId") Long roomId); + + + /** + * 查询未读消息条数 + * @param userEmails + * @return Map,键为用户邮箱,值为未读消息条数 + */ + @MapKey("userEmail") + Map findUnReadNums(@Param("userEmails") List userEmails); + +} \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatRoomMapper.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatRoomMapper.java new file mode 100644 index 0000000..d54240b --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/mapper/ChatRoomMapper.java @@ -0,0 +1,35 @@ +package com.m2pool.chat.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.m2pool.chat.dto.ChatRoomDto; +import com.m2pool.chat.entity.ChatRoom; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface ChatRoomMapper extends BaseMapper { + + + /** + * 查询客服的聊天室列表 + * @param userEmail 客服邮箱 + * @return + */ + List findRoomList(@Param("userEmail") String userEmail); + + + + /** + * 查找当前用户与对应用户是否已存在创建的聊天室 + * @param userEmail 用户邮箱 + * @param email 客服邮箱 + * @return + */ + String findRoomByUserEmail(@Param("userEmail") String userEmail,@Param("email") String email); + + + +} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatMessageService.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatMessageService.java new file mode 100644 index 0000000..cc8c132 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatMessageService.java @@ -0,0 +1,42 @@ +package com.m2pool.chat.service; + +import com.m2pool.common.core.web.Result.AjaxResult; + +public interface ChatMessageService{ + + + /** + * 游标分页 查询7天前的历史记录 + * @param id 游标 + * @param pageNum 每页条数 + * @param roomId 聊天室id + * @return + */ + AjaxResult findHistoryMessage(Long id, Integer pageNum,Long roomId); + + /** + * 游标分页 查询7天内数据 + * @param id 游标 + * @param pageNum 每页条数 + * @param roomId 聊天室id + * @return + */ + AjaxResult findRecentlyMessage(Long id,Integer pageNum,Long roomId); + + + /** + * 根据消息id 删除 + * @param id 消息id + * @param type 消息类型 0 文本 1 图片 + * @return + */ + AjaxResult deleteMessage(Long id,Integer type); + + + /** + * 根据聊天室修改用户未读信息 + * @param roomId + * @return + */ + AjaxResult readMessage(Long roomId); +} \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatRoomService.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatRoomService.java new file mode 100644 index 0000000..836e170 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatRoomService.java @@ -0,0 +1,30 @@ +package com.m2pool.chat.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.m2pool.chat.entity.ChatRoom; +import com.m2pool.chat.vo.CharRoomVo; +import com.m2pool.common.core.web.Result.AjaxResult; +import com.m2pool.common.core.web.page.TableDataInfo; + +public interface ChatRoomService extends IService { + + /** + * 查询客服的聊天室列表 + * @return + */ + TableDataInfo findRoomList(); + + /** + * 根据当前用户邮箱查询聊天室 + * @return + */ + AjaxResult findRoomByUserid(String email); + + /** + * 修改聊天室信息 + * @param charRoomVo + * @return + */ + AjaxResult updateRoom( CharRoomVo charRoomVo); + +} \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatService.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatService.java deleted file mode 100644 index cefc38d..0000000 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatService.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.m2pool.chat.service; - -import com.m2pool.common.core.web.Result.AjaxResult; -import com.m2pool.system.api.entity.SysUser; -import org.springframework.cache.CacheManager; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @Description TODO - * @Date 2025/2/28 18:06 - * @Author 杜懿 - */ -public interface ChatService { - - //public AjaxResult userList(UserItem userItem, SysUser data); - - public AjaxResult getHistory(String identifier); - -} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/StompService.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/StompService.java new file mode 100644 index 0000000..7789735 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/StompService.java @@ -0,0 +1,15 @@ +package com.m2pool.chat.service; + +import com.m2pool.chat.vo.UserMessageVo; +import com.m2pool.common.core.web.Result.AjaxResult; + +public interface StompService { + + /** + * 发送消息给用户 + * @param userMessageVo + * @return + */ + AjaxResult sendMessageToUser(UserMessageVo userMessageVo); + +} \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/WebSocketServer.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/WebSocketServer.java deleted file mode 100644 index 673edad..0000000 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/WebSocketServer.java +++ /dev/null @@ -1,169 +0,0 @@ -package com.m2pool.chat.service; - -import com.alibaba.fastjson.JSONObject; -import com.m2pool.chat.entity.ChatMsg; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cache.CacheManager; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import javax.websocket.*; -import javax.websocket.server.ServerEndpoint; -import java.io.IOException; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @Description TODO - * @Date 2025/2/28 18:02 - * @Author 杜懿 - */ -@ServerEndpoint(value = "/ws/asset") -@Component -public class WebSocketServer { - - private static ChatService chatService; - @Autowired - public void setChatService(ChatService chatService) { - WebSocketServer.chatService = chatService; - } - - @PostConstruct - public void init() { - System.out.println("websocket 加载"); - } - private static Logger log = LoggerFactory.getLogger(WebSocketServer.class); - private static final AtomicInteger OnlineCount = new AtomicInteger(0); - // concurrent包的线程安全Set,用来存放每个客户端对应的Session对象。 - private static CopyOnWriteArraySet SessionSet = new CopyOnWriteArraySet(); - /** - * 连接建立成功调用的方法 - */ - @OnOpen - public void onOpen(Session session) { - SessionSet.add(session); - int cnt = OnlineCount.incrementAndGet(); - log.info("有连接加入,当前连接数为:{}", cnt); - SendMessage(session, "连接成功"); - } - - /** - * 连接关闭调用的方法 - */ - @OnClose - public void onClose(Session session) { - SessionSet.remove(session); - int cnt = OnlineCount.decrementAndGet(); - log.info("有连接关闭,当前连接数为:{}", cnt); - } - - /** - * 收到客户端消息后调用的方法 - * @param message 客户端发送过来的消息 - */ - @OnMessage - public void onMessage(String message, Session session) { - log.info("来自客户端的消息:{}",message); - try{ - JSONObject jsonObject = JSONObject.parseObject(message); - String linkType = jsonObject.getString("linkType"); - String sendId = jsonObject.getString("sendId"); - if (linkType.equals("bind")){ - //CacheManager.set("bind_"+sendId,session); - SendMessage(session, "连接成功"); - }else if (linkType.equals("msg")){ - //聊天 - ChatMsg msg = new ChatMsg(); - //发消息 - String chatMsg = jsonObject.getString("chatMsg"); - String receiveId = jsonObject.getString("receiveId"); - msg.setChatMsg(chatMsg); - msg.setSendId(sendId); - msg.setMsgKey(sendId+"_"+receiveId); - msg.setReceiveId(receiveId); - msg.setReadState("0"); - //chatService.sendOne(msg); - } - }catch (Exception e){ - e.printStackTrace(); - } - } - - /** - * 出现错误 - * @param session - * @param error - */ - @OnError - public void onError(Session session, Throwable error) { - log.error("发生错误:{},Session ID: {}",error.getMessage(),session.getId()); - error.printStackTrace(); - } - - /** - * 发送消息,实践表明,每次浏览器刷新,session会发生变化。 - * @param session - * @param message - */ - public static void SendMessage(Session session, String message) { - try { - //session.getBasicRemote().sendText(String.format("%s (From Server,Session ID=%s)",message,session.getId())); - log.info("sessionID="+session.getId()); - session.getBasicRemote().sendText(message); - } catch (IOException e) { - log.error("发送消息出错:{}", e.getMessage()); - e.printStackTrace(); - } - } - - - /** - * 指定Session发送消息 - * @param sessionId - * @param message - * @throws IOException - */ - public static void SendMessageById(String message,String sessionId) throws IOException { - Session session = null; - for (Session s : SessionSet) { - if(s.getId().equals(sessionId)){ - session = s; - break; - } - } - if(session!=null){ - SendMessage(session, message); - } - else{ - log.warn("没有找到你指定ID的会话:{}",sessionId); - } - } - /** - * @description: 指定发送 - * @author: lvyq - * @date: 2021/9/24 11:30 - * @version 1.0 - */ - public static void SendMessageByRecId(String message,String receiveId) throws IOException { - //Session session= CacheManager.get("bind_"+receiveId); - Session session= null; - String sessionId = ""; - if (session!=null){ - sessionId=session.getId(); - } - for (Session s : SessionSet) { - if(s.getId().equals(sessionId)){ - session = s; - break; - } - } - if(session!=null){ - SendMessage(session, message); - } - else{ - System.out.println("没有找到你指定ID的会话:"+sessionId); - } - } -} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatMessageServiceImpl.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatMessageServiceImpl.java new file mode 100644 index 0000000..8ece644 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatMessageServiceImpl.java @@ -0,0 +1,69 @@ +package com.m2pool.chat.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.m2pool.chat.dto.ChatMessageDto; +import com.m2pool.chat.entity.ChatMessage; +import com.m2pool.chat.entity.ChatRoom; +import com.m2pool.chat.mapper.ChatMessageHistoryMapper; +import com.m2pool.chat.mapper.ChatMessageMapper; +import com.m2pool.chat.mapper.ChatRoomMapper; +import com.m2pool.chat.service.ChatMessageService; +import com.m2pool.common.core.web.Result.AjaxResult; +import com.m2pool.common.security.utils.SecurityUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; + +@Service +public class ChatMessageServiceImpl implements ChatMessageService { + + @Resource + private ChatMessageMapper chatMessageMapper; + + @Resource + private ChatMessageHistoryMapper chatMessageHistoryMapper; + + @Resource + private ChatRoomMapper chatRoomMapper; + + @Override + public AjaxResult findHistoryMessage(Long id,Integer pageNum,Long roomId) { + List historyMessage = chatMessageHistoryMapper.findHistoryMessage(id, pageNum, roomId); + return AjaxResult.success(historyMessage); + } + + @Override + public AjaxResult findRecentlyMessage(Long id,Integer pageNum,Long roomId) { + List recentlyMessage = chatMessageMapper.findRecentlyMessage(id, pageNum, roomId); + return AjaxResult.success(recentlyMessage); + } + + @Override + public AjaxResult deleteMessage(Long id,Integer type) { + if(chatMessageMapper.deleteById(id) > 0){ + //TODO 对象图片存储删除 + return AjaxResult.success("删除成功"); + } + return AjaxResult.error("删除失败"); + } + + + @Override + @Transactional + public AjaxResult readMessage(Long roomId) { + ChatRoom chatRoom = chatRoomMapper.selectById(roomId); + String username = SecurityUtils.getUsername(); + + String updateUserEmail = ""; + if(username.equals(chatRoom.getUserOneEmail())){ + updateUserEmail = chatRoom.getUserTwoEmail(); + }else if(username.equals(chatRoom.getUserTwoEmail())){ + updateUserEmail = chatRoom.getUserOneEmail(); + } + int update = chatMessageMapper.update(ChatMessage.builder().read(1).build(), + new LambdaUpdateWrapper().eq(ChatMessage::getSendEmail, updateUserEmail).eq(ChatMessage::getRoomId, roomId)); + return update > 0 ? AjaxResult.success("已读") : AjaxResult.error("消息读取失败"); + } +} \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatRoomServiceImpl.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatRoomServiceImpl.java new file mode 100644 index 0000000..4667eb3 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatRoomServiceImpl.java @@ -0,0 +1,89 @@ +package com.m2pool.chat.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.github.pagehelper.PageInfo; +import com.m2pool.chat.dto.ChatRoomDto; +import com.m2pool.chat.entity.ChatRoom; +import com.m2pool.chat.mapper.ChatMessageMapper; +import com.m2pool.chat.mapper.ChatRoomMapper; +import com.m2pool.chat.service.ChatRoomService; +import com.m2pool.chat.vo.CharRoomVo; +import com.m2pool.common.core.constant.HttpStatus; +import com.m2pool.common.core.utils.PageUtils; +import com.m2pool.common.core.utils.StringUtils; +import com.m2pool.common.core.web.Result.AjaxResult; +import com.m2pool.common.core.web.page.TableDataInfo; +import com.m2pool.common.security.utils.SecurityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class ChatRoomServiceImpl extends ServiceImpl implements ChatRoomService { + + @Autowired + private ChatRoomMapper chatRoomMapper; + + @Resource + private ChatMessageMapper chatMessageMapper; + + @Override + public TableDataInfo findRoomList() { + PageUtils.startPage(); + //1.查找当前客服对应的聊天室 + List roomList = chatRoomMapper.findRoomList(SecurityUtils.getUsername()); + List userEmails = roomList.stream().map(ChatRoomDto::getUserEmail).collect(Collectors.toList()); + //2.查询未读数量 + Map unReadNums = chatMessageMapper.findUnReadNums(userEmails); + + for (ChatRoomDto room : roomList) { + Integer i = unReadNums.get(room.getUserEmail()); + room.setUnReadNumber(i == null ? 0 : i); + } + return getDataTable(roomList); + } + + private TableDataInfo getDataTable(List list) + { + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setRows(list); + rspData.setMsg("查询成功"); + PageInfo pageInfo = new PageInfo(list); + rspData.setTotal(pageInfo.getTotal()); + rspData.setTotalPage(pageInfo.getPages()); + return rspData; + } + + + @Override + @Transactional + public AjaxResult findRoomByUserid(String email) { + //1.查询当前用户与对应用户是否已存在创建的聊天室 + String userEmail = SecurityUtils.getUsername(); + String roomByUserEmail = chatRoomMapper.findRoomByUserEmail(userEmail, email); + if(StringUtils.isNotEmpty(roomByUserEmail)){ + return AjaxResult.success(roomByUserEmail); + } + //2.不存在创建一个聊天室 + int insert = chatRoomMapper.insert(ChatRoom.builder().userOneEmail(userEmail).userTwoEmail(email).build()); + if (insert > 0){ + return AjaxResult.success(roomByUserEmail); + } + return AjaxResult.error("聊天室不存在,并且创建聊天室失败"); + } + + @Override + public AjaxResult updateRoom(CharRoomVo charRoomVo) { + int i = chatRoomMapper.updateById(ChatRoom.builder().id(charRoomVo.getId()).flag(charRoomVo.getFlag()).build()); + if(i > 0){ + return AjaxResult.success("修改成功"); + } + return AjaxResult.error("修改失败"); + } +} \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatServiceImpl.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatServiceImpl.java deleted file mode 100644 index dccd4a7..0000000 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatServiceImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.m2pool.chat.service.impl; - -import com.m2pool.chat.entity.ChatMessage; -import com.m2pool.chat.mapper.ChatMapper; -import com.m2pool.chat.service.ChatService; -import com.m2pool.common.core.web.Result.AjaxResult; -import com.m2pool.common.security.utils.SecurityUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; - - -/** - * @Description TODO - * @Date 2025/2/28 18:08 - * @Author 杜懿 - */ -@Service -public class ChatServiceImpl implements ChatService { - - @Autowired - private ChatMapper chatMapper; - - @Async("messageExecutor") - public void saveMessageAsync(ChatMessage message) { - // 批量插入优化 - chatMapper.insert(message); - } - - @Override - public AjaxResult getHistory(String identifier) { - - return null; - } - - -} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/StompServiceImpl.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/StompServiceImpl.java new file mode 100644 index 0000000..e1fb381 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/StompServiceImpl.java @@ -0,0 +1,97 @@ +package com.m2pool.chat.service.impl; + +import cn.hutool.core.date.DateTime; +import com.m2pool.chat.constant.Destination; +import com.m2pool.chat.dto.WebsocketMessageDto; +import com.m2pool.chat.entity.ChatMessage; +import com.m2pool.chat.entity.ChatRoom; +import com.m2pool.chat.mapper.ChatMessageMapper; +import com.m2pool.chat.mapper.ChatRoomMapper; +import com.m2pool.chat.service.StompService; +import com.m2pool.chat.vo.UserMessageVo; +import com.m2pool.common.core.web.Result.AjaxResult; +import com.m2pool.common.security.utils.SecurityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.messaging.simp.user.SimpUserRegistry; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +import static com.m2pool.chat.constant.UserType.CUSTOMER; +import static com.m2pool.chat.constant.UserType.TOURIST; + +@Service +public class StompServiceImpl implements StompService { + + @Autowired + private SimpUserRegistry userRegistry; + + @Autowired + private SimpMessagingTemplate messagingTemplate; + + @Resource + private ChatMessageMapper chatMessageMapper; + + @Resource + private ChatRoomMapper chatRoomMapper; + + @Override + public AjaxResult sendMessageToUser(UserMessageVo userMessageVo) { + WebsocketMessageDto websocketMessageDto = new WebsocketMessageDto(); + websocketMessageDto.setType(userMessageVo.getType()); + websocketMessageDto.setContent(userMessageVo.getContent()); + // 检查目标用户是否在线 + if (!checkOnline(userMessageVo)) { + return AjaxResult.error("目标用户不在线"); + } + //当前用户发送其他人, 发送给指定用户. 否则默认发送给当前发送者 + messagingTemplate.convertAndSendToUser(userMessageVo.getEmail(), Destination.QUEUE + "/" + userMessageVo.getEmail(), userMessageVo.getContent()); + // 接收者和发送者 都不是游客才能存储消息 和修改聊天室信息 + if (!TOURIST.equals(userMessageVo.getReceiveUserType()) && TOURIST.equals(userMessageVo.getSendUserType())){ + Long id = insertMessage(userMessageVo); + websocketMessageDto.setId(id); + updateRoom(userMessageVo); + } + return AjaxResult.success(websocketMessageDto); + } + + /** + * 检查用户是否在线 + * @return + */ + private boolean checkOnline(UserMessageVo userMessageVo){ + return userRegistry.getUsers().stream() + .anyMatch(user -> user.getName().equals(userMessageVo.getEmail())); + } + + /** + * 新增消息 + * @param userMessageVo + * @return + */ + private Long insertMessage(UserMessageVo userMessageVo){ + ChatMessage message = ChatMessage.builder() + .sendEmail(SecurityUtils.getUsername()) + .content(userMessageVo.getContent()) + .type(userMessageVo.getType()) + .roomId(userMessageVo.getRoomId()) + .build(); + chatMessageMapper.insert(message); + return message.getId(); + } + + /** + * 修改聊天信息 + * @param userMessageVo + */ + private void updateRoom(UserMessageVo userMessageVo){ + ChatRoom room = ChatRoom.builder().id(userMessageVo.getRoomId()).build(); + if (CUSTOMER.equals(userMessageVo.getSendUserType())) { + room.setLastCustomerSendTime(DateTime.now()); + } else { + room.setLastUserSendTime(DateTime.now()); + } + chatRoomMapper.insert(room); + } +} \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/task/ChatTask.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/task/ChatTask.java new file mode 100644 index 0000000..104e353 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/task/ChatTask.java @@ -0,0 +1,13 @@ +package com.m2pool.chat.task; + +/** + * @ClassName ChatTask + * @Description chat 聊天室和消息定时任务 + * @Author yyb + * @Date 2025/4/15 11:51 + */ +public class ChatTask { + + + +} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/CharRoomVo.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/CharRoomVo.java new file mode 100644 index 0000000..a3d1354 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/CharRoomVo.java @@ -0,0 +1,15 @@ +package com.m2pool.chat.vo; + +import lombok.Data; + +/** + * @ClassName CharRoomVo + * @Description 聊天室请求对象 + * @Author yyb + * @Date 2025/4/15 10:42 + */ +@Data +public class CharRoomVo { + private Long id; + private Boolean flag; +} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/ChatHistoryVo.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/ChatHistoryVo.java deleted file mode 100644 index df10153..0000000 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/ChatHistoryVo.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.m2pool.chat.vo; - -import lombok.Data; - -/** - * @Description TODO - * @Date 2025/3/7 15:55 - * @Author 杜懿 - */ -@Data -public class ChatHistoryVo { - private String email; - private String browserId; -} diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/UserMessageVo.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/UserMessageVo.java index 139e2b8..f9497fd 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/UserMessageVo.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/UserMessageVo.java @@ -14,10 +14,32 @@ public class UserMessageVo { /** * 消息类型 */ - private String type; + private Integer type; /** - * 消息体 + * 消息内容 */ - private String message; + private String content; + + /** + * 接收者 + */ + private String email; + + /** + * 接受用户类型 0 游客 1 登录用户 2 客服人员 + */ + private Integer receiveUserType; + + /** + * 发送者类型 0 游客 1 登录用户 2 客服人员 + */ + private Integer sendUserType; + + /** + * 聊天室id + */ + private Long roomId; + + } diff --git a/m2pool-modules/m2pool-chat/src/main/resources/bootstrap-prod.yml b/m2pool-modules/m2pool-chat/src/main/resources/bootstrap-prod.yml new file mode 100644 index 0000000..66ea7d0 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,76 @@ +server: + port: 9209 + compression: + enabled: true + mime-types: application/json + +spring: + #邮箱基本配置 + mail: + # 配置在limit_time内,用户可以发送limit次验证码 + limit: 2 这个是我额外的配置,结合邮箱服务用的 + limitTime: 10 这个是我额外的配置 + #配置smtp服务主机地址 + # sina smtp.sina.cn + # aliyun smtp.aliyun.com + # 163 smtp.163.com 端口号465或994 + host: mail.privateemail.com + #发送者邮箱 + username: support@m2pool.cc + #配置密码,注意不是真正的密码,而是刚刚申请到的授权码 + # password: + # password: m2pool2024@! + # password: axvm-zfgx-cgcg-qhhu + password: m2pool2024@! + #端口号 + port: 587 + #默认的邮件编码为UTF-8 + default-encoding: UTF-8 + #其他参数 + properties: + mail: + #配置SSL 加密工厂 + smtp: + ssl: + #本地测试,先放开ssl + enable: false + required: false + #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误 + debug: false + socketFactory: + class: javax.net.ssl.SSLSocketFactory + + application: + # 应用名称 + name: m2pool-chat +# profiles: +# # 环境配置 +# active: prod + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8808 + namespace: m2_prod + group: m2_prod_group + # server-addr: 127.0.0.1:8808 + config: + # 配置中心地址 + server-addr: 127.0.0.1:8808 + # server-addr: 127.0.0.1:8808 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: m2_prod + group: m2_prod_group + servlet: + multipart: + max-file-size: 2MB + max-request-size: 8MB + +myenv: + domain: https://www.m2pool.com + path: /var/www/html/web + img: /img diff --git a/m2pool-modules/m2pool-chat/src/main/resources/bootstrap-test.yml b/m2pool-modules/m2pool-chat/src/main/resources/bootstrap-test.yml new file mode 100644 index 0000000..f89cb1e --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/resources/bootstrap-test.yml @@ -0,0 +1,43 @@ +#测试环境 +server: + port: 9509 + compression: + enabled: true + mime-types: application/json + +spring: + application: + # 应用名称 + name: m2pool-chat +# profiles: +# # 环境配置 +# active: test + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + namespace: m2_test + group: m2_test_group + # server-addr: 127.0.0.1:8808 + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # server-addr: 127.0.0.1:8808 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: m2_test + group: m2_test_group + servlet: + multipart: + max-file-size: 2MB + max-request-size: 8MB + +myenv: + domain: https://test.m2pool.com + path: /var/www/html/web_test + img: /imgpp + diff --git a/m2pool-modules/m2pool-chat/src/main/resources/bootstrap.yml b/m2pool-modules/m2pool-chat/src/main/resources/bootstrap.yml index 8233eb9..90385b2 100644 --- a/m2pool-modules/m2pool-chat/src/main/resources/bootstrap.yml +++ b/m2pool-modules/m2pool-chat/src/main/resources/bootstrap.yml @@ -1,156 +1,3 @@ -server: - port: 9209 - compression: - enabled: true - mime-types: application/json - spring: - #邮箱基本配置 - mail: - # 配置在limit_time内,用户可以发送limit次验证码 - limit: 2 这个是我额外的配置,结合邮箱服务用的 - limitTime: 10 这个是我额外的配置 - #配置smtp服务主机地址 - # sina smtp.sina.cn - # aliyun smtp.aliyun.com - # 163 smtp.163.com 端口号465或994 - host: mail.privateemail.com - #发送者邮箱 - username: support@m2pool.cc - #配置密码,注意不是真正的密码,而是刚刚申请到的授权码 - # password: - # password: m2pool2024@! - # password: axvm-zfgx-cgcg-qhhu - password: m2pool2024@! - #端口号 - port: 587 - #默认的邮件编码为UTF-8 - default-encoding: UTF-8 - #其他参数 - properties: - mail: - #配置SSL 加密工厂 - smtp: - ssl: - #本地测试,先放开ssl - enable: false - required: false - #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误 - debug: false - socketFactory: - class: javax.net.ssl.SSLSocketFactory - - application: - # 应用名称 - name: m2pool-chat profiles: - # 环境配置 - active: prod - cloud: - nacos: - discovery: - # 服务注册地址 - server-addr: 127.0.0.1:8808 - namespace: m2_prod - group: m2_prod_group - # server-addr: 127.0.0.1:8808 - config: - # 配置中心地址 - server-addr: 127.0.0.1:8808 - # server-addr: 127.0.0.1:8808 - # 配置文件格式 - file-extension: yml - # 共享配置 - shared-configs: - - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} - namespace: m2_prod - group: m2_prod_group - servlet: - multipart: - max-file-size: 2MB - max-request-size: 8MB - -myenv: - domain: https://www.m2pool.com - path: /var/www/html/web - img: /img - - -#测试环境 -#server: -# port: 9509 -# compression: -# enabled: true -# mime-types: application/json -# -#spring: -# #邮箱基本配置 -# mail: -# # 配置在limit_time内,用户可以发送limit次验证码 -# limit: 2 这个是我额外的配置,结合邮箱服务用的 -# limitTime: 10 这个是我额外的配置 -# #配置smtp服务主机地址 -# # sina smtp.sina.cn -# # aliyun smtp.aliyun.com -# # 163 smtp.163.com 端口号465或994 -# host: mail.privateemail.com -# #发送者邮箱 -# username: support@m2pool.cc -# #配置密码,注意不是真正的密码,而是刚刚申请到的授权码 -# # password: -# # password: m2pool2024@! -# # password: axvm-zfgx-cgcg-qhhu -# password: m2pool2024@! -# #端口号 -# port: 587 -# #默认的邮件编码为UTF-8 -# default-encoding: UTF-8 -# #其他参数 -# properties: -# mail: -# #配置SSL 加密工厂 -# smtp: -# ssl: -# #本地测试,先放开ssl -# enable: false -# required: false -# #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误 -# debug: false -# socketFactory: -# class: javax.net.ssl.SSLSocketFactory -# -# application: -# # 应用名称 -# name: m2pool-chat -# profiles: -# # 环境配置 -# active: test -# cloud: -# nacos: -# discovery: -# # 服务注册地址 -# server-addr: 127.0.0.1:8808 -# namespace: m2_test -# group: m2_test_group -# # server-addr: 127.0.0.1:8808 -# config: -# # 配置中心地址 -# server-addr: 127.0.0.1:8808 -# # server-addr: 127.0.0.1:8808 -# # 配置文件格式 -# file-extension: yml -# # 共享配置 -# shared-configs: -# - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} -# namespace: m2_test -# group: m2_test_group -# servlet: -# multipart: -# max-file-size: 2MB -# max-request-size: 8MB -# -#myenv: -# domain: https://test.m2pool.com -# path: /var/www/html/web_test -# img: /imgpp -# + active: prod \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatMessageHistoryMapper.xml b/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatMessageHistoryMapper.xml new file mode 100644 index 0000000..e1097df --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatMessageHistoryMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatMessageMapper.xml b/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatMessageMapper.xml new file mode 100644 index 0000000..99deca7 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatMessageMapper.xml @@ -0,0 +1,29 @@ + + + + + + + + + \ No newline at end of file diff --git a/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatRoomMapper.xml b/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatRoomMapper.xml new file mode 100644 index 0000000..07d45cd --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatRoomMapper.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/m2pool-modules/m2pool-system/src/main/java/com/m2pool/system/M2PoolSystemApplication.java b/m2pool-modules/m2pool-system/src/main/java/com/m2pool/system/M2PoolSystemApplication.java index 8758501..122d11c 100644 --- a/m2pool-modules/m2pool-system/src/main/java/com/m2pool/system/M2PoolSystemApplication.java +++ b/m2pool-modules/m2pool-system/src/main/java/com/m2pool/system/M2PoolSystemApplication.java @@ -3,6 +3,7 @@ package com.m2pool.system; import com.m2pool.common.security.annotation.EnableCustomConfig; import com.m2pool.common.security.annotation.EnableM2PoolFeignClients; import com.m2pool.common.swagger.annotation.EnableCustomSwagger2; +import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -16,6 +17,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @EnableCustomSwagger2 @EnableM2PoolFeignClients @SpringBootApplication +@MapperScan({"com.m2pool.system.mapper"}) public class M2PoolSystemApplication { public static void main(String[] args) { diff --git a/m2pool-modules/m2pool-system/src/main/resources/bootstrap-prod.yml b/m2pool-modules/m2pool-system/src/main/resources/bootstrap-prod.yml new file mode 100644 index 0000000..5dc7215 --- /dev/null +++ b/m2pool-modules/m2pool-system/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,28 @@ +# Tomcat +server: + port: 9201 + +# Spring +spring: + application: + # 应用名称 + name: m2pool-system + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8808 + namespace: m2_prod + group: m2_prod_group + config: + # 配置中心地址 + server-addr: 127.0.0.1:8808 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: m2_prod + group: m2_prod_group + + diff --git a/m2pool-modules/m2pool-system/src/main/resources/bootstrap-test.yml b/m2pool-modules/m2pool-system/src/main/resources/bootstrap-test.yml new file mode 100644 index 0000000..1f2a5bb --- /dev/null +++ b/m2pool-modules/m2pool-system/src/main/resources/bootstrap-test.yml @@ -0,0 +1,24 @@ +server: + port: 9501 + +spring: + application: + # 应用名称 + name: m2pool-system + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + namespace: m2_test + group: m2_test_group + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: m2_test + group: m2_test_group diff --git a/m2pool-modules/m2pool-system/src/main/resources/bootstrap.yml b/m2pool-modules/m2pool-system/src/main/resources/bootstrap.yml index f430808..90385b2 100644 --- a/m2pool-modules/m2pool-system/src/main/resources/bootstrap.yml +++ b/m2pool-modules/m2pool-system/src/main/resources/bootstrap.yml @@ -1,58 +1,3 @@ -## Tomcat -#server: -# port: 9201 -# -## Spring -#spring: -# application: -# # 应用名称 -# name: m2pool-system -# profiles: -# # 环境配置 -# active: prod -# cloud: -# nacos: -# discovery: -# # 服务注册地址 -# server-addr: 127.0.0.1:8808 -# namespace: m2_prod -# group: m2_prod_group -# config: -# # 配置中心地址 -# server-addr: 127.0.0.1:8808 -# # 配置文件格式 -# file-extension: yml -# # 共享配置 -# shared-configs: -# - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} -# namespace: m2_prod -# group: m2_prod_group - - -server: - port: 9501 - spring: - application: - # 应用名称 - name: m2pool-system profiles: - # 环境配置 - active: test - cloud: - nacos: - discovery: - # 服务注册地址 - server-addr: 127.0.0.1:8808 - namespace: m2_test - group: m2_test_group - config: - # 配置中心地址 - server-addr: 127.0.0.1:8808 - # 配置文件格式 - file-extension: yml - # 共享配置 - shared-configs: - - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} - namespace: m2_test - group: m2_test_group + active: prod \ No newline at end of file