Browse Source

修复离线已读消息状态的bug

master
xie.bx 2 years ago
parent
commit
8f7b1ba025
  1. 7
      im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java
  2. 14
      im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java
  3. 7
      im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java
  4. 6
      im-platform/src/main/java/com/bx/implatform/service/IGroupMessageService.java
  5. 12
      im-platform/src/main/java/com/bx/implatform/service/IPrivateMessageService.java
  6. 37
      im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java
  7. 61
      im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java
  8. 17
      im-ui/src/components/chat/ChatBox.vue
  9. 8
      im-ui/src/store/chatStore.js
  10. 2
      im-ui/src/view/Home.vue
  11. 2
      im-uniapp/App.vue
  12. 12
      im-uniapp/pages/chat/chat-box.vue
  13. 8
      im-uniapp/store/chatStore.js

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

@ -37,13 +37,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条")

14
im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java

@ -36,14 +36,6 @@ public class PrivateMessageController {
return ResultUtils.success();
}
// todo 删除
@PostMapping("/pullUnreadMessage")
@ApiOperation(value = "拉取未读消息",notes="拉取未读消息")
public Result pullUnreadMessage(){
privateMessageService.pullUnreadMessage();
return ResultUtils.success();
}
@GetMapping("/loadMessage")
@ApiOperation(value = "拉取消息",notes="拉取消息,一次最多拉取100条")
@ -58,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,

7
im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java

@ -22,12 +22,7 @@ public class GroupMessageListener implements MessageListener<GroupMessageVO> {
@Override
public void process(IMSendResult<GroupMessageVO> result){
GroupMessageVO messageInfo = result.getData();
// todo 删除
// 保存该用户已拉取的最大消息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());
}
// 空空如也
}
}

6
im-platform/src/main/java/com/bx/implatform/service/IGroupMessageService.java

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

12
im-platform/src/main/java/com/bx/implatform/service/IPrivateMessageService.java

@ -36,10 +36,6 @@ public interface IPrivateMessageService extends IService<PrivateMessage> {
*/
List<PrivateMessageVO> findHistoryMessage(Long friendId, Long page,Long size);
/**
* 异步拉取私聊消息通过websocket异步推送
*/
void pullUnreadMessage();
/**
* 拉取消息只能拉取最近1个月的消息一次拉取100条
@ -49,10 +45,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);
}

37
im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java

@ -133,41 +133,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) {
@ -234,7 +199,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 = StrUtil.join(":", RedisKey.IM_GROUP_READED_POSITION, groupId, session.getUserId());

61
im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java

@ -29,10 +29,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
@ -107,7 +104,6 @@ public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper,
}
@Override
public List<PrivateMessageVO> findHistoryMessage(Long friendId, Long page, Long size) {
page = page > 0 ? page : 1;
@ -131,43 +127,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();
@ -208,7 +167,6 @@ public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper,
}
@Transactional(rollbackFor = Exception.class)
@Override
public void readedMessage(Long friendId) {
@ -235,4 +193,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();
}
}

17
im-ui/src/components/chat/ChatBox.vue

@ -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;
@ -784,6 +798,7 @@
.send-image-area {
text-align: left;
border: #53a0e7 solid 1px;
.send-image-box {
position: relative;
display: inline-block;

8
im-ui/src/store/chatStore.js

@ -70,14 +70,18 @@ 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) {
// pos.maxId为空表示整个会话已读
if(!pos.maxId || m.id <= pos.maxId){
m.status = MESSAGE_STATUS.READED
}
}
})
}
}

2
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;
}

2
im-uniapp/App.vue

@ -119,7 +119,7 @@
store.commit("resetUnreadCount", chatInfo)
} else {
//
store.commit("readedMessage", friendId)
store.commit("readedMessage", {friendId:friendId})
}
return;

12
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() {

8
im-uniapp/store/chatStore.js

@ -75,14 +75,18 @@ 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) {
// pos.maxId为空表示整个会话已读
if(!pos.maxId || m.id <= pos.maxId){
m.status = MESSAGE_STATUS.READED
}
}
})
}
}

Loading…
Cancel
Save