diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/config/WebSocketBrokerConfig.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/config/WebSocketBrokerConfig.java index bfc2bbd..9d512c2 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/config/WebSocketBrokerConfig.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/config/WebSocketBrokerConfig.java @@ -34,6 +34,7 @@ public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer { @Resource private ApplicationEventPublisher applicationEventPublisher; + /** * 注册 Stomp的端点 可以注册多个端点 * addEndpoint:添加STOMP协议的端点。客户端访问地址 diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/ExceptionEnum.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/ExceptionEnum.java index e2e42e7..77a2cf9 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/ExceptionEnum.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/constant/ExceptionEnum.java @@ -14,6 +14,7 @@ public enum ExceptionEnum { MAX_LIMIT_CONNECT(1021, "服务器websocket连接数已达上限,服务器拒绝链接"), SET_PRINCIPAL_FAIL(1022, "websocket链接异常,用户身份设置失败"), GET_PRINCIPAL_FAIL(1023, "websocket链接异常,用户信息邮箱获取失败"), + ACCOUNT_HAS_CONNECTED(1024, "当前登录用户在其他地方链接"), ; private final int code; diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatMessageController.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatMessageController.java index 2361895..f5117e8 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatMessageController.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatMessageController.java @@ -34,9 +34,8 @@ public class ChatMessageController { @PostMapping("/find/recently/message") @ApiOperation(value = "查询七天内的记录", notes = "根据ID查询七天内的记录") - @RequiresLogin public R> findRecentlyMessage(@RequestBody MessagePageVo pageVo) { - return chatMessageService.findRecentlyMessage(pageVo.getId(), pageVo.getPageNum(), pageVo.getRoomId()); + return chatMessageService.findRecentlyMessage(pageVo.getEmail(),pageVo.getId(), pageVo.getPageNum(), pageVo.getRoomId()); } @GetMapping("/delete/message") diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatRoomController.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatRoomController.java index 2380a2f..b76d090 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatRoomController.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/controller/ChatRoomController.java @@ -4,6 +4,7 @@ import com.m2pool.chat.dto.ChatRoomDto; import com.m2pool.chat.service.ChatRoomService; import com.m2pool.chat.vo.CharRoomVo; import com.m2pool.chat.vo.RoomPageVo; +import com.m2pool.chat.vo.RoomVo; import com.m2pool.common.core.Result.R; import com.m2pool.common.core.web.page.TableDataInfo; import com.m2pool.common.security.annotation.RequiresLogin; @@ -35,11 +36,10 @@ public class ChatRoomController { return chatRoomService.findRoomList(roomPageVo); } - @GetMapping("/find/room/by/userid") + @PostMapping("/find/room/by/userid") @ApiOperation(value = "客户端:根据当前用户邮箱查询聊天室") - @RequiresLogin - public R findRoomByUserid() { - return chatRoomService.findRoomByUserid(); + public R findRoomByUserid(@RequestBody RoomVo roomVo) { + return chatRoomService.findRoomByUserid(roomVo); } diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/ChatRoomDto.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/ChatRoomDto.java index 1d20acb..92e96ba 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/ChatRoomDto.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/dto/ChatRoomDto.java @@ -28,9 +28,9 @@ public class ChatRoomDto { @ApiModelProperty(value = "聊天室id", example = "1") private String id; /** - * 聊天对象id + * 聊天对象id:一般为客服 */ - @ApiModelProperty(value = "聊天对象id", example = "1") + @ApiModelProperty(value = "聊天对象id:一般为客服", example = "1") private String userEmail; /** * 聊天室重要程度 @@ -56,4 +56,10 @@ public class ChatRoomDto { */ @ApiModelProperty(value = "客服回复时间", example = "2025-10-01 12:32:01") private LocalDateTime lastCustomerSendTime; + + /** + * 聊天发起者id :一般为游客或登录用户 + */ + @ApiModelProperty(value = "聊天发起者id :一般为游客或登录用户", example = "1") + private String selfEmail; } diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/interceptor/WebsocketChannelInterceptor.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/interceptor/WebsocketChannelInterceptor.java index f868d55..cd51965 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/interceptor/WebsocketChannelInterceptor.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/interceptor/WebsocketChannelInterceptor.java @@ -43,7 +43,6 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor { */ private static final ConcurrentHashMap ipConnectionCountMap = new ConcurrentHashMap<>(); - /** * 当前链接数 */ @@ -56,7 +55,9 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor { private ApplicationEventPublisher applicationEventPublisher; - public WebsocketChannelInterceptor(CustomWebSocketConfig customWebSocketConfig, ApplicationEventPublisher applicationEventPublisher) { + + public WebsocketChannelInterceptor(CustomWebSocketConfig customWebSocketConfig, + ApplicationEventPublisher applicationEventPublisher) { this.customWebSocketConfig = customWebSocketConfig; this.applicationEventPublisher = applicationEventPublisher; } @@ -128,11 +129,14 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor { } //本次链接为登录用户,并且已经链接.直接拒绝本次链接(多用户登录) if ( type == LOGIN_USER ) { - if(email.equals(hasConnectionEmail) || ipConnectionCountMap.containsValue(email)){ + if(email.equals(hasConnectionEmail) ){ // StompPrincipal principal = new StompPrincipal(email, type, true); // applicationEventPublisher.publishEvent(new IpLimitEvent(this, principal)); throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.IP_LIMIT_CONNECT)); } + if(ipConnectionCountMap.containsValue(email)){ + throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.ACCOUNT_HAS_CONNECTED)); + } } ipConnectionCountMap.put(ipAddr,email); diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/listener/WebSocketEventListener.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/listener/WebSocketEventListener.java index 86bca19..5fee3cd 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/listener/WebSocketEventListener.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/listener/WebSocketEventListener.java @@ -1,6 +1,11 @@ package com.m2pool.chat.listener; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.m2pool.chat.entity.ChatMessage; +import com.m2pool.chat.entity.ChatRoom; import com.m2pool.chat.entity.StompPrincipal; +import com.m2pool.chat.mapper.ChatMessageMapper; +import com.m2pool.chat.mapper.ChatRoomMapper; import com.m2pool.chat.service.impl.StompServiceImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,6 +31,12 @@ public class WebSocketEventListener implements ApplicationListener().eq(ChatRoom::getUserOneEmail, user.getName())); + chatMessageMapper.delete(new LambdaUpdateWrapper().eq(ChatMessage::getSendEmail, user.getName())); } } } diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatMessageService.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatMessageService.java index 515a375..e00d075 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatMessageService.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatMessageService.java @@ -19,12 +19,13 @@ public interface ChatMessageService{ /** * 游标分页 查询7天内数据 + * @param email 用户邮箱 * @param id 游标 * @param pageNum 每页条数 * @param roomId 聊天室id * @return */ - R> findRecentlyMessage(Long id,Integer pageNum,Long roomId); + R> findRecentlyMessage(String email,Long id,Integer pageNum,Long roomId); /** diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatRoomService.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatRoomService.java index 791b0d2..6022f24 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatRoomService.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/ChatRoomService.java @@ -5,6 +5,7 @@ import com.m2pool.chat.dto.ChatRoomDto; import com.m2pool.chat.entity.ChatRoom; import com.m2pool.chat.vo.CharRoomVo; import com.m2pool.chat.vo.RoomPageVo; +import com.m2pool.chat.vo.RoomVo; import com.m2pool.common.core.Result.R; import com.m2pool.common.core.web.page.TableDataInfo; @@ -21,7 +22,7 @@ public interface ChatRoomService extends IService { * 根据当前用户邮箱查询聊天室 * @return */ - R findRoomByUserid(); + R findRoomByUserid(RoomVo roomVo); /** * 修改聊天室信息 diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatMessageServiceImpl.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatMessageServiceImpl.java index 519b589..9deb1ab 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatMessageServiceImpl.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatMessageServiceImpl.java @@ -41,8 +41,7 @@ public class ChatMessageServiceImpl implements ChatMessageService { } @Override - public R> findRecentlyMessage(Long id,Integer pageNum,Long roomId) { - String email = SecurityUtils.getUsername(); + public R> findRecentlyMessage(String email,Long id,Integer pageNum,Long roomId) { ChatMessage chatMessage = chatMessageMapper.selectById(id); List recentlyMessage; if(chatMessage != null){ diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatRoomServiceImpl.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatRoomServiceImpl.java index 9189390..d4c43c9 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatRoomServiceImpl.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/ChatRoomServiceImpl.java @@ -10,6 +10,7 @@ import com.m2pool.chat.mapper.ChatRoomMapper; import com.m2pool.chat.service.ChatRoomService; import com.m2pool.chat.vo.CharRoomVo; import com.m2pool.chat.vo.RoomPageVo; +import com.m2pool.chat.vo.RoomVo; import com.m2pool.common.core.Result.R; import com.m2pool.common.core.constant.HttpStatus; import com.m2pool.common.core.utils.PageUtils; @@ -75,9 +76,9 @@ public class ChatRoomServiceImpl extends ServiceImpl i @Override @Transactional - public R findRoomByUserid() { + public R findRoomByUserid(RoomVo roomVo) { //1.查询当前用户与对应用户是否已存在创建的聊天室 - String userEmail = SecurityUtils.getUsername(); + String userEmail = roomVo.getEmail(); ChatRoomDto roomByUserEmail = chatRoomMapper.findRoomByUserEmail(userEmail); if(roomByUserEmail != null){ return R.success(roomByUserEmail); @@ -93,7 +94,7 @@ public class ChatRoomServiceImpl extends ServiceImpl i ChatRoom build = ChatRoom.builder().userOneEmail(userEmail).userTwoEmail(sysUser.getEmail()).build(); int insert = chatRoomMapper.insert(build); if (insert > 0){ - return R.success(ChatRoomDto.builder().id(String.valueOf(build.getId())).userEmail(build.getUserTwoEmail()).build()); + return R.success(ChatRoomDto.builder().id(String.valueOf(build.getId())).selfEmail(userEmail).userEmail(build.getUserTwoEmail()).build()); } return R.fail("聊天室不存在,并且创建聊天室失败"); } diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/StompServiceImpl.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/StompServiceImpl.java index 2ab51c4..09dce3e 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/StompServiceImpl.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/service/impl/StompServiceImpl.java @@ -1,5 +1,6 @@ package com.m2pool.chat.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.m2pool.chat.config.CustomWebSocketConfig; import com.m2pool.chat.constant.Destination; import com.m2pool.chat.dto.WebsocketMessageDto; @@ -10,7 +11,6 @@ import com.m2pool.chat.mapper.ChatMessageMapper; import com.m2pool.chat.mapper.ChatRoomMapper; import com.m2pool.chat.service.StompService; import com.m2pool.chat.vo.UserMessageVo; -import com.m2pool.common.core.utils.StringUtils; import com.m2pool.common.core.web.Result.AjaxResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.simp.SimpMessagingTemplate; @@ -24,7 +24,7 @@ import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.Date; -import static com.m2pool.chat.constant.UserType.*; +import static com.m2pool.chat.constant.UserType.CUSTOMER; @Service public class StompServiceImpl implements StompService { @@ -49,10 +49,6 @@ public class StompServiceImpl implements StompService { @Override public AjaxResult sendMessageToUser(StompPrincipal principal, UserMessageVo userMessageVo) { - if(StringUtils.isEmpty(userMessageVo.getEmail())){ - userMessageVo.setEmail(webSocketConfig.getDefaultCustomerEmail()); - } - userRegistry.getUsers().forEach(user -> System.out.println(user.getName())); Boolean isCreate = principal.getIsCreate(); WebsocketMessageDto build = WebsocketMessageDto.builder() .type(userMessageVo.getType()) @@ -66,44 +62,45 @@ public class StompServiceImpl implements StompService { if (isCreate){ principal.setIsCreate(false); } - //获取当前聊天室对象 - ChatRoom chatRoom = chatRoomMapper.selectById(userMessageVo.getRoomId()); - if (chatRoom != null ){ - build.setRoomId(String.valueOf(userMessageVo.getRoomId())); - if(LOGIN_USER.equals(principal.getType())){ - build.setClientReadNum(chatRoom.getServiceReadNum() + 1); - }else { - build.setClientReadNum(chatRoom.getClientReadNum() + 1); - } + ChatRoom chatRoom; - }else{ - build.setRoomId(TOURIST.equals(userMessageVo.getType()) ? userMessageVo.getEmail() : principal.getName()); + if(!CUSTOMER.equals(principal.getType())){ + chatRoom = chatRoomMapper.selectOne(new LambdaQueryWrapper() + .eq(ChatRoom::getUserOneEmail, principal.getName()) + .eq(ChatRoom::getUserTwoEmail, userMessageVo.getEmail())); + build.setRoomId(String.valueOf(userMessageVo.getRoomId())); + build.setClientReadNum(chatRoom.getServiceReadNum() + 1); + }else { + chatRoom = chatRoomMapper.selectOne(new LambdaQueryWrapper() + .eq(ChatRoom::getUserOneEmail, userMessageVo.getEmail()) + .eq(ChatRoom::getUserTwoEmail, principal.getName())); + build.setRoomId(String.valueOf(userMessageVo.getRoomId())); + build.setClientReadNum(chatRoom.getClientReadNum() + 1); } + boolean bool = checkOnline(userMessageVo); //在线用户才发送消息 if (bool){ messagingTemplate.convertAndSendToUser(userMessageVo.getEmail(), Destination.QUEUE + "/" + userMessageVo.getEmail(),build); } - // 接收者和发送者 都不是游客才能存储消息 和修改聊天室信息。后续可改为消息中间件解耦形式。 - if (!TOURIST.equals(userMessageVo.getReceiveUserType()) && !TOURIST.equals(principal.getType()) && chatRoom != null){ - transactionTemplate.execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus status) { - try { - // 插入消息并获取 ID - insertMessage(principal,userMessageVo); - //聊天室,已读未读数量,更新。 - updateRoom(chatRoom,principal.getType(),bool); - } catch (Exception e) { - // 回滚事务 - status.setRollbackOnly(); - throw e; - } + // 消息存储 + transactionTemplate.execute(new TransactionCallbackWithoutResult() { + @Override + protected void doInTransactionWithoutResult(TransactionStatus status) { + try { + // 插入消息并获取 ID + insertMessage(principal,userMessageVo); + //聊天室,已读未读数量,更新。 + updateRoom(chatRoom,principal.getType(),bool); + } catch (Exception e) { + // 回滚事务 + status.setRollbackOnly(); + throw e; } - }); - } - //可以用void + } + }); + return AjaxResult.success("成功"); } diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/MessagePageVo.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/MessagePageVo.java index 5493ce2..fc42e01 100644 --- a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/MessagePageVo.java +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/MessagePageVo.java @@ -25,6 +25,10 @@ public class MessagePageVo { @ApiModelProperty(value = "用户类型 0 游客 1 登录用户 2 客服", example = "1",required = true) private Integer userType; + + @ApiModelProperty(value = "当前登录用户邮箱;游客就是生成的唯一id", example = "54544@qq.com",required = true) + private String email; + public MessagePageVo() { this.pageNum = 20; } diff --git a/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/RoomVo.java b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/RoomVo.java new file mode 100644 index 0000000..ce53125 --- /dev/null +++ b/m2pool-modules/m2pool-chat/src/main/java/com/m2pool/chat/vo/RoomVo.java @@ -0,0 +1,18 @@ +package com.m2pool.chat.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @ClassName RoomVo + * @Description TODO + * @Author yyb + * @Date 2025/4/30 16:27 + */ +@Data +@ApiModel(description = "根据用户邮箱查询聊天室") +public class RoomVo { + @ApiModelProperty(value = "当前登录用户邮箱;游客就是生成的唯一id", example = "54544@qq.com",required = true) + private String email; +} diff --git a/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatRoomMapper.xml b/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatRoomMapper.xml index e86c5f0..5298eac 100644 --- a/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatRoomMapper.xml +++ b/m2pool-modules/m2pool-chat/src/main/resources/mapper/chat/ChatRoomMapper.xml @@ -30,7 +30,7 @@