From 43b5de5192bef52a4c3c68edb5e432da90d1e1c5 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 5 May 2026 18:41:11 +0800 Subject: [PATCH] feat(im): 群封禁(GROUP_BANNED)全链路实现 --- yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/ImGroupManagerController.java | 5 +++-- yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/vo/ImGroupManagerRespVO.java | 3 +++ yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/vo/member/ImGroupMemberManagerRespVO.java | 3 +++ yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java | 8 +++++++- yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java | 6 ++++-- yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java | 14 ++++++++++++-- yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/dto/ImGroupMessageSendDTO.java | 8 ++++++++ yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupBannedNotification.java | 16 ++++++++++++++++ 8 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupBannedNotification.java diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/ImGroupManagerController.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/ImGroupManagerController.java index 1da326d..0bf3d1c 100644 --- a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/ImGroupManagerController.java +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/ImGroupManagerController.java @@ -26,6 +26,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "管理后台 - IM 群聊管理") @RestController @@ -76,7 +77,7 @@ public class ImGroupManagerController { @Operation(summary = "封禁群") @PreAuthorize("@ss.hasPermission('im:manager:group:ban')") public CommonResult banGroup(@Valid @RequestBody ImGroupManagerBanReqVO reqVO) { - groupService.banGroup(reqVO); + groupService.banGroup(getLoginUserId(), reqVO); return success(true); } @@ -85,7 +86,7 @@ public class ImGroupManagerController { @Parameter(name = "id", description = "群编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('im:manager:group:ban')") public CommonResult unbanGroup(@RequestParam("id") Long id) { - groupService.unbanGroup(id); + groupService.unbanGroup(getLoginUserId(), id); return success(true); } diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/vo/ImGroupManagerRespVO.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/vo/ImGroupManagerRespVO.java index 22649fd..c1de792 100644 --- a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/vo/ImGroupManagerRespVO.java +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/vo/ImGroupManagerRespVO.java @@ -39,6 +39,9 @@ public class ImGroupManagerRespVO { @Schema(description = "是否封禁", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") private Boolean banned; + @Schema(description = "是否全群禁言") + private Boolean mutedAll; + @Schema(description = "封禁原因") private String bannedReason; diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/vo/member/ImGroupMemberManagerRespVO.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/vo/member/ImGroupMemberManagerRespVO.java index e564f1d..b5d1346 100644 --- a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/vo/member/ImGroupMemberManagerRespVO.java +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/vo/member/ImGroupMemberManagerRespVO.java @@ -39,4 +39,7 @@ public class ImGroupMemberManagerRespVO { @Schema(description = "退群时间") private LocalDateTime quitTime; + @Schema(description = "禁言到期时间") + private LocalDateTime muteEndTime; + } diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java index b14eb4a..4ffc803 100644 --- a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java @@ -227,7 +227,13 @@ public enum ImMessageTypeEnum implements ArrayValuable { * 对应自己的类:GroupMessageUnpinNotification * 场景:群主 / 管理员取消置顶,全员广播;前端按 messageId 从 group.pinnedMessages 移除 */ - GROUP_MESSAGE_UNPIN(1532, "群消息取消置顶", true, false); + GROUP_MESSAGE_UNPIN(1532, "群消息取消置顶", true, false), + /** + * 对应 OpenIM:无(OpenIM 无群封禁概念,自有扩展) + * 对应自己的类:GroupBannedNotification + * 场景:管理后台封禁 / 解封群,全员广播;前端按 banned 字段切换输入栏封禁覆盖层 + */ + GROUP_BANNED(1533, "群封禁变更", true, false); public static final Integer[] ARRAYS = Arrays.stream(values()).map(ImMessageTypeEnum::getType).toArray(Integer[]::new); diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java index 6c5fed2..07208a9 100644 --- a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java @@ -216,15 +216,17 @@ public interface ImGroupService { /** * 【管理后台】封禁群 * + * @param operatorUserId 操作人用户编号 * @param banReqVO 封禁信息(含群编号、封禁原因) */ - void banGroup(@Valid ImGroupManagerBanReqVO banReqVO); + void banGroup(Long operatorUserId, @Valid ImGroupManagerBanReqVO banReqVO); /** * 【管理后台】解封群 * + * @param operatorUserId 操作人用户编号 * @param id 群编号 */ - void unbanGroup(Long id); + void unbanGroup(Long operatorUserId, Long id); } diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java index 7db533d..8938672 100644 --- a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java @@ -509,25 +509,35 @@ public class ImGroupServiceImpl implements ImGroupService { @Override @CacheEvict(cacheNames = GROUP, key = "#banReqVO.id") - public void banGroup(ImGroupManagerBanReqVO banReqVO) { + public void banGroup(Long operatorUserId, ImGroupManagerBanReqVO banReqVO) { // 1. 校验群存在 if (getSelf().getGroup(banReqVO.getId()) == null) { throw exception(GROUP_NOT_EXISTS); } + // 2. 更新封禁状态 groupMapper.updateById(new ImGroupDO().setId(banReqVO.getId()) .setBanned(true).setBannedReason(banReqVO.getReason()).setBannedTime(LocalDateTime.now())); + + // 3. 广播通知 + groupMessageService.sendGroupMessage(operatorUserId, + ImGroupMessageSendDTO.ofGroupBanned(banReqVO.getId(), operatorUserId, true)); } @Override @CacheEvict(cacheNames = GROUP, key = "#id") - public void unbanGroup(Long id) { + public void unbanGroup(Long operatorUserId, Long id) { // 1. 校验群存在 if (getSelf().getGroup(id) == null) { throw exception(GROUP_NOT_EXISTS); } + // 2. 解封(保留 bannedReason / bannedTime 作为历史记录) groupMapper.updateById(new ImGroupDO().setId(id).setBanned(false)); + + // 3. 广播通知 + groupMessageService.sendGroupMessage(operatorUserId, + ImGroupMessageSendDTO.ofGroupBanned(id, operatorUserId, false)); } // ==================== 群禁言 ==================== diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/dto/ImGroupMessageSendDTO.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/dto/ImGroupMessageSendDTO.java index 95f4820..e08ac7a 100644 --- a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/dto/ImGroupMessageSendDTO.java +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/dto/ImGroupMessageSendDTO.java @@ -207,4 +207,12 @@ public class ImGroupMessageSendDTO { .setType(ImMessageTypeEnum.GROUP_CANCEL_MUTED.getType()).setContent(notification); } + public static ImGroupMessageSendDTO ofGroupBanned(Long groupId, Long operatorUserId, boolean banned) { + GroupBannedNotification notification = new GroupBannedNotification(); + notification.setOperatorUserId(operatorUserId); + notification.setBanned(banned); + return new ImGroupMessageSendDTO().setGroupId(groupId) + .setType(ImMessageTypeEnum.GROUP_BANNED.getType()).setContent(notification); + } + } diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupBannedNotification.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupBannedNotification.java new file mode 100644 index 0000000..bdfe9d5 --- /dev/null +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupBannedNotification.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; + +import lombok.Data; + +/** + * 群封禁 / 解封通知 + */ +@Data +public class GroupBannedNotification extends BaseGroupNotification { + + /** + * 是否封禁 + */ + private Boolean banned; + +} -- libgit2 0.21.4