Sfoglia il codice sorgente

Merge branch 'v_2.0.0' of gitee.com:bluexsx/box-im into master

Signed-off-by: blue <825657193@qq.com>
blue 2 anni fa
parent
commit
af28628ef8

+ 0 - 7
im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java

@@ -35,13 +35,6 @@ public class GroupMessageController {
         return ResultUtils.success();
     }
 
-    // todo 删除
-    @PostMapping("/pullUnreadMessage")
-    @ApiOperation(value = "拉取未读消息", notes = "拉取未读消息")
-    public Result pullUnreadMessage() {
-        groupMessageService.pullUnreadMessage();
-        return ResultUtils.success();
-    }
 
     @GetMapping("/loadMessage")
     @ApiOperation(value = "拉取消息", notes = "拉取消息,一次最多拉取100条")

+ 6 - 7
im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java

@@ -36,13 +36,6 @@ public class PrivateMessageController {
         return ResultUtils.success();
     }
 
-    @PostMapping("/pullUnreadMessage")
-    @ApiOperation(value = "拉取未读消息", notes = "拉取未读消息")
-    public Result pullUnreadMessage() {
-        privateMessageService.pullUnreadMessage();
-        return ResultUtils.success();
-    }
-
 
     @GetMapping("/loadMessage")
     @ApiOperation(value = "拉取消息", notes = "拉取消息,一次最多拉取100条")
@@ -57,6 +50,12 @@ public class PrivateMessageController {
         return ResultUtils.success();
     }
 
+    @GetMapping("/maxReadedId")
+    @ApiOperation(value = "获取最大已读消息的id",notes="获取某个会话中已读消息的最大id")
+    public Result<Long> getMaxReadedId(@RequestParam Long friendId){
+        return ResultUtils.success(privateMessageService.getMaxReadedId(friendId));
+    }
+
     @GetMapping("/history")
     @ApiOperation(value = "查询聊天记录", notes = "查询聊天记录")
     public Result<List<PrivateMessageVO>> recallMessage(@NotNull(message = "好友id不能为空") @RequestParam Long friendId,

+ 1 - 5
im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java

@@ -21,11 +21,7 @@ public class GroupMessageListener implements MessageListener<GroupMessageVO> {
     @Override
     public void process(IMSendResult<GroupMessageVO> result) {
         GroupMessageVO messageInfo = result.getData();
-        // 保存该用户已拉取的最大消息id
-        if (result.getCode().equals(IMSendCode.SUCCESS.code())) {
-            String key = String.join(":", RedisKey.IM_GROUP_READED_POSITION, messageInfo.getGroupId().toString(), result.getReceiver().getId().toString());
-            redisTemplate.opsForValue().set(key, messageInfo.getId());
-        }
+        // 空空如也
     }
 
 }

+ 0 - 5
im-platform/src/main/java/com/bx/implatform/service/IGroupMessageService.java

@@ -24,11 +24,6 @@ public interface IGroupMessageService extends IService<GroupMessage> {
      */
     void recallMessage(Long id);
 
-    /**
-     * 异步拉取群聊消息,通过websocket异步推送
-     */
-    void pullUnreadMessage();
-
     /**
      * 拉取消息,只能拉取最近1个月的消息,一次拉取100条
      *

+ 8 - 4
im-platform/src/main/java/com/bx/implatform/service/IPrivateMessageService.java

@@ -35,10 +35,6 @@ public interface IPrivateMessageService extends IService<PrivateMessage> {
      */
     List<PrivateMessageVO> findHistoryMessage(Long friendId, Long page, Long size);
 
-    /**
-     * 异步拉取私聊消息,通过websocket异步推送
-     */
-    void pullUnreadMessage();
 
     /**
      * 拉取消息,只能拉取最近1个月的消息,一次拉取100条
@@ -48,10 +44,18 @@ public interface IPrivateMessageService extends IService<PrivateMessage> {
      */
     List<PrivateMessageVO> loadMessage(Long minId);
 
+
     /**
      * 消息已读,将整个会话的消息都置为已读状态
      *
      * @param friendId 好友id
      */
     void readedMessage(Long friendId);
+
+    /**
+     *  获取某个会话中已读消息的最大id
+     *
+     * @param friendId 好友id
+     */
+    Long getMaxReadedId(Long friendId);
 }

+ 1 - 36
im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java

@@ -136,41 +136,6 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
         log.info("撤回群聊消息,发送id:{},群聊id:{},内容:{}", session.getUserId(), msg.getGroupId(), msg.getContent());
     }
 
-    @Override
-    public void pullUnreadMessage() {
-        UserSession session = SessionContext.getSession();
-        List<GroupMember> members = groupMemberService.findByUserId(session.getUserId());
-        for (GroupMember member : members) {
-            // 获取群聊已读的最大消息id,只推送未读消息
-            String key = String.join(":", RedisKey.IM_GROUP_READED_POSITION, member.getGroupId().toString(), session.getUserId().toString());
-            Integer maxReadedId = (Integer) redisTemplate.opsForValue().get(key);
-            LambdaQueryWrapper<GroupMessage> wrapper = Wrappers.lambdaQuery();
-            wrapper.eq(GroupMessage::getGroupId, member.getGroupId()).gt(GroupMessage::getSendTime, member.getCreatedTime())
-                    .ne(GroupMessage::getSendId, session.getUserId()).ne(GroupMessage::getStatus, MessageStatus.RECALL.code());
-            if (maxReadedId != null) {
-                wrapper.gt(GroupMessage::getId, maxReadedId);
-            }
-            wrapper.last("limit 100");
-            List<GroupMessage> messages = this.list(wrapper);
-            if (messages.isEmpty()) {
-                continue;
-            }
-            // 推送
-            for (GroupMessage message : messages) {
-                GroupMessageVO msgInfo = BeanUtils.copyProperties(message, GroupMessageVO.class);
-                IMGroupMessage<GroupMessageVO> sendMessage = new IMGroupMessage<>();
-                sendMessage.setSender(new IMUserInfo(session.getUserId(), session.getTerminal()));
-                // 只推给自己当前终端
-                sendMessage.setRecvIds(Collections.singletonList(session.getUserId()));
-                sendMessage.setRecvTerminals(Collections.singletonList(session.getTerminal()));
-                sendMessage.setData(msgInfo);
-                imClient.sendGroupMessage(sendMessage);
-            }
-            // 发送消息
-            log.info("拉取未读群聊消息,用户id:{},群聊id:{},数量:{}", session.getUserId(), member.getGroupId(), messages.size());
-        }
-
-    }
 
     @Override
     public List<GroupMessageVO> loadMessage(Long minId) {
@@ -239,7 +204,7 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
         sendMessage.setSender(new IMUserInfo(session.getUserId(), session.getTerminal()));
         sendMessage.setSendToSelf(true);
         sendMessage.setData(msgInfo);
-        sendMessage.setSendResult(false);
+        sendMessage.setSendResult(true);
         imClient.sendGroupMessage(sendMessage);
         // 记录已读消息位置
         String key = CharSequenceUtil.join(":", RedisKey.IM_GROUP_READED_POSITION, groupId, session.getUserId());

+ 18 - 40
im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java

@@ -30,10 +30,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -131,42 +128,6 @@ public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper,
     }
 
 
-    @Override
-    public void pullUnreadMessage() {
-        UserSession session = SessionContext.getSession();
-        // 获取当前连接的channelId
-        if (!imClient.isOnline(session.getUserId())) {
-            throw new GlobalException(ResultCode.PROGRAM_ERROR, "用户未建立连接");
-        }
-
-        List<Friend> friends = friendService.findFriendByUserId(session.getUserId());
-        if (friends.isEmpty()) {
-            return;
-        }
-        List<Long> friendIds = friends.stream().map(Friend::getFriendId).collect(Collectors.toList());
-        // 获取当前用户所有未读消息
-        LambdaQueryWrapper<PrivateMessage> queryWrapper = Wrappers.lambdaQuery();
-        queryWrapper.eq(PrivateMessage::getRecvId, session.getUserId())
-                .eq(PrivateMessage::getStatus, MessageStatus.UNSEND)
-                .in(PrivateMessage::getSendId, friendIds);
-        List<PrivateMessage> messages = this.list(queryWrapper);
-        // 上传至redis,等待推送
-        for (PrivateMessage message : messages) {
-            PrivateMessageVO msgInfo = BeanUtils.copyProperties(message, PrivateMessageVO.class);
-            // 推送消息
-            IMPrivateMessage<PrivateMessageVO> sendMessage = new IMPrivateMessage<>();
-            sendMessage.setSender(new IMUserInfo(session.getUserId(), session.getTerminal()));
-            sendMessage.setRecvId(session.getUserId());
-            sendMessage.setRecvTerminals(Collections.singletonList(session.getTerminal()));
-            sendMessage.setSendToSelf(false);
-            sendMessage.setData(msgInfo);
-            imClient.sendPrivateMessage(sendMessage);
-        }
-        log.info("拉取未读私聊消息,用户id:{},数量:{}", session.getUserId(), messages.size());
-
-    }
-
-
     @Override
     public List<PrivateMessageVO> loadMessage(Long minId) {
         UserSession session = SessionContext.getSession();
@@ -233,4 +194,21 @@ public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper,
         this.update(updateWrapper);
         log.info("消息已读,接收方id:{},发送方id:{}", session.getUserId(), friendId);
     }
+
+
+    @Override
+    public Long getMaxReadedId(Long friendId) {
+        UserSession session = SessionContext.getSession();
+        LambdaQueryWrapper<PrivateMessage> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(PrivateMessage::getSendId, session.getUserId())
+                .eq(PrivateMessage::getRecvId, friendId)
+                .orderByDesc(PrivateMessage::getId)
+                .select(PrivateMessage::getId)
+                .last("limit 1");
+        PrivateMessage message = this.getOne(wrapper);
+        if(Objects.isNull(message)){
+            return -1L;
+        }
+        return message.getId();
+    }
 }

+ 20 - 5
im-ui/src/components/chat/ChatBox.vue

@@ -462,7 +462,7 @@
 				let file = this.sendImageFile;
 				this.onImageBefore(this.sendImageFile);
 				let formData = new FormData()
-				formData.append('file',  file)
+				formData.append('file', file)
 				this.$http.post("/image/upload", formData, {
 					headers: {
 						'Content-Type': 'multipart/form-data'
@@ -543,7 +543,7 @@
 				});
 			},
 			readedMessage() {
-				if(this.chat.unreadCount==0){
+				if (this.chat.unreadCount == 0) {
 					return;
 				}
 				this.$store.commit("resetUnreadCount", this.chat)
@@ -557,6 +557,17 @@
 					method: 'put'
 				}).then(() => {})
 			},
+			loadReaded(fId) {
+				this.$http({
+					url: `/message/private/maxReadedId?friendId=${fId}`,
+					method: 'get'
+				}).then((id) => {
+					this.$store.commit("readedMessage", {
+						friendId: fId,
+						maxId: id
+					});
+				});
+			},
 			loadGroup(groupId) {
 				this.$http({
 					url: `/group/find/${groupId}`,
@@ -646,6 +657,8 @@
 							this.loadGroup(this.chat.targetId);
 						} else {
 							this.loadFriend(this.chat.targetId);
+							// 加载已读状态
+							this.loadReaded(this.chat.targetId)
 						}
 						// 滚到底部
 						this.scrollToBottom();
@@ -683,6 +696,7 @@
 		width: 100%;
 		background: #f8f8f8;
 		border: #dddddd solid 1px;
+
 		.el-header {
 			padding: 5px;
 			background-color: white;
@@ -754,8 +768,8 @@
 				flex-direction: column;
 				height: 100%;
 				background-color: white !important;
-				
-				
+
+
 				.send-text-area {
 					box-sizing: border-box;
 					padding: 5px;
@@ -765,7 +779,7 @@
 					font-size: 16px;
 					color: black;
 					outline-color: rgba(83, 160, 231, 0.61);
-					
+
 					text-align: left;
 					line-height: 30 px;
 
@@ -784,6 +798,7 @@
 				.send-image-area {
 					text-align: left;
 					border: #53a0e7 solid 1px;
+
 					.send-image-box {
 						position: relative;
 						display: inline-block;

+ 7 - 3
im-ui/src/store/chatStore.js

@@ -70,13 +70,17 @@ export default {
 			}
 			this.commit("saveToStorage");
 		},
-		readedMessage(state, friendId) {
+		readedMessage(state, pos) {
 			for (let idx in state.chats) {
 				if (state.chats[idx].type == 'PRIVATE' &&
-					state.chats[idx].targetId == friendId) {
+					state.chats[idx].targetId == pos.friendId) {
 					state.chats[idx].messages.forEach((m) => {
 						if (m.selfSend && m.status != MESSAGE_STATUS.RECALL) {
-							m.status = MESSAGE_STATUS.READED
+							// pos.maxId为空表示整个会话已读
+							if(!pos.maxId || m.id <= pos.maxId){
+								m.status = MESSAGE_STATUS.READED
+							}
+							
 						}
 					})
 				}

+ 1 - 1
im-ui/src/view/Home.vue

@@ -177,7 +177,7 @@
 						this.$store.commit("resetUnreadCount", chatInfo)
 					} else {
 						// 对方已读我的消息,修改消息状态为已读
-						this.$store.commit("readedMessage", friendId)
+						this.$store.commit("readedMessage", {friendId:friendId})
 					}
 					return;
 				}

+ 1 - 1
im-uniapp/App.vue

@@ -119,7 +119,7 @@
 						store.commit("resetUnreadCount", chatInfo)
 					} else {
 						// 对方已读我的消息,修改消息状态为已读
-						store.commit("readedMessage", friendId)
+						store.commit("readedMessage", {friendId:friendId})
 						
 					}
 					return;

+ 4 - 4
im-uniapp/package.json

@@ -6,16 +6,16 @@
 				"browser":"chrome",
 				"env": {
 					"UNI_PLATFORM": "h5",
-					"BASE_URL": "http://192.168.43.6:8888",
-					"WS_URL": "ws://192.168.43.6:8878/im"
+					"BASE_URL": "http://127.0.0.1:8888",
+					"WS_URL": "ws://127.0.0.1:8878/im"
 				}
 			},
 			"dev-wx-mini": {
 				"title": "开发环境-微信小程序",
 				"env": {
 					"UNI_PLATFORM": "mp-weixin",
-					"BASE_URL": "http://192.168.43.6:8888",
-					"WS_URL": "ws://192.168.43.6:8878/im"
+					"BASE_URL": "http://127.0.0.1:8888",
+					"WS_URL": "ws://127.0.0.1:8878/im"
 				}
 			},
 			"prod-h5": {

+ 12 - 0
im-uniapp/pages/chat/chat-box.vue

@@ -424,6 +424,17 @@
 					})
 				}
 			},
+			loadReaded(fId) {
+				this.$http({
+					url: `/message/private/maxReadedId?friendId=${fId}`,
+					method: 'get'
+				}).then((id) => {
+					this.$store.commit("readedMessage", {
+						friendId: fId,
+						maxId: id
+					});
+				});
+			},
 			readedMessage() {
 				if (this.chat.type == "GROUP") {
 					var url = `/message/group/readed?groupId=${this.chat.targetId}`
@@ -552,6 +563,7 @@
 				this.loadGroup(this.chat.targetId);
 			} else {
 				this.loadFriend(this.chat.targetId);
+				this.loadReaded(this.chat.targetId)
 			}
 		},
 		onUnload() {

+ 7 - 3
im-uniapp/store/chatStore.js

@@ -75,13 +75,17 @@ export default {
 			}
 			this.commit("saveToStorage");
 		},
-		readedMessage(state, friendId) {
+		readedMessage(state, pos) {
 			for (let idx in state.chats) {
 				if (state.chats[idx].type == 'PRIVATE' &&
-					state.chats[idx].targetId == friendId) {
+					state.chats[idx].targetId == pos.friendId) {
 					state.chats[idx].messages.forEach((m) => {
 						if (m.selfSend && m.status != MESSAGE_STATUS.RECALL) {
-							m.status = MESSAGE_STATUS.READED
+							// pos.maxId为空表示整个会话已读
+							if(!pos.maxId || m.id <= pos.maxId){
+								m.status = MESSAGE_STATUS.READED
+							}
+							
 						}
 					})
 				}