From 851f434e1e3f8d8b8115a00276a76a39500d3518 Mon Sep 17 00:00:00 2001 From: liyd-b Date: Tue, 27 Jun 2023 16:44:42 +0800 Subject: [PATCH 01/42] =?UTF-8?q?fix:=20=E5=8E=BB=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E4=BB=A3=E7=A0=81=EF=BC=88sout=EF=BC=89=EF=BC=8C?= =?UTF-8?q?=E7=83=A6=E8=AF=B7=E4=BD=9C=E8=80=85=E9=80=9A=E8=BF=87pr?= =?UTF-8?q?=E5=93=88=EF=BC=8C=E8=AF=81=E6=98=8E=E6=88=91=E4=B9=9F=E6=98=AF?= =?UTF-8?q?=E4=B8=80=E5=90=8Dcontributor=20=20=E5=93=88=E5=93=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/abin/mallchat/custom/chat/controller/ChatController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ChatController.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ChatController.java index ac0154e..61e862f 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ChatController.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ChatController.java @@ -124,7 +124,6 @@ public class ChatController { private void filterBlackMsg(CursorPageBaseResp memberPage) { Set blackMembers = getBlackUidSet(); memberPage.getList().removeIf(a -> blackMembers.contains(a.getFromUser().getUid().toString())); - System.out.println(1); } @PostMapping("/msg") From d08a22d6b150083a9cb6fec652d3c2f3bc912b53 Mon Sep 17 00:00:00 2001 From: yangzhengwu <947380458@qq.com> Date: Mon, 3 Jul 2023 16:27:50 +0800 Subject: [PATCH 02/42] =?UTF-8?q?bugFix:NullPointerException=E7=9A=84getMe?= =?UTF-8?q?ssage=E9=BB=98=E8=AE=A4=E6=98=AFnull,=E6=89=80=E4=BB=A5?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E5=BF=85=E8=A6=81=E6=89=93=E5=8D=B0=E5=87=BA?= =?UTF-8?q?=E6=9D=A5=EF=BC=8C=E7=9B=B4=E6=8E=A5=E6=89=93=E5=8D=B0=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=A0=86=E6=A0=88=E5=8D=B3=E5=8F=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/common/exception/GlobalExceptionHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/GlobalExceptionHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/GlobalExceptionHandler.java index 3a986e1..a5a06eb 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/GlobalExceptionHandler.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/GlobalExceptionHandler.java @@ -42,7 +42,7 @@ public class GlobalExceptionHandler { */ @ExceptionHandler(value = NullPointerException.class) public ApiResult exceptionHandler(NullPointerException e) { - log.error("null point exception!The reason is:{}", e.getMessage(), e); + log.error("null point exception!The reason is: ", e); return ApiResult.fail(CommonErrorEnum.SYSTEM_ERROR); } From 6cf7379ac4d420464dea038f16adc9191a8f7004 Mon Sep 17 00:00:00 2001 From: zbzbzzz Date: Mon, 3 Jul 2023 18:06:04 +0800 Subject: [PATCH 03/42] =?UTF-8?q?fix:=E4=BC=98=E5=8C=96ws=E6=8F=A1?= =?UTF-8?q?=E6=89=8B=E5=90=8C=E6=97=B6=E8=AE=A4=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/algorithm/ac/CreateTokenTest.java | 11 +- .../service/impl/WebSocketServiceImpl.java | 4 + .../custom/user/websocket/NettyUtil.java | 2 + .../user/websocket/NettyWebSocketServer.java | 4 +- .../NettyWebSocketServerHandler.java | 19 +- .../NettyWebSocketServerProtocolHandler.java | 61 +++++++ .../websocket/WebSocketHandshakeHandler.java | 165 +++++++++++++++--- 7 files changed, 223 insertions(+), 43 deletions(-) create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerProtocolHandler.java diff --git a/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java b/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java index 50908e4..34d4035 100644 --- a/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java +++ b/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java @@ -6,7 +6,6 @@ import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.JWTVerifier; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.junit.Test; import java.util.Date; @@ -18,7 +17,7 @@ public class CreateTokenTest { @Test public void create(){ String token = JWT.create() - .withClaim("uid", 123L) // 只存一个uid信息,其他的自己去redis查 + .withClaim("uid", 10004L) // 只存一个uid信息,其他的自己去redis查 .withClaim("createTime", new Date()) .sign(Algorithm.HMAC256("dsfsdfsdfsdfsd")); // signature log.info("生成的token为 {}",token); @@ -33,12 +32,4 @@ public class CreateTokenTest { } } - @Test - public void verifyToken(){ - String token = JWT.create() - .withClaim("uid", 1) // 只存一个uid信息,其他的自己去redis查 - .withClaim("createTime", new Date()) - .sign(Algorithm.HMAC256("dsfsdfsdfsdfsd")); // signature - log.info("生成的token为{}",token); - } } diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java index 7282473..96d0f68 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java @@ -29,6 +29,7 @@ import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; @@ -140,7 +141,10 @@ public class WebSocketServiceImpl implements WebSocketService { } } + // 这里可以加异步或者事件去处理登录 + // 因为登录和推送消息其实是不用同步的两个步骤 这样可以加快连接的速度不占用nio线程 @Override + @Async public void authorize(Channel channel, WSAuthorize wsAuthorize) { //校验token boolean verifySuccess = loginService.verify(wsAuthorize.getToken()); diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyUtil.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyUtil.java index 79daafa..bcc5b05 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyUtil.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyUtil.java @@ -1,6 +1,7 @@ package com.abin.mallchat.custom.user.websocket; import io.netty.channel.Channel; +import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker; import io.netty.util.Attribute; import io.netty.util.AttributeKey; @@ -15,6 +16,7 @@ public class NettyUtil { public static AttributeKey TOKEN = AttributeKey.valueOf("token"); public static AttributeKey IP = AttributeKey.valueOf("ip"); public static AttributeKey UID = AttributeKey.valueOf("uid"); + public static AttributeKey HANDSHAKER_ATTR_KEY = AttributeKey.valueOf(WebSocketServerHandshaker.class, "HANDSHAKER"); public static void setAttr(Channel channel, AttributeKey attributeKey, T data) { Attribute attr = channel.attr(attributeKey); diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java index b70b867..b84bc06 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java @@ -10,6 +10,7 @@ import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.stream.ChunkedWriteHandler; @@ -88,7 +89,8 @@ public class NettyWebSocketServer { * 4. WebSocketServerProtocolHandler 核心功能是把 http协议升级为 ws 协议,保持长连接; * 是通过一个状态码 101 来切换的 */ - pipeline.addLast(new WebSocketHandshakeHandler()); + pipeline.addLast(new NettyWebSocketServerProtocolHandler("/")); + new WebSocketServerProtocolHandler("/"); // 自定义handler ,处理业务逻辑 pipeline.addLast(new NettyWebSocketServerHandler()); } diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java index 3d75069..b4fbb0a 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java @@ -1,6 +1,5 @@ package com.abin.mallchat.custom.user.websocket; -import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; import cn.hutool.json.JSONUtil; import com.abin.mallchat.custom.user.domain.enums.WSReqTypeEnum; @@ -19,10 +18,11 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class NettyWebSocketServerHandler extends SimpleChannelInboundHandler { + private WebSocketService webSocketService; // 当web客户端连接后,触发该方法 @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { -// getService().connect(ctx.channel()); + this.webSocketService = getService(); } // 客户端离线 @@ -45,7 +45,7 @@ public class NettyWebSocketServerHandler extends SimpleChannelInboundHandler out) throws Exception { + if (this.webSocketServerProtocolConfig.handleCloseFrames() && frame instanceof CloseWebSocketFrame) { + WebSocketServerHandshaker handshaker = NettyUtil.getAttr(ctx.channel(),NettyUtil.HANDSHAKER_ATTR_KEY); + if (handshaker != null) { + frame.retain(); + ChannelPromise promise = ctx.newPromise(); + Method closeSent = ReflectUtil.getMethod(super.getClass(), "closeSent", ChannelPromise.class); + closeSent.setAccessible(true); + closeSent.invoke(this,promise); + handshaker.close(ctx, (CloseWebSocketFrame)frame, promise); + } else { + ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); + } + } else { + super.decode(ctx, frame, out); + } + } +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/WebSocketHandshakeHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/WebSocketHandshakeHandler.java index f501602..8054c90 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/WebSocketHandshakeHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/WebSocketHandshakeHandler.java @@ -5,38 +5,159 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.ChannelPromise; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpObject; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpUtil; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakeException; import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker; import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory; +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolConfig; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; +import io.netty.handler.ssl.SslHandler; +import io.netty.util.ReferenceCountUtil; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.FutureListener; +import io.netty.util.internal.ObjectUtil; + +import java.util.concurrent.TimeUnit; public class WebSocketHandshakeHandler extends ChannelInboundHandlerAdapter { + + private final WebSocketServerProtocolConfig serverConfig; + private ChannelHandlerContext ctx; + private ChannelPromise handshakePromise; + private boolean isWebSocketPath; + + public WebSocketHandshakeHandler(WebSocketServerProtocolConfig serverConfig) { + this.serverConfig = (WebSocketServerProtocolConfig)ObjectUtil.checkNotNull(serverConfig, "serverConfig"); + } + @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof FullHttpRequest) { - FullHttpRequest request = (FullHttpRequest) msg; - String token = request.headers().get("Sec-Websocket-Protocol"); - NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token); - // 构建WebSocket握手处理器 - WebSocketServerHandshakerFactory handshakeFactory = new WebSocketServerHandshakerFactory( - request.uri(), token, false); - WebSocketServerHandshaker handshake = handshakeFactory.newHandshaker(request); - final ChannelFuture handshakeFuture = handshake.handshake(ctx.channel(), request); - ctx.pipeline().remove(this); - handshakeFuture.addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) { - if (!future.isSuccess()) { - ctx.fireExceptionCaught(future.cause()); + public void handlerAdded(ChannelHandlerContext ctx) { + this.ctx = ctx; + this.handshakePromise = ctx.newPromise(); + } + + @Override + public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception { + HttpObject httpObject = (HttpObject)msg; + if (httpObject instanceof HttpRequest) { + final HttpRequest req = (HttpRequest)httpObject; + this.isWebSocketPath = this.isWebSocketPath(req); + if (!this.isWebSocketPath) { + ctx.fireChannelRead(msg); + return; + } + try { + if (HttpMethod.GET.equals(req.method())) { + final String token = req.headers().get("Sec-Websocket-Protocol"); + WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketLocation(ctx.pipeline(), req, this.serverConfig.websocketPath()), token, this.serverConfig.decoderConfig()); + final WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req); + NettyUtil.setAttr(ctx.channel(),NettyUtil.HANDSHAKER_ATTR_KEY,handshaker); + final ChannelPromise localHandshakePromise = this.handshakePromise; + if (handshaker == null) { + WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { - // 手动触发WebSocket握手状态事件 - ctx.fireUserEventTriggered( - WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE); + + ctx.pipeline().remove(this); + ChannelFuture handshakeFuture = handshaker.handshake(ctx.channel(), req); + handshakeFuture.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) { + if (!future.isSuccess()) { + localHandshakePromise.tryFailure(future.cause()); + ctx.fireExceptionCaught(future.cause()); + } else { + localHandshakePromise.trySuccess(); + NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token); + ctx.fireUserEventTriggered(WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE); + } + } + }); + this.applyHandshakeTimeout(); } + + return; } - }); + + sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.FORBIDDEN, ctx.alloc().buffer(0))); + } finally { + ReferenceCountUtil.release(req); + } + + return; + } else if (!this.isWebSocketPath) { + ctx.fireChannelRead(msg); } else { - super.channelRead(ctx, msg); + ReferenceCountUtil.release(msg); + } + + } + + private boolean isWebSocketPath(HttpRequest req) { + String websocketPath = this.serverConfig.websocketPath(); + String uri = req.uri(); + boolean checkStartUri = uri.startsWith(websocketPath); + boolean checkNextUri = "/".equals(websocketPath) || this.checkNextUri(uri, websocketPath); + return this.serverConfig.checkStartsWith() ? checkStartUri && checkNextUri : uri.equals(websocketPath); + } + + private boolean checkNextUri(String uri, String websocketPath) { + int len = websocketPath.length(); + if (uri.length() <= len) { + return true; + } else { + char nextUri = uri.charAt(len); + return nextUri == '/' || nextUri == '?'; } } + + private static void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) { + ChannelFuture f = ctx.channel().writeAndFlush(res); + if (!HttpUtil.isKeepAlive(req) || res.status().code() != 200) { + f.addListener(ChannelFutureListener.CLOSE); + } + + } + + private static String getWebSocketLocation(ChannelPipeline cp, HttpRequest req, String path) { + String protocol = "ws"; + if (cp.get(SslHandler.class) != null) { + protocol = "wss"; + } + + String host = req.headers().get(HttpHeaderNames.HOST); + return protocol + "://" + host + path; + } + + private void applyHandshakeTimeout() { + final ChannelPromise localHandshakePromise = this.handshakePromise; + long handshakeTimeoutMillis = this.serverConfig.handshakeTimeoutMillis(); + if (handshakeTimeoutMillis > 0L && !localHandshakePromise.isDone()) { + final Future timeoutFuture = this.ctx.executor().schedule(new Runnable() { + @Override + public void run() { + if (!localHandshakePromise.isDone() && localHandshakePromise.tryFailure(new WebSocketServerHandshakeException("handshake timed out"))) { + WebSocketHandshakeHandler.this.ctx.flush().fireUserEventTriggered(WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_TIMEOUT).close(); + } + + } + }, handshakeTimeoutMillis, TimeUnit.MILLISECONDS); + localHandshakePromise.addListener(new FutureListener() { + @Override + public void operationComplete(Future f) { + timeoutFuture.cancel(false); + } + }); + } + } + } From f7a80fa8d9da58ae85d5725fb5aa9b4d5f2c8b2c Mon Sep 17 00:00:00 2001 From: zbzbzzz Date: Mon, 3 Jul 2023 18:09:27 +0800 Subject: [PATCH 04/42] =?UTF-8?q?fix:=E4=BC=98=E5=8C=96ws=E6=8F=A1?= =?UTF-8?q?=E6=89=8B=E5=90=8C=E6=97=B6=E8=AE=A4=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mallchat/custom/user/websocket/NettyWebSocketServer.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java index b84bc06..3448528 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java @@ -10,7 +10,6 @@ import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; -import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.stream.ChunkedWriteHandler; @@ -90,7 +89,6 @@ public class NettyWebSocketServer { * 是通过一个状态码 101 来切换的 */ pipeline.addLast(new NettyWebSocketServerProtocolHandler("/")); - new WebSocketServerProtocolHandler("/"); // 自定义handler ,处理业务逻辑 pipeline.addLast(new NettyWebSocketServerHandler()); } From 5347d4f56bf60ed4b0362a6c952617d3e40d8671 Mon Sep 17 00:00:00 2001 From: WSJ <996387929@qq.com> Date: Mon, 3 Jul 2023 18:17:08 +0800 Subject: [PATCH 05/42] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=A1=A8=E6=83=85?= =?UTF-8?q?=E5=8C=85=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/version/emojis.sql | 10 +++ .../common/chat/domain/entity/McEmojis.java | 58 +++++++++++++ .../common/user/mapper/EmojisMapper.java | 13 +++ .../user/controller/EmojisController.java | 84 +++++++++++++++++++ .../domain/vo/request/user/EmojisPageReq.java | 14 ++++ .../custom/user/service/EmojisService.java | 26 ++++++ .../user/service/impl/EmojisServiceImpl.java | 43 ++++++++++ 7 files changed, 248 insertions(+) create mode 100644 docs/version/emojis.sql create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/McEmojis.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/EmojisMapper.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/EmojisController.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/request/user/EmojisPageReq.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/EmojisService.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/EmojisServiceImpl.java diff --git a/docs/version/emojis.sql b/docs/version/emojis.sql new file mode 100644 index 0000000..ea238de --- /dev/null +++ b/docs/version/emojis.sql @@ -0,0 +1,10 @@ +CREATE TABLE `mc_emojis` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `user_id` bigint(20) NOT NULL COMMENT '用户表ID', + `expression_url` varchar(255) NOT NULL COMMENT '表情地址', + `create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', + `update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间', + `del_flg` int(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除(0-正常,1-删除)', + PRIMARY KEY (`id`), + KEY `IDX_MC_EMOJIS_USER_ID` (`user_id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='用户表情包'; \ No newline at end of file diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/McEmojis.java b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/McEmojis.java new file mode 100644 index 0000000..09d7ecf --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/McEmojis.java @@ -0,0 +1,58 @@ +package com.abin.mallchat.common.chat.domain.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; + +/** + * 用户表情包 + * + * @author: WuShiJie + * @createTime: 2023/7/2 22:00 + */ +@Data +@TableName(value = "mc_emojis") +public class McEmojis implements Serializable { + private static final long serialVersionUID = -7690290707154737263L; + + /** + * id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 用户表ID + */ + @TableField(value = "user_id") + private Long userId; + + + /** + * 表情地址 + */ + @NotNull + @TableField(value = "expression_url") + private String expressionUrl; + + /** + * 创建时间 + */ + @TableField("create_time") + private Date createTime; + + /** + * 修改时间 + */ + @TableField("update_time") + private Date updateTime; + + @TableField(value = "del_flg") + @TableLogic(value = "0",delval = "1") + private Integer delFlg; + + +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/EmojisMapper.java b/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/EmojisMapper.java new file mode 100644 index 0000000..67af9e6 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/EmojisMapper.java @@ -0,0 +1,13 @@ +package com.abin.mallchat.common.user.mapper; + +import com.abin.mallchat.common.chat.domain.entity.McEmojis; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 用户表情包 Mapper + * + * @author: WuShiJie + * @createTime: 2023/7/3 14:24 + */ +public interface EmojisMapper extends BaseMapper { +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/EmojisController.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/EmojisController.java new file mode 100644 index 0000000..2121797 --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/EmojisController.java @@ -0,0 +1,84 @@ +package com.abin.mallchat.custom.user.controller; + +import cn.hutool.core.util.StrUtil; +import com.abin.mallchat.common.chat.domain.entity.McEmojis; +import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; +import com.abin.mallchat.common.common.domain.vo.response.ApiResult; +import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; +import com.abin.mallchat.common.common.utils.RequestHolder; +import com.abin.mallchat.custom.user.service.EmojisService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 用户表情包 + * + * @author: WuShiJie + * @createTime: 2023/7/3 14:21 + */ +@RestController +@RequestMapping("/capi/emojis") +@Api(tags = "用户表情包管理相关接口") +public class EmojisController { + + /** + * 用户表情包 Service + */ + @Resource + private EmojisService emojisService; + + + /** + * 表情包列表 + * + * @param request 游标翻页请求参数 + * @return 表情包列表 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + @GetMapping("/getEmojisPage") + @ApiOperation("表情包列表") + public ApiResult> getEmojisPage(@Valid CursorPageBaseReq request) { + return ApiResult.success(emojisService.getEmojisPage(request, RequestHolder.get().getUid())); + } + + + /** + * 新增表情包 + * + * @param emojis 用户表情包 + * @return 表情包 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + @PostMapping("/insertEmojis") + @ApiOperation("表情包列表") + public ApiResult insertEmojis(@Valid @RequestBody McEmojis emojis) { + emojis.setUserId(RequestHolder.get().getUid()); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(McEmojis::getUserId,emojis.getUserId()); + queryWrapper.eq(McEmojis::getExpressionUrl,emojis.getExpressionUrl()); + emojisService.saveOrUpdate(emojis, queryWrapper); + return ApiResult.success(emojis); + } + + /** + * 删除表情包 + * + * @param id 用户表情包ID + * @return 删除结果 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + @GetMapping("/deleteEmojis") + @ApiOperation("表情包列表") + public ApiResult deleteEmojis(@RequestParam("id") String id) { + emojisService.removeById(id); + return ApiResult.success(); + } +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/request/user/EmojisPageReq.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/request/user/EmojisPageReq.java new file mode 100644 index 0000000..9dfe00f --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/request/user/EmojisPageReq.java @@ -0,0 +1,14 @@ +package com.abin.mallchat.custom.user.domain.vo.request.user; + +import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; +import lombok.Data; + +/** + * 描述此类的作用 + * + * @author: WuShiJie + * @createTime: 2023/7/3 14:52 + */ +@Data +public class EmojisPageReq extends CursorPageBaseReq { +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/EmojisService.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/EmojisService.java new file mode 100644 index 0000000..89fb81f --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/EmojisService.java @@ -0,0 +1,26 @@ +package com.abin.mallchat.custom.user.service; + +import com.abin.mallchat.common.chat.domain.entity.McEmojis; +import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; +import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; +import com.abin.mallchat.custom.chat.domain.vo.response.ChatRoomResp; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * 用户表情包 Service + * + * @author: WuShiJie + * @createTime: 2023/7/3 14:22 + */ +public interface EmojisService extends IService { + + /** + * 表情包列表 + * + * @param request 游标翻页请求参数 + * @return 表情包列表 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + CursorPageBaseResp getEmojisPage(CursorPageBaseReq request, Long uid); +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/EmojisServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/EmojisServiceImpl.java new file mode 100644 index 0000000..26dbe09 --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/EmojisServiceImpl.java @@ -0,0 +1,43 @@ +package com.abin.mallchat.custom.user.service.impl; + +import com.abin.mallchat.common.chat.domain.entity.McEmojis; +import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; +import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; +import com.abin.mallchat.common.common.utils.CursorUtils; +import com.abin.mallchat.common.user.mapper.EmojisMapper; +import com.abin.mallchat.custom.chat.service.adapter.RoomAdapter; +import com.abin.mallchat.custom.user.service.EmojisService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * 用户表情包 ServiceImpl + * + * @author: WuShiJie + * @createTime: 2023/7/3 14:23 + */ +@Service +@Slf4j +public class EmojisServiceImpl extends ServiceImpl implements EmojisService { + + @Autowired + private CursorUtils cursorUtils; + + /** + * 表情包列表 + * + * @param request 游标翻页请求参数 + * @return 表情包列表 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + @Override + public CursorPageBaseResp getEmojisPage(CursorPageBaseReq request, Long uid) { + CursorPageBaseResp cursorPageByMysql = cursorUtils.getCursorPageByMysql(this, request, wrapper -> { + wrapper.eq(McEmojis::getUserId, uid); + }, McEmojis::getId); + return cursorPageByMysql; + } +} From e671c66a26a90de73de339c14339dac93e7ad484 Mon Sep 17 00:00:00 2001 From: zbzbzzz Date: Mon, 3 Jul 2023 18:34:14 +0800 Subject: [PATCH 06/42] =?UTF-8?q?fix:=E4=BC=98=E5=8C=96ws=E6=8F=A1?= =?UTF-8?q?=E6=89=8B=E5=90=8C=E6=97=B6=E8=AE=A4=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/websocket/NettyWebSocketServerProtocolHandler.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerProtocolHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerProtocolHandler.java index 4ada0c9..73c7471 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerProtocolHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerProtocolHandler.java @@ -8,6 +8,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame; +import io.netty.handler.codec.http.websocketx.Utf8FrameValidator; import io.netty.handler.codec.http.websocketx.WebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolConfig; @@ -37,6 +38,10 @@ public class NettyWebSocketServerProtocolHandler extends WebSocketServerProtocol cp.addBefore(ctx.name(), WebSocketHandshakeHandler.class.getName(), new WebSocketHandshakeHandler(this.webSocketServerProtocolConfig)); } + if (this.webSocketServerProtocolConfig.decoderConfig().withUTF8Validator() && cp.get(Utf8FrameValidator.class) == null) { + cp.addBefore(ctx.name(), Utf8FrameValidator.class.getName(), new Utf8FrameValidator(this.webSocketServerProtocolConfig.decoderConfig().closeOnProtocolViolation())); + } + } @Override From 41660e189b034a2e6053a4533288ec49b679ce61 Mon Sep 17 00:00:00 2001 From: wangchao Date: Mon, 3 Jul 2023 21:44:35 +0800 Subject: [PATCH 07/42] =?UTF-8?q?feat=EF=BC=9A=E4=BD=BF=E7=94=A8caffine?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E5=AD=98=E5=82=A8=EF=BC=8C=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E4=B8=8Elru=E6=B7=98=E6=B1=B0=E7=AD=96?= =?UTF-8?q?=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/WebSocketServiceImpl.java | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java index 7282473..d451d86 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java @@ -20,6 +20,8 @@ import com.abin.mallchat.custom.user.service.LoginService; import com.abin.mallchat.custom.user.service.WebSocketService; import com.abin.mallchat.custom.user.service.adapter.WSAdapter; import com.abin.mallchat.custom.user.websocket.NettyUtil; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import io.netty.channel.Channel; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import lombok.SneakyThrows; @@ -32,9 +34,11 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; +import java.time.Duration; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -47,12 +51,18 @@ import java.util.concurrent.locks.ReentrantLock; @Slf4j public class WebSocketServiceImpl implements WebSocketService { + private static final Duration EXPIRE_TIME = Duration.ofHours(1); + private static final Long MAX_MUM_SIZE = 10000L; + + private static final AtomicInteger CODE = new AtomicInteger(); /** * 所有请求登录的code与channel关系 - * todo 有可能有人请求了二维码,就是不登录,留个坑,之后处理 */ - private static final ConcurrentHashMap WAIT_LOGIN_MAP = new ConcurrentHashMap<>(); + private static final Cache WAIT_LOGIN_MAP = Caffeine.newBuilder() + .expireAfterWrite(EXPIRE_TIME) + .maximumSize(MAX_MUM_SIZE) + .build(); /** * 所有已连接的websocket连接列表和一些额外参数 */ @@ -66,7 +76,6 @@ public class WebSocketServiceImpl implements WebSocketService { return ONLINE_WS_MAP; } - public static final int EXPIRE_SECONDS = 60 * 60; @Autowired private WxMpService wxMpService; @Autowired @@ -95,7 +104,7 @@ public class WebSocketServiceImpl implements WebSocketService { //生成随机不重复的登录码 Integer code = generateLoginCode(channel); //请求微信接口,获取登录码地址 - WxMpQrCodeTicket wxMpQrCodeTicket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(code, EXPIRE_SECONDS); + WxMpQrCodeTicket wxMpQrCodeTicket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(code, (int) EXPIRE_TIME.getSeconds()); //返回给前端 sendMsg(channel, WSAdapter.buildLoginResp(wxMpQrCodeTicket)); } @@ -107,12 +116,11 @@ public class WebSocketServiceImpl implements WebSocketService { * @return */ private Integer generateLoginCode(Channel channel) { - int code; do { - code = RandomUtil.randomInt(Integer.MAX_VALUE); - } while (WAIT_LOGIN_MAP.contains(code) - || Objects.nonNull(WAIT_LOGIN_MAP.putIfAbsent(code, channel))); - return code; + CODE.set(RandomUtil.randomInt(Integer.MAX_VALUE)); + } while (WAIT_LOGIN_MAP.asMap().containsKey(CODE.get()) + || Objects.isNull(WAIT_LOGIN_MAP.get(CODE.get(), c -> channel))); + return CODE.get(); } /** @@ -199,12 +207,12 @@ public class WebSocketServiceImpl implements WebSocketService { @Override public Boolean scanLoginSuccess(Integer loginCode, User user, String token) { //发送消息 - Channel channel = WAIT_LOGIN_MAP.get(loginCode); + Channel channel = WAIT_LOGIN_MAP.getIfPresent(loginCode); if (Objects.isNull(channel)) { return Boolean.FALSE; } //移除code - WAIT_LOGIN_MAP.remove(loginCode); + WAIT_LOGIN_MAP.invalidate(loginCode); //用户登录 loginSuccess(channel, user, token); return true; @@ -212,7 +220,7 @@ public class WebSocketServiceImpl implements WebSocketService { @Override public Boolean scanSuccess(Integer loginCode) { - Channel channel = WAIT_LOGIN_MAP.get(loginCode); + Channel channel = WAIT_LOGIN_MAP.getIfPresent(loginCode); if (Objects.isNull(channel)) { return Boolean.FALSE; } @@ -287,4 +295,6 @@ public class WebSocketServiceImpl implements WebSocketService { reentrantLock.unlock(); Thread.sleep(1000); } + + } From f25e535c04cb96800631fa606ff9d248e85ff816 Mon Sep 17 00:00:00 2001 From: wangchao Date: Mon, 3 Jul 2023 23:08:23 +0800 Subject: [PATCH 08/42] =?UTF-8?q?fix=EF=BC=9ACODE=20=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E8=87=AA=E5=A2=9E=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/user/service/impl/WebSocketServiceImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java index d451d86..03cda4d 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java @@ -2,7 +2,6 @@ package com.abin.mallchat.custom.user.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.RandomUtil; import cn.hutool.json.JSONUtil; import com.abin.mallchat.common.common.annotation.FrequencyControl; import com.abin.mallchat.common.common.config.ThreadPoolConfig; @@ -117,7 +116,7 @@ public class WebSocketServiceImpl implements WebSocketService { */ private Integer generateLoginCode(Channel channel) { do { - CODE.set(RandomUtil.randomInt(Integer.MAX_VALUE)); + CODE.getAndIncrement(); } while (WAIT_LOGIN_MAP.asMap().containsKey(CODE.get()) || Objects.isNull(WAIT_LOGIN_MAP.get(CODE.get(), c -> channel))); return CODE.get(); From ae1c1ed098b6b24d9c7bb72b251094f153985066 Mon Sep 17 00:00:00 2001 From: WSJ <996387929@qq.com> Date: Tue, 4 Jul 2023 09:22:35 +0800 Subject: [PATCH 09/42] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=A1=A8=E6=83=85?= =?UTF-8?q?=E5=8C=85=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/version/emojis.sql | 10 --- docs/version/user_emojis.sql | 10 +++ .../entity/{McEmojis.java => UserEmojis.java} | 12 +-- ...mojisMapper.java => UserEmojisMapper.java} | 4 +- ...troller.java => UserEmojisController.java} | 26 +++--- .../custom/user/service/EmojisService.java | 26 ------ .../user/service/UserEmojisService.java | 37 +++++++++ .../user/service/impl/EmojisServiceImpl.java | 43 ---------- .../service/impl/UserEmojisServiceImpl.java | 82 +++++++++++++++++++ 9 files changed, 147 insertions(+), 103 deletions(-) delete mode 100644 docs/version/emojis.sql create mode 100644 docs/version/user_emojis.sql rename mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/{McEmojis.java => UserEmojis.java} (80%) rename mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/{EmojisMapper.java => UserEmojisMapper.java} (60%) rename mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/{EmojisController.java => UserEmojisController.java} (65%) delete mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/EmojisService.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/UserEmojisService.java delete mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/EmojisServiceImpl.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojisServiceImpl.java diff --git a/docs/version/emojis.sql b/docs/version/emojis.sql deleted file mode 100644 index ea238de..0000000 --- a/docs/version/emojis.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE `mc_emojis` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', - `user_id` bigint(20) NOT NULL COMMENT '用户表ID', - `expression_url` varchar(255) NOT NULL COMMENT '表情地址', - `create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', - `update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间', - `del_flg` int(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除(0-正常,1-删除)', - PRIMARY KEY (`id`), - KEY `IDX_MC_EMOJIS_USER_ID` (`user_id`) -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='用户表情包'; \ No newline at end of file diff --git a/docs/version/user_emojis.sql b/docs/version/user_emojis.sql new file mode 100644 index 0000000..875edf0 --- /dev/null +++ b/docs/version/user_emojis.sql @@ -0,0 +1,10 @@ +CREATE TABLE `user_emojis` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `uid` bigint(20) NOT NULL COMMENT '用户表ID', + `expression_url` varchar(255) NOT NULL COMMENT '表情地址', + `create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', + `update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间', + `delete_status` int(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除(0-正常,1-删除)', + PRIMARY KEY (`id`), + KEY `IDX_MC_EMOJIS_USER_ID` (`uid`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='用户表情包'; \ No newline at end of file diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/McEmojis.java b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/UserEmojis.java similarity index 80% rename from mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/McEmojis.java rename to mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/UserEmojis.java index 09d7ecf..de707ff 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/McEmojis.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/UserEmojis.java @@ -14,8 +14,8 @@ import java.util.Date; * @createTime: 2023/7/2 22:00 */ @Data -@TableName(value = "mc_emojis") -public class McEmojis implements Serializable { +@TableName(value = "user_emojis") +public class UserEmojis implements Serializable { private static final long serialVersionUID = -7690290707154737263L; /** @@ -27,8 +27,8 @@ public class McEmojis implements Serializable { /** * 用户表ID */ - @TableField(value = "user_id") - private Long userId; + @TableField(value = "uid") + private Long uid; /** @@ -50,9 +50,9 @@ public class McEmojis implements Serializable { @TableField("update_time") private Date updateTime; - @TableField(value = "del_flg") + @TableField(value = "delete_status") @TableLogic(value = "0",delval = "1") - private Integer delFlg; + private Integer deleteStatus; } diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/EmojisMapper.java b/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/UserEmojisMapper.java similarity index 60% rename from mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/EmojisMapper.java rename to mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/UserEmojisMapper.java index 67af9e6..dd6b5b2 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/EmojisMapper.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/UserEmojisMapper.java @@ -1,6 +1,6 @@ package com.abin.mallchat.common.user.mapper; -import com.abin.mallchat.common.chat.domain.entity.McEmojis; +import com.abin.mallchat.common.chat.domain.entity.UserEmojis; import com.baomidou.mybatisplus.core.mapper.BaseMapper; /** @@ -9,5 +9,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; * @author: WuShiJie * @createTime: 2023/7/3 14:24 */ -public interface EmojisMapper extends BaseMapper { +public interface UserEmojisMapper extends BaseMapper { } diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/EmojisController.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/UserEmojisController.java similarity index 65% rename from mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/EmojisController.java rename to mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/UserEmojisController.java index 2121797..f88e69a 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/EmojisController.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/UserEmojisController.java @@ -1,12 +1,11 @@ package com.abin.mallchat.custom.user.controller; -import cn.hutool.core.util.StrUtil; -import com.abin.mallchat.common.chat.domain.entity.McEmojis; +import com.abin.mallchat.common.chat.domain.entity.UserEmojis; import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; import com.abin.mallchat.common.common.domain.vo.response.ApiResult; import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; import com.abin.mallchat.common.common.utils.RequestHolder; -import com.abin.mallchat.custom.user.service.EmojisService; +import com.abin.mallchat.custom.user.service.UserEmojisService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -22,15 +21,15 @@ import javax.validation.Valid; * @createTime: 2023/7/3 14:21 */ @RestController -@RequestMapping("/capi/emojis") +@RequestMapping("/capi/userEmojis") @Api(tags = "用户表情包管理相关接口") -public class EmojisController { +public class UserEmojisController { /** * 用户表情包 Service */ @Resource - private EmojisService emojisService; + private UserEmojisService emojisService; /** @@ -43,7 +42,7 @@ public class EmojisController { **/ @GetMapping("/getEmojisPage") @ApiOperation("表情包列表") - public ApiResult> getEmojisPage(@Valid CursorPageBaseReq request) { + public ApiResult> getEmojisPage(@Valid CursorPageBaseReq request) { return ApiResult.success(emojisService.getEmojisPage(request, RequestHolder.get().getUid())); } @@ -57,14 +56,9 @@ public class EmojisController { * @createTime 2023/7/3 14:46 **/ @PostMapping("/insertEmojis") - @ApiOperation("表情包列表") - public ApiResult insertEmojis(@Valid @RequestBody McEmojis emojis) { - emojis.setUserId(RequestHolder.get().getUid()); - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(McEmojis::getUserId,emojis.getUserId()); - queryWrapper.eq(McEmojis::getExpressionUrl,emojis.getExpressionUrl()); - emojisService.saveOrUpdate(emojis, queryWrapper); - return ApiResult.success(emojis); + @ApiOperation("新增表情包") + public ApiResult insertEmojis(@Valid @RequestBody UserEmojis emojis) { + return emojisService.insertEmojis(emojis,RequestHolder.get().getUid()); } /** @@ -76,7 +70,7 @@ public class EmojisController { * @createTime 2023/7/3 14:46 **/ @GetMapping("/deleteEmojis") - @ApiOperation("表情包列表") + @ApiOperation("删除表情包") public ApiResult deleteEmojis(@RequestParam("id") String id) { emojisService.removeById(id); return ApiResult.success(); diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/EmojisService.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/EmojisService.java deleted file mode 100644 index 89fb81f..0000000 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/EmojisService.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.abin.mallchat.custom.user.service; - -import com.abin.mallchat.common.chat.domain.entity.McEmojis; -import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; -import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; -import com.abin.mallchat.custom.chat.domain.vo.response.ChatRoomResp; -import com.baomidou.mybatisplus.extension.service.IService; - -/** - * 用户表情包 Service - * - * @author: WuShiJie - * @createTime: 2023/7/3 14:22 - */ -public interface EmojisService extends IService { - - /** - * 表情包列表 - * - * @param request 游标翻页请求参数 - * @return 表情包列表 - * @author WuShiJie - * @createTime 2023/7/3 14:46 - **/ - CursorPageBaseResp getEmojisPage(CursorPageBaseReq request, Long uid); -} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/UserEmojisService.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/UserEmojisService.java new file mode 100644 index 0000000..31a8ddd --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/UserEmojisService.java @@ -0,0 +1,37 @@ +package com.abin.mallchat.custom.user.service; + +import com.abin.mallchat.common.chat.domain.entity.UserEmojis; +import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; +import com.abin.mallchat.common.common.domain.vo.response.ApiResult; +import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * 用户表情包 Service + * + * @author: WuShiJie + * @createTime: 2023/7/3 14:22 + */ +public interface UserEmojisService extends IService { + + /** + * 表情包列表 + * + * @param request 游标翻页请求参数 + * @return 表情包列表 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + CursorPageBaseResp getEmojisPage(CursorPageBaseReq request, Long uid); + + /** + * 新增表情包 + * + * @param emojis 用户表情包 + * @param uid 用户ID + * @return 表情包 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + ApiResult insertEmojis(UserEmojis emojis, Long uid); +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/EmojisServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/EmojisServiceImpl.java deleted file mode 100644 index 26dbe09..0000000 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/EmojisServiceImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.abin.mallchat.custom.user.service.impl; - -import com.abin.mallchat.common.chat.domain.entity.McEmojis; -import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; -import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; -import com.abin.mallchat.common.common.utils.CursorUtils; -import com.abin.mallchat.common.user.mapper.EmojisMapper; -import com.abin.mallchat.custom.chat.service.adapter.RoomAdapter; -import com.abin.mallchat.custom.user.service.EmojisService; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** - * 用户表情包 ServiceImpl - * - * @author: WuShiJie - * @createTime: 2023/7/3 14:23 - */ -@Service -@Slf4j -public class EmojisServiceImpl extends ServiceImpl implements EmojisService { - - @Autowired - private CursorUtils cursorUtils; - - /** - * 表情包列表 - * - * @param request 游标翻页请求参数 - * @return 表情包列表 - * @author WuShiJie - * @createTime 2023/7/3 14:46 - **/ - @Override - public CursorPageBaseResp getEmojisPage(CursorPageBaseReq request, Long uid) { - CursorPageBaseResp cursorPageByMysql = cursorUtils.getCursorPageByMysql(this, request, wrapper -> { - wrapper.eq(McEmojis::getUserId, uid); - }, McEmojis::getId); - return cursorPageByMysql; - } -} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojisServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojisServiceImpl.java new file mode 100644 index 0000000..0f2302d --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojisServiceImpl.java @@ -0,0 +1,82 @@ +package com.abin.mallchat.custom.user.service.impl; + +import com.abin.mallchat.common.chat.domain.entity.UserEmojis; +import com.abin.mallchat.common.common.annotation.RedissonLock; +import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; +import com.abin.mallchat.common.common.domain.vo.response.ApiResult; +import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; +import com.abin.mallchat.common.common.utils.CursorUtils; +import com.abin.mallchat.common.common.utils.RequestHolder; +import com.abin.mallchat.common.user.mapper.UserEmojisMapper; +import com.abin.mallchat.custom.user.service.UserEmojisService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 用户表情包 ServiceImpl + * + * @author: WuShiJie + * @createTime: 2023/7/3 14:23 + */ +@Service +@Slf4j +public class UserEmojisServiceImpl extends ServiceImpl implements UserEmojisService { + + /** + * 游标分页工具类 + */ + @Resource + private CursorUtils cursorUtils; + + /** + * 表情包列表 + * + * @param request 游标翻页请求参数 + * @return 表情包列表 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + @Override + public CursorPageBaseResp getEmojisPage(CursorPageBaseReq request, Long uid) { + CursorPageBaseResp cursorPageByMysql = cursorUtils.getCursorPageByMysql(this, request, wrapper -> { + wrapper.eq(UserEmojis::getUid, uid); + }, UserEmojis::getId); + return cursorPageByMysql; + } + + + /** + * 新增表情包 + * + * @param emojis 用户表情包 + * @param uid 用户ID + * @return 表情包 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + @Override + @RedissonLock(key = "#uid") + public ApiResult insertEmojis(UserEmojis emojis, Long uid) { + //校验表情数量是否超过30 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(UserEmojis::getUid,uid); + int count = this.count(queryWrapper); + if (count>30){ + return ApiResult.fail(-1,"最多只能添加30个表情"); + } + //校验表情是否存在 + queryWrapper.eq(UserEmojis::getExpressionUrl,emojis.getExpressionUrl()); + count = this.count(queryWrapper); + if (count >0){ + return ApiResult.fail(-1,"当前表情已存在"); + } + emojis.setUid(RequestHolder.get().getUid()); + this.saveOrUpdate(emojis, queryWrapper); + return ApiResult.success(emojis); + } +} From 8610078169d1e9688771324ad9b0dc331d94910c Mon Sep 17 00:00:00 2001 From: WSJ <996387929@qq.com> Date: Tue, 4 Jul 2023 09:31:16 +0800 Subject: [PATCH 10/42] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=A1=A8=E6=83=85?= =?UTF-8?q?=E5=8C=85=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/version/user_emojis.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/version/user_emojis.sql b/docs/version/user_emojis.sql index 875edf0..f0078ce 100644 --- a/docs/version/user_emojis.sql +++ b/docs/version/user_emojis.sql @@ -6,5 +6,5 @@ CREATE TABLE `user_emojis` ( `update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间', `delete_status` int(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除(0-正常,1-删除)', PRIMARY KEY (`id`), - KEY `IDX_MC_EMOJIS_USER_ID` (`uid`) + KEY `IDX_USER_EMOJIS_UID` (`uid`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='用户表情包'; \ No newline at end of file From 5d8e32abf86646fc962801fe09d5d3268f2d2359 Mon Sep 17 00:00:00 2001 From: zbzbzzz Date: Tue, 4 Jul 2023 09:56:35 +0800 Subject: [PATCH 11/42] =?UTF-8?q?fix:=E4=BC=98=E5=8C=96ws=E6=8F=A1?= =?UTF-8?q?=E6=89=8B=E5=90=8C=E6=97=B6=E8=AE=A4=E8=AF=81=20=E5=8A=A0?= =?UTF-8?q?=E4=B8=8Atoken=E4=B8=BA=E7=A9=BA=E5=88=A4=E6=96=AD=20=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E5=BC=82=E6=AD=A5=E8=AE=A4=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/user/service/impl/WebSocketServiceImpl.java | 10 +++++----- .../user/websocket/NettyWebSocketServerHandler.java | 9 ++++++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java index 96d0f68..8515083 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/WebSocketServiceImpl.java @@ -29,11 +29,14 @@ import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; -import java.util.*; +import java.util.Date; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Condition; @@ -141,10 +144,7 @@ public class WebSocketServiceImpl implements WebSocketService { } } - // 这里可以加异步或者事件去处理登录 - // 因为登录和推送消息其实是不用同步的两个步骤 这样可以加快连接的速度不占用nio线程 @Override - @Async public void authorize(Channel channel, WSAuthorize wsAuthorize) { //校验token boolean verifySuccess = loginService.verify(wsAuthorize.getToken()); diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java index b4fbb0a..ecbbb24 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java @@ -1,5 +1,6 @@ package com.abin.mallchat.custom.user.websocket; +import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; import cn.hutool.json.JSONUtil; import com.abin.mallchat.custom.user.domain.enums.WSReqTypeEnum; @@ -19,6 +20,7 @@ import lombok.extern.slf4j.Slf4j; public class NettyWebSocketServerHandler extends SimpleChannelInboundHandler { private WebSocketService webSocketService; + // 当web客户端连接后,触发该方法 @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { @@ -67,9 +69,10 @@ public class NettyWebSocketServerHandler extends SimpleChannelInboundHandler Date: Tue, 4 Jul 2023 10:09:36 +0800 Subject: [PATCH 12/42] =?UTF-8?q?feat:=E5=86=85=E5=AD=98=E6=B3=84=E9=9C=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mallchat/custom/common/intecepter/TokenInterceptor.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/intecepter/TokenInterceptor.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/intecepter/TokenInterceptor.java index 719fb0d..814297b 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/intecepter/TokenInterceptor.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/intecepter/TokenInterceptor.java @@ -45,6 +45,11 @@ public class TokenInterceptor implements HandlerInterceptor { return true; } + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + MDC.remove(MDCKey.UID); + } + /** * 判断是不是公共方法,可以未登录访问的 * From 919bdc7c9906fb8c974f47aa1f9236d050b41630 Mon Sep 17 00:00:00 2001 From: zbzbzzz Date: Tue, 4 Jul 2023 17:04:52 +0800 Subject: [PATCH 13/42] =?UTF-8?q?fix:=E6=8F=A1=E6=89=8B=E8=AE=A4=E8=AF=81?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=E6=94=B9=E4=B8=BA=E5=8F=82=E6=95=B0=E8=AE=A4?= =?UTF-8?q?=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/algorithm/ac/CreateTokenTest.java | 1 - .../user/websocket/HttpHeadersHandler.java | 17 +- .../user/websocket/NettyWebSocketServer.java | 3 +- .../NettyWebSocketServerHandler.java | 2 +- .../NettyWebSocketServerProtocolHandler.java | 66 ------- .../websocket/WebSocketHandshakeHandler.java | 163 ------------------ 6 files changed, 18 insertions(+), 234 deletions(-) delete mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerProtocolHandler.java delete mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/WebSocketHandshakeHandler.java diff --git a/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java b/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java index 34d4035..06c1845 100644 --- a/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java +++ b/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java @@ -31,5 +31,4 @@ public class CreateTokenTest { log.info("decode error,token:{}", token, e); } } - } diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java index 30f6cdd..b6cdd43 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java @@ -1,5 +1,6 @@ package com.abin.mallchat.custom.user.websocket; +import cn.hutool.core.net.url.UrlBuilder; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.codec.http.FullHttpRequest; @@ -13,7 +14,16 @@ public class HttpHeadersHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof FullHttpRequest) { - HttpHeaders headers = ((FullHttpRequest) msg).headers(); + FullHttpRequest request = (FullHttpRequest) msg; + UrlBuilder urlBuilder = UrlBuilder.ofHttp(request.uri()); + + // 获取token参数 + String token = urlBuilder.getQuery().get("token").toString(); + NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token); + + // 获取请求路径 + request.setUri(urlBuilder.getPath().toString()); + HttpHeaders headers = request.headers(); String ip = headers.get("X-Real-IP"); if (StringUtils.isEmpty(ip)) {//如果没经过nginx,就直接获取远端地址 InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress(); @@ -21,7 +31,10 @@ public class HttpHeadersHandler extends ChannelInboundHandlerAdapter { } NettyUtil.setAttr(ctx.channel(), NettyUtil.IP, ip); ctx.pipeline().remove(this); + ctx.fireChannelRead(request); + }else + { + ctx.fireChannelRead(msg); } - ctx.fireChannelRead(msg); } } \ No newline at end of file diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java index 3448528..4ebf470 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java @@ -10,6 +10,7 @@ import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.stream.ChunkedWriteHandler; @@ -88,7 +89,7 @@ public class NettyWebSocketServer { * 4. WebSocketServerProtocolHandler 核心功能是把 http协议升级为 ws 协议,保持长连接; * 是通过一个状态码 101 来切换的 */ - pipeline.addLast(new NettyWebSocketServerProtocolHandler("/")); + pipeline.addLast(new WebSocketServerProtocolHandler("/")); // 自定义handler ,处理业务逻辑 pipeline.addLast(new NettyWebSocketServerHandler()); } diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java index ecbbb24..dbc62f9 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java @@ -71,7 +71,7 @@ public class NettyWebSocketServerHandler extends SimpleChannelInboundHandler out) throws Exception { - if (this.webSocketServerProtocolConfig.handleCloseFrames() && frame instanceof CloseWebSocketFrame) { - WebSocketServerHandshaker handshaker = NettyUtil.getAttr(ctx.channel(),NettyUtil.HANDSHAKER_ATTR_KEY); - if (handshaker != null) { - frame.retain(); - ChannelPromise promise = ctx.newPromise(); - Method closeSent = ReflectUtil.getMethod(super.getClass(), "closeSent", ChannelPromise.class); - closeSent.setAccessible(true); - closeSent.invoke(this,promise); - handshaker.close(ctx, (CloseWebSocketFrame)frame, promise); - } else { - ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); - } - } else { - super.decode(ctx, frame, out); - } - } -} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/WebSocketHandshakeHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/WebSocketHandshakeHandler.java deleted file mode 100644 index 8054c90..0000000 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/WebSocketHandshakeHandler.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.abin.mallchat.custom.user.websocket; - - -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.DefaultFullHttpResponse; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpObject; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpUtil; -import io.netty.handler.codec.http.HttpVersion; -import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakeException; -import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker; -import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory; -import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolConfig; -import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; -import io.netty.handler.ssl.SslHandler; -import io.netty.util.ReferenceCountUtil; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.internal.ObjectUtil; - -import java.util.concurrent.TimeUnit; - -public class WebSocketHandshakeHandler extends ChannelInboundHandlerAdapter { - - private final WebSocketServerProtocolConfig serverConfig; - private ChannelHandlerContext ctx; - private ChannelPromise handshakePromise; - private boolean isWebSocketPath; - - public WebSocketHandshakeHandler(WebSocketServerProtocolConfig serverConfig) { - this.serverConfig = (WebSocketServerProtocolConfig)ObjectUtil.checkNotNull(serverConfig, "serverConfig"); - } - - @Override - public void handlerAdded(ChannelHandlerContext ctx) { - this.ctx = ctx; - this.handshakePromise = ctx.newPromise(); - } - - @Override - public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception { - HttpObject httpObject = (HttpObject)msg; - if (httpObject instanceof HttpRequest) { - final HttpRequest req = (HttpRequest)httpObject; - this.isWebSocketPath = this.isWebSocketPath(req); - if (!this.isWebSocketPath) { - ctx.fireChannelRead(msg); - return; - } - try { - if (HttpMethod.GET.equals(req.method())) { - final String token = req.headers().get("Sec-Websocket-Protocol"); - WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketLocation(ctx.pipeline(), req, this.serverConfig.websocketPath()), token, this.serverConfig.decoderConfig()); - final WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req); - NettyUtil.setAttr(ctx.channel(),NettyUtil.HANDSHAKER_ATTR_KEY,handshaker); - final ChannelPromise localHandshakePromise = this.handshakePromise; - if (handshaker == null) { - WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); - } else { - - ctx.pipeline().remove(this); - ChannelFuture handshakeFuture = handshaker.handshake(ctx.channel(), req); - handshakeFuture.addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) { - if (!future.isSuccess()) { - localHandshakePromise.tryFailure(future.cause()); - ctx.fireExceptionCaught(future.cause()); - } else { - localHandshakePromise.trySuccess(); - NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token); - ctx.fireUserEventTriggered(WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE); - } - } - }); - this.applyHandshakeTimeout(); - } - - return; - } - - sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.FORBIDDEN, ctx.alloc().buffer(0))); - } finally { - ReferenceCountUtil.release(req); - } - - return; - } else if (!this.isWebSocketPath) { - ctx.fireChannelRead(msg); - } else { - ReferenceCountUtil.release(msg); - } - - } - - private boolean isWebSocketPath(HttpRequest req) { - String websocketPath = this.serverConfig.websocketPath(); - String uri = req.uri(); - boolean checkStartUri = uri.startsWith(websocketPath); - boolean checkNextUri = "/".equals(websocketPath) || this.checkNextUri(uri, websocketPath); - return this.serverConfig.checkStartsWith() ? checkStartUri && checkNextUri : uri.equals(websocketPath); - } - - private boolean checkNextUri(String uri, String websocketPath) { - int len = websocketPath.length(); - if (uri.length() <= len) { - return true; - } else { - char nextUri = uri.charAt(len); - return nextUri == '/' || nextUri == '?'; - } - } - - private static void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) { - ChannelFuture f = ctx.channel().writeAndFlush(res); - if (!HttpUtil.isKeepAlive(req) || res.status().code() != 200) { - f.addListener(ChannelFutureListener.CLOSE); - } - - } - - private static String getWebSocketLocation(ChannelPipeline cp, HttpRequest req, String path) { - String protocol = "ws"; - if (cp.get(SslHandler.class) != null) { - protocol = "wss"; - } - - String host = req.headers().get(HttpHeaderNames.HOST); - return protocol + "://" + host + path; - } - - private void applyHandshakeTimeout() { - final ChannelPromise localHandshakePromise = this.handshakePromise; - long handshakeTimeoutMillis = this.serverConfig.handshakeTimeoutMillis(); - if (handshakeTimeoutMillis > 0L && !localHandshakePromise.isDone()) { - final Future timeoutFuture = this.ctx.executor().schedule(new Runnable() { - @Override - public void run() { - if (!localHandshakePromise.isDone() && localHandshakePromise.tryFailure(new WebSocketServerHandshakeException("handshake timed out"))) { - WebSocketHandshakeHandler.this.ctx.flush().fireUserEventTriggered(WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_TIMEOUT).close(); - } - - } - }, handshakeTimeoutMillis, TimeUnit.MILLISECONDS); - localHandshakePromise.addListener(new FutureListener() { - @Override - public void operationComplete(Future f) { - timeoutFuture.cancel(false); - } - }); - } - } - -} From 3c77ed3c5fd5386c7d2c5ebc31ac3b9dc698d73a Mon Sep 17 00:00:00 2001 From: zhaoqichao <1416537683@qq.com> Date: Wed, 5 Jul 2023 09:29:21 +0800 Subject: [PATCH 14/42] =?UTF-8?q?Url=E8=A7=A3=E6=9E=90=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=8F=8A=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Discover.java => AbstractUrlDiscover.java} | 38 +++++++----- .../utils/discover/CommonUrlDiscover.java | 56 +++++++++++++++++ .../discover/CommonUrlTitleDiscover.java | 15 ----- .../discover/PrioritizedUrlDiscover.java | 60 +++++++++++++++++++ .../discover/PrioritizedUrlTitleDiscover.java | 33 ---------- .../common/utils/discover/UrlDiscover.java | 46 ++++++++++++++ .../utils/discover/UrlTitleDiscover.java | 35 ----------- .../common/utils/discover/WxUrlDiscover.java | 30 ++++++++++ .../utils/discover/WxUrlTitleDiscover.java | 15 ----- .../service/strategy/msg/TextMsgHandler.java | 4 +- 10 files changed, 218 insertions(+), 114 deletions(-) rename mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/{AbstractUrlTitleDiscover.java => AbstractUrlDiscover.java} (64%) create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/CommonUrlDiscover.java delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/CommonUrlTitleDiscover.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlDiscover.java delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlTitleDiscover.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/UrlDiscover.java delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/UrlTitleDiscover.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/WxUrlDiscover.java delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/WxUrlTitleDiscover.java diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/AbstractUrlTitleDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/AbstractUrlDiscover.java similarity index 64% rename from mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/AbstractUrlTitleDiscover.java rename to mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/AbstractUrlDiscover.java index 79cbefe..80d7ab8 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/AbstractUrlTitleDiscover.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/AbstractUrlDiscover.java @@ -3,14 +3,15 @@ package com.abin.mallchat.common.common.utils.discover; import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.StrUtil; import com.abin.mallchat.common.common.utils.FutureUtils; +import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.Nullable; import org.jsoup.Connection; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.springframework.data.util.Pair; -import javax.annotation.Nullable; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -20,46 +21,55 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; /** - * Description: urlTitle查询抽象类 - * Author: abin - * Date: 2023-05-27 + * @author zhaoqichao + * @date 2023/7/3 16:38 */ @Slf4j -public abstract class AbstractUrlTitleDiscover implements UrlTitleDiscover { +public abstract class AbstractUrlDiscover implements UrlDiscover { //链接识别的正则 private static final Pattern PATTERN = Pattern.compile("((http|https)://)?(www.)?([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?"); - @Nullable + + @javax.annotation.Nullable @Override - public Map getContentTitleMap(String content) { + public Map getUrlContentMap(String content) { + if (StrUtil.isBlank(content)) { return new HashMap<>(); } List matchList = ReUtil.findAll(PATTERN, content, 0); + //并行请求 - List>> futures = matchList.stream().map(match -> CompletableFuture.supplyAsync(() -> { - String title = getUrlTitle(match); - return StringUtils.isNotEmpty(title) ? Pair.of(match, title) : null; + List>> futures = matchList.stream().map(match -> CompletableFuture.supplyAsync(() -> { + UrlInfo urlInfo = getContent(match); + return Objects.isNull(urlInfo) ? null : Pair.of(match, urlInfo); })).collect(Collectors.toList()); - CompletableFuture>> future = FutureUtils.sequenceNonNull(futures); + CompletableFuture>> future = FutureUtils.sequenceNonNull(futures); //结果组装 return future.join().stream().collect(Collectors.toMap(Pair::getFirst, Pair::getSecond, (a, b) -> a)); } @Nullable @Override - public String getUrlTitle(String url) { + public UrlInfo getContent(String url) { Document document = getUrlDocument(assemble(url)); if (Objects.isNull(document)) { return null; } - return getDocTitle(document); + + return UrlInfo.builder() + .title(getTitle(document)) + .description(getDescription(document)) + .image(getImage(assemble(url),document)).build(); } + private String assemble(String url) { + if (!StrUtil.startWith(url, "http")) { return "http://" + url; } + return url; } @@ -69,7 +79,7 @@ public abstract class AbstractUrlTitleDiscover implements UrlTitleDiscover { connect.timeout(2000); return connect.get(); } catch (Exception e) { - log.error("find title error:url:{}", matchUrl, e); + log.error("find error:url:{}", matchUrl, e); } return null; } diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/CommonUrlDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/CommonUrlDiscover.java new file mode 100644 index 0000000..b73c81d --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/CommonUrlDiscover.java @@ -0,0 +1,56 @@ +package com.abin.mallchat.common.common.utils.discover; + +import cn.hutool.core.util.StrUtil; +import io.jsonwebtoken.lang.Objects; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.Nullable; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; + +/** + * @author zhaoqichao + * @date 2023/7/3 16:54 + */ +public class CommonUrlDiscover extends AbstractUrlDiscover { + @Nullable + @Override + public String getTitle(Document document) { + return document.title(); + } + + @Nullable + @Override + public String getDescription(Document document) { + String description = document.head().select("meta[name=description]").attr("content"); + String keywords = document.head().select("meta[name=keywords]").attr("content"); + String content = StrUtil.isNotBlank(description) ? description : keywords; + //只保留一句话的描述 + return StrUtil.isNotBlank(content) ? content.substring(0, content.indexOf("。")) : content; + } + + @Nullable + @Override + public String getImage(String url, Document document) { + //如果包含og则是微信链接 + if(StrUtil.isNotBlank(document.getElementsByAttributeValue("property", "og:title").attr("content"))){ + return null; + } + String image = document.select("link[type=image/x-icon]").attr("href"); + //如果没有去匹配含有icon属性的logo + String href = StrUtil.isEmpty(image) ? document.select("link[rel$=icon]").attr("href") : image; + //如果icon中已经包含了url部分域名 + if (StrUtil.isNotBlank(StrUtil.removeAny(StrUtil.removeAny(href, "/"), "favicon.ico")) && + StrUtil.containsAny(StrUtil.removePrefix(url, "http://"), StrUtil.removeAny(StrUtil.removeAny(href, "/"), "favicon.ico"))) { + return "http://" + StrUtil.removePrefix(href, "/"); + } + //如果url已经包含了logo + if (StrUtil.containsAny(url, "favicon")) { + return url; + } + //如果logo中有url + if (StrUtil.containsAny(href, "http") || StrUtil.containsAny(href, "https")) { + return href; + } + return StrUtil.format("{}/{}", url, StrUtil.removePrefix(href, "/")); + } +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/CommonUrlTitleDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/CommonUrlTitleDiscover.java deleted file mode 100644 index 6471610..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/CommonUrlTitleDiscover.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.abin.mallchat.common.common.utils.discover; - -import org.jsoup.nodes.Document; - -/** - * Description: 通用的标题解析类 - * Author: abin - * Date: 2023-05-27 - */ -public class CommonUrlTitleDiscover extends AbstractUrlTitleDiscover { - @Override - public String getDocTitle(Document document) { - return document.title(); - } -} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlDiscover.java new file mode 100644 index 0000000..ab57334 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlDiscover.java @@ -0,0 +1,60 @@ +package com.abin.mallchat.common.common.utils.discover; + +import cn.hutool.core.util.StrUtil; +import org.jetbrains.annotations.Nullable; +import org.jsoup.nodes.Document; + +import java.util.ArrayList; +import java.util.List; + +/** + * Description: 具有优先级的title查询器 + * Author: abin + * Date: 2023-05-27 + */ +public class PrioritizedUrlDiscover extends AbstractUrlDiscover { + + private final List urlTitleDiscovers = new ArrayList<>(2); + + public PrioritizedUrlDiscover() { + urlTitleDiscovers.add(new CommonUrlDiscover()); + urlTitleDiscovers.add(new WxUrlDiscover()); + } + + + @Nullable + @Override + public String getTitle(Document document) { + for (UrlDiscover urlDiscover : urlTitleDiscovers) { + String urlTitle = urlDiscover.getTitle(document); + if (StrUtil.isNotBlank(urlTitle)) { + return urlTitle; + } + } + return null; + } + + @Nullable + @Override + public String getDescription(Document document) { + for (UrlDiscover urlDiscover : urlTitleDiscovers) { + String urlDescription = urlDiscover.getDescription(document); + if (StrUtil.isNotBlank(urlDescription)) { + return urlDescription; + } + } + return null; + } + + @Nullable + @Override + public String getImage(String url, Document document) { + for (UrlDiscover urlDiscover : urlTitleDiscovers) { + String urlImage = urlDiscover.getImage(url,document); + if (StrUtil.isNotBlank(urlImage)) { + return urlImage; + } + } + return null; + } +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlTitleDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlTitleDiscover.java deleted file mode 100644 index 8c7fb4d..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlTitleDiscover.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.abin.mallchat.common.common.utils.discover; - -import cn.hutool.core.util.StrUtil; -import org.jsoup.nodes.Document; - -import java.util.ArrayList; -import java.util.List; - -/** - * Description: 具有优先级的title查询器 - * Author: abin - * Date: 2023-05-27 - */ -public class PrioritizedUrlTitleDiscover extends AbstractUrlTitleDiscover { - - private final List urlTitleDiscovers = new ArrayList<>(2); - - public PrioritizedUrlTitleDiscover() { - urlTitleDiscovers.add(new CommonUrlTitleDiscover()); - urlTitleDiscovers.add(new WxUrlTitleDiscover()); - } - - @Override - public String getDocTitle(Document document) { - for (UrlTitleDiscover urlTitleDiscover : urlTitleDiscovers) { - String urlTitle = urlTitleDiscover.getDocTitle(document); - if (StrUtil.isNotBlank(urlTitle)) { - return urlTitle; - } - } - return null; - } -} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/UrlDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/UrlDiscover.java new file mode 100644 index 0000000..3515c28 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/UrlDiscover.java @@ -0,0 +1,46 @@ +package com.abin.mallchat.common.common.utils.discover; + +import cn.hutool.core.date.StopWatch; +import cn.hutool.core.util.StrUtil; +import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; +import org.jsoup.nodes.Document; + +import javax.annotation.Nullable; +import java.util.Map; + +/** + * @author zhaoqichao + * @date 2023/7/3 16:34 + */ +public interface UrlDiscover { + + + @Nullable + Map getUrlContentMap(String content); + + @Nullable + UrlInfo getContent(String url); + + @Nullable + String getTitle(Document document); + + @Nullable + String getDescription(Document document); + + @Nullable + String getImage(String url, Document document); + + public static void main(String[] args) { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + String longStr = "其中包含一个URL www.baidu.com,一个带有端口号的URL http://www.jd.com:80, 一个带有路径的URL http://mallchat.cn, 还有美团技术文章https://mp.weixin.qq.com/s/hwTf4bDck9_tlFpgVDeIKg "; +// String longStr = "一个带有端口号的URL http://www.jd.com:80,"; +// String longStr = "一个带有路径的URL http://mallchat.cn"; + PrioritizedUrlDiscover discover = new PrioritizedUrlDiscover(); + final Map map = discover.getUrlContentMap(longStr); + System.out.println(map); + stopWatch.stop(); + long cost = stopWatch.getTotalTimeMillis(); + System.out.println(cost); + } +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/UrlTitleDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/UrlTitleDiscover.java deleted file mode 100644 index e2fac68..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/UrlTitleDiscover.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.abin.mallchat.common.common.utils.discover; - -import cn.hutool.core.date.StopWatch; -import org.jsoup.nodes.Document; - -import javax.annotation.Nullable; -import java.util.Map; - -public interface UrlTitleDiscover { - - - @Nullable - Map getContentTitleMap(String content); - - - @Nullable - String getUrlTitle(String url); - - @Nullable - String getDocTitle(Document document); - - public static void main(String[] args) {//用异步多任务查询并合并 974 //串行访问的速度1349 1291 1283 1559 - StopWatch stopWatch = new StopWatch(); - stopWatch.start(); - String longStr = "这是一个很长的字符串再来 www.github.com,其中包含一个URL www.baidu.com,, 一个带有端口号的URL http://www.jd.com:80, 一个带有路径的URL http://mallchat.cn, 还有美团技术文章https://mp.weixin.qq.com/s/hwTf4bDck9_tlFpgVDeIKg "; - PrioritizedUrlTitleDiscover discover = new PrioritizedUrlTitleDiscover(); - Map contentTitleMap = discover.getContentTitleMap(longStr); - System.out.println(contentTitleMap); -// -// Jsoup.connect("http:// www.github.com"); - stopWatch.stop(); - long cost = stopWatch.getTotalTimeMillis(); - System.out.println(cost); - }//{http://mallchat.cn=MallChat, www.baidu.com=百度一下,你就知道, https://mp.weixin.qq.com/s/hwTf4bDck9_tlFpgVDeIKg=超大规模数据库集群保稳系列之二:数据库攻防演练建设实践, http://www.jd.com:80=京东(JD.COM)-正品低价、品质保障、配送及时、轻松购物!} -} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/WxUrlDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/WxUrlDiscover.java new file mode 100644 index 0000000..a5bb330 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/WxUrlDiscover.java @@ -0,0 +1,30 @@ +package com.abin.mallchat.common.common.utils.discover; + +import org.jetbrains.annotations.Nullable; +import org.jsoup.nodes.Document; + +/** + * Description: 针对微信公众号文章的标题获取类 + * Author: abin + * Date: 2023-05-27 + */ +public class WxUrlDiscover extends AbstractUrlDiscover { + + @Nullable + @Override + public String getTitle(Document document) { + return document.getElementsByAttributeValue("property", "og:title").attr("content"); + } + + @Nullable + @Override + public String getDescription(Document document) { + return document.getElementsByAttributeValue("property", "og:description").attr("content"); + } + + @Nullable + @Override + public String getImage(String url, Document document) { + return document.getElementsByAttributeValue("property", "og:image").attr("content"); + } +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/WxUrlTitleDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/WxUrlTitleDiscover.java deleted file mode 100644 index 29b1172..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/WxUrlTitleDiscover.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.abin.mallchat.common.common.utils.discover; - -import org.jsoup.nodes.Document; - -/** - * Description: 针对微信公众号文章的标题获取类 - * Author: abin - * Date: 2023-05-27 - */ -public class WxUrlTitleDiscover extends AbstractUrlTitleDiscover { - @Override - public String getDocTitle(Document document) { - return document.getElementsByAttributeValue("property", "og:title").attr("content"); - } -} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java index d8e347a..6b63a31 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java @@ -11,7 +11,7 @@ import com.abin.mallchat.common.chat.service.cache.MsgCache; import com.abin.mallchat.common.common.domain.enums.YesOrNoEnum; import com.abin.mallchat.common.common.utils.AssertUtil; import com.abin.mallchat.common.common.utils.SensitiveWordUtils; -import com.abin.mallchat.common.common.utils.discover.PrioritizedUrlTitleDiscover; +import com.abin.mallchat.common.common.utils.discover.PrioritizedUrlDiscover; import com.abin.mallchat.common.user.domain.entity.User; import com.abin.mallchat.common.user.domain.enums.RoleEnum; import com.abin.mallchat.common.user.service.IRoleService; @@ -47,7 +47,7 @@ public class TextMsgHandler extends AbstractMsgHandler { @Autowired private IRoleService iRoleService; - private static final PrioritizedUrlTitleDiscover URL_TITLE_DISCOVER = new PrioritizedUrlTitleDiscover(); + private static final PrioritizedUrlDiscover URL_TITLE_DISCOVER = new PrioritizedUrlDiscover(); @Override MessageTypeEnum getMsgTypeEnum() { From 27a7709f08e2da30cfa00edc7faa3e78095c55cb Mon Sep 17 00:00:00 2001 From: zhaoqichao <1416537683@qq.com> Date: Wed, 5 Jul 2023 09:42:04 +0800 Subject: [PATCH 15/42] =?UTF-8?q?Url=E8=A7=A3=E6=9E=90=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=8F=8A=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MallChat | 1 + .../common/utils/discover/domain/UrlInfo.java | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 160000 MallChat create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/domain/UrlInfo.java diff --git a/MallChat b/MallChat new file mode 160000 index 0000000..c47b487 --- /dev/null +++ b/MallChat @@ -0,0 +1 @@ +Subproject commit c47b48760dd1eaaed6cf1c62930c65032ed66752 diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/domain/UrlInfo.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/domain/UrlInfo.java new file mode 100644 index 0000000..8f02b7c --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/domain/UrlInfo.java @@ -0,0 +1,32 @@ +package com.abin.mallchat.common.common.utils.discover.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author zhaoqichao + * @date 2023/7/3 16:12 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class UrlInfo { + /** + * 标题 + **/ + String title; + + /** + * 描述 + **/ + String description; + + /** + * 网站LOGO + **/ + String image; + +} From b516e51bc931bc96ffa08acdfa2dfe1f13db13bf Mon Sep 17 00:00:00 2001 From: zhaoqichao <1416537683@qq.com> Date: Wed, 5 Jul 2023 18:12:17 +0800 Subject: [PATCH 16/42] =?UTF-8?q?Url=E8=A7=A3=E6=9E=90=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=8Cserver=E7=AB=AF=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/chat/domain/entity/msg/MessageExtra.java | 3 ++- .../common/utils/discover/AbstractUrlDiscover.java | 4 ++-- .../utils/discover/PrioritizedUrlDiscover.java | 12 ++++++------ .../chat/domain/vo/response/ChatMessageResp.java | 3 ++- .../chat/domain/vo/response/msg/TextMsgResp.java | 3 ++- .../custom/chat/service/adapter/MessageAdapter.java | 2 +- .../chat/service/strategy/msg/TextMsgHandler.java | 7 ++++--- 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/MessageExtra.java b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/MessageExtra.java index 9a68c74..fa3af00 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/MessageExtra.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/MessageExtra.java @@ -1,5 +1,6 @@ package com.abin.mallchat.common.chat.domain.entity.msg; +import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AllArgsConstructor; import lombok.Builder; @@ -23,7 +24,7 @@ import java.util.Map; public class MessageExtra implements Serializable { private static final long serialVersionUID = 1L; //url跳转链接 - private Map urlTitleMap; + private Map urlContentMap; //消息撤回详情 private MsgRecall recall; //艾特的uid diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/AbstractUrlDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/AbstractUrlDiscover.java index 80d7ab8..4da24e9 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/AbstractUrlDiscover.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/AbstractUrlDiscover.java @@ -5,7 +5,6 @@ import cn.hutool.core.util.StrUtil; import com.abin.mallchat.common.common.utils.FutureUtils; import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.Nullable; import org.jsoup.Connection; import org.jsoup.Jsoup; @@ -30,7 +29,7 @@ public abstract class AbstractUrlDiscover implements UrlDiscover { private static final Pattern PATTERN = Pattern.compile("((http|https)://)?(www.)?([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?"); - @javax.annotation.Nullable + @Nullable @Override public Map getUrlContentMap(String content) { @@ -83,4 +82,5 @@ public abstract class AbstractUrlDiscover implements UrlDiscover { } return null; } + } diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlDiscover.java index ab57334..106f598 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlDiscover.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlDiscover.java @@ -14,18 +14,18 @@ import java.util.List; */ public class PrioritizedUrlDiscover extends AbstractUrlDiscover { - private final List urlTitleDiscovers = new ArrayList<>(2); + private final List urlDiscovers = new ArrayList<>(2); public PrioritizedUrlDiscover() { - urlTitleDiscovers.add(new CommonUrlDiscover()); - urlTitleDiscovers.add(new WxUrlDiscover()); + urlDiscovers.add(new CommonUrlDiscover()); + urlDiscovers.add(new WxUrlDiscover()); } @Nullable @Override public String getTitle(Document document) { - for (UrlDiscover urlDiscover : urlTitleDiscovers) { + for (UrlDiscover urlDiscover : urlDiscovers) { String urlTitle = urlDiscover.getTitle(document); if (StrUtil.isNotBlank(urlTitle)) { return urlTitle; @@ -37,7 +37,7 @@ public class PrioritizedUrlDiscover extends AbstractUrlDiscover { @Nullable @Override public String getDescription(Document document) { - for (UrlDiscover urlDiscover : urlTitleDiscovers) { + for (UrlDiscover urlDiscover : urlDiscovers) { String urlDescription = urlDiscover.getDescription(document); if (StrUtil.isNotBlank(urlDescription)) { return urlDescription; @@ -49,7 +49,7 @@ public class PrioritizedUrlDiscover extends AbstractUrlDiscover { @Nullable @Override public String getImage(String url, Document document) { - for (UrlDiscover urlDiscover : urlTitleDiscovers) { + for (UrlDiscover urlDiscover : urlDiscovers) { String urlImage = urlDiscover.getImage(url,document); if (StrUtil.isNotBlank(urlImage)) { return urlImage; diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageResp.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageResp.java index 968aae9..2cfed96 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageResp.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageResp.java @@ -1,5 +1,6 @@ package com.abin.mallchat.custom.chat.domain.vo.response; +import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Builder; @@ -50,7 +51,7 @@ public class ChatMessageResp { private String content; @ApiModelProperty("消息链接映射-废弃") @Deprecated - private Map urlTitleMap; + private Map urlContentMap; @ApiModelProperty("消息类型 1正常文本 2.撤回消息") private Integer type; @ApiModelProperty("消息内容不同的消息类型,内容体不同,见https://www.yuque.com/snab/mallcaht/rkb2uz5k1qqdmcmd") diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/msg/TextMsgResp.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/msg/TextMsgResp.java index 34db6c5..17a7b48 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/msg/TextMsgResp.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/msg/TextMsgResp.java @@ -1,5 +1,6 @@ package com.abin.mallchat.custom.chat.domain.vo.response.msg; +import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Builder; @@ -22,7 +23,7 @@ public class TextMsgResp { @ApiModelProperty("消息内容") private String content; @ApiModelProperty("消息链接映射") - private Map urlTitleMap; + private Map urlContentMap; @ApiModelProperty("艾特的uid") private List atUidList; @ApiModelProperty("父消息,如果没有父消息,返回的是null") diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/MessageAdapter.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/MessageAdapter.java index 53e10fa..a751ad6 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/MessageAdapter.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/MessageAdapter.java @@ -56,7 +56,7 @@ public class MessageAdapter { messageVO.setSendTime(message.getCreateTime()); AbstractMsgHandler msgHandler = MsgHandlerFactory.getStrategyNoNull(message.getType()); messageVO.setBody(msgHandler.showMsg(message)); - messageVO.setUrlTitleMap(Optional.ofNullable(message.getExtra()).map(MessageExtra::getUrlTitleMap).orElse(null)); + messageVO.setUrlContentMap(Optional.ofNullable(message.getExtra()).map(MessageExtra::getUrlContentMap).orElse(null)); Message replyMessage = replyMap.get(message.getReplyMsgId()); //回复消息 diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java index 6b63a31..1cc3f25 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java @@ -12,6 +12,7 @@ import com.abin.mallchat.common.common.domain.enums.YesOrNoEnum; import com.abin.mallchat.common.common.utils.AssertUtil; import com.abin.mallchat.common.common.utils.SensitiveWordUtils; import com.abin.mallchat.common.common.utils.discover.PrioritizedUrlDiscover; +import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; import com.abin.mallchat.common.user.domain.entity.User; import com.abin.mallchat.common.user.domain.enums.RoleEnum; import com.abin.mallchat.common.user.service.IRoleService; @@ -91,8 +92,8 @@ public class TextMsgHandler extends AbstractMsgHandler { } //判断消息url跳转 - Map urlTitleMap = URL_TITLE_DISCOVER.getContentTitleMap(body.getContent()); - extra.setUrlTitleMap(urlTitleMap); + Map urlContentMap = URL_TITLE_DISCOVER.getUrlContentMap(body.getContent()); + extra.setUrlContentMap(urlContentMap); //艾特功能 if (CollectionUtil.isNotEmpty(body.getAtUidList())) { extra.setAtUidList(body.getAtUidList()); @@ -106,7 +107,7 @@ public class TextMsgHandler extends AbstractMsgHandler { public Object showMsg(Message msg) { TextMsgResp resp = new TextMsgResp(); resp.setContent(msg.getContent()); - resp.setUrlTitleMap(Optional.ofNullable(msg.getExtra()).map(MessageExtra::getUrlTitleMap).orElse(null)); + resp.setUrlContentMap(Optional.ofNullable(msg.getExtra()).map(MessageExtra::getUrlContentMap).orElse(null)); resp.setAtUidList(Optional.ofNullable(msg.getExtra()).map(MessageExtra::getAtUidList).orElse(null)); //回复消息 Optional reply = Optional.ofNullable(msg.getReplyMsgId()) From 36101b405df79f9343c2006062a25546510bf509 Mon Sep 17 00:00:00 2001 From: wj Date: Wed, 5 Jul 2023 22:43:23 +0800 Subject: [PATCH 17/42] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD:=20=E5=A2=9E=E5=8A=A0=E5=BC=80=E5=85=B3?= =?UTF-8?q?=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/mallchat.sql | 1 + .../com/abin/mallchat/common/user/domain/entity/User.java | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/docs/mallchat.sql b/docs/mallchat.sql index 9a94090..eccb347 100644 --- a/docs/mallchat.sql +++ b/docs/mallchat.sql @@ -101,6 +101,7 @@ CREATE TABLE `user` ( `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户头像', `sex` int(11) NULL DEFAULT NULL COMMENT '性别 1为男性,2为女性', `open_id` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '微信openid用户标识', + `publish_chat_to_wechat_switch` bool DEFAULT 0 COMMENT '群聊消息推送开关', `last_opt_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '最后上下线时间', `ip_info` json NULL COMMENT 'ip信息', `item_id` bigint(20) NULL DEFAULT NULL COMMENT '佩戴的徽章id', diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/User.java b/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/User.java index 0421526..59c8c82 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/User.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/User.java @@ -58,6 +58,12 @@ public class User implements Serializable { @TableField("open_id") private String openId; + /** + * 是否开启微信消息推送 + */ + @TableField("publish_chat_to_wechat_switch") + private boolean publishChatToWechatSwitch; + /** * 最后上下线时间 */ From 9e4808f46682191b455082ddaff1ea9970d7df59 Mon Sep 17 00:00:00 2001 From: wj Date: Wed, 5 Jul 2023 22:44:24 +0800 Subject: [PATCH 18/42] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD:=20=E4=B8=BB=E6=B5=81=E7=A8=8B=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GlobalUncaughtExceptionHandler.java | 1 - .../service/WeChatMsgOperationService.java | 14 +++ .../impl/WeChatMsgOperationServiceImpl.java | 102 ++++++++++++++++++ .../event/listener/MessageSendListener.java | 15 +++ 4 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/WeChatMsgOperationService.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/handler/GlobalUncaughtExceptionHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/handler/GlobalUncaughtExceptionHandler.java index b3229e6..4dc9775 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/handler/GlobalUncaughtExceptionHandler.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/handler/GlobalUncaughtExceptionHandler.java @@ -9,7 +9,6 @@ public class GlobalUncaughtExceptionHandler implements Thread.UncaughtException @Override public void uncaughtException(Thread t, Throwable e) { log.error("Exception in thread {} ", t.getName(), e); - e.printStackTrace(); } } diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/WeChatMsgOperationService.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/WeChatMsgOperationService.java new file mode 100644 index 0000000..1e08b4a --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/WeChatMsgOperationService.java @@ -0,0 +1,14 @@ +package com.abin.mallchat.custom.chat.service; + +import java.util.List; + +public interface WeChatMsgOperationService { + /** + * 向被at的用户微信推送群聊消息 + * + * @param senderUid senderUid + * @param receiverUidList receiverUidList + * @param msg msg + */ + void publishChatMsgToWeChatUser(long senderUid, List receiverUidList, String msg); +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java new file mode 100644 index 0000000..10347a6 --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java @@ -0,0 +1,102 @@ +package com.abin.mallchat.custom.chat.service.impl; + +import cn.hutool.core.thread.NamedThreadFactory; +import com.abin.mallchat.common.common.handler.GlobalUncaughtExceptionHandler; +import com.abin.mallchat.common.common.utils.JsonUtils; +import com.abin.mallchat.common.user.domain.entity.User; +import com.abin.mallchat.common.user.service.cache.UserCache; +import com.abin.mallchat.custom.chat.service.WeChatMsgOperationService; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.WxMpTemplateMsgService; +import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; +import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Component +public class WeChatMsgOperationServiceImpl implements WeChatMsgOperationService { + + private static final ExecutorService executor = new ThreadPoolExecutor(1, 10, 3000L, + TimeUnit.MILLISECONDS, + new LinkedBlockingQueue(20), + new NamedThreadFactory("wechat-operation-thread", null, false, + new GlobalUncaughtExceptionHandler())); + + // at消息的微信推送模板id + private final String atMsgPublishTemplateId = ""; + + private final String WE_CHAT_MSG_COLOR = "#A349A4"; + + @Autowired + private UserCache userCache; + + @Autowired + WxMpService wxMpService; + + @Override + public void publishChatMsgToWeChatUser(long senderUid, List receiverUidList, String msg) { + User sender = userCache.getUserInfo(senderUid); + Set uidSet = new HashSet(); + uidSet.addAll(receiverUidList); + Map userMap = userCache.getUserInfoBatch(uidSet); + userMap.values().forEach(user -> { + if (Objects.nonNull(user.getOpenId()) && user.isPublishChatToWechatSwitch()) { + executor.execute(() -> { + WxMpTemplateMessage msgTemplate = getAtMsgTemplate(sender, user.getOpenId(), msg); + publishTemplateMsg(msgTemplate); + }); + } + }); + } + + /* + * 构造微信模板消息 + */ + private WxMpTemplateMessage getAtMsgTemplate(User sender, String openId, String msg) { + return WxMpTemplateMessage.builder() + .toUser(openId) + .templateId(atMsgPublishTemplateId) + .data(generateAtMsgData(sender, msg)) + .build(); + } + + /* + * 构造微信消息模板的数据 + */ + private List generateAtMsgData(User sender, String msg) { + List dataList = new ArrayList(); +// todo: 没有消息模板,暂不实现 +// dataList.add(new WxMpTemplateData("senderName", sender.getName() , WE_CHAT_MSG_COLOR)); +// dataList.add(new WxMpTemplateData("content", msg , WE_CHAT_MSG_COLOR)); + return dataList; + } + + /** + * 推送微信模板消息 + * + * @param templateMsg 微信模板消息 + */ + protected void publishTemplateMsg(WxMpTemplateMessage templateMsg) { + WxMpTemplateMsgService wxMpTemplateMsgService = wxMpService.getTemplateMsgService(); + try { + wxMpTemplateMsgService.sendTemplateMsg(templateMsg); + } catch (WxErrorException e) { + log.error("publish we chat msg failed! open id is {}, msg is {}.", + templateMsg.getToUser(), JsonUtils.toStr(templateMsg.getData())); + } + } +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/event/listener/MessageSendListener.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/event/listener/MessageSendListener.java index ba8bcf0..e87bc0a 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/event/listener/MessageSendListener.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/event/listener/MessageSendListener.java @@ -5,6 +5,8 @@ import com.abin.mallchat.common.chat.domain.entity.Message; import com.abin.mallchat.common.common.event.MessageSendEvent; import com.abin.mallchat.custom.chat.domain.vo.response.ChatMessageResp; import com.abin.mallchat.custom.chat.service.ChatService; +import com.abin.mallchat.custom.chat.service.WeChatMsgOperationService; +import com.abin.mallchat.custom.chat.service.impl.WeChatMsgOperationServiceImpl; import com.abin.mallchat.custom.chatai.service.IChatAIService; import com.abin.mallchat.custom.user.service.WebSocketService; import com.abin.mallchat.custom.user.service.adapter.WSAdapter; @@ -15,6 +17,8 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import org.springframework.transaction.event.TransactionalEventListener; +import java.util.Objects; + /** * 消息发送监听器 * @@ -32,6 +36,9 @@ public class MessageSendListener { @Autowired private IChatAIService openAIService; + @Autowired + WeChatMsgOperationService weChatMsgOperationService; + @Async @TransactionalEventListener(classes = MessageSendEvent.class, fallbackExecution = true) public void notifyAllOnline(MessageSendEvent event) { @@ -46,4 +53,12 @@ public class MessageSendListener { openAIService.chat(message); } + @TransactionalEventListener(classes = MessageSendEvent.class, fallbackExecution = true) + public void publishChatToWechat(@NotNull MessageSendEvent event) { + Message message = messageDao.getById(event.getMsgId()); + if (Objects.nonNull(message.getExtra().getAtUidList())) { + weChatMsgOperationService.publishChatMsgToWeChatUser(message.getFromUid(), message.getExtra().getAtUidList(), + message.getContent()); + } + } } From a6635834908162a6c7009f0aa2df9359d36a1e63 Mon Sep 17 00:00:00 2001 From: zhongzb <972627721@qq.com> Date: Thu, 6 Jul 2023 00:10:57 +0800 Subject: [PATCH 19/42] fix:readme --- .../abin/mallchat/common/common/exception/CommonErrorEnum.java | 2 +- .../mallchat/common/common/algorithm/ac/CreateTokenTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/CommonErrorEnum.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/CommonErrorEnum.java index edcd880..b1b7ec8 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/CommonErrorEnum.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/CommonErrorEnum.java @@ -13,7 +13,7 @@ import lombok.Getter; public enum CommonErrorEnum implements ErrorEnum { SYSTEM_ERROR(-1, "系统出小差了,请稍后再试哦~~"), - PARAM_VALID(-2, "参数校验失败"), + PARAM_VALID(-2, "参数校验失败{0}"), FREQUENCY_LIMIT(-3, "请求太频繁了,请稍后再试哦~~"), LOCK_LIMIT(-4, "请求太频繁了,请稍后再试哦~~"), ; diff --git a/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java b/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java index 06c1845..e73a9a9 100644 --- a/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java +++ b/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java @@ -24,7 +24,7 @@ public class CreateTokenTest { try { - JWTVerifier verifier = JWT.require(Algorithm.HMAC256("dsfsdfsdfsdfsd")).build(); + JWTVerifier verifier = JWT.require(Algorithm.HMAC256("dsfsdfsdfsdfsc")).build(); DecodedJWT jwt = verifier.verify(token); log.info(jwt.getClaims().toString()); } catch (Exception e) { From 21ea09cd4cb3e24941a5d1ee1e6e414dd3c8f3e3 Mon Sep 17 00:00:00 2001 From: zhaoqichao <1416537683@qq.com> Date: Thu, 6 Jul 2023 10:23:44 +0800 Subject: [PATCH 20/42] =?UTF-8?q?Url=E8=A7=A3=E6=9E=90=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E9=87=8D=E6=9E=84=EF=BC=88=E4=B8=8D=E5=BD=B1?= =?UTF-8?q?=E5=93=8D=E6=97=A7=E7=89=88=E6=9C=AC=E4=BD=BF=E7=94=A8=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/utils/chain/Application.java | 22 +++++ .../common/utils/chain/FactoryUrlHandler.java | 96 +++++++++++++++++++ .../utils/chain/PrioritizedUrlHandler.java | 39 ++++++++ .../common/common/utils/chain/UrlHandler.java | 25 +++++ .../common/utils/chain/WxUrlHandler.java | 32 +++++++ .../common/utils/chain/dto/UrlInfo.java | 32 +++++++ 6 files changed, 246 insertions(+) create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/Application.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/FactoryUrlHandler.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/PrioritizedUrlHandler.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/UrlHandler.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/WxUrlHandler.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/dto/UrlInfo.java diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/Application.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/Application.java new file mode 100644 index 0000000..b2c5d70 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/Application.java @@ -0,0 +1,22 @@ +package com.abin.mallchat.common.common.utils.chain; + +import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; +import org.jetbrains.annotations.Nullable; +import org.jsoup.nodes.Document; + +import java.util.Map; + +/** + * Description: 测试 + * Author: achao + * Date: 2023/7/6 9:29 + */ +public class Application { + public static void main(String[] args) { + PrioritizedUrlHandler handler = new PrioritizedUrlHandler(); + String longStr = "其中包含一个URL www.baidu.com,一个带有端口号的URL http://www.jd.com:80, 一个带有路径的URL http://mallchat.cn, 还有美团技术文章https://mp.weixin.qq.com/s/hwTf4bDck9_tlFpgVDeIKg "; + + Map urlContentMap = handler.getUrlContentMap(longStr); + System.out.println(urlContentMap); + } +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/FactoryUrlHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/FactoryUrlHandler.java new file mode 100644 index 0000000..bd8d0e8 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/FactoryUrlHandler.java @@ -0,0 +1,96 @@ +package com.abin.mallchat.common.common.utils.chain; + +import cn.hutool.core.util.ReUtil; +import cn.hutool.core.util.StrUtil; +import com.abin.mallchat.common.common.utils.FutureUtils; +import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; +import lombok.extern.slf4j.Slf4j; +import org.jsoup.Connection; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.springframework.data.util.Pair; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * Description: 链接处理工厂 + * Author: achao + * Date: 2023/7/6 9:12 + */ +@Slf4j +public abstract class FactoryUrlHandler extends UrlHandler{ + + //链接识别的正则 + private static final Pattern PATTERN = Pattern.compile("((http|https)://)?(www.)?([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?"); + + @Override + @Nullable + public Map getUrlContentMap(String content) { + + if (StrUtil.isBlank(content)) { + return new HashMap<>(); + } + List matchList = ReUtil.findAll(PATTERN, content, 0); + + //并行请求 + List>> futures = matchList.stream().map(match -> CompletableFuture.supplyAsync(() -> { + UrlInfo urlInfo = getContent(match); + return Objects.isNull(urlInfo) ? null : Pair.of(match, urlInfo); + })).collect(Collectors.toList()); + CompletableFuture>> future = FutureUtils.sequenceNonNull(futures); + //结果组装 + return future.join().stream().collect(Collectors.toMap(Pair::getFirst, Pair::getSecond, (a, b) -> a)); + } + + private UrlInfo getContent(String url){ + url = !StrUtil.startWith(url, "http") ? "http://" + url : url; + Document document = getUrlDocument(url); + return UrlInfo.builder() + .title(getTitle(document)) + .description(getDescription(document)) + .image(getImage(url,document)).build(); + } + + protected Document getUrlDocument(String matchUrl) { + try { + Connection connect = Jsoup.connect(matchUrl); + connect.timeout(2000); + return connect.get(); + } catch (Exception e) { + log.error("find error:url:{}", matchUrl, e); + } + return null; + } + + /** + * 获取链接的标题 + * @param document + * @return + */ + @Nullable + abstract String getTitle(Document document); + + /** + * 获取链接的描述 + * @param document + * @return + */ + @Nullable + abstract String getDescription(Document document); + + /** + * 获取链接的LOGO + * @param document + * @return + */ + @Nullable + abstract String getImage(String url, Document document); + +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/PrioritizedUrlHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/PrioritizedUrlHandler.java new file mode 100644 index 0000000..b06ad32 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/PrioritizedUrlHandler.java @@ -0,0 +1,39 @@ +package com.abin.mallchat.common.common.utils.chain; + +import cn.hutool.core.util.StrUtil; +import com.abin.mallchat.common.common.utils.discover.UrlDiscover; +import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; +import org.jetbrains.annotations.Nullable; +import org.jsoup.nodes.Document; + +import java.util.List; +import java.util.Map; + +/** + * Description: 优先级链接统一处理扩展类 + * Author: achao + * Date: 2023/7/6 9:36 + */ +public class PrioritizedUrlHandler extends FactoryUrlHandler { + + private final FactoryUrlHandler commonUrlHandler = new CommonUrlHandler(); + private final FactoryUrlHandler wxUrlHandler = new WxUrlHandler(); + + @Nullable + @Override + String getTitle(Document document) { + return StrUtil.isBlank(wxUrlHandler.getTitle(document)) ? commonUrlHandler.getTitle(document) : wxUrlHandler.getTitle(document); + } + + @Nullable + @Override + String getDescription(Document document) { + return StrUtil.isBlank(wxUrlHandler.getDescription(document)) ? commonUrlHandler.getDescription(document) : wxUrlHandler.getDescription(document); + } + + @Nullable + @Override + String getImage(String url, Document document) { + return StrUtil.isBlank(wxUrlHandler.getImage(url, document)) ? commonUrlHandler.getImage(url, document) : wxUrlHandler.getImage(url, document); + } +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/UrlHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/UrlHandler.java new file mode 100644 index 0000000..c9a9a3d --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/UrlHandler.java @@ -0,0 +1,25 @@ +package com.abin.mallchat.common.common.utils.chain; + +import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; +import org.jsoup.nodes.Document; + +import javax.annotation.Nullable; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * Description: url集合处理抽象接口定义类 + * Author: achao + * Date: 2023/7/6 8:58 + */ +public abstract class UrlHandler { + + /** + * 提取消息中的所有链接,并组装Map + * @param content + * @return + */ + @Nullable + abstract Map getUrlContentMap(String content); + +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/WxUrlHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/WxUrlHandler.java new file mode 100644 index 0000000..f8356d9 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/WxUrlHandler.java @@ -0,0 +1,32 @@ +package com.abin.mallchat.common.common.utils.chain; + +import cn.hutool.core.util.StrUtil; +import org.jetbrains.annotations.Nullable; +import org.jsoup.nodes.Document; + +/** + * Description: + * Author: achao + * Date: 2023/7/6 9:34 + */ +public class WxUrlHandler extends FactoryUrlHandler { + + @Nullable + @Override + public String getTitle(Document document) { + return document.getElementsByAttributeValue("property", "og:title").attr("content"); + } + + @Nullable + @Override + public String getDescription(Document document) { + String description = document.getElementsByAttributeValue("property", "og:description").attr("content"); + return StrUtil.isNotBlank(description) ? description.substring(0, description.indexOf("。")) : description; + } + + @Nullable + @Override + public String getImage(String url, Document document) { + return document.getElementsByAttributeValue("property", "og:image").attr("content"); + } +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/dto/UrlInfo.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/dto/UrlInfo.java new file mode 100644 index 0000000..ad1050a --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/dto/UrlInfo.java @@ -0,0 +1,32 @@ +package com.abin.mallchat.common.common.utils.chain.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Description: 链接信息提取类 + * Author: achao + * Date: 2023/7/6 8:54 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class UrlInfo { + /** + * 标题 + **/ + String title; + + /** + * 描述 + **/ + String description; + + /** + * 网站LOGO + **/ + String image; +} From a30d5f27661174788bb13f8759cd175eeb2d8bc6 Mon Sep 17 00:00:00 2001 From: zhaoqichao <1416537683@qq.com> Date: Thu, 6 Jul 2023 10:26:45 +0800 Subject: [PATCH 21/42] =?UTF-8?q?Url=E8=A7=A3=E6=9E=90=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E4=BC=98=E5=85=88=E7=BA=A7=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/common/utils/discover/CommonUrlDiscover.java | 4 ---- .../common/common/utils/discover/PrioritizedUrlDiscover.java | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/CommonUrlDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/CommonUrlDiscover.java index b73c81d..2f3b842 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/CommonUrlDiscover.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/CommonUrlDiscover.java @@ -31,10 +31,6 @@ public class CommonUrlDiscover extends AbstractUrlDiscover { @Nullable @Override public String getImage(String url, Document document) { - //如果包含og则是微信链接 - if(StrUtil.isNotBlank(document.getElementsByAttributeValue("property", "og:title").attr("content"))){ - return null; - } String image = document.select("link[type=image/x-icon]").attr("href"); //如果没有去匹配含有icon属性的logo String href = StrUtil.isEmpty(image) ? document.select("link[rel$=icon]").attr("href") : image; diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlDiscover.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlDiscover.java index 106f598..eef3c11 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlDiscover.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/discover/PrioritizedUrlDiscover.java @@ -17,8 +17,8 @@ public class PrioritizedUrlDiscover extends AbstractUrlDiscover { private final List urlDiscovers = new ArrayList<>(2); public PrioritizedUrlDiscover() { - urlDiscovers.add(new CommonUrlDiscover()); urlDiscovers.add(new WxUrlDiscover()); + urlDiscovers.add(new CommonUrlDiscover()); } From eddee5647fa893626197d16d062cc481d6c0c459 Mon Sep 17 00:00:00 2001 From: zhaoqichao <1416537683@qq.com> Date: Thu, 6 Jul 2023 10:28:04 +0800 Subject: [PATCH 22/42] =?UTF-8?q?Url=E8=A7=A3=E6=9E=90=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E9=87=8D=E6=9E=84=EF=BC=88=E4=B8=8D=E5=BD=B1?= =?UTF-8?q?=E5=93=8D=E6=97=A7=E7=89=88=E6=9C=AC=E4=BD=BF=E7=94=A8=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/utils/chain/CommonUrlHandler.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/CommonUrlHandler.java diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/CommonUrlHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/CommonUrlHandler.java new file mode 100644 index 0000000..5d85f00 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/CommonUrlHandler.java @@ -0,0 +1,51 @@ +package com.abin.mallchat.common.common.utils.chain; + +import cn.hutool.core.util.StrUtil; +import org.jetbrains.annotations.Nullable; +import org.jsoup.nodes.Document; + +/** + * Description: + * Author: achao + * Date: 2023/7/6 9:25 + */ +public class CommonUrlHandler extends FactoryUrlHandler { + + @Nullable + @Override + public String getTitle(Document document) { + return document.title(); + } + + @Nullable + @Override + public String getDescription(Document document) { + String description = document.head().select("meta[name=description]").attr("content"); + String keywords = document.head().select("meta[name=keywords]").attr("content"); + String content = StrUtil.isNotBlank(description) ? description : keywords; + //只保留一句话的描述 + return StrUtil.isNotBlank(content) ? content.substring(0, content.indexOf("。")) : content; + } + + @Nullable + @Override + public String getImage(String url, Document document) { + String image = document.select("link[type=image/x-icon]").attr("href"); + //如果没有去匹配含有icon属性的logo + String href = StrUtil.isEmpty(image) ? document.select("link[rel$=icon]").attr("href") : image; + //如果icon中已经包含了url部分域名 + if (StrUtil.isNotBlank(StrUtil.removeAny(StrUtil.removeAny(href, "/"), "favicon.ico")) && + StrUtil.containsAny(StrUtil.removePrefix(url, "http://"), StrUtil.removeAny(StrUtil.removeAny(href, "/"), "favicon.ico"))) { + return "http://" + StrUtil.removePrefix(href, "/"); + } + //如果url已经包含了logo + if (StrUtil.containsAny(url, "favicon")) { + return url; + } + //如果logo中有url + if (StrUtil.containsAny(href, "http") || StrUtil.containsAny(href, "https")) { + return href; + } + return StrUtil.format("{}/{}", url, StrUtil.removePrefix(href, "/")); + } +} From cc3a764aaf1c9f0ed9a505697e4d01c34d6f070a Mon Sep 17 00:00:00 2001 From: limeng Date: Thu, 6 Jul 2023 16:28:09 +0800 Subject: [PATCH 23/42] =?UTF-8?q?=E5=B0=86=E5=BA=9F=E5=BC=83=E7=9A=84Serve?= =?UTF-8?q?rHandshakeStateEvent.HANDSHAKE=5FCOMPLETE=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=E4=B8=BAHandshakeComplete?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mallchat/custom/user/websocket/HttpHeadersHandler.java | 3 ++- .../custom/user/websocket/NettyWebSocketServerHandler.java | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java index b6cdd43..b60f78b 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java @@ -19,11 +19,12 @@ public class HttpHeadersHandler extends ChannelInboundHandlerAdapter { // 获取token参数 String token = urlBuilder.getQuery().get("token").toString(); - NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token); + //NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token); // 获取请求路径 request.setUri(urlBuilder.getPath().toString()); HttpHeaders headers = request.headers(); + headers.set("token", token); String ip = headers.get("X-Real-IP"); if (StringUtils.isEmpty(ip)) {//如果没经过nginx,就直接获取远端地址 InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress(); diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java index dbc62f9..d97122c 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java @@ -67,9 +67,10 @@ public class NettyWebSocketServerHandler extends SimpleChannelInboundHandler Date: Thu, 6 Jul 2023 21:04:59 +0800 Subject: [PATCH 24/42] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E4=BB=8Echannel?= =?UTF-8?q?=E4=B8=AD=E5=AD=98=E6=94=BEtoken?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mallchat/custom/user/websocket/HttpHeadersHandler.java | 3 +-- .../custom/user/websocket/NettyWebSocketServerHandler.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java index b60f78b..b6cdd43 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java @@ -19,12 +19,11 @@ public class HttpHeadersHandler extends ChannelInboundHandlerAdapter { // 获取token参数 String token = urlBuilder.getQuery().get("token").toString(); - //NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token); + NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token); // 获取请求路径 request.setUri(urlBuilder.getPath().toString()); HttpHeaders headers = request.headers(); - headers.set("token", token); String ip = headers.get("X-Real-IP"); if (StringUtils.isEmpty(ip)) {//如果没经过nginx,就直接获取远端地址 InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress(); diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java index d97122c..fe8a92a 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java @@ -69,8 +69,7 @@ public class NettyWebSocketServerHandler extends SimpleChannelInboundHandler Date: Thu, 6 Jul 2023 21:51:16 +0800 Subject: [PATCH 25/42] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E4=B8=8D=E4=BC=A0token=E5=87=BA=E7=8E=B0NPE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../abin/mallchat/custom/user/service/LoginService.java | 1 + .../custom/user/websocket/HttpHeadersHandler.java | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/LoginService.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/LoginService.java index ed28384..3f57542 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/LoginService.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/LoginService.java @@ -38,4 +38,5 @@ public interface LoginService { * @return */ Long getValidUid(String token); + } diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java index b6cdd43..5434151 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java @@ -8,6 +8,7 @@ import io.netty.handler.codec.http.HttpHeaders; import org.apache.commons.lang3.StringUtils; import java.net.InetSocketAddress; +import java.util.Objects; public class HttpHeadersHandler extends ChannelInboundHandlerAdapter { @@ -18,8 +19,11 @@ public class HttpHeadersHandler extends ChannelInboundHandlerAdapter { UrlBuilder urlBuilder = UrlBuilder.ofHttp(request.uri()); // 获取token参数 - String token = urlBuilder.getQuery().get("token").toString(); - NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token); + CharSequence sequence = urlBuilder.getQuery().get("token"); + if (Objects.nonNull(sequence)) { + String token = sequence.toString(); + NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token); + } // 获取请求路径 request.setUri(urlBuilder.getPath().toString()); From 58daaef47ca302d5fbc76652253039a9626871ca Mon Sep 17 00:00:00 2001 From: linzhihan <935336957@qq.com> Date: Thu, 6 Jul 2023 21:54:04 +0800 Subject: [PATCH 26/42] =?UTF-8?q?=E7=BC=96=E7=A8=8B=E5=BC=8F=E9=99=90?= =?UTF-8?q?=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/aspect/FrequencyControlAspect.java | 52 ++++---- .../domain/dto/FrequencyControlDTO.java | 42 +++++++ .../exception/FrequencyControlException.java | 39 ++++++ .../exception/GlobalExceptionHandler.java | 8 ++ .../AbstractFrequencyControlService.java | 113 ++++++++++++++++++ .../FrequencyControlStrategyFactory.java | 51 ++++++++ .../FrequencyControlUtil.java | 55 +++++++++ ...CountWithInFixTimeFrequencyController.java | 64 ++++++++++ .../custom/chatai/dto/GPTRequestDTO.java | 21 ++++ .../chatai/handler/ChatGLM2Handler.java | 65 ++++++---- .../chatai/handler/GPTChatAIHandler.java | 68 ++++++----- .../user/websocket/HttpHeadersHandler.java | 3 +- 12 files changed, 506 insertions(+), 75 deletions(-) create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/domain/dto/FrequencyControlDTO.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/FrequencyControlException.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/AbstractFrequencyControlService.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/FrequencyControlStrategyFactory.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/FrequencyControlUtil.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/TotalCountWithInFixTimeFrequencyController.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/dto/GPTRequestDTO.java diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/aspect/FrequencyControlAspect.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/aspect/FrequencyControlAspect.java index 25418a6..f0290ab 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/aspect/FrequencyControlAspect.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/aspect/FrequencyControlAspect.java @@ -2,9 +2,8 @@ package com.abin.mallchat.common.common.aspect; import cn.hutool.core.util.StrUtil; import com.abin.mallchat.common.common.annotation.FrequencyControl; -import com.abin.mallchat.common.common.exception.BusinessException; -import com.abin.mallchat.common.common.exception.CommonErrorEnum; -import com.abin.mallchat.common.common.utils.RedisUtils; +import com.abin.mallchat.common.common.domain.dto.FrequencyControlDTO; +import com.abin.mallchat.common.common.service.frequencycontrol.FrequencyControlUtil; import com.abin.mallchat.common.common.utils.RequestHolder; import com.abin.mallchat.common.common.utils.SpElUtils; import lombok.extern.slf4j.Slf4j; @@ -15,7 +14,12 @@ import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.lang.reflect.Method; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static com.abin.mallchat.common.common.service.frequencycontrol.FrequencyControlStrategyFactory.TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER; /** * Description: 频控实现 @@ -48,25 +52,25 @@ public class FrequencyControlAspect { } keyMap.put(prefix + ":" + key, frequencyControl); } - //批量获取redis统计的值 - ArrayList keyList = new ArrayList<>(keyMap.keySet()); - List countList = RedisUtils.mget(keyList, Integer.class); - for (int i = 0; i < keyList.size(); i++) { - String key = keyList.get(i); - Integer count = countList.get(i); - FrequencyControl frequencyControl = keyMap.get(key); - if (Objects.nonNull(count) && count >= frequencyControl.count()) {//频率超过了 - log.warn("frequencyControl limit key:{},count:{}", key, count); - throw new BusinessException(CommonErrorEnum.FREQUENCY_LIMIT); - } - } - try { - return joinPoint.proceed(); - } finally { - //不管成功还是失败,都增加次数 - keyMap.forEach((k, v) -> { - RedisUtils.inc(k, v.time(), v.unit()); - }); - } + // 将注解的参数转换为编程式调用需要的参数 + List frequencyControlDTOS = keyMap.entrySet().stream().map(entrySet -> buildFrequencyControlDTO(entrySet.getKey(), entrySet.getValue())).collect(Collectors.toList()); + // 调用编程式注解 + return FrequencyControlUtil.executeWithFrequencyControlList(TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER, frequencyControlDTOS, joinPoint::proceed); + } + + /** + * 将注解参数转换为编程式调用所需要的参数 + * + * @param key 频率控制Key + * @param frequencyControl 注解 + * @return 编程式调用所需要的参数-FrequencyControlDTO + */ + private FrequencyControlDTO buildFrequencyControlDTO(String key, FrequencyControl frequencyControl) { + FrequencyControlDTO frequencyControlDTO = new FrequencyControlDTO(); + frequencyControlDTO.setCount(frequencyControl.count()); + frequencyControlDTO.setTime(frequencyControl.time()); + frequencyControlDTO.setUnit(frequencyControl.unit()); + frequencyControlDTO.setKey(key); + return frequencyControlDTO; } } diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/domain/dto/FrequencyControlDTO.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/domain/dto/FrequencyControlDTO.java new file mode 100644 index 0000000..3399773 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/domain/dto/FrequencyControlDTO.java @@ -0,0 +1,42 @@ +package com.abin.mallchat.common.common.domain.dto; + +import lombok.*; + +import java.util.concurrent.TimeUnit; + +@Data +@ToString +@Builder +@NoArgsConstructor +@AllArgsConstructor +/** 限流策略定义 + * @author linzhihan + * @date 2023/07/03 + * + */ +public class FrequencyControlDTO { + /** + * 代表频控的Key 如果target为Key的话 这里要传值用于构建redis的Key target为Ip或者UID的话会从上下文取值 Key字段无需传值 + */ + private String key; + /** + * 频控时间范围,默认单位秒 + * + * @return 时间范围 + */ + private Integer time; + + /** + * 频控时间单位,默认秒 + * + * @return 单位 + */ + private TimeUnit unit; + + /** + * 单位时间内最大访问次数 + * + * @return 次数 + */ + private Integer count; +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/FrequencyControlException.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/FrequencyControlException.java new file mode 100644 index 0000000..fbcaff7 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/FrequencyControlException.java @@ -0,0 +1,39 @@ +package com.abin.mallchat.common.common.exception; + +import lombok.Data; + +/** + * 自定义限流异常 + * + * @author linzhihan + * @date 2023/07/034 + */ +@Data +public class FrequencyControlException extends RuntimeException { + private static final long serialVersionUID = 1L; + + /** + *  错误码 + */ + protected Integer errorCode; + + /** + *  错误信息 + */ + protected String errorMsg; + + public FrequencyControlException() { + super(); + } + + public FrequencyControlException(String errorMsg) { + super(errorMsg); + this.errorMsg = errorMsg; + } + + public FrequencyControlException(ErrorEnum error) { + super(error.getErrorMsg()); + this.errorCode = error.getErrorCode(); + this.errorMsg = error.getErrorMsg(); + } +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/GlobalExceptionHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/GlobalExceptionHandler.java index a5a06eb..066e210 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/GlobalExceptionHandler.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/GlobalExceptionHandler.java @@ -73,4 +73,12 @@ public class GlobalExceptionHandler { return ApiResult.fail(-1, String.format("不支持'%s'请求", e.getMethod())); } + /** + * 限流异常 + */ + @ExceptionHandler(value = FrequencyControlException.class) + public ApiResult frequencyControlExceptionHandler(FrequencyControlException e) { + log.info("frequencyControl exception!The reason is:{}", e.getMessage(), e); + return ApiResult.fail(e.getErrorCode(), e.getMessage()); + } } diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/AbstractFrequencyControlService.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/AbstractFrequencyControlService.java new file mode 100644 index 0000000..5b884c5 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/AbstractFrequencyControlService.java @@ -0,0 +1,113 @@ +package com.abin.mallchat.common.common.service.frequencycontrol; + +import com.abin.mallchat.common.common.domain.dto.FrequencyControlDTO; +import com.abin.mallchat.common.common.exception.CommonErrorEnum; +import com.abin.mallchat.common.common.exception.FrequencyControlException; +import com.abin.mallchat.common.common.utils.AssertUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; + +import javax.annotation.PostConstruct; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 抽象类频控服务 其他类如果要实现限流服务 直接注入使用通用限流类 + * 后期会通过继承此类实现令牌桶等算法 + * + * @author linzhihan + * @date 2023/07/03 + * @see TotalCountWithInFixTimeFrequencyController 通用限流类 + */ +@Slf4j +public abstract class AbstractFrequencyControlService { + + @PostConstruct + protected void registerMyselfToFactory() { + FrequencyControlStrategyFactory.registerFrequencyController(getStrategyName(), this); + } + + /** + * @param frequencyControlMap 定义的注解频控 Map中的Key-对应redis的单个频控的Key Map中的Value-对应redis的单个频控的Key限制的Value + * @param supplier 函数式入参-代表每个频控方法执行的不同的业务逻辑 + * @return 业务方法执行的返回值 + * @throws Throwable + */ + private T executeWithFrequencyControlMap(Map frequencyControlMap, SupplierThrowWithoutParam supplier) throws Throwable { + if (reachRateLimit(frequencyControlMap)) { + throw new FrequencyControlException(CommonErrorEnum.FREQUENCY_LIMIT); + } + try { + return supplier.get(); + } finally { + //不管成功还是失败,都增加次数 + addFrequencyControlStatisticsCount(frequencyControlMap); + } + } + + + /** + * 多限流策略的编程式调用方法 无参的调用方法 + * + * @param frequencyControlList 频控列表 包含每一个频率控制的定义以及顺序 + * @param supplier 函数式入参-代表每个频控方法执行的不同的业务逻辑 + * @return 业务方法执行的返回值 + * @throws Throwable 被限流或者限流策略定义错误 + */ + @SuppressWarnings("unchecked") + public T executeWithFrequencyControlList(List frequencyControlList, SupplierThrowWithoutParam supplier) throws Throwable { + boolean existsFrequencyControlHasNullKey = frequencyControlList.stream().anyMatch(frequencyControl -> ObjectUtils.isEmpty(frequencyControl.getKey())); + AssertUtil.isFalse(existsFrequencyControlHasNullKey, "限流策略的Key字段不允许出现空值"); + Map frequencyControlDTOMap = frequencyControlList.stream().collect(Collectors.groupingBy(FrequencyControlDTO::getKey, Collectors.collectingAndThen(Collectors.toList(), list -> list.get(0)))); + return executeWithFrequencyControlMap((Map) frequencyControlDTOMap, supplier); + } + + /** + * 单限流策略的调用方法-编程式调用 + * + * @param frequencyControl 单个频控对象 + * @param supplier 服务提供着 + * @return 业务方法执行结果 + * @throws Throwable + */ + public T executeWithFrequencyControl(K frequencyControl, SupplierThrowWithoutParam supplier) throws Throwable { + return executeWithFrequencyControlList(Collections.singletonList(frequencyControl), supplier); + } + + + @FunctionalInterface + public interface SupplierThrowWithoutParam { + + /** + * Gets a result. + * + * @return a result + */ + T get() throws Throwable; + } + + /** + * 是否达到限流阈值 子类实现 每个子类都可以自定义自己的限流逻辑判断 + * + * @param frequencyControlMap 定义的注解频控 Map中的Key-对应redis的单个频控的Key Map中的Value-对应redis的单个频控的Key限制的Value + * @return true-方法被限流 false-方法没有被限流 + */ + protected abstract boolean reachRateLimit(Map frequencyControlMap); + + /** + * 增加限流统计次数 子类实现 每个子类都可以自定义自己的限流统计信息增加的逻辑 + * + * @param frequencyControlMap 定义的注解频控 Map中的Key-对应redis的单个频控的Key Map中的Value-对应redis的单个频控的Key限制的Value + */ + protected abstract void addFrequencyControlStatisticsCount(Map frequencyControlMap); + + /** + * 获取策略名称 + * + * @return 策略名称 + */ + protected abstract String getStrategyName(); + +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/FrequencyControlStrategyFactory.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/FrequencyControlStrategyFactory.java new file mode 100644 index 0000000..ec211a8 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/FrequencyControlStrategyFactory.java @@ -0,0 +1,51 @@ +package com.abin.mallchat.common.common.service.frequencycontrol; + +import com.abin.mallchat.common.common.domain.dto.FrequencyControlDTO; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 限流策略工厂 + * + * @author linzhihan + * @date 2023/07/03 + */ +public class FrequencyControlStrategyFactory { + /** + * 指定时间内总次数限流 + */ + public static final String TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER = "TotalCountWithInFixTime"; + /** + * 限流策略集合 + */ + static Map> frequencyControlServiceStrategyMap = new ConcurrentHashMap<>(8); + + /** + * 将策略类放入工厂 + * + * @param strategyName 策略名称 + * @param abstractFrequencyControlService 策略类 + */ + public static void registerFrequencyController(String strategyName, AbstractFrequencyControlService abstractFrequencyControlService) { + frequencyControlServiceStrategyMap.put(strategyName, abstractFrequencyControlService); + } + + /** + * 根据名称获取策略类 + * + * @param strategyName 策略名称 + * @return 对应的限流策略类 + */ + @SuppressWarnings("unchecked") + public static AbstractFrequencyControlService getFrequencyControllerByName(String strategyName) { + return (AbstractFrequencyControlService) frequencyControlServiceStrategyMap.get(strategyName); + } + + /** + * 构造器私有 + */ + private FrequencyControlStrategyFactory() { + + } +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/FrequencyControlUtil.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/FrequencyControlUtil.java new file mode 100644 index 0000000..aa9a30e --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/FrequencyControlUtil.java @@ -0,0 +1,55 @@ +package com.abin.mallchat.common.common.service.frequencycontrol; + +import com.abin.mallchat.common.common.domain.dto.FrequencyControlDTO; +import com.abin.mallchat.common.common.utils.AssertUtil; +import org.apache.commons.lang3.ObjectUtils; + +import java.util.List; + +/** + * 限流工具类 提供编程式的限流调用方法 + * + * @author linzhihan + * @date 2023/07/03 + */ +public class FrequencyControlUtil { + + /** + * 单限流策略的调用方法-编程式调用 + * + * @param strategyName 策略名称 + * @param frequencyControl 单个频控对象 + * @param supplier 服务提供着 + * @return 业务方法执行结果 + * @throws Throwable + */ + public static T executeWithFrequencyControl(String strategyName, K frequencyControl, AbstractFrequencyControlService.SupplierThrowWithoutParam supplier) throws Throwable { + AbstractFrequencyControlService frequencyController = FrequencyControlStrategyFactory.getFrequencyControllerByName(strategyName); + return frequencyController.executeWithFrequencyControl(frequencyControl, supplier); + } + + + /** + * 多限流策略的编程式调用方法调用方法 + * + * @param strategyName 策略名称 + * @param frequencyControlList 频控列表 包含每一个频率控制的定义以及顺序 + * @param supplier 函数式入参-代表每个频控方法执行的不同的业务逻辑 + * @return 业务方法执行的返回值 + * @throws Throwable 被限流或者限流策略定义错误 + */ + public static T executeWithFrequencyControlList(String strategyName, List frequencyControlList, AbstractFrequencyControlService.SupplierThrowWithoutParam supplier) throws Throwable { + boolean existsFrequencyControlHasNullKey = frequencyControlList.stream().anyMatch(frequencyControl -> ObjectUtils.isEmpty(frequencyControl.getKey())); + AssertUtil.isFalse(existsFrequencyControlHasNullKey, "限流策略的Key字段不允许出现空值"); + AbstractFrequencyControlService frequencyController = FrequencyControlStrategyFactory.getFrequencyControllerByName(strategyName); + return frequencyController.executeWithFrequencyControlList(frequencyControlList, supplier); + } + + /** + * 构造器私有 + */ + private FrequencyControlUtil() { + + } + +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/TotalCountWithInFixTimeFrequencyController.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/TotalCountWithInFixTimeFrequencyController.java new file mode 100644 index 0000000..531e36c --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/TotalCountWithInFixTimeFrequencyController.java @@ -0,0 +1,64 @@ +package com.abin.mallchat.common.common.service.frequencycontrol; + +import com.abin.mallchat.common.common.domain.dto.FrequencyControlDTO; +import com.abin.mallchat.common.common.utils.RedisUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static com.abin.mallchat.common.common.service.frequencycontrol.FrequencyControlStrategyFactory.TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER; + +/** + * 抽象类频控服务 -使用redis实现 固定时间内不超过固定次数的限流类 + * + * @author linzhihan + * @date 2023/07/03 + */ +@Slf4j +@Service +public class TotalCountWithInFixTimeFrequencyController extends AbstractFrequencyControlService { + + + /** + * 是否达到限流阈值 子类实现 每个子类都可以自定义自己的限流逻辑判断 + * + * @param frequencyControlMap 定义的注解频控 Map中的Key-对应redis的单个频控的Key Map中的Value-对应redis的单个频控的Key限制的Value + * @return true-方法被限流 false-方法没有被限流 + */ + @Override + protected boolean reachRateLimit(Map frequencyControlMap) { + //批量获取redis统计的值 + List frequencyKeys = new ArrayList<>(frequencyControlMap.keySet()); + List countList = RedisUtils.mget(frequencyKeys, Integer.class); + for (int i = 0; i < frequencyKeys.size(); i++) { + String key = frequencyKeys.get(i); + Integer count = countList.get(i); + int frequencyControlCount = frequencyControlMap.get(key).getCount(); + if (Objects.nonNull(count) && count >= frequencyControlCount) { + //频率超过了 + log.warn("frequencyControl limit key:{},count:{}", key, count); + return true; + } + } + return false; + } + + /** + * 增加限流统计次数 子类实现 每个子类都可以自定义自己的限流统计信息增加的逻辑 + * + * @param frequencyControlMap 定义的注解频控 Map中的Key-对应redis的单个频控的Key Map中的Value-对应redis的单个频控的Key限制的Value + */ + @Override + protected void addFrequencyControlStatisticsCount(Map frequencyControlMap) { + frequencyControlMap.forEach((k, v) -> RedisUtils.inc(k, v.getTime(), v.getUnit())); + } + + @Override + protected String getStrategyName() { + return TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER; + } +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/dto/GPTRequestDTO.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/dto/GPTRequestDTO.java new file mode 100644 index 0000000..cb72432 --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/dto/GPTRequestDTO.java @@ -0,0 +1,21 @@ +package com.abin.mallchat.custom.chatai.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class GPTRequestDTO { + /** + * 聊天内容 + */ + private String content; + /** + * 用户Id + */ + private Long uid; +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/ChatGLM2Handler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/ChatGLM2Handler.java index 0f7ff1b..83f665a 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/ChatGLM2Handler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/ChatGLM2Handler.java @@ -4,12 +4,17 @@ import cn.hutool.http.HttpResponse; import com.abin.mallchat.common.chat.domain.entity.Message; import com.abin.mallchat.common.chat.domain.entity.msg.MessageExtra; import com.abin.mallchat.common.common.constant.RedisKey; +import com.abin.mallchat.common.common.domain.dto.FrequencyControlDTO; +import com.abin.mallchat.common.common.exception.FrequencyControlException; +import com.abin.mallchat.common.common.service.frequencycontrol.FrequencyControlUtil; import com.abin.mallchat.common.common.utils.RedisUtils; +import com.abin.mallchat.custom.chatai.dto.GPTRequestDTO; import com.abin.mallchat.custom.chatai.properties.ChatGLM2Properties; import com.abin.mallchat.custom.chatai.utils.ChatGLM2Utils; import com.abin.mallchat.custom.user.domain.vo.response.user.UserInfoResp; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -21,10 +26,15 @@ import java.util.Random; import java.util.concurrent.TimeUnit; import static com.abin.mallchat.common.common.constant.RedisKey.USER_GLM2_TIME_LAST; +import static com.abin.mallchat.common.common.service.frequencycontrol.FrequencyControlStrategyFactory.TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER; @Slf4j @Component public class ChatGLM2Handler extends AbstractChatAIHandler { + /** + * ChatGLM2Handler限流前缀 + */ + private static final String CHAT_GLM2_FREQUENCY_PREFIX = "ChatGLM2Handler"; private static final List ERROR_MSG = Arrays.asList( "还摸鱼呢?你不下班我还要下班呢。。。。", @@ -74,27 +84,42 @@ public class ChatGLM2Handler extends AbstractChatAIHandler { protected String doChat(Message message) { String content = message.getContent().replace("@" + AI_NAME, "").trim(); Long uid = message.getFromUid(); - Long minute; + try { + FrequencyControlDTO frequencyControlDTO = new FrequencyControlDTO(); + frequencyControlDTO.setKey(CHAT_GLM2_FREQUENCY_PREFIX + ":" + uid); + frequencyControlDTO.setUnit(TimeUnit.MINUTES); + frequencyControlDTO.setCount(1); + frequencyControlDTO.setTime(glm2Properties.getMinute().intValue()); + return FrequencyControlUtil.executeWithFrequencyControl(TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER, frequencyControlDTO, () -> sendRequestToGPT(new GPTRequestDTO(content, uid))); + } catch (FrequencyControlException e) { + return "你太快了亲爱的~过一会再来找人家~"; + } catch (Throwable e) { + return "系统开小差啦~~"; + } + } + + /** + * TODO + * + * @param gptRequestDTO + * @return + */ + @Nullable + private String sendRequestToGPT(GPTRequestDTO gptRequestDTO) { + String content = gptRequestDTO.getContent(); String text; - if ((minute = userMinutesLater(uid)) > 0) { - text = "你太快了 " + minute + "分钟后重试"; - } else { - HttpResponse response = null; - try { - response = ChatGLM2Utils - .create() - .url(glm2Properties.getUrl()) - .prompt(content) - .timeout(glm2Properties.getTimeout()) - .send(); - text = ChatGLM2Utils.parseText(response); - } catch (Exception e) { - log.warn("glm2 doChat warn:", e); - return getErrorText(); - } - if (StringUtils.isNotBlank(text)) { - RedisUtils.set(RedisKey.getKey(USER_GLM2_TIME_LAST, uid), new Date(), glm2Properties.getMinute(), TimeUnit.MINUTES); - } + HttpResponse response = null; + try { + response = ChatGLM2Utils + .create() + .url(glm2Properties.getUrl()) + .prompt(content) + .timeout(glm2Properties.getTimeout()) + .send(); + text = ChatGLM2Utils.parseText(response); + } catch (Exception e) { + log.warn("glm2 doChat warn:", e); + return getErrorText(); } return text; } diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/GPTChatAIHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/GPTChatAIHandler.java index 440c1d9..fd8a594 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/GPTChatAIHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/GPTChatAIHandler.java @@ -3,9 +3,10 @@ package com.abin.mallchat.custom.chatai.handler; import cn.hutool.http.HttpResponse; import com.abin.mallchat.common.chat.domain.entity.Message; import com.abin.mallchat.common.chat.domain.entity.msg.MessageExtra; -import com.abin.mallchat.common.common.constant.RedisKey; -import com.abin.mallchat.common.common.utils.DateUtils; -import com.abin.mallchat.common.common.utils.RedisUtils; +import com.abin.mallchat.common.common.domain.dto.FrequencyControlDTO; +import com.abin.mallchat.common.common.exception.FrequencyControlException; +import com.abin.mallchat.common.common.service.frequencycontrol.FrequencyControlUtil; +import com.abin.mallchat.custom.chatai.dto.GPTRequestDTO; import com.abin.mallchat.custom.chatai.properties.ChatGPTProperties; import com.abin.mallchat.custom.chatai.utils.ChatGPTUtils; import com.abin.mallchat.custom.user.domain.vo.response.user.UserInfoResp; @@ -17,9 +18,15 @@ import org.springframework.util.CollectionUtils; import java.util.concurrent.TimeUnit; +import static com.abin.mallchat.common.common.service.frequencycontrol.FrequencyControlStrategyFactory.TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER; + @Slf4j @Component public class GPTChatAIHandler extends AbstractChatAIHandler { + /** + * GPTChatAIHandler限流前缀 + */ + private static final String CHAT_FREQUENCY_PREFIX = "GPTChatAIHandler"; @Autowired private ChatGPTProperties chatGPTProperties; @@ -51,43 +58,44 @@ public class GPTChatAIHandler extends AbstractChatAIHandler { return chatGPTProperties.getAIUserId(); } - @Override protected String doChat(Message message) { String content = message.getContent().replace("@" + AI_NAME, "").trim(); Long uid = message.getFromUid(); - Long chatNum; + try { + FrequencyControlDTO frequencyControlDTO = new FrequencyControlDTO(); + frequencyControlDTO.setKey(CHAT_FREQUENCY_PREFIX + ":" + uid); + frequencyControlDTO.setUnit(TimeUnit.HOURS); + frequencyControlDTO.setCount(chatGPTProperties.getLimit()); + frequencyControlDTO.setTime(24); + return FrequencyControlUtil.executeWithFrequencyControl(TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER, frequencyControlDTO, () -> sendRequestToGPT(new GPTRequestDTO(content, uid))); + } catch (FrequencyControlException e) { + return "亲爱的,你今天找我聊了" + chatGPTProperties.getLimit() + "次了~人家累了~明天见"; + } catch (Throwable e) { + return "系统开小差啦~~"; + } + } + + private String sendRequestToGPT(GPTRequestDTO gptRequestDTO) { + String content = gptRequestDTO.getContent(); String text; - if ((chatNum = getUserChatNum(uid)) > chatGPTProperties.getLimit()) { - text = "你今天已经和我聊了" + chatNum + "次了,我累了,明天再聊吧"; - } else { - HttpResponse response = null; - try { - response = ChatGPTUtils.create(chatGPTProperties.getKey()) - .proxyUrl(chatGPTProperties.getProxyUrl()) - .model(chatGPTProperties.getModelName()) - .timeout(chatGPTProperties.getTimeout()) - .prompt(content) - .send(); - text = ChatGPTUtils.parseText(response); - userChatNumInrc(uid); - } catch (Exception e) { - log.warn("gpt doChat warn:", e); - text = "我累了,明天再聊吧"; - } + HttpResponse response = null; + try { + response = ChatGPTUtils.create(chatGPTProperties.getKey()) + .proxyUrl(chatGPTProperties.getProxyUrl()) + .model(chatGPTProperties.getModelName()) + .timeout(chatGPTProperties.getTimeout()) + .prompt(content) + .send(); + text = ChatGPTUtils.parseText(response); + } catch (Exception e) { + log.warn("gpt doChat warn:", e); + text= "我累了,明天再聊吧"; } return text; } - private Long userChatNumInrc(Long uid) { - return RedisUtils.inc(RedisKey.getKey(RedisKey.USER_CHAT_NUM, uid), DateUtils.getEndTimeByToday().intValue(), TimeUnit.MILLISECONDS); - } - private Long getUserChatNum(Long uid) { - Long num = RedisUtils.get(RedisKey.getKey(RedisKey.USER_CHAT_NUM, uid), Long.class); - return num == null ? 0 : num; - - } @Override diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java index b6cdd43..6752060 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java @@ -8,6 +8,7 @@ import io.netty.handler.codec.http.HttpHeaders; import org.apache.commons.lang3.StringUtils; import java.net.InetSocketAddress; +import java.util.Optional; public class HttpHeadersHandler extends ChannelInboundHandlerAdapter { @@ -18,7 +19,7 @@ public class HttpHeadersHandler extends ChannelInboundHandlerAdapter { UrlBuilder urlBuilder = UrlBuilder.ofHttp(request.uri()); // 获取token参数 - String token = urlBuilder.getQuery().get("token").toString(); + String token = Optional.ofNullable(urlBuilder.getQuery()).map(k->k.get("token")).map(CharSequence::toString).orElse(""); NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token); // 获取请求路径 From dacc458ad280a88cdefb967e593db21030a16a2e Mon Sep 17 00:00:00 2001 From: limeng Date: Thu, 6 Jul 2023 22:03:09 +0800 Subject: [PATCH 27/42] =?UTF-8?q?token=E8=A7=A3=E6=9E=90=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E6=89=93=E5=8D=B0error=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/abin/mallchat/common/common/utils/JwtUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/JwtUtils.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/JwtUtils.java index fe2a97e..f9ce4d5 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/JwtUtils.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/JwtUtils.java @@ -67,7 +67,7 @@ public class JwtUtils { DecodedJWT jwt = verifier.verify(token); return jwt.getClaims(); } catch (Exception e) { - log.info("decode error,token:{}", token, e); + log.error("decode error,token:{}", token, e); } return null; } From 3587889fa27f27b633abf0682b11fe3f827f5f65 Mon Sep 17 00:00:00 2001 From: zhongzb <972627721@qq.com> Date: Thu, 6 Jul 2023 22:27:54 +0800 Subject: [PATCH 28/42] fix:readme --- README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b642c57..5620fdf 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,6 @@ - [![MallChat](https://github.com/Evansy/MallChatWeb/actions/workflows/deploy.yml/badge.svg?branch=main)](https://github.com/Evansy/MallChatWeb/actions/workflows/deploy.yml) Commit @@ -130,7 +129,7 @@ 虚拟列表 - 后端 + 后端 @@ -145,6 +144,18 @@ Ac自动机敏感词检测 + + + + + 限流编程式 + + + + + + 握手认证 + From a14b9036a338e725a03b28dfd8bd6c907236304f Mon Sep 17 00:00:00 2001 From: zongzibinbin <58972270+zongzibinbin@users.noreply.github.com> Date: Thu, 6 Jul 2023 22:41:11 +0800 Subject: [PATCH 29/42] Update mallchat.sql --- docs/mallchat.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/mallchat.sql b/docs/mallchat.sql index eccb347..be0146d 100644 --- a/docs/mallchat.sql +++ b/docs/mallchat.sql @@ -101,7 +101,6 @@ CREATE TABLE `user` ( `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户头像', `sex` int(11) NULL DEFAULT NULL COMMENT '性别 1为男性,2为女性', `open_id` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '微信openid用户标识', - `publish_chat_to_wechat_switch` bool DEFAULT 0 COMMENT '群聊消息推送开关', `last_opt_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '最后上下线时间', `ip_info` json NULL COMMENT 'ip信息', `item_id` bigint(20) NULL DEFAULT NULL COMMENT '佩戴的徽章id', @@ -191,4 +190,4 @@ CREATE TABLE `sensitive_word` ( `word` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '敏感词' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='敏感词库'; INSERT INTO `sensitive_word` (`word`) VALUES ('TMD'); -INSERT INTO `sensitive_word` (`word`) VALUES ('tmd'); \ No newline at end of file +INSERT INTO `sensitive_word` (`word`) VALUES ('tmd'); From 8b8b8835521e2d97635c4c20aef6bca684b6513d Mon Sep 17 00:00:00 2001 From: zongzibinbin <58972270+zongzibinbin@users.noreply.github.com> Date: Thu, 6 Jul 2023 22:43:37 +0800 Subject: [PATCH 30/42] Update User.java --- .../com/abin/mallchat/common/user/domain/entity/User.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/User.java b/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/User.java index 59c8c82..0421526 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/User.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/User.java @@ -58,12 +58,6 @@ public class User implements Serializable { @TableField("open_id") private String openId; - /** - * 是否开启微信消息推送 - */ - @TableField("publish_chat_to_wechat_switch") - private boolean publishChatToWechatSwitch; - /** * 最后上下线时间 */ From 65f8735d28a53d9c74ce2e831f71c413de809a4f Mon Sep 17 00:00:00 2001 From: zhongzb <972627721@qq.com> Date: Thu, 6 Jul 2023 23:08:06 +0800 Subject: [PATCH 31/42] =?UTF-8?q?fix:=E5=BE=AE=E4=BF=A1=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E6=8E=A5=E5=85=A5=E9=A2=91=E6=8E=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractFrequencyControlService.java | 11 ++++++ .../FrequencyControlUtil.java | 8 +++++ .../impl/WeChatMsgOperationServiceImpl.java | 34 ++++++++++++++----- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/AbstractFrequencyControlService.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/AbstractFrequencyControlService.java index 5b884c5..211f9f8 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/AbstractFrequencyControlService.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/frequencycontrol/AbstractFrequencyControlService.java @@ -88,6 +88,17 @@ public abstract class AbstractFrequencyControlService void executeWithFrequencyControl(String strategyName, K frequencyControl, AbstractFrequencyControlService.Executor executor) throws Throwable { + AbstractFrequencyControlService frequencyController = FrequencyControlStrategyFactory.getFrequencyControllerByName(strategyName); + frequencyController.executeWithFrequencyControl(frequencyControl, () -> { + executor.execute(); + return null; + }); + } + /** * 多限流策略的编程式调用方法调用方法 diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java index 10347a6..640d58a 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java @@ -1,7 +1,10 @@ package com.abin.mallchat.custom.chat.service.impl; import cn.hutool.core.thread.NamedThreadFactory; +import com.abin.mallchat.common.common.domain.dto.FrequencyControlDTO; +import com.abin.mallchat.common.common.exception.FrequencyControlException; import com.abin.mallchat.common.common.handler.GlobalUncaughtExceptionHandler; +import com.abin.mallchat.common.common.service.frequencycontrol.FrequencyControlUtil; import com.abin.mallchat.common.common.utils.JsonUtils; import com.abin.mallchat.common.user.domain.entity.User; import com.abin.mallchat.common.user.service.cache.UserCache; @@ -15,20 +18,17 @@ import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import static com.abin.mallchat.common.common.service.frequencycontrol.FrequencyControlStrategyFactory.TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER; + @Slf4j @Component -public class WeChatMsgOperationServiceImpl implements WeChatMsgOperationService { +public class WeChatMsgOperationServiceImpl implements WeChatMsgOperationService { private static final ExecutorService executor = new ThreadPoolExecutor(1, 10, 3000L, TimeUnit.MILLISECONDS, @@ -54,15 +54,31 @@ public class WeChatMsgOperationServiceImpl implements WeChatMsgOperationService uidSet.addAll(receiverUidList); Map userMap = userCache.getUserInfoBatch(uidSet); userMap.values().forEach(user -> { - if (Objects.nonNull(user.getOpenId()) && user.isPublishChatToWechatSwitch()) { + if (Objects.nonNull(user.getOpenId())) { executor.execute(() -> { WxMpTemplateMessage msgTemplate = getAtMsgTemplate(sender, user.getOpenId(), msg); - publishTemplateMsg(msgTemplate); + publishTemplateMsgCheckLimit(msgTemplate); }); } }); } + private void publishTemplateMsgCheckLimit(WxMpTemplateMessage msgTemplate) { + try { + FrequencyControlDTO frequencyControlDTO = new FrequencyControlDTO(); + frequencyControlDTO.setKey("TemplateMsg:" + msgTemplate.getToUser()); + frequencyControlDTO.setUnit(TimeUnit.HOURS); + frequencyControlDTO.setCount(1); + frequencyControlDTO.setTime(1); + FrequencyControlUtil.executeWithFrequencyControl(TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER, frequencyControlDTO, + () -> publishTemplateMsg(msgTemplate)); + } catch (FrequencyControlException e) { + log.info("wx push limit openid:{}", msgTemplate.getToUser()); + } catch (Throwable e) { + log.error("wx push error openid:{}", msgTemplate.getToUser()); + } + } + /* * 构造微信模板消息 */ From c80a48e85c31803e91803217d093f831caa5244a Mon Sep 17 00:00:00 2001 From: zhongzb <972627721@qq.com> Date: Fri, 7 Jul 2023 00:04:55 +0800 Subject: [PATCH 32/42] =?UTF-8?q?fix:=E6=A8=A1=E6=9D=BF=E9=A2=91=E6=8E=A7?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mallchat-common/pom.xml | 10 ++++++ mallchat-custom-server/pom.xml | 13 ++++++++ .../impl/WeChatMsgOperationServiceImpl.java | 23 ++++++-------- .../abin/mallchat/custom}/ac/ACTrieTest.java | 4 ++- .../mallchat/custom}/ac/CreateTokenTest.java | 2 +- .../mallchat/custom/spring/WXTemplate.java | 31 +++++++++++++++++++ 6 files changed, 68 insertions(+), 15 deletions(-) rename {mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm => mallchat-custom-server/src/test/java/com/abin/mallchat/custom}/ac/ACTrieTest.java (93%) rename {mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm => mallchat-custom-server/src/test/java/com/abin/mallchat/custom}/ac/CreateTokenTest.java (94%) create mode 100644 mallchat-custom-server/src/test/java/com/abin/mallchat/custom/spring/WXTemplate.java diff --git a/mallchat-common/pom.xml b/mallchat-common/pom.xml index 8d7c72f..65433e7 100644 --- a/mallchat-common/pom.xml +++ b/mallchat-common/pom.xml @@ -119,6 +119,16 @@ ${junit.version} test + + org.springframework + spring-test + 5.3.19 + test + + + org.springframework.boot + spring-boot-test + diff --git a/mallchat-custom-server/pom.xml b/mallchat-custom-server/pom.xml index e2fd0c7..601d321 100644 --- a/mallchat-custom-server/pom.xml +++ b/mallchat-custom-server/pom.xml @@ -16,6 +16,19 @@ com.abin.mallchat mallchat-common + + + junit + junit + ${junit.version} + test + + + org.springframework + spring-test + 5.3.19 + test + diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java index 640d58a..429068c 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java @@ -5,14 +5,11 @@ import com.abin.mallchat.common.common.domain.dto.FrequencyControlDTO; import com.abin.mallchat.common.common.exception.FrequencyControlException; import com.abin.mallchat.common.common.handler.GlobalUncaughtExceptionHandler; import com.abin.mallchat.common.common.service.frequencycontrol.FrequencyControlUtil; -import com.abin.mallchat.common.common.utils.JsonUtils; import com.abin.mallchat.common.user.domain.entity.User; import com.abin.mallchat.common.user.service.cache.UserCache; import com.abin.mallchat.custom.chat.service.WeChatMsgOperationService; import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.api.WxMpTemplateMsgService; import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; import org.springframework.beans.factory.annotation.Autowired; @@ -37,7 +34,7 @@ public class WeChatMsgOperationServiceImpl implements WeChatMsgOperationService new GlobalUncaughtExceptionHandler())); // at消息的微信推送模板id - private final String atMsgPublishTemplateId = ""; + private final String atMsgPublishTemplateId = "Xd7sWPZsuWa0UmpvLaZPvaJVjNj1KjEa0zLOm5_Z7IU"; private final String WE_CHAT_MSG_COLOR = "#A349A4"; @@ -96,8 +93,8 @@ public class WeChatMsgOperationServiceImpl implements WeChatMsgOperationService private List generateAtMsgData(User sender, String msg) { List dataList = new ArrayList(); // todo: 没有消息模板,暂不实现 -// dataList.add(new WxMpTemplateData("senderName", sender.getName() , WE_CHAT_MSG_COLOR)); -// dataList.add(new WxMpTemplateData("content", msg , WE_CHAT_MSG_COLOR)); + dataList.add(new WxMpTemplateData("name", sender.getName(), WE_CHAT_MSG_COLOR)); + dataList.add(new WxMpTemplateData("content", msg, WE_CHAT_MSG_COLOR)); return dataList; } @@ -107,12 +104,12 @@ public class WeChatMsgOperationServiceImpl implements WeChatMsgOperationService * @param templateMsg 微信模板消息 */ protected void publishTemplateMsg(WxMpTemplateMessage templateMsg) { - WxMpTemplateMsgService wxMpTemplateMsgService = wxMpService.getTemplateMsgService(); - try { - wxMpTemplateMsgService.sendTemplateMsg(templateMsg); - } catch (WxErrorException e) { - log.error("publish we chat msg failed! open id is {}, msg is {}.", - templateMsg.getToUser(), JsonUtils.toStr(templateMsg.getData())); - } +// WxMpTemplateMsgService wxMpTemplateMsgService = wxMpService.getTemplateMsgService();todo 等审核通过 +// try { +// wxMpTemplateMsgService.sendTemplateMsg(templateMsg); +// } catch (WxErrorException e) { +// log.error("publish we chat msg failed! open id is {}, msg is {}.", +// templateMsg.getToUser(), JsonUtils.toStr(templateMsg.getData())); +// } } } diff --git a/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/ACTrieTest.java b/mallchat-custom-server/src/test/java/com/abin/mallchat/custom/ac/ACTrieTest.java similarity index 93% rename from mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/ACTrieTest.java rename to mallchat-custom-server/src/test/java/com/abin/mallchat/custom/ac/ACTrieTest.java index 2fb749f..1d80ab3 100644 --- a/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/ACTrieTest.java +++ b/mallchat-custom-server/src/test/java/com/abin/mallchat/custom/ac/ACTrieTest.java @@ -1,5 +1,7 @@ -package com.abin.mallchat.common.common.algorithm.ac; +package com.abin.mallchat.custom.ac; +import com.abin.mallchat.common.common.algorithm.ac.ACTrie; +import com.abin.mallchat.common.common.algorithm.ac.MatchResult; import com.google.common.collect.Lists; import org.junit.Test; diff --git a/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java b/mallchat-custom-server/src/test/java/com/abin/mallchat/custom/ac/CreateTokenTest.java similarity index 94% rename from mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java rename to mallchat-custom-server/src/test/java/com/abin/mallchat/custom/ac/CreateTokenTest.java index e73a9a9..2acb222 100644 --- a/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java +++ b/mallchat-custom-server/src/test/java/com/abin/mallchat/custom/ac/CreateTokenTest.java @@ -1,4 +1,4 @@ -package com.abin.mallchat.common.common.algorithm.ac; +package com.abin.mallchat.custom.ac; import com.auth0.jwt.JWT; diff --git a/mallchat-custom-server/src/test/java/com/abin/mallchat/custom/spring/WXTemplate.java b/mallchat-custom-server/src/test/java/com/abin/mallchat/custom/spring/WXTemplate.java new file mode 100644 index 0000000..599b2ec --- /dev/null +++ b/mallchat-custom-server/src/test/java/com/abin/mallchat/custom/spring/WXTemplate.java @@ -0,0 +1,31 @@ +package com.abin.mallchat.custom.spring; + +import com.abin.mallchat.custom.chat.service.WeChatMsgOperationService; +import com.abin.mallchat.custom.chat.service.impl.ChatServiceImpl; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.Collections; + +/** + * Description: 微信模板测试 + * Author: abin + * Date: 2023-07-06 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +public class WXTemplate { + + @Autowired + private WeChatMsgOperationService chatMsgOperationService; + @Autowired + private ChatServiceImpl chatService; + + @Test + public void test() { + chatMsgOperationService.publishChatMsgToWeChatUser(1L, Collections.singletonList(10008L), "你家规下去"); + } +} From 2951647685b8660f20442a3649c1d476a4ac0979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=B1=9F=E8=BE=B0?= Date: Fri, 7 Jul 2023 15:05:31 +0800 Subject: [PATCH 33/42] fix: README.md --- README.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5620fdf..f5efd35 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,22 @@ - [![MallChat](https://github.com/Evansy/MallChatWeb/actions/workflows/deploy.yml/badge.svg?branch=main)](https://github.com/Evansy/MallChatWeb/actions/workflows/deploy.yml) +
+
+ Commit + - Commit + Commit - Issues [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/zongzibinbin/MallChat/blob/master/LICENSE) - [![GitHub stars](https://img.shields.io/github/stars/zongzibinbin/MallChat.svg?style=social)](https://github.com/zongzibinbin/MallChat/stargazers) + Issues + + + License + + + License + + ## 项目导航 From 29a0f315087a0089b1673c20a2113cbb44676ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=B1=9F=E8=BE=B0?= Date: Fri, 7 Jul 2023 15:12:16 +0800 Subject: [PATCH 34/42] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E6=AD=A3?= =?UTF-8?q?=E7=A1=AE=E7=9A=84=E5=BC=80=E6=BA=90=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f5efd35..b4572a8 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Issues - License + License: Apache-2.0 License From 7d62a59da5cc64d47d2b75318ab984fea1c668fd Mon Sep 17 00:00:00 2001 From: WSJ <996387929@qq.com> Date: Sat, 8 Jul 2023 17:49:21 +0800 Subject: [PATCH 35/42] =?UTF-8?q?=E8=A1=A8=E6=83=85=E5=8C=85=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E5=A2=9E=E5=8A=A0=E4=B8=8A=E4=BC=A0=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../abin/mallchat/custom/user/domain/enums/OssSceneEnum.java | 1 + .../custom/user/domain/vo/request/oss/UploadUrlReq.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/enums/OssSceneEnum.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/enums/OssSceneEnum.java index ce7c7ac..a21f94a 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/enums/OssSceneEnum.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/enums/OssSceneEnum.java @@ -17,6 +17,7 @@ import java.util.stream.Collectors; @Getter public enum OssSceneEnum { CHAT(1, "聊天", "/chat"), + EMOJIS(2, "表情包", "/emojis"), ; private final Integer type; diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/request/oss/UploadUrlReq.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/request/oss/UploadUrlReq.java index d0b0028..df1f473 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/request/oss/UploadUrlReq.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/request/oss/UploadUrlReq.java @@ -23,7 +23,7 @@ public class UploadUrlReq { @ApiModelProperty(value = "文件名(带后缀)") @NotBlank private String fileName; - @ApiModelProperty(value = "上传场景1.聊天室") + @ApiModelProperty(value = "上传场景1.聊天室,2.表情包") @NotNull private Integer scene; } From 5bdad1351c0018a28a394fce98e7a7f4eddafe3e Mon Sep 17 00:00:00 2001 From: WSJ <996387929@qq.com> Date: Sat, 8 Jul 2023 18:28:20 +0800 Subject: [PATCH 36/42] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=A1=A8=E6=83=85?= =?UTF-8?q?=E5=8C=85=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/domain/entity/msg/EmojisMsgDTO.java | 29 ++++++++++ .../chat/domain/entity/msg/MessageExtra.java | 5 ++ .../chat/domain/enums/MessageTypeEnum.java | 1 + .../strategy/msg/EmojisMsgHandler.java | 58 +++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/EmojisMsgDTO.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/EmojisMsgHandler.java diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/EmojisMsgDTO.java b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/EmojisMsgDTO.java new file mode 100644 index 0000000..d8aaa2c --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/EmojisMsgDTO.java @@ -0,0 +1,29 @@ +package com.abin.mallchat.common.chat.domain.entity.msg; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * Description: 表情图片消息入参 + * Author: abin + * Date: 2023-06-04 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class EmojisMsgDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("下载地址") + @NotBlank + private String url; +} + + diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/MessageExtra.java b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/MessageExtra.java index 9a68c74..ffbc008 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/MessageExtra.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/MessageExtra.java @@ -36,4 +36,9 @@ public class MessageExtra implements Serializable { private SoundMsgDTO soundMsgDTO; //文件消息 private VideoMsgDTO videoMsgDTO; + + /** + * 表情图片信息 + */ + private EmojisMsgDTO emojisMsgDTO; } diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/enums/MessageTypeEnum.java b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/enums/MessageTypeEnum.java index cc262a9..7d66214 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/enums/MessageTypeEnum.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/enums/MessageTypeEnum.java @@ -22,6 +22,7 @@ public enum MessageTypeEnum { FILE(4, "文件"), SOUND(5, "语音"), VIDEO(6, "视频"), + EMOJIS(7, "表情"), ; private final Integer type; diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/EmojisMsgHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/EmojisMsgHandler.java new file mode 100644 index 0000000..1012160 --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/EmojisMsgHandler.java @@ -0,0 +1,58 @@ +package com.abin.mallchat.custom.chat.service.strategy.msg; + +import cn.hutool.core.bean.BeanUtil; +import com.abin.mallchat.common.chat.dao.MessageDao; +import com.abin.mallchat.common.chat.domain.entity.Message; +import com.abin.mallchat.common.chat.domain.entity.msg.EmojisMsgDTO; +import com.abin.mallchat.common.chat.domain.entity.msg.ImgMsgDTO; +import com.abin.mallchat.common.chat.domain.entity.msg.MessageExtra; +import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum; +import com.abin.mallchat.common.common.utils.AssertUtil; +import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +/** + * Description:表情消息 + * Author: abin + * Date: 2023-06-04 + */ +@Component +public class EmojisMsgHandler extends AbstractMsgHandler { + @Autowired + private MessageDao messageDao; + + @Override + MessageTypeEnum getMsgTypeEnum() { + return MessageTypeEnum.EMOJIS; + } + + @Override + public void checkMsg(ChatMessageReq request, Long uid) { + EmojisMsgDTO body = BeanUtil.toBean(request.getBody(), EmojisMsgDTO.class); + AssertUtil.allCheckValidateThrow(body); + } + + @Override + public void saveMsg(Message msg, ChatMessageReq request) { + EmojisMsgDTO body = BeanUtil.toBean(request.getBody(), EmojisMsgDTO.class); + MessageExtra extra = Optional.ofNullable(msg.getExtra()).orElse(new MessageExtra()); + Message update = new Message(); + update.setId(msg.getId()); + update.setExtra(extra); + extra.setEmojisMsgDTO(body); + messageDao.updateById(update); + } + + @Override + public Object showMsg(Message msg) { + return msg.getExtra().getImgMsgDTO(); + } + + @Override + public Object showReplyMsg(Message msg) { + return "表情"; + } +} From 630e6da05c2eb2b870960e760c41bb4ba86b94e2 Mon Sep 17 00:00:00 2001 From: WSJ <996387929@qq.com> Date: Sat, 8 Jul 2023 18:35:32 +0800 Subject: [PATCH 37/42] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=A1=A8=E6=83=85?= =?UTF-8?q?=E5=8C=85=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/user/service/impl/UserEmojisServiceImpl.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojisServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojisServiceImpl.java index 0f2302d..fe51f7a 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojisServiceImpl.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojisServiceImpl.java @@ -5,6 +5,7 @@ import com.abin.mallchat.common.common.annotation.RedissonLock; import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; import com.abin.mallchat.common.common.domain.vo.response.ApiResult; import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; +import com.abin.mallchat.common.common.utils.AssertUtil; import com.abin.mallchat.common.common.utils.CursorUtils; import com.abin.mallchat.common.common.utils.RequestHolder; import com.abin.mallchat.common.user.mapper.UserEmojisMapper; @@ -66,15 +67,11 @@ public class UserEmojisServiceImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(UserEmojis::getUid,uid); int count = this.count(queryWrapper); - if (count>30){ - return ApiResult.fail(-1,"最多只能添加30个表情"); - } + AssertUtil.isFalse(count>30, "最多只能添加30个表情哦~~"); //校验表情是否存在 queryWrapper.eq(UserEmojis::getExpressionUrl,emojis.getExpressionUrl()); count = this.count(queryWrapper); - if (count >0){ - return ApiResult.fail(-1,"当前表情已存在"); - } + AssertUtil.isFalse(count >0, "当前表情已存在哦~~"); emojis.setUid(RequestHolder.get().getUid()); this.saveOrUpdate(emojis, queryWrapper); return ApiResult.success(emojis); From e64659b4912ae3a0e6adcacfa6de2b32b3fd6b00 Mon Sep 17 00:00:00 2001 From: WSJ <996387929@qq.com> Date: Sat, 8 Jul 2023 19:07:12 +0800 Subject: [PATCH 38/42] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=A1=A8=E6=83=85?= =?UTF-8?q?=E5=8C=85=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/chat/service/strategy/msg/EmojisMsgHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/EmojisMsgHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/EmojisMsgHandler.java index 1012160..969595d 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/EmojisMsgHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/EmojisMsgHandler.java @@ -48,7 +48,7 @@ public class EmojisMsgHandler extends AbstractMsgHandler { @Override public Object showMsg(Message msg) { - return msg.getExtra().getImgMsgDTO(); + return msg.getExtra().getEmojisMsgDTO(); } @Override From 8e1c3d890aacdce85ded02dc8ddad51adda2bd59 Mon Sep 17 00:00:00 2001 From: zhongzb <972627721@qq.com> Date: Sun, 9 Jul 2023 18:38:49 +0800 Subject: [PATCH 39/42] =?UTF-8?q?fix:url=E8=A7=A3=E6=9E=90=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/utils/chain/Application.java | 22 ----- .../common/utils/chain/CommonUrlHandler.java | 51 ---------- .../common/utils/chain/FactoryUrlHandler.java | 96 ------------------- .../utils/chain/PrioritizedUrlHandler.java | 39 -------- .../common/common/utils/chain/UrlHandler.java | 25 ----- .../common/utils/chain/WxUrlHandler.java | 32 ------- .../common/utils/chain/dto/UrlInfo.java | 32 ------- 7 files changed, 297 deletions(-) delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/Application.java delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/CommonUrlHandler.java delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/FactoryUrlHandler.java delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/PrioritizedUrlHandler.java delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/UrlHandler.java delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/WxUrlHandler.java delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/dto/UrlInfo.java diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/Application.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/Application.java deleted file mode 100644 index b2c5d70..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/Application.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.abin.mallchat.common.common.utils.chain; - -import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; -import org.jetbrains.annotations.Nullable; -import org.jsoup.nodes.Document; - -import java.util.Map; - -/** - * Description: 测试 - * Author: achao - * Date: 2023/7/6 9:29 - */ -public class Application { - public static void main(String[] args) { - PrioritizedUrlHandler handler = new PrioritizedUrlHandler(); - String longStr = "其中包含一个URL www.baidu.com,一个带有端口号的URL http://www.jd.com:80, 一个带有路径的URL http://mallchat.cn, 还有美团技术文章https://mp.weixin.qq.com/s/hwTf4bDck9_tlFpgVDeIKg "; - - Map urlContentMap = handler.getUrlContentMap(longStr); - System.out.println(urlContentMap); - } -} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/CommonUrlHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/CommonUrlHandler.java deleted file mode 100644 index 5d85f00..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/CommonUrlHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.abin.mallchat.common.common.utils.chain; - -import cn.hutool.core.util.StrUtil; -import org.jetbrains.annotations.Nullable; -import org.jsoup.nodes.Document; - -/** - * Description: - * Author: achao - * Date: 2023/7/6 9:25 - */ -public class CommonUrlHandler extends FactoryUrlHandler { - - @Nullable - @Override - public String getTitle(Document document) { - return document.title(); - } - - @Nullable - @Override - public String getDescription(Document document) { - String description = document.head().select("meta[name=description]").attr("content"); - String keywords = document.head().select("meta[name=keywords]").attr("content"); - String content = StrUtil.isNotBlank(description) ? description : keywords; - //只保留一句话的描述 - return StrUtil.isNotBlank(content) ? content.substring(0, content.indexOf("。")) : content; - } - - @Nullable - @Override - public String getImage(String url, Document document) { - String image = document.select("link[type=image/x-icon]").attr("href"); - //如果没有去匹配含有icon属性的logo - String href = StrUtil.isEmpty(image) ? document.select("link[rel$=icon]").attr("href") : image; - //如果icon中已经包含了url部分域名 - if (StrUtil.isNotBlank(StrUtil.removeAny(StrUtil.removeAny(href, "/"), "favicon.ico")) && - StrUtil.containsAny(StrUtil.removePrefix(url, "http://"), StrUtil.removeAny(StrUtil.removeAny(href, "/"), "favicon.ico"))) { - return "http://" + StrUtil.removePrefix(href, "/"); - } - //如果url已经包含了logo - if (StrUtil.containsAny(url, "favicon")) { - return url; - } - //如果logo中有url - if (StrUtil.containsAny(href, "http") || StrUtil.containsAny(href, "https")) { - return href; - } - return StrUtil.format("{}/{}", url, StrUtil.removePrefix(href, "/")); - } -} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/FactoryUrlHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/FactoryUrlHandler.java deleted file mode 100644 index bd8d0e8..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/FactoryUrlHandler.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.abin.mallchat.common.common.utils.chain; - -import cn.hutool.core.util.ReUtil; -import cn.hutool.core.util.StrUtil; -import com.abin.mallchat.common.common.utils.FutureUtils; -import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; -import lombok.extern.slf4j.Slf4j; -import org.jsoup.Connection; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.springframework.data.util.Pair; - -import javax.annotation.Nullable; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -/** - * Description: 链接处理工厂 - * Author: achao - * Date: 2023/7/6 9:12 - */ -@Slf4j -public abstract class FactoryUrlHandler extends UrlHandler{ - - //链接识别的正则 - private static final Pattern PATTERN = Pattern.compile("((http|https)://)?(www.)?([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?"); - - @Override - @Nullable - public Map getUrlContentMap(String content) { - - if (StrUtil.isBlank(content)) { - return new HashMap<>(); - } - List matchList = ReUtil.findAll(PATTERN, content, 0); - - //并行请求 - List>> futures = matchList.stream().map(match -> CompletableFuture.supplyAsync(() -> { - UrlInfo urlInfo = getContent(match); - return Objects.isNull(urlInfo) ? null : Pair.of(match, urlInfo); - })).collect(Collectors.toList()); - CompletableFuture>> future = FutureUtils.sequenceNonNull(futures); - //结果组装 - return future.join().stream().collect(Collectors.toMap(Pair::getFirst, Pair::getSecond, (a, b) -> a)); - } - - private UrlInfo getContent(String url){ - url = !StrUtil.startWith(url, "http") ? "http://" + url : url; - Document document = getUrlDocument(url); - return UrlInfo.builder() - .title(getTitle(document)) - .description(getDescription(document)) - .image(getImage(url,document)).build(); - } - - protected Document getUrlDocument(String matchUrl) { - try { - Connection connect = Jsoup.connect(matchUrl); - connect.timeout(2000); - return connect.get(); - } catch (Exception e) { - log.error("find error:url:{}", matchUrl, e); - } - return null; - } - - /** - * 获取链接的标题 - * @param document - * @return - */ - @Nullable - abstract String getTitle(Document document); - - /** - * 获取链接的描述 - * @param document - * @return - */ - @Nullable - abstract String getDescription(Document document); - - /** - * 获取链接的LOGO - * @param document - * @return - */ - @Nullable - abstract String getImage(String url, Document document); - -} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/PrioritizedUrlHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/PrioritizedUrlHandler.java deleted file mode 100644 index b06ad32..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/PrioritizedUrlHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.abin.mallchat.common.common.utils.chain; - -import cn.hutool.core.util.StrUtil; -import com.abin.mallchat.common.common.utils.discover.UrlDiscover; -import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; -import org.jetbrains.annotations.Nullable; -import org.jsoup.nodes.Document; - -import java.util.List; -import java.util.Map; - -/** - * Description: 优先级链接统一处理扩展类 - * Author: achao - * Date: 2023/7/6 9:36 - */ -public class PrioritizedUrlHandler extends FactoryUrlHandler { - - private final FactoryUrlHandler commonUrlHandler = new CommonUrlHandler(); - private final FactoryUrlHandler wxUrlHandler = new WxUrlHandler(); - - @Nullable - @Override - String getTitle(Document document) { - return StrUtil.isBlank(wxUrlHandler.getTitle(document)) ? commonUrlHandler.getTitle(document) : wxUrlHandler.getTitle(document); - } - - @Nullable - @Override - String getDescription(Document document) { - return StrUtil.isBlank(wxUrlHandler.getDescription(document)) ? commonUrlHandler.getDescription(document) : wxUrlHandler.getDescription(document); - } - - @Nullable - @Override - String getImage(String url, Document document) { - return StrUtil.isBlank(wxUrlHandler.getImage(url, document)) ? commonUrlHandler.getImage(url, document) : wxUrlHandler.getImage(url, document); - } -} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/UrlHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/UrlHandler.java deleted file mode 100644 index c9a9a3d..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/UrlHandler.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.abin.mallchat.common.common.utils.chain; - -import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; -import org.jsoup.nodes.Document; - -import javax.annotation.Nullable; -import java.util.Map; -import java.util.regex.Pattern; - -/** - * Description: url集合处理抽象接口定义类 - * Author: achao - * Date: 2023/7/6 8:58 - */ -public abstract class UrlHandler { - - /** - * 提取消息中的所有链接,并组装Map - * @param content - * @return - */ - @Nullable - abstract Map getUrlContentMap(String content); - -} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/WxUrlHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/WxUrlHandler.java deleted file mode 100644 index f8356d9..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/WxUrlHandler.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.abin.mallchat.common.common.utils.chain; - -import cn.hutool.core.util.StrUtil; -import org.jetbrains.annotations.Nullable; -import org.jsoup.nodes.Document; - -/** - * Description: - * Author: achao - * Date: 2023/7/6 9:34 - */ -public class WxUrlHandler extends FactoryUrlHandler { - - @Nullable - @Override - public String getTitle(Document document) { - return document.getElementsByAttributeValue("property", "og:title").attr("content"); - } - - @Nullable - @Override - public String getDescription(Document document) { - String description = document.getElementsByAttributeValue("property", "og:description").attr("content"); - return StrUtil.isNotBlank(description) ? description.substring(0, description.indexOf("。")) : description; - } - - @Nullable - @Override - public String getImage(String url, Document document) { - return document.getElementsByAttributeValue("property", "og:image").attr("content"); - } -} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/dto/UrlInfo.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/dto/UrlInfo.java deleted file mode 100644 index ad1050a..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/chain/dto/UrlInfo.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.abin.mallchat.common.common.utils.chain.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Description: 链接信息提取类 - * Author: achao - * Date: 2023/7/6 8:54 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class UrlInfo { - /** - * 标题 - **/ - String title; - - /** - * 描述 - **/ - String description; - - /** - * 网站LOGO - **/ - String image; -} From 2c2131098233f37b424598d633ed8c742f4710bb Mon Sep 17 00:00:00 2001 From: zhongzb <972627721@qq.com> Date: Sun, 9 Jul 2023 19:46:50 +0800 Subject: [PATCH 40/42] =?UTF-8?q?fix:1.=E4=BC=98=E5=8C=96=E8=A1=A8?= =?UTF-8?q?=E6=83=85=E5=8C=85=E5=8A=9F=E8=83=BD=202.=E4=BC=98=E5=8C=96oss?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E8=B7=AF=E5=BE=84=203.=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E5=8E=86=E5=8F=B2=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/mallchat.sql | 12 +++ docs/version/2023-07-09.sql | 10 +++ docs/version/user_emojis.sql | 10 --- .../chat/domain/enums/MessageTypeEnum.java | 2 +- .../common/domain/vo/request/IdReqVO.java | 20 +++++ .../common/utils/oss/MinIOTemplate.java | 4 +- .../common/user/dao/UserEmojiDao.java | 28 +++++++ .../domain/entity/UserEmoji.java} | 39 +++++---- .../common/user/mapper/UserEmojiMapper.java | 16 ++++ .../common/user/mapper/UserEmojisMapper.java | 4 +- .../resources/mapper/user/UserEmojiMapper.xml | 5 ++ .../chat/controller/ChatController.java | 2 +- .../domain/vo/request/ChatMessageReq.java | 3 +- .../domain/vo/response/ChatMessageResp.java | 42 ---------- .../chat/service/adapter/MessageAdapter.java | 43 ++-------- .../chat/service/impl/ChatServiceImpl.java | 12 +-- .../strategy/msg/EmojisMsgHandler.java | 3 +- .../user/controller/UserEmojiController.java | 77 ++++++++++++++++++ .../user/controller/UserEmojisController.java | 78 ------------------ .../user/domain/enums/OssSceneEnum.java | 2 +- .../domain/vo/request/user/UserEmojiReq.java | 26 ++++++ .../vo/response/user/UserEmojiResp.java | 32 ++++++++ .../custom/user/service/UserEmojiService.java | 45 +++++++++++ .../user/service/UserEmojisService.java | 37 --------- .../user/service/impl/OssServiceImpl.java | 1 - .../service/impl/UserEmojiServiceImpl.java | 75 ++++++++++++++++++ .../service/impl/UserEmojisServiceImpl.java | 79 ------------------- 27 files changed, 387 insertions(+), 320 deletions(-) create mode 100644 docs/version/2023-07-09.sql delete mode 100644 docs/version/user_emojis.sql create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/domain/vo/request/IdReqVO.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/user/dao/UserEmojiDao.java rename mallchat-common/src/main/java/com/abin/mallchat/common/{chat/domain/entity/UserEmojis.java => user/domain/entity/UserEmoji.java} (51%) create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/UserEmojiMapper.java create mode 100644 mallchat-common/src/main/resources/mapper/user/UserEmojiMapper.xml create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/UserEmojiController.java delete mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/UserEmojisController.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/request/user/UserEmojiReq.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/user/UserEmojiResp.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/UserEmojiService.java delete mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/UserEmojisService.java create mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojiServiceImpl.java delete mode 100644 mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojisServiceImpl.java diff --git a/docs/mallchat.sql b/docs/mallchat.sql index be0146d..f2db654 100644 --- a/docs/mallchat.sql +++ b/docs/mallchat.sql @@ -191,3 +191,15 @@ CREATE TABLE `sensitive_word` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='敏感词库'; INSERT INTO `sensitive_word` (`word`) VALUES ('TMD'); INSERT INTO `sensitive_word` (`word`) VALUES ('tmd'); + +DROP TABLE IF EXISTS `user_emoji`; +CREATE TABLE `user_emoji` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uid` bigint(20) NOT NULL COMMENT '用户表ID', + `expression_url` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '表情地址', + `delete_status` int(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除(0-正常,1-删除)', + `create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', + `update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间', + PRIMARY KEY (`id`) USING BTREE, + KEY `IDX_USER_EMOJIS_UID` (`uid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='用户表情包'; \ No newline at end of file diff --git a/docs/version/2023-07-09.sql b/docs/version/2023-07-09.sql new file mode 100644 index 0000000..22ea074 --- /dev/null +++ b/docs/version/2023-07-09.sql @@ -0,0 +1,10 @@ +CREATE TABLE `user_emoji` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uid` bigint(20) NOT NULL COMMENT '用户表ID', + `expression_url` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '表情地址', + `delete_status` int(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除(0-正常,1-删除)', + `create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', + `update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间', + PRIMARY KEY (`id`) USING BTREE, + KEY `IDX_USER_EMOJIS_UID` (`uid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='用户表情包'; \ No newline at end of file diff --git a/docs/version/user_emojis.sql b/docs/version/user_emojis.sql deleted file mode 100644 index f0078ce..0000000 --- a/docs/version/user_emojis.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE `user_emojis` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', - `uid` bigint(20) NOT NULL COMMENT '用户表ID', - `expression_url` varchar(255) NOT NULL COMMENT '表情地址', - `create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', - `update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间', - `delete_status` int(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除(0-正常,1-删除)', - PRIMARY KEY (`id`), - KEY `IDX_USER_EMOJIS_UID` (`uid`) -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='用户表情包'; \ No newline at end of file diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/enums/MessageTypeEnum.java b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/enums/MessageTypeEnum.java index 7d66214..73d7b97 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/enums/MessageTypeEnum.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/enums/MessageTypeEnum.java @@ -22,7 +22,7 @@ public enum MessageTypeEnum { FILE(4, "文件"), SOUND(5, "语音"), VIDEO(6, "视频"), - EMOJIS(7, "表情"), + EMOJI(7, "表情"), ; private final Integer type; diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/domain/vo/request/IdReqVO.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/domain/vo/request/IdReqVO.java new file mode 100644 index 0000000..9c0f417 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/domain/vo/request/IdReqVO.java @@ -0,0 +1,20 @@ +package com.abin.mallchat.common.common.domain.vo.request; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * @author zhongzb create on 2021/05/31 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class IdReqVO { + @ApiModelProperty("id") + @NotNull + private long id; +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/oss/MinIOTemplate.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/oss/MinIOTemplate.java index f49a5fa..99e6e6a 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/oss/MinIOTemplate.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/oss/MinIOTemplate.java @@ -136,8 +136,8 @@ public class MinIOTemplate { String uid = Optional.ofNullable(req.getUid()).map(String::valueOf).orElse("000000"); cn.hutool.core.lang.UUID uuid = cn.hutool.core.lang.UUID.fastUUID(); String suffix = FileNameUtil.getSuffix(req.getFileName()); - String year = DateUtil.format(new Date(), DatePattern.NORM_YEAR_PATTERN); - return req.getFilePath() + StrUtil.SLASH + year + StrUtil.SLASH + uid + StrUtil.SLASH + uuid + StrUtil.DOT + suffix; + String yearAndMonth = DateUtil.format(new Date(), DatePattern.NORM_MONTH_PATTERN); + return req.getFilePath() + StrUtil.SLASH + yearAndMonth + StrUtil.SLASH + uid + StrUtil.SLASH + uuid + StrUtil.DOT + suffix; } /** diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/user/dao/UserEmojiDao.java b/mallchat-common/src/main/java/com/abin/mallchat/common/user/dao/UserEmojiDao.java new file mode 100644 index 0000000..8b8b2ad --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/user/dao/UserEmojiDao.java @@ -0,0 +1,28 @@ +package com.abin.mallchat.common.user.dao; + +import com.abin.mallchat.common.user.domain.entity.UserEmoji; +import com.abin.mallchat.common.user.mapper.UserEmojiMapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + *

+ * 用户表情包 服务实现类 + *

+ * + * @author abin + * @since 2023-07-09 + */ +@Service +public class UserEmojiDao extends ServiceImpl { + + public List listByUid(Long uid) { + return lambdaQuery().eq(UserEmoji::getUid, uid).list(); + } + + public int countByUid(Long uid) { + return lambdaQuery().eq(UserEmoji::getUid, uid).count(); + } +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/UserEmojis.java b/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/UserEmoji.java similarity index 51% rename from mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/UserEmojis.java rename to mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/UserEmoji.java index de707ff..4a9f2dd 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/UserEmojis.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/UserEmoji.java @@ -1,22 +1,28 @@ -package com.abin.mallchat.common.chat.domain.entity; +package com.abin.mallchat.common.user.domain.entity; import com.baomidou.mybatisplus.annotation.*; -import lombok.Data; +import lombok.*; -import javax.validation.constraints.NotNull; import java.io.Serializable; import java.util.Date; /** + *

* 用户表情包 + *

* - * @author: WuShiJie - * @createTime: 2023/7/2 22:00 + * @author abin + * @since 2023-07-09 */ @Data -@TableName(value = "user_emojis") -public class UserEmojis implements Serializable { - private static final long serialVersionUID = -7690290707154737263L; +@Builder +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode(callSuper = false) +@TableName("user_emoji") +public class UserEmoji implements Serializable { + + private static final long serialVersionUID = 1L; /** * id @@ -27,17 +33,22 @@ public class UserEmojis implements Serializable { /** * 用户表ID */ - @TableField(value = "uid") + @TableField("uid") private Long uid; - /** * 表情地址 */ - @NotNull - @TableField(value = "expression_url") + @TableField("expression_url") private String expressionUrl; + /** + * 逻辑删除(0-正常,1-删除) + */ + @TableField("delete_status") + @TableLogic(value = "0", delval = "1") + private Integer deleteStatus; + /** * 创建时间 */ @@ -50,9 +61,5 @@ public class UserEmojis implements Serializable { @TableField("update_time") private Date updateTime; - @TableField(value = "delete_status") - @TableLogic(value = "0",delval = "1") - private Integer deleteStatus; - } diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/UserEmojiMapper.java b/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/UserEmojiMapper.java new file mode 100644 index 0000000..cc36c9c --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/UserEmojiMapper.java @@ -0,0 +1,16 @@ +package com.abin.mallchat.common.user.mapper; + +import com.abin.mallchat.common.user.domain.entity.UserEmoji; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 用户表情包 Mapper 接口 + *

+ * + * @author abin + * @since 2023-07-09 + */ +public interface UserEmojiMapper extends BaseMapper { + +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/UserEmojisMapper.java b/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/UserEmojisMapper.java index dd6b5b2..2f1fbd2 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/UserEmojisMapper.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/user/mapper/UserEmojisMapper.java @@ -1,6 +1,6 @@ package com.abin.mallchat.common.user.mapper; -import com.abin.mallchat.common.chat.domain.entity.UserEmojis; +import com.abin.mallchat.common.user.domain.entity.UserEmoji; import com.baomidou.mybatisplus.core.mapper.BaseMapper; /** @@ -9,5 +9,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; * @author: WuShiJie * @createTime: 2023/7/3 14:24 */ -public interface UserEmojisMapper extends BaseMapper { +public interface UserEmojisMapper extends BaseMapper { } diff --git a/mallchat-common/src/main/resources/mapper/user/UserEmojiMapper.xml b/mallchat-common/src/main/resources/mapper/user/UserEmojiMapper.xml new file mode 100644 index 0000000..eea5b91 --- /dev/null +++ b/mallchat-common/src/main/resources/mapper/user/UserEmojiMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ChatController.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ChatController.java index 1f32401..10bbbd6 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ChatController.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ChatController.java @@ -84,7 +84,7 @@ public class ChatController { @GetMapping("/public/msg/page") @ApiOperation("消息列表") @FrequencyControl(time = 120, count = 20, target = FrequencyControl.Target.IP) - public ApiResult> getMsgPage1(@Valid ChatMessagePageReq request) { + public ApiResult> getMsgPage(@Valid ChatMessagePageReq request) { // black(request); CursorPageBaseResp msgPage = chatService.getMsgPage(request, RequestHolder.get().getUid()); filterBlackMsg(msgPage); diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReq.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReq.java index 2fd2040..b255a34 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReq.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReq.java @@ -1,6 +1,5 @@ package com.abin.mallchat.custom.chat.domain.vo.request; -import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Builder; @@ -30,7 +29,7 @@ public class ChatMessageReq { @ApiModelProperty("消息类型") @NotNull - private Integer msgType = MessageTypeEnum.TEXT.getType(); + private Integer msgType; @ApiModelProperty("消息内容,类型不同传值不同,见https://www.yuque.com/snab/mallcaht/rkb2uz5k1qqdmcmd") @NotNull diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageResp.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageResp.java index 2cfed96..096eaf7 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageResp.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageResp.java @@ -1,6 +1,5 @@ package com.abin.mallchat.custom.chat.domain.vo.response; -import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Builder; @@ -8,7 +7,6 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.util.Date; -import java.util.Map; /** * Description: 消息 @@ -28,16 +26,8 @@ public class ChatMessageResp { @Data public static class UserInfo { - @ApiModelProperty("用户名称") - private String username; @ApiModelProperty("用户id") private Long uid; - @ApiModelProperty("头像") - private String avatar; - @ApiModelProperty("归属地") - private String locPlace; - @ApiModelProperty("徽章标识,如果没有展示null") - private Badge badge; } @Data @@ -46,36 +36,12 @@ public class ChatMessageResp { private Long id; @ApiModelProperty("消息发送时间") private Date sendTime; - @ApiModelProperty("消息内容-废弃") - @Deprecated - private String content; - @ApiModelProperty("消息链接映射-废弃") - @Deprecated - private Map urlContentMap; @ApiModelProperty("消息类型 1正常文本 2.撤回消息") private Integer type; @ApiModelProperty("消息内容不同的消息类型,内容体不同,见https://www.yuque.com/snab/mallcaht/rkb2uz5k1qqdmcmd") private Object body; @ApiModelProperty("消息标记") private MessageMark messageMark; - @ApiModelProperty("父消息,如果没有父消息,返回的是null") - private ReplyMsg reply; - - } - - @Data - @Deprecated - public static class ReplyMsg { - @ApiModelProperty("消息id") - private Long id; - @ApiModelProperty("用户名称") - private String username; - @ApiModelProperty("消息内容") - private String content; - @ApiModelProperty("是否可消息跳转 0否 1是") - private Integer canCallback; - @ApiModelProperty("跳转间隔的消息条数") - private Integer gapCount; } @Data @@ -89,12 +55,4 @@ public class ChatMessageResp { @ApiModelProperty("该用户是否已经举报 0否 1是") private Integer userDislike; } - - @Data - public static class Badge { - @ApiModelProperty("徽章图像") - private String img; - @ApiModelProperty("徽章说明") - private String describe; - } } diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/MessageAdapter.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/MessageAdapter.java index a751ad6..38f0a3c 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/MessageAdapter.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/MessageAdapter.java @@ -3,14 +3,9 @@ package com.abin.mallchat.custom.chat.service.adapter; import cn.hutool.core.bean.BeanUtil; import com.abin.mallchat.common.chat.domain.entity.Message; import com.abin.mallchat.common.chat.domain.entity.MessageMark; -import com.abin.mallchat.common.chat.domain.entity.msg.MessageExtra; import com.abin.mallchat.common.chat.domain.enums.MessageMarkTypeEnum; import com.abin.mallchat.common.chat.domain.enums.MessageStatusEnum; import com.abin.mallchat.common.common.domain.enums.YesOrNoEnum; -import com.abin.mallchat.common.user.domain.entity.IpDetail; -import com.abin.mallchat.common.user.domain.entity.IpInfo; -import com.abin.mallchat.common.user.domain.entity.ItemConfig; -import com.abin.mallchat.common.user.domain.entity.User; import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq; import com.abin.mallchat.custom.chat.domain.vo.response.ChatMessageResp; import com.abin.mallchat.custom.chat.service.strategy.msg.AbstractMsgHandler; @@ -38,37 +33,25 @@ public class MessageAdapter { } - public static List buildMsgResp(List messages, Map replyMap, Map userMap, List msgMark, Long receiveUid, Map itemMap) { + public static List buildMsgResp(List messages, Map replyMap, List msgMark, Long receiveUid) { Map> markMap = msgMark.stream().collect(Collectors.groupingBy(MessageMark::getMsgId)); return messages.stream().map(a -> { ChatMessageResp resp = new ChatMessageResp(); - resp.setFromUser(buildFromUser(userMap.get(a.getFromUid()), itemMap)); - resp.setMessage(buildMessage(a, replyMap, userMap, markMap.getOrDefault(a.getId(), new ArrayList<>()), receiveUid)); + resp.setFromUser(buildFromUser(a.getFromUid())); + resp.setMessage(buildMessage(a, replyMap, markMap.getOrDefault(a.getId(), new ArrayList<>()), receiveUid)); return resp; }) .sorted(Comparator.comparing(a -> a.getMessage().getSendTime()))//帮前端排好序,更方便它展示 .collect(Collectors.toList()); } - private static ChatMessageResp.Message buildMessage(Message message, Map replyMap, Map userMap, List marks, Long receiveUid) { + private static ChatMessageResp.Message buildMessage(Message message, Map replyMap, List marks, Long receiveUid) { ChatMessageResp.Message messageVO = new ChatMessageResp.Message(); BeanUtil.copyProperties(message, messageVO); messageVO.setSendTime(message.getCreateTime()); AbstractMsgHandler msgHandler = MsgHandlerFactory.getStrategyNoNull(message.getType()); - messageVO.setBody(msgHandler.showMsg(message)); - messageVO.setUrlContentMap(Optional.ofNullable(message.getExtra()).map(MessageExtra::getUrlContentMap).orElse(null)); - Message replyMessage = replyMap.get(message.getReplyMsgId()); - - //回复消息 - if (Objects.nonNull(replyMessage)) { - ChatMessageResp.ReplyMsg replyMsgVO = new ChatMessageResp.ReplyMsg(); - replyMsgVO.setId(replyMessage.getId()); - replyMsgVO.setContent(replyMessage.getContent()); - User replyUser = userMap.get(replyMessage.getFromUid()); - replyMsgVO.setUsername(replyUser.getName()); - replyMsgVO.setCanCallback(YesOrNoEnum.toStatus(Objects.nonNull(message.getGapCount()) && message.getGapCount() <= CAN_CALLBACK_GAP_COUNT)); - replyMsgVO.setGapCount(message.getGapCount()); - messageVO.setReply(replyMsgVO); + if (Objects.nonNull(msgHandler)) { + messageVO.setBody(msgHandler.showMsg(message)); } //消息标记 messageVO.setMessageMark(buildMsgMark(marks, receiveUid)); @@ -87,19 +70,9 @@ public class MessageAdapter { return mark; } - private static ChatMessageResp.UserInfo buildFromUser(User fromUser, Map itemMap) { + private static ChatMessageResp.UserInfo buildFromUser(Long fromUid) { ChatMessageResp.UserInfo userInfo = new ChatMessageResp.UserInfo(); - userInfo.setUsername(fromUser.getName()); - userInfo.setAvatar(fromUser.getAvatar()); - userInfo.setLocPlace(Optional.ofNullable(fromUser.getIpInfo()).map(IpInfo::getUpdateIpDetail).map(IpDetail::getCity).orElse(null)); - userInfo.setUid(fromUser.getId()); - if (Objects.nonNull(fromUser.getItemId())) { - ChatMessageResp.Badge badge = new ChatMessageResp.Badge(); - ItemConfig itemConfig = itemMap.get(fromUser.getItemId()); - badge.setImg(itemConfig.getImg()); - badge.setDescribe(itemConfig.getDescribe()); - userInfo.setBadge(badge); - } + userInfo.setUid(fromUid); return userInfo; } diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/ChatServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/ChatServiceImpl.java index adbb1d3..03ab62f 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/ChatServiceImpl.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/ChatServiceImpl.java @@ -19,8 +19,6 @@ import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; import com.abin.mallchat.common.common.event.MessageSendEvent; import com.abin.mallchat.common.common.utils.AssertUtil; import com.abin.mallchat.common.user.dao.UserDao; -import com.abin.mallchat.common.user.domain.entity.ItemConfig; -import com.abin.mallchat.common.user.domain.entity.User; import com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum; import com.abin.mallchat.common.user.domain.enums.RoleEnum; import com.abin.mallchat.common.user.service.IRoleService; @@ -49,7 +47,6 @@ import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; -import java.util.stream.Stream; /** * Description: 消息处理类 @@ -226,21 +223,14 @@ public class ChatServiceImpl implements ChatService { return new ArrayList<>(); } Map replyMap = new HashMap<>(); - Map userMap; - Map itemMap; //批量查出回复的消息 List replyIds = messages.stream().map(Message::getReplyMsgId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); if (CollectionUtil.isNotEmpty(replyIds)) { replyMap = messageDao.listByIds(replyIds).stream().collect(Collectors.toMap(Message::getId, Function.identity())); } - //批量查询消息关联用户 - Set uidSet = Stream.concat(replyMap.values().stream().map(Message::getFromUid), messages.stream().map(Message::getFromUid)).collect(Collectors.toSet()); - userMap = userCache.getUserInfoBatch(uidSet); - //批量查询item信息 - itemMap = userMap.values().stream().map(User::getItemId).distinct().filter(Objects::nonNull).map(itemCache::getById).collect(Collectors.toMap(ItemConfig::getId, Function.identity())); //查询消息标志 List msgMark = messageMarkDao.getValidMarkByMsgIdBatch(messages.stream().map(Message::getId).collect(Collectors.toList())); - return MessageAdapter.buildMsgResp(messages, replyMap, userMap, msgMark, receiveUid, itemMap); + return MessageAdapter.buildMsgResp(messages, replyMap, msgMark, receiveUid); } } diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/EmojisMsgHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/EmojisMsgHandler.java index 969595d..d7f93a5 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/EmojisMsgHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/EmojisMsgHandler.java @@ -4,7 +4,6 @@ import cn.hutool.core.bean.BeanUtil; import com.abin.mallchat.common.chat.dao.MessageDao; import com.abin.mallchat.common.chat.domain.entity.Message; import com.abin.mallchat.common.chat.domain.entity.msg.EmojisMsgDTO; -import com.abin.mallchat.common.chat.domain.entity.msg.ImgMsgDTO; import com.abin.mallchat.common.chat.domain.entity.msg.MessageExtra; import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum; import com.abin.mallchat.common.common.utils.AssertUtil; @@ -26,7 +25,7 @@ public class EmojisMsgHandler extends AbstractMsgHandler { @Override MessageTypeEnum getMsgTypeEnum() { - return MessageTypeEnum.EMOJIS; + return MessageTypeEnum.EMOJI; } @Override diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/UserEmojiController.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/UserEmojiController.java new file mode 100644 index 0000000..9692359 --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/UserEmojiController.java @@ -0,0 +1,77 @@ +package com.abin.mallchat.custom.user.controller; + +import com.abin.mallchat.common.common.domain.vo.request.IdReqVO; +import com.abin.mallchat.common.common.domain.vo.response.ApiResult; +import com.abin.mallchat.common.common.domain.vo.response.IdRespVO; +import com.abin.mallchat.common.common.utils.RequestHolder; +import com.abin.mallchat.custom.user.domain.vo.request.user.UserEmojiReq; +import com.abin.mallchat.custom.user.domain.vo.response.user.UserEmojiResp; +import com.abin.mallchat.custom.user.service.UserEmojiService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * 用户表情包 + * + * @author: WuShiJie + * @createTime: 2023/7/3 14:21 + */ +@RestController +@RequestMapping("/capi/user/emoji") +@Api(tags = "用户表情包管理相关接口") +public class UserEmojiController { + + /** + * 用户表情包 Service + */ + @Resource + private UserEmojiService emojiService; + + + /** + * 表情包列表 + * + * @return 表情包列表 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + @GetMapping("/list") + @ApiOperation("表情包列表") + public ApiResult> getEmojisPage() { + return ApiResult.success(emojiService.list(RequestHolder.get().getUid())); + } + + + /** + * 新增表情包 + * + * @param req 用户表情包 + * @return 表情包 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + @PostMapping() + @ApiOperation("新增表情包") + public ApiResult insertEmojis(@Valid @RequestBody UserEmojiReq req) { + return emojiService.insert(req, RequestHolder.get().getUid()); + } + + /** + * 删除表情包 + * + * @return 删除结果 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + @DeleteMapping() + @ApiOperation("删除表情包") + public ApiResult deleteEmojis(@Valid @RequestBody IdReqVO reqVO) { + emojiService.remove(reqVO.getId(), RequestHolder.get().getUid()); + return ApiResult.success(); + } +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/UserEmojisController.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/UserEmojisController.java deleted file mode 100644 index f88e69a..0000000 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/UserEmojisController.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.abin.mallchat.custom.user.controller; - -import com.abin.mallchat.common.chat.domain.entity.UserEmojis; -import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; -import com.abin.mallchat.common.common.domain.vo.response.ApiResult; -import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; -import com.abin.mallchat.common.common.utils.RequestHolder; -import com.abin.mallchat.custom.user.service.UserEmojisService; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; - -/** - * 用户表情包 - * - * @author: WuShiJie - * @createTime: 2023/7/3 14:21 - */ -@RestController -@RequestMapping("/capi/userEmojis") -@Api(tags = "用户表情包管理相关接口") -public class UserEmojisController { - - /** - * 用户表情包 Service - */ - @Resource - private UserEmojisService emojisService; - - - /** - * 表情包列表 - * - * @param request 游标翻页请求参数 - * @return 表情包列表 - * @author WuShiJie - * @createTime 2023/7/3 14:46 - **/ - @GetMapping("/getEmojisPage") - @ApiOperation("表情包列表") - public ApiResult> getEmojisPage(@Valid CursorPageBaseReq request) { - return ApiResult.success(emojisService.getEmojisPage(request, RequestHolder.get().getUid())); - } - - - /** - * 新增表情包 - * - * @param emojis 用户表情包 - * @return 表情包 - * @author WuShiJie - * @createTime 2023/7/3 14:46 - **/ - @PostMapping("/insertEmojis") - @ApiOperation("新增表情包") - public ApiResult insertEmojis(@Valid @RequestBody UserEmojis emojis) { - return emojisService.insertEmojis(emojis,RequestHolder.get().getUid()); - } - - /** - * 删除表情包 - * - * @param id 用户表情包ID - * @return 删除结果 - * @author WuShiJie - * @createTime 2023/7/3 14:46 - **/ - @GetMapping("/deleteEmojis") - @ApiOperation("删除表情包") - public ApiResult deleteEmojis(@RequestParam("id") String id) { - emojisService.removeById(id); - return ApiResult.success(); - } -} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/enums/OssSceneEnum.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/enums/OssSceneEnum.java index a21f94a..67a5214 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/enums/OssSceneEnum.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/enums/OssSceneEnum.java @@ -17,7 +17,7 @@ import java.util.stream.Collectors; @Getter public enum OssSceneEnum { CHAT(1, "聊天", "/chat"), - EMOJIS(2, "表情包", "/emojis"), + EMOJI(2, "表情包", "/emoji"), ; private final Integer type; diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/request/user/UserEmojiReq.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/request/user/UserEmojiReq.java new file mode 100644 index 0000000..5a31343 --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/request/user/UserEmojiReq.java @@ -0,0 +1,26 @@ +package com.abin.mallchat.custom.user.domain.vo.request.user; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * Description: 表情包反参 + * Author: abin + * Date: 2023-07-09 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class UserEmojiReq { + /** + * 表情地址 + */ + @ApiModelProperty(value = "新增的表情url") + private String expressionUrl; + +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/user/UserEmojiResp.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/user/UserEmojiResp.java new file mode 100644 index 0000000..696393d --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/user/UserEmojiResp.java @@ -0,0 +1,32 @@ +package com.abin.mallchat.custom.user.domain.vo.response.user; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * Description: 表情包反参 + * Author: abin + * Date: 2023-07-09 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class UserEmojiResp { + /** + * id + */ + @ApiModelProperty(value = "id") + private Long id; + + /** + * 表情地址 + */ + @ApiModelProperty(value = "表情url") + private String expressionUrl; + +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/UserEmojiService.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/UserEmojiService.java new file mode 100644 index 0000000..302a58b --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/UserEmojiService.java @@ -0,0 +1,45 @@ +package com.abin.mallchat.custom.user.service; + +import com.abin.mallchat.common.common.domain.vo.response.ApiResult; +import com.abin.mallchat.common.common.domain.vo.response.IdRespVO; +import com.abin.mallchat.custom.user.domain.vo.request.user.UserEmojiReq; +import com.abin.mallchat.custom.user.domain.vo.response.user.UserEmojiResp; + +import java.util.List; + +/** + * 用户表情包 Service + * + * @author: WuShiJie + * @createTime: 2023/7/3 14:22 + */ +public interface UserEmojiService { + + /** + * 表情包列表 + * + * @return 表情包列表 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + List list(Long uid); + + /** + * 新增表情包 + * + * @param emojis 用户表情包 + * @param uid 用户ID + * @return 表情包 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + ApiResult insert(UserEmojiReq emojis, Long uid); + + /** + * 删除表情包 + * + * @param id + * @param uid + */ + void remove(Long id, Long uid); +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/UserEmojisService.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/UserEmojisService.java deleted file mode 100644 index 31a8ddd..0000000 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/UserEmojisService.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.abin.mallchat.custom.user.service; - -import com.abin.mallchat.common.chat.domain.entity.UserEmojis; -import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; -import com.abin.mallchat.common.common.domain.vo.response.ApiResult; -import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; -import com.baomidou.mybatisplus.extension.service.IService; - -/** - * 用户表情包 Service - * - * @author: WuShiJie - * @createTime: 2023/7/3 14:22 - */ -public interface UserEmojisService extends IService { - - /** - * 表情包列表 - * - * @param request 游标翻页请求参数 - * @return 表情包列表 - * @author WuShiJie - * @createTime 2023/7/3 14:46 - **/ - CursorPageBaseResp getEmojisPage(CursorPageBaseReq request, Long uid); - - /** - * 新增表情包 - * - * @param emojis 用户表情包 - * @param uid 用户ID - * @return 表情包 - * @author WuShiJie - * @createTime 2023/7/3 14:46 - **/ - ApiResult insertEmojis(UserEmojis emojis, Long uid); -} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/OssServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/OssServiceImpl.java index 08bf513..fa533e8 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/OssServiceImpl.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/OssServiceImpl.java @@ -17,7 +17,6 @@ import org.springframework.stereotype.Service; */ @Service public class OssServiceImpl implements OssService { - private static final String BUCKET_NAME = "mallchat"; @Autowired private MinIOTemplate minIOTemplate; diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojiServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojiServiceImpl.java new file mode 100644 index 0000000..3a0b882 --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojiServiceImpl.java @@ -0,0 +1,75 @@ +package com.abin.mallchat.custom.user.service.impl; + +import com.abin.mallchat.common.common.annotation.RedissonLock; +import com.abin.mallchat.common.common.domain.vo.response.ApiResult; +import com.abin.mallchat.common.common.domain.vo.response.IdRespVO; +import com.abin.mallchat.common.common.utils.AssertUtil; +import com.abin.mallchat.common.user.dao.UserEmojiDao; +import com.abin.mallchat.common.user.domain.entity.UserEmoji; +import com.abin.mallchat.custom.user.domain.vo.request.user.UserEmojiReq; +import com.abin.mallchat.custom.user.domain.vo.response.user.UserEmojiResp; +import com.abin.mallchat.custom.user.service.UserEmojiService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 用户表情包 ServiceImpl + * + * @author: WuShiJie + * @createTime: 2023/7/3 14:23 + */ +@Service +@Slf4j +public class UserEmojiServiceImpl implements UserEmojiService { + + @Autowired + private UserEmojiDao userEmojiDao; + + @Override + public List list(Long uid) { + return userEmojiDao.listByUid(uid). + stream() + .map(a -> UserEmojiResp.builder() + .id(a.getId()) + .expressionUrl(a.getExpressionUrl()) + .build()) + .collect(Collectors.toList()); + } + + /** + * 新增表情包 + * + * @param uid 用户ID + * @return 表情包 + * @author WuShiJie + * @createTime 2023/7/3 14:46 + **/ + @Override + @RedissonLock(key = "#uid") + public ApiResult insert(UserEmojiReq req, Long uid) { + //校验表情数量是否超过30 + int count = userEmojiDao.countByUid(uid); + AssertUtil.isFalse(count > 30, "最多只能添加30个表情哦~~"); + //校验表情是否存在 + Integer existsCount = userEmojiDao.lambdaQuery() + .eq(UserEmoji::getExpressionUrl, req.getExpressionUrl()) + .eq(UserEmoji::getUid, uid) + .count(); + AssertUtil.isFalse(existsCount > 0, "当前表情已存在哦~~"); + UserEmoji insert = UserEmoji.builder().uid(uid).expressionUrl(req.getExpressionUrl()).build(); + userEmojiDao.save(insert); + return ApiResult.success(IdRespVO.id(insert.getId())); + } + + @Override + public void remove(Long id, Long uid) { + UserEmoji userEmoji = userEmojiDao.getById(id); + AssertUtil.isNotEmpty(userEmoji, "表情不能为空"); + AssertUtil.equal(userEmoji.getUid(), uid, "小黑子,别人表情不是你能删的"); + userEmojiDao.removeById(id); + } +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojisServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojisServiceImpl.java deleted file mode 100644 index fe51f7a..0000000 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserEmojisServiceImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.abin.mallchat.custom.user.service.impl; - -import com.abin.mallchat.common.chat.domain.entity.UserEmojis; -import com.abin.mallchat.common.common.annotation.RedissonLock; -import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; -import com.abin.mallchat.common.common.domain.vo.response.ApiResult; -import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; -import com.abin.mallchat.common.common.utils.AssertUtil; -import com.abin.mallchat.common.common.utils.CursorUtils; -import com.abin.mallchat.common.common.utils.RequestHolder; -import com.abin.mallchat.common.user.mapper.UserEmojisMapper; -import com.abin.mallchat.custom.user.service.UserEmojisService; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; - -/** - * 用户表情包 ServiceImpl - * - * @author: WuShiJie - * @createTime: 2023/7/3 14:23 - */ -@Service -@Slf4j -public class UserEmojisServiceImpl extends ServiceImpl implements UserEmojisService { - - /** - * 游标分页工具类 - */ - @Resource - private CursorUtils cursorUtils; - - /** - * 表情包列表 - * - * @param request 游标翻页请求参数 - * @return 表情包列表 - * @author WuShiJie - * @createTime 2023/7/3 14:46 - **/ - @Override - public CursorPageBaseResp getEmojisPage(CursorPageBaseReq request, Long uid) { - CursorPageBaseResp cursorPageByMysql = cursorUtils.getCursorPageByMysql(this, request, wrapper -> { - wrapper.eq(UserEmojis::getUid, uid); - }, UserEmojis::getId); - return cursorPageByMysql; - } - - - /** - * 新增表情包 - * - * @param emojis 用户表情包 - * @param uid 用户ID - * @return 表情包 - * @author WuShiJie - * @createTime 2023/7/3 14:46 - **/ - @Override - @RedissonLock(key = "#uid") - public ApiResult insertEmojis(UserEmojis emojis, Long uid) { - //校验表情数量是否超过30 - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(UserEmojis::getUid,uid); - int count = this.count(queryWrapper); - AssertUtil.isFalse(count>30, "最多只能添加30个表情哦~~"); - //校验表情是否存在 - queryWrapper.eq(UserEmojis::getExpressionUrl,emojis.getExpressionUrl()); - count = this.count(queryWrapper); - AssertUtil.isFalse(count >0, "当前表情已存在哦~~"); - emojis.setUid(RequestHolder.get().getUid()); - this.saveOrUpdate(emojis, queryWrapper); - return ApiResult.success(emojis); - } -} From 6546b9fe16a783fadc5b085ba893878ddcb18bf2 Mon Sep 17 00:00:00 2001 From: zhaoyuhang <1045078399@qq.com> Date: Mon, 10 Jul 2023 20:38:01 +0800 Subject: [PATCH 41/42] =?UTF-8?q?=E6=95=8F=E6=84=9F=E8=AF=8D=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=B1=BB=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/config/SensitiveWordConfig.java | 30 ++++++ .../ACFilter.java} | 10 +- .../DFAFilter.java} | 35 +++--- .../common/utils/sensitiveWord/IWordDeny.java | 18 ++++ .../utils/sensitiveWord/SensitiveWordBs.java | 102 ++++++++++++++++++ .../sensitiveWord/SensitiveWordFilter.java | 37 +++++++ .../mallchat/common/sensitive/MyWordDeny.java | 24 +++++ .../service/ISensitiveWordService.java | 5 - .../impl/SensitiveWordServiceImpl.java | 39 ------- .../service/strategy/msg/TextMsgHandler.java | 6 +- .../chatai/handler/GPTChatAIHandler.java | 24 ++--- .../user/service/impl/UserServiceImpl.java | 6 +- 12 files changed, 252 insertions(+), 84 deletions(-) create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/config/SensitiveWordConfig.java rename mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/{SensitiveWordUtils0.java => sensitiveWord/ACFilter.java} (88%) rename mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/{SensitiveWordUtils.java => sensitiveWord/DFAFilter.java} (87%) create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/IWordDeny.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/SensitiveWordBs.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/SensitiveWordFilter.java create mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/sensitive/MyWordDeny.java delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/sensitive/service/ISensitiveWordService.java delete mode 100644 mallchat-common/src/main/java/com/abin/mallchat/common/sensitive/service/impl/SensitiveWordServiceImpl.java diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/config/SensitiveWordConfig.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/config/SensitiveWordConfig.java new file mode 100644 index 0000000..6220d51 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/config/SensitiveWordConfig.java @@ -0,0 +1,30 @@ +package com.abin.mallchat.common.common.config; + +import com.abin.mallchat.common.common.utils.sensitiveWord.DFAFilter; +import com.abin.mallchat.common.common.utils.sensitiveWord.SensitiveWordBs; +import com.abin.mallchat.common.sensitive.MyWordDeny; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SensitiveWordConfig { + + @Autowired + private MyWordDeny myWordDeny; + + /** + * 初始化引导类 + * + * @return 初始化引导类 + * @since 1.0.0 + */ + @Bean + public SensitiveWordBs sensitiveWordBs() { + return SensitiveWordBs.newInstance() + .filterStrategy(DFAFilter.getInstance()) + .sensitiveWord(myWordDeny) + .init(); + } + +} \ No newline at end of file diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/SensitiveWordUtils0.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/ACFilter.java similarity index 88% rename from mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/SensitiveWordUtils0.java rename to mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/ACFilter.java index f67c694..618908f 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/SensitiveWordUtils0.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/ACFilter.java @@ -1,4 +1,4 @@ -package com.abin.mallchat.common.common.utils; +package com.abin.mallchat.common.common.utils.sensitiveWord; import com.abin.mallchat.common.common.algorithm.ac.ACTrie; import com.abin.mallchat.common.common.algorithm.ac.MatchResult; @@ -15,7 +15,7 @@ import java.util.Objects; * * Created by berg on 2023/6/18. */ -public class SensitiveWordUtils0 { +public class ACFilter implements SensitiveWordFilter { private final static char mask_char = '*'; // 替代字符 @@ -27,7 +27,7 @@ public class SensitiveWordUtils0 { * @param text 文本 * @return boolean */ - public static boolean hasSensitiveWord(String text) { + public boolean hasSensitiveWord(String text) { if (StringUtils.isBlank(text)) return false; return !Objects.equals(filter(text), text); } @@ -38,7 +38,7 @@ public class SensitiveWordUtils0 { * @param text 待替换文本 * @return 替换后的文本 */ - public static String filter(String text) { + public String filter(String text) { if (StringUtils.isBlank(text)) return text; List matchResults = ac_trie.matches(text); StringBuffer result = new StringBuffer(text); @@ -62,7 +62,7 @@ public class SensitiveWordUtils0 { * * @param words 敏感词数组 */ - public static void loadWord(List words) { + public void loadWord(List words) { if (words == null) return; ac_trie = new ACTrie(words); } diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/SensitiveWordUtils.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/DFAFilter.java similarity index 87% rename from mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/SensitiveWordUtils.java rename to mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/DFAFilter.java index 298f876..e766e2e 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/SensitiveWordUtils.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/DFAFilter.java @@ -1,4 +1,4 @@ -package com.abin.mallchat.common.common.utils; +package com.abin.mallchat.common.common.utils.sensitiveWord; import org.apache.commons.lang3.StringUtils; import org.springframework.util.CollectionUtils; @@ -18,7 +18,10 @@ import java.util.*; * @author zhaoyuhang * @date 2023/06/19 */ -public final class SensitiveWordUtils { +public final class DFAFilter implements SensitiveWordFilter { + + private DFAFilter() { + } private static Word root = new Word(' '); // 敏感词字典的根节点 private final static char replace = '*'; // 替代字符 private final static String skipChars = " !*-+_=,,.@;:;:。、??()()【】[]《》<>“”\"‘’"; // 遇到这些字符就会跳过 @@ -30,6 +33,10 @@ public final class SensitiveWordUtils { } } + public static DFAFilter getInstance() { + return new DFAFilter(); + } + /** * 判断文本中是否存在敏感词 @@ -37,7 +44,7 @@ public final class SensitiveWordUtils { * @param text 文本 * @return true: 存在敏感词, false: 不存在敏感词 */ - public static boolean hasSensitiveWord(String text) { + public boolean hasSensitiveWord(String text) { if (StringUtils.isBlank(text)) return false; return !Objects.equals(filter(text), text); } @@ -48,7 +55,7 @@ public final class SensitiveWordUtils { * @param text 待替换文本 * @return 替换后的文本 */ - public static String filter(String text) { + public String filter(String text) { StringBuilder result = new StringBuilder(text); int index = 0; while (index < result.length()) { @@ -93,7 +100,7 @@ public final class SensitiveWordUtils { * * @param words 敏感词数组 */ - public static void loadWord(List words) { + public void loadWord(List words) { if (!CollectionUtils.isEmpty(words)) { Word newRoot = new Word(' '); words.forEach(word -> loadWord(word, newRoot)); @@ -106,7 +113,7 @@ public final class SensitiveWordUtils { * * @param word 词 */ - public static void loadWord(String word, Word root) { + public void loadWord(String word, Word root) { if (StringUtils.isBlank(word)) { return; } @@ -136,7 +143,7 @@ public final class SensitiveWordUtils { * * @param path 文本文件的绝对路径 */ - public static void loadWordFromFile(String path) { + public void loadWordFromFile(String path) { try (InputStream inputStream = Files.newInputStream(Paths.get(path))) { loadWord(inputStream); } catch (IOException e) { @@ -150,7 +157,7 @@ public final class SensitiveWordUtils { * @param inputStream 文本文件输入流 * @throws IOException IO异常 */ - public static void loadWord(InputStream inputStream) throws IOException { + public void loadWord(InputStream inputStream) throws IOException { try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { String line; ArrayList list = new ArrayList<>(); @@ -167,7 +174,7 @@ public final class SensitiveWordUtils { * @param c 待检测字符 * @return true: 需要跳过, false: 不需要跳过 */ - private static boolean skip(char c) { + private boolean skip(char c) { return skipSet.contains(c); } @@ -186,17 +193,7 @@ public final class SensitiveWordUtils { public Word(char c) { this.c = c; - this.end = false; this.next = new HashMap<>(); } } - - public static void main(String[] args) { - String text = "白日,梦"; - String filter = filter(text); - System.out.println(filter); - - - } - } diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/IWordDeny.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/IWordDeny.java new file mode 100644 index 0000000..4259c91 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/IWordDeny.java @@ -0,0 +1,18 @@ +package com.abin.mallchat.common.common.utils.sensitiveWord; + +import java.util.List; + +/** + * 敏感词 + * + * @author zhaoyuhang + * @date 2023/07/09 + */ +public interface IWordDeny { + /** + * 获取结果 + * @return 结果 + * @since 0.0.13 + */ + List deny(); +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/SensitiveWordBs.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/SensitiveWordBs.java new file mode 100644 index 0000000..006fd2f --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/SensitiveWordBs.java @@ -0,0 +1,102 @@ +package com.abin.mallchat.common.common.utils.sensitiveWord; + +import java.util.List; + +/** + * 敏感词引导类 + * + * @author zhaoyuhang + * @date 2023/07/08 + */ +public class SensitiveWordBs { + + /** + * 私有化构造器 + */ + private SensitiveWordBs() { + } + + /** + * 脱敏策略 + */ + private SensitiveWordFilter sensitiveWordFilter = DFAFilter.getInstance(); + + /** + * 敏感词列表 + */ + private IWordDeny wordDeny; + + public static SensitiveWordBs newInstance() { + return new SensitiveWordBs(); + } + + /** + * 初始化 + * + * 1. 根据配置,初始化对应的 map。比较消耗性能。 + * @since 0.0.13 + * @return this + */ + public SensitiveWordBs init() { + + List words = wordDeny.deny(); + loadWord(words); + return this; + } + + /** + * 过滤策略 + * + * @param filter 过滤器 + * @return 结果 + * @since 0.7.0 + */ + public SensitiveWordBs filterStrategy(SensitiveWordFilter filter) { + if (filter == null) { + throw new IllegalArgumentException("filter can not be null"); + } + this.sensitiveWordFilter = filter; + return this; + } + + public SensitiveWordBs sensitiveWord(IWordDeny wordDeny) { + if (wordDeny == null) { + throw new IllegalArgumentException("wordDeny can not be null"); + } + this.wordDeny = wordDeny; + return this; + } + + + + + /** + * 有敏感词 + * + * @param text 文本 + * @return boolean + */ + public boolean hasSensitiveWord(String text) { + return sensitiveWordFilter.hasSensitiveWord(text); + } + + /** + * 过滤 + * + * @param text 文本 + * @return {@link String} + */ + public String filter(String text) { + return sensitiveWordFilter.filter(text); + } + + /** + * 加载敏感词列表 + * + * @param words 敏感词数组 + */ + private void loadWord(List words) { + sensitiveWordFilter.loadWord(words); + } + +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/SensitiveWordFilter.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/SensitiveWordFilter.java new file mode 100644 index 0000000..afe2533 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/sensitiveWord/SensitiveWordFilter.java @@ -0,0 +1,37 @@ +package com.abin.mallchat.common.common.utils.sensitiveWord; + + +import java.util.List; + +/** + * 敏感词过滤 + * + * @author zhaoyuhang + * @date 2023/07/08 + */ +public interface SensitiveWordFilter { + /** + * 有敏感词 + * + * @param text 文本 + * @return boolean + */ + boolean hasSensitiveWord(String text); + + /** + * 过滤 + * + * @param text 文本 + * @return {@link String} + */ + String filter(String text); + + /** + * 加载敏感词列表 + * + * @param words 敏感词数组 + */ + void loadWord(List words); + + +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/sensitive/MyWordDeny.java b/mallchat-common/src/main/java/com/abin/mallchat/common/sensitive/MyWordDeny.java new file mode 100644 index 0000000..a47d623 --- /dev/null +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/sensitive/MyWordDeny.java @@ -0,0 +1,24 @@ +package com.abin.mallchat.common.sensitive; + +import com.abin.mallchat.common.common.utils.sensitiveWord.IWordDeny; +import com.abin.mallchat.common.sensitive.dao.SensitiveWordDao; +import com.abin.mallchat.common.sensitive.domain.SensitiveWord; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +@Component +public class MyWordDeny implements IWordDeny { + @Autowired + private SensitiveWordDao sensitiveWordDao; + + @Override + public List deny() { + return sensitiveWordDao.list() + .stream() + .map(SensitiveWord::getWord) + .collect(Collectors.toList()); + } +} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/sensitive/service/ISensitiveWordService.java b/mallchat-common/src/main/java/com/abin/mallchat/common/sensitive/service/ISensitiveWordService.java deleted file mode 100644 index f62783a..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/sensitive/service/ISensitiveWordService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.abin.mallchat.common.sensitive.service; - -public interface ISensitiveWordService { - -} diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/sensitive/service/impl/SensitiveWordServiceImpl.java b/mallchat-common/src/main/java/com/abin/mallchat/common/sensitive/service/impl/SensitiveWordServiceImpl.java deleted file mode 100644 index d7fd50f..0000000 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/sensitive/service/impl/SensitiveWordServiceImpl.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.abin.mallchat.common.sensitive.service.impl; - -import com.abin.mallchat.common.common.utils.SensitiveWordUtils; -import com.abin.mallchat.common.sensitive.dao.SensitiveWordDao; -import com.abin.mallchat.common.sensitive.domain.SensitiveWord; -import com.abin.mallchat.common.sensitive.service.ISensitiveWordService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import javax.annotation.PostConstruct; -import java.util.List; -import java.util.stream.Collectors; - -@Service -@Slf4j -public class SensitiveWordServiceImpl implements ISensitiveWordService { - @Autowired - private SensitiveWordDao sensitiveWordDao; - @Autowired - private ThreadPoolTaskExecutor threadPoolTaskExecutor; - - @PostConstruct - public void initSensitiveWord() { - threadPoolTaskExecutor.execute(() -> { - log.info("[initSensitiveWord] start"); - List list = sensitiveWordDao.list(); - if (!CollectionUtils.isEmpty(list)) { - List wordList = list.stream() - .map(SensitiveWord::getWord) - .collect(Collectors.toList()); - SensitiveWordUtils.loadWord(wordList); - } - log.info("[initSensitiveWord] end; loading sensitiveWords num:{}", list.size()); - }); - } -} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java index d8e347a..c597c06 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java @@ -10,8 +10,8 @@ import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum; import com.abin.mallchat.common.chat.service.cache.MsgCache; import com.abin.mallchat.common.common.domain.enums.YesOrNoEnum; import com.abin.mallchat.common.common.utils.AssertUtil; -import com.abin.mallchat.common.common.utils.SensitiveWordUtils; import com.abin.mallchat.common.common.utils.discover.PrioritizedUrlTitleDiscover; +import com.abin.mallchat.common.common.utils.sensitiveWord.SensitiveWordBs; import com.abin.mallchat.common.user.domain.entity.User; import com.abin.mallchat.common.user.domain.enums.RoleEnum; import com.abin.mallchat.common.user.service.IRoleService; @@ -46,6 +46,8 @@ public class TextMsgHandler extends AbstractMsgHandler { private UserInfoCache userInfoCache; @Autowired private IRoleService iRoleService; + @Autowired + private SensitiveWordBs sensitiveWordBs; private static final PrioritizedUrlTitleDiscover URL_TITLE_DISCOVER = new PrioritizedUrlTitleDiscover(); @@ -81,7 +83,7 @@ public class TextMsgHandler extends AbstractMsgHandler { MessageExtra extra = Optional.ofNullable(msg.getExtra()).orElse(new MessageExtra()); Message update = new Message(); update.setId(msg.getId()); - update.setContent(SensitiveWordUtils.filter(body.getContent())); + update.setContent(sensitiveWordBs.filter(body.getContent())); update.setExtra(extra); //如果有回复消息 if (Objects.nonNull(body.getReplyMsgId())) { diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/GPTChatAIHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/GPTChatAIHandler.java index fd8a594..f50093d 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/GPTChatAIHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/GPTChatAIHandler.java @@ -36,16 +36,18 @@ public class GPTChatAIHandler extends AbstractChatAIHandler { @Override protected void init() { super.init(); - UserInfoResp userInfo = userService.getUserInfo(chatGPTProperties.getAIUserId()); - if (userInfo == null) { - log.error("根据AIUserId:{} 找不到用户信息", chatGPTProperties.getAIUserId()); - throw new RuntimeException("根据AIUserId: " + chatGPTProperties.getAIUserId() + " 找不到用户信息"); + if (isUse()) { + UserInfoResp userInfo = userService.getUserInfo(chatGPTProperties.getAIUserId()); + if (userInfo == null) { + log.error("根据AIUserId:{} 找不到用户信息", chatGPTProperties.getAIUserId()); + throw new RuntimeException("根据AIUserId: " + chatGPTProperties.getAIUserId() + " 找不到用户信息"); + } + if (StringUtils.isBlank(userInfo.getName())) { + log.warn("根据AIUserId:{} 找到的用户信息没有name", chatGPTProperties.getAIUserId()); + throw new RuntimeException("根据AIUserId: " + chatGPTProperties.getAIUserId() + " 找到的用户没有名字"); + } + AI_NAME = userInfo.getName(); } - if (StringUtils.isBlank(userInfo.getName())) { - log.warn("根据AIUserId:{} 找到的用户信息没有name", chatGPTProperties.getAIUserId()); - throw new RuntimeException("根据AIUserId: " + chatGPTProperties.getAIUserId() + " 找到的用户没有名字"); - } - AI_NAME = userInfo.getName(); } @Override @@ -90,14 +92,12 @@ public class GPTChatAIHandler extends AbstractChatAIHandler { text = ChatGPTUtils.parseText(response); } catch (Exception e) { log.warn("gpt doChat warn:", e); - text= "我累了,明天再聊吧"; + text = "我累了,明天再聊吧"; } return text; } - - @Override protected boolean supports(Message message) { if (!chatGPTProperties.isUse()) { diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserServiceImpl.java index dc63558..e8e5d62 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserServiceImpl.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/UserServiceImpl.java @@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil; import com.abin.mallchat.common.common.event.UserBlackEvent; import com.abin.mallchat.common.common.event.UserRegisterEvent; import com.abin.mallchat.common.common.utils.AssertUtil; -import com.abin.mallchat.common.common.utils.SensitiveWordUtils; +import com.abin.mallchat.common.common.utils.sensitiveWord.SensitiveWordBs; import com.abin.mallchat.common.user.dao.BlackDao; import com.abin.mallchat.common.user.dao.ItemConfigDao; import com.abin.mallchat.common.user.dao.UserBackpackDao; @@ -63,6 +63,8 @@ public class UserServiceImpl implements UserService { private BlackDao blackDao; @Autowired private UserSummaryCache userSummaryCache; + @Autowired + private SensitiveWordBs sensitiveWordBs; @Override public UserInfoResp getUserInfo(Long uid) { @@ -76,7 +78,7 @@ public class UserServiceImpl implements UserService { public void modifyName(Long uid, ModifyNameReq req) { //判断名字是不是重复 String newName = req.getName(); - AssertUtil.isFalse(SensitiveWordUtils.hasSensitiveWord(newName), "名字中包含敏感词,请重新输入"); // 判断名字中有没有敏感词 + AssertUtil.isFalse(sensitiveWordBs.hasSensitiveWord(newName), "名字中包含敏感词,请重新输入"); // 判断名字中有没有敏感词 User oldUser = userDao.getByName(newName); AssertUtil.isEmpty(oldUser, "名字已经被抢占了,请换一个哦~~"); //判断改名卡够不够 From b6d9cad31c5e94876dfa53169de19186381dc0f0 Mon Sep 17 00:00:00 2001 From: zhaoyuhang <1045078399@qq.com> Date: Mon, 10 Jul 2023 20:42:57 +0800 Subject: [PATCH 42/42] =?UTF-8?q?=E6=95=8F=E6=84=9F=E8=AF=8D=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=B1=BB=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/chat/service/strategy/msg/TextMsgHandler.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java index 60fa1b0..5ec867a 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/TextMsgHandler.java @@ -10,11 +10,9 @@ import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum; import com.abin.mallchat.common.chat.service.cache.MsgCache; import com.abin.mallchat.common.common.domain.enums.YesOrNoEnum; import com.abin.mallchat.common.common.utils.AssertUtil; -import com.abin.mallchat.common.common.utils.discover.PrioritizedUrlTitleDiscover; -import com.abin.mallchat.common.common.utils.sensitiveWord.SensitiveWordBs; -import com.abin.mallchat.common.common.utils.SensitiveWordUtils; import com.abin.mallchat.common.common.utils.discover.PrioritizedUrlDiscover; import com.abin.mallchat.common.common.utils.discover.domain.UrlInfo; +import com.abin.mallchat.common.common.utils.sensitiveWord.SensitiveWordBs; import com.abin.mallchat.common.user.domain.entity.User; import com.abin.mallchat.common.user.domain.enums.RoleEnum; import com.abin.mallchat.common.user.service.IRoleService;