diff --git a/im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java b/im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java index ef01033..250c249 100644 --- a/im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java +++ b/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条") diff --git a/im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java b/im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java index d272b45..5f4822e 100644 --- a/im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java +++ b/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 getMaxReadedId(@RequestParam Long friendId){ + return ResultUtils.success(privateMessageService.getMaxReadedId(friendId)); + } + @GetMapping("/history") @ApiOperation(value = "查询聊天记录", notes = "查询聊天记录") public Result> recallMessage(@NotNull(message = "好友id不能为空") @RequestParam Long friendId, diff --git a/im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java b/im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java index 2f8f55a..745d606 100644 --- a/im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java +++ b/im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java @@ -21,11 +21,7 @@ public class GroupMessageListener implements MessageListener { @Override public void process(IMSendResult 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()); - } + // 空空如也 } } diff --git a/im-platform/src/main/java/com/bx/implatform/service/IGroupMessageService.java b/im-platform/src/main/java/com/bx/implatform/service/IGroupMessageService.java index cfe4a9b..51f0075 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/IGroupMessageService.java +++ b/im-platform/src/main/java/com/bx/implatform/service/IGroupMessageService.java @@ -24,11 +24,6 @@ public interface IGroupMessageService extends IService { */ void recallMessage(Long id); - /** - * 异步拉取群聊消息,通过websocket异步推送 - */ - void pullUnreadMessage(); - /** * 拉取消息,只能拉取最近1个月的消息,一次拉取100条 * diff --git a/im-platform/src/main/java/com/bx/implatform/service/IPrivateMessageService.java b/im-platform/src/main/java/com/bx/implatform/service/IPrivateMessageService.java index e68e443..f57061d 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/IPrivateMessageService.java +++ b/im-platform/src/main/java/com/bx/implatform/service/IPrivateMessageService.java @@ -35,10 +35,6 @@ public interface IPrivateMessageService extends IService { */ List findHistoryMessage(Long friendId, Long page, Long size); - /** - * 异步拉取私聊消息,通过websocket异步推送 - */ - void pullUnreadMessage(); /** * 拉取消息,只能拉取最近1个月的消息,一次拉取100条 @@ -48,10 +44,18 @@ public interface IPrivateMessageService extends IService { */ List loadMessage(Long minId); + /** * 消息已读,将整个会话的消息都置为已读状态 * * @param friendId 好友id */ void readedMessage(Long friendId); + + /** + * 获取某个会话中已读消息的最大id + * + * @param friendId 好友id + */ + Long getMaxReadedId(Long friendId); } diff --git a/im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java b/im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java index 27a794e..3ca8b03 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java +++ b/im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java @@ -136,41 +136,6 @@ public class GroupMessageServiceImpl extends ServiceImpl 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 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 messages = this.list(wrapper); - if (messages.isEmpty()) { - continue; - } - // 推送 - for (GroupMessage message : messages) { - GroupMessageVO msgInfo = BeanUtils.copyProperties(message, GroupMessageVO.class); - IMGroupMessage 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 loadMessage(Long minId) { @@ -239,7 +204,7 @@ public class GroupMessageServiceImpl extends ServiceImpl friends = friendService.findFriendByUserId(session.getUserId()); - if (friends.isEmpty()) { - return; - } - List friendIds = friends.stream().map(Friend::getFriendId).collect(Collectors.toList()); - // 获取当前用户所有未读消息 - LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); - queryWrapper.eq(PrivateMessage::getRecvId, session.getUserId()) - .eq(PrivateMessage::getStatus, MessageStatus.UNSEND) - .in(PrivateMessage::getSendId, friendIds); - List messages = this.list(queryWrapper); - // 上传至redis,等待推送 - for (PrivateMessage message : messages) { - PrivateMessageVO msgInfo = BeanUtils.copyProperties(message, PrivateMessageVO.class); - // 推送消息 - IMPrivateMessage 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 loadMessage(Long minId) { UserSession session = SessionContext.getSession(); @@ -233,4 +194,21 @@ public class PrivateMessageServiceImpl extends ServiceImpl 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(); + } } diff --git a/im-ui/src/components/chat/ChatBox.vue b/im-ui/src/components/chat/ChatBox.vue index eb401ff..01cd2fe 100644 --- a/im-ui/src/components/chat/ChatBox.vue +++ b/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; diff --git a/im-ui/src/store/chatStore.js b/im-ui/src/store/chatStore.js index 4bb1fd0..26cf9df 100644 --- a/im-ui/src/store/chatStore.js +++ b/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 + } + } }) } diff --git a/im-ui/src/view/Home.vue b/im-ui/src/view/Home.vue index 6448b19..7112d48 100644 --- a/im-ui/src/view/Home.vue +++ b/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; } diff --git a/im-uniapp/App.vue b/im-uniapp/App.vue index 0e05e6c..70db41a 100644 --- a/im-uniapp/App.vue +++ b/im-uniapp/App.vue @@ -119,7 +119,7 @@ store.commit("resetUnreadCount", chatInfo) } else { // 对方已读我的消息,修改消息状态为已读 - store.commit("readedMessage", friendId) + store.commit("readedMessage", {friendId:friendId}) } return; diff --git a/im-uniapp/package.json b/im-uniapp/package.json index 440479f..91b9952 100644 --- a/im-uniapp/package.json +++ b/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": { diff --git a/im-uniapp/pages/chat/chat-box.vue b/im-uniapp/pages/chat/chat-box.vue index dd6a8c6..8342242 100644 --- a/im-uniapp/pages/chat/chat-box.vue +++ b/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() { diff --git a/im-uniapp/store/chatStore.js b/im-uniapp/store/chatStore.js index 2149da2..87761e2 100644 --- a/im-uniapp/store/chatStore.js +++ b/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 + } + } }) }