Commit cce3dd61108431a91d2586de6a51e180965b8f37

Authored by YunaiV
1 parent 443d91d7

✨ feat(group): 添加群消息已读位置管理功能

新增删除用户在群中的已读位置和清理群所有用户已读位置的功能,支持成员退群和群解散场景。此功能提升了群消息管理的灵活性和用户体验。
yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java
... ... @@ -26,10 +26,14 @@ public enum ImMessageTypeEnum implements ArrayValuable<Integer> {
26 26 RECEIPT(12, "回执"), // 暂无
27 27 TIP_TEXT(21, "提示文本"), // 对应 TextMessage 类
28 28  
29   - RECALL(10, "撤回"),
30   - READ(11, "已读"),
31   - RECEIPT(12, "回执"),
32   - TIP_TEXT(21, "提示文本");
  29 + // ==================== 非单聊、群聊存储的类型,100 开始 ====================
  30 +
  31 + FRIEND_ADD(100, "好友添加"), // 暂无
  32 + FRIEND_DELETE(101, "好友删除"), // 暂无
  33 + FRIEND_UPDATE(102, "好友更新"), // 对应 FriendUpdateMessage 类
  34 +
  35 + GROUP_CREATE(200, "群创建"), // 暂无
  36 + GROUP_UPDATE(201, "群信息变更"); // 暂无
33 37  
34 38 public static final Integer[] ARRAYS = Arrays.stream(values()).map(ImMessageTypeEnum::getType).toArray(Integer[]::new);
35 39  
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/message/GroupMessageReadRedisDAO.java
... ... @@ -61,6 +61,27 @@ public class GroupMessageReadRedisDAO {
61 61 return result;
62 62 }
63 63  
  64 + /**
  65 + * 删除用户在某群的已读位置
  66 + *
  67 + * @param groupId 群编号
  68 + * @param userId 用户编号
  69 + */
  70 + public void deleteReadMaxMessageId(Long groupId, Long userId) {
  71 + String key = formatKey(groupId);
  72 + stringRedisTemplate.opsForHash().delete(key, userId.toString());
  73 + }
  74 +
  75 + /**
  76 + * 删除某群所有用户的已读位置(整个 Hash Key)
  77 + *
  78 + * @param groupId 群编号
  79 + */
  80 + public void deleteReadMaxMessageIdMap(Long groupId) {
  81 + String key = formatKey(groupId);
  82 + stringRedisTemplate.delete(key);
  83 + }
  84 +
64 85 private static String formatKey(Long groupId) {
65 86 return String.format(GROUP_MESSAGE_READ, groupId);
66 87 }
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImpl.java
... ... @@ -73,7 +73,6 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService {
73 73 return imGroupMemberMapper.selectById(id);
74 74 }
75 75  
76   -
77 76 @Override
78 77 public List<ImGroupMemberDO> getGroupMemberListByGroupId(Long groupId) {
79 78 return imGroupMemberMapper.selectListByGroupId(groupId);
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java
... ... @@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupUpdateReqVO;
12 12 import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO;
13 13 import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO;
14 14 import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMapper;
  15 +import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService;
15 16 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
16 17 import cn.iocoder.yudao.module.im.service.websocket.dto.ImGroupMessageDTO;
17 18 import jakarta.annotation.Resource;
... ... @@ -33,7 +34,6 @@ import static cn.iocoder.yudao.module.im.dal.redis.RedisKeyConstants.GROUP;
33 34 import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*;
34 35  
35 36 // TODO @芋艿:群主的调整,暂时不考虑。后续在弄;
36   -// DONE @AI:groupdo 增加一个缓存;spring cache 实现;
37 37 /**
38 38 * 群 Service 实现类
39 39 *
... ... @@ -50,6 +50,9 @@ public class ImGroupServiceImpl implements ImGroupService {
50 50 @Lazy // 避免循环依赖
51 51 private ImGroupMemberService groupMemberService;
52 52 @Resource
  53 + @Lazy // 避免循环依赖
  54 + private ImGroupMessageService groupMessageService;
  55 + @Resource
53 56 private ImWebSocketService webSocketService;
54 57  
55 58 @Override
... ... @@ -125,7 +128,8 @@ public class ImGroupServiceImpl implements ImGroupService {
125 128 updateObj.setDissolvedTime(LocalDateTime.now());
126 129 groupMapper.updateById(updateObj);
127 130  
128   - // TODO @AI:清理已读缓存;
  131 + // 4. 清理已读缓存
  132 + groupMessageService.deleteReadMaxMessageIdMap(id);
129 133 // TODO @AI:推送群解散的提示;
130 134 // TODO @AI:推送群信息变化;
131 135 }
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageService.java
... ... @@ -69,4 +69,24 @@ public interface ImGroupMessageService {
69 69 */
70 70 List<ImGroupMessageDO> getGroupMessageList(Long userId, ImGroupMessageListReqVO reqVO);
71 71  
  72 + /**
  73 + * 清理用户在某群的已读位置缓存
  74 + * <p>
  75 + * 用于成员退群场景
  76 + *
  77 + * @param groupId 群编号
  78 + * @param userId 用户编号
  79 + */
  80 + void deleteReadMaxMessageId(Long groupId, Long userId);
  81 +
  82 + /**
  83 + * 清理某群所有用户的已读位置缓存
  84 + * <p>
  85 + * 用于群解散场景
  86 + *
  87 + * @param groupId 群编号
  88 + */
  89 + void deleteReadMaxMessageIdMap(Long groupId);
  90 +
72 91 }
  92 +
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImpl.java
... ... @@ -471,9 +471,18 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
471 471 member -> isMessageVisible(msg, member, member.getUserId()));
472 472 }
473 473  
  474 + @Override
  475 + public void deleteReadMaxMessageId(Long groupId, Long userId) {
  476 + groupMessageReadRedisDAO.deleteReadMaxMessageId(groupId, userId);
  477 + }
  478 +
  479 + @Override
  480 + public void deleteReadMaxMessageIdMap(Long groupId) {
  481 + groupMessageReadRedisDAO.deleteReadMaxMessageIdMap(groupId);
  482 + }
474 483  
475 484 private ImGroupMessageServiceImpl getSelf() {
476 485 return SpringUtil.getBean(getClass());
477 486 }
478 487  
479 488 -}
  489 +}
480 490 \ No newline at end of file
... ...