Commit 4d2f470499f38894d040055747544ff699a7f626

Authored by YunaiV
1 parent 6e823f84

✨ feat(im): 增加群消息的置顶

yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java
... ... @@ -2,15 +2,8 @@ package cn.iocoder.yudao.module.im.controller.admin.group;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7   -import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupAdminAddReqVO;
8   -import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupAdminRemoveReqVO;
9   -import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupCreateReqVO;
10   -import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupMessagePinReqVO;
11   -import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupRespVO;
12   -import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupTransferOwnerReqVO;
13   -import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupUpdateReqVO;
  6 +import cn.iocoder.yudao.module.im.controller.admin.group.vo.*;
14 7 import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberInviteReqVO;
15 8 import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberRemoveReqVO;
16 9 import cn.iocoder.yudao.module.im.controller.admin.message.vo.group.ImGroupMessageRespVO;
... ... @@ -28,17 +21,11 @@ import jakarta.validation.Valid;
28 21 import org.springframework.validation.annotation.Validated;
29 22 import org.springframework.web.bind.annotation.*;
30 23  
31   -import java.util.Collections;
32   -import java.util.List;
33   -import java.util.Map;
34   -import java.util.Objects;
35   -import java.util.Set;
36   -import java.util.stream.Collectors;
  24 +import java.util.*;
37 25 import java.util.stream.Stream;
38 26  
39 27 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
40   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
41   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
  28 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
42 29 import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
43 30  
44 31 @Tag(name = "管理后台 - 群")
... ... @@ -175,25 +162,21 @@ public class ImGroupController {
175 162 if (CollUtil.isEmpty(groups)) {
176 163 return Collections.emptyList();
177 164 }
178   - // 仅当前用户是有效成员的群才允许回填置顶消息(按 groupId 一次性 IN 查成员关系)
  165 + // 仅当前用户是有效成员的群才允许回填置顶消息
179 166 Set<Long> activeGroupIds = convertSet(
180 167 groupMemberService.getActiveGroupMemberListByUserId(loginUserId), ImGroupMemberDO::getGroupId);
181   - // 把 active 群的 pinnedMessageIds 一次性聚合 IN 查询,避免 N+1
182 168 Set<Long> allMessageIds = convertSetByFlatMap(groups, group -> activeGroupIds.contains(group.getId())
183 169 ? CollUtil.emptyIfNull(group.getPinnedMessageIds()).stream() : Stream.empty());
184 170 Map<Long, ImGroupMessageDO> messageMap = groupMessageService.getGroupMessageMap(allMessageIds);
185   - return CollectionUtils.convertList(groups, group -> {
  171 + // 转换输出
  172 + return convertList(groups, group -> {
186 173 ImGroupRespVO vo = BeanUtils.toBean(group, ImGroupRespVO.class);
187 174 if (!activeGroupIds.contains(group.getId()) || CollUtil.isEmpty(group.getPinnedMessageIds())) {
188 175 return vo;
189 176 }
190 177 // 按 pin 顺序输出,已被删除的消息(messageMap 没命中)跳过
191   - // TODO @AI:使用 CollUtils convert 进一步简化。
192   - List<ImGroupMessageRespVO> pinned = group.getPinnedMessageIds().stream()
193   - .map(messageMap::get).filter(Objects::nonNull)
194   - .map(msg -> BeanUtils.toBean(msg, ImGroupMessageRespVO.class))
195   - .collect(Collectors.toList());
196   - return vo.setPinnedMessages(pinned);
  178 + List<ImGroupMessageDO> pinnedMesages = convertList(group.getPinnedMessageIds(), messageMap::get);
  179 + return vo.setPinnedMessages(BeanUtils.toBean(pinnedMesages, ImGroupMessageRespVO.class));
197 180 });
198 181 }
199 182  
... ...
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImGroupMessageController.java
... ... @@ -64,8 +64,7 @@ public class ImGroupMessageController {
64 64 return success(BeanUtils.toBean(message, ImGroupMessageRespVO.class));
65 65 }
66 66  
67   - // TODO @AI:改成 get-read-user-ids
68   - @GetMapping("/read-users")
  67 + @GetMapping("/get-read-user-ids")
69 68 @Operation(summary = "获取群消息已读用户列表")
70 69 @Parameter(name = "groupId", description = "群编号", required = true, example = "1")
71 70 @Parameter(name = "messageId", description = "消息编号", required = true, example = "1")
... ...
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java
... ... @@ -160,13 +160,16 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; {
160 160 * 场景:用户改自己的群免打扰 / 群备注,仅推该用户其他在线终端做多端同步
161 161 */
162 162 GROUP_MEMBER_SETTING_UPDATE(1530, "群成员个人设置变更", false, false),
163   - // TODO @AI:注释风格,还是参考上面的
164 163 /**
165   - * 自有扩展:群主 / 管理员置顶一条群消息,全员广播;前端把 messageId 加入 group.pinnedMessageIds
  164 + * 对应 OpenIM:无(OpenIM 无群消息置顶功能,自有扩展)
  165 + * 对应自己的类:GroupMessagePinNotification
  166 + * 场景:群主 / 管理员置顶一条群消息,全员广播;payload 直接带消息对象,前端把 message push 进 group.pinnedMessages
166 167 */
167 168 GROUP_MESSAGE_PIN(1531, "群消息置顶", true, false),
168 169 /**
169   - * 自有扩展:群主 / 管理员取消置顶,全员广播;前端把 messageId 从 group.pinnedMessageIds 移除
  170 + * 对应 OpenIM:无(OpenIM 无群消息置顶功能,自有扩展)
  171 + * 对应自己的类:GroupMessageUnpinNotification
  172 + * 场景:群主 / 管理员取消置顶,全员广播;前端按 messageId 从 group.pinnedMessages 移除
170 173 */
171 174 GROUP_MESSAGE_UNPIN(1532, "群消息取消置顶", true, false);
172 175  
... ...