Commit 43b5de5192bef52a4c3c68edb5e432da90d1e1c5

Authored by YunaiV
1 parent 96ae9bbc

feat(im): 群封禁(GROUP_BANNED)全链路实现

1. ImMessageTypeEnum 新增 GROUP_BANNED(1533) 枚举
2. 新增 GroupBannedNotification 通知 DTO
3. ImGroupMessageSendDTO 新增 ofGroupBanned 工厂方法
4. banGroup / unbanGroup 添加 operatorUserId 参数,
   封禁/解封后广播 GROUP_BANNED 通知到全群成员
5. ImGroupManagerController 传递 getLoginUserId()
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;
26 26  
27 27 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
28 28 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  29 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
29 30  
30 31 @Tag(name = "管理后台 - IM 群聊管理")
31 32 @RestController
... ... @@ -76,7 +77,7 @@ public class ImGroupManagerController {
76 77 @Operation(summary = "封禁群")
77 78 @PreAuthorize("@ss.hasPermission('im:manager:group:ban')")
78 79 public CommonResult<Boolean> banGroup(@Valid @RequestBody ImGroupManagerBanReqVO reqVO) {
79   - groupService.banGroup(reqVO);
  80 + groupService.banGroup(getLoginUserId(), reqVO);
80 81 return success(true);
81 82 }
82 83  
... ... @@ -85,7 +86,7 @@ public class ImGroupManagerController {
85 86 @Parameter(name = "id", description = "群编号", required = true, example = "1024")
86 87 @PreAuthorize("@ss.hasPermission('im:manager:group:ban')")
87 88 public CommonResult<Boolean> unbanGroup(@RequestParam("id") Long id) {
88   - groupService.unbanGroup(id);
  89 + groupService.unbanGroup(getLoginUserId(), id);
89 90 return success(true);
90 91 }
91 92  
... ...
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 {
39 39 @Schema(description = "是否封禁", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
40 40 private Boolean banned;
41 41  
  42 + @Schema(description = "是否全群禁言")
  43 + private Boolean mutedAll;
  44 +
42 45 @Schema(description = "封禁原因")
43 46 private String bannedReason;
44 47  
... ...
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 {
39 39 @Schema(description = "退群时间")
40 40 private LocalDateTime quitTime;
41 41  
  42 + @Schema(description = "禁言到期时间")
  43 + private LocalDateTime muteEndTime;
  44 +
42 45 }
... ...
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java
... ... @@ -227,7 +227,13 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; {
227 227 * 对应自己的类:GroupMessageUnpinNotification
228 228 * 场景:群主 / 管理员取消置顶,全员广播;前端按 messageId 从 group.pinnedMessages 移除
229 229 */
230   - GROUP_MESSAGE_UNPIN(1532, "群消息取消置顶", true, false);
  230 + GROUP_MESSAGE_UNPIN(1532, "群消息取消置顶", true, false),
  231 + /**
  232 + * 对应 OpenIM:无(OpenIM 无群封禁概念,自有扩展)
  233 + * 对应自己的类:GroupBannedNotification
  234 + * 场景:管理后台封禁 / 解封群,全员广播;前端按 banned 字段切换输入栏封禁覆盖层
  235 + */
  236 + GROUP_BANNED(1533, "群封禁变更", true, false);
231 237  
232 238 public static final Integer[] ARRAYS = Arrays.stream(values()).map(ImMessageTypeEnum::getType).toArray(Integer[]::new);
233 239  
... ...
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java
... ... @@ -216,15 +216,17 @@ public interface ImGroupService {
216 216 /**
217 217 * 【管理后台】封禁群
218 218 *
  219 + * @param operatorUserId 操作人用户编号
219 220 * @param banReqVO 封禁信息(含群编号、封禁原因)
220 221 */
221   - void banGroup(@Valid ImGroupManagerBanReqVO banReqVO);
  222 + void banGroup(Long operatorUserId, @Valid ImGroupManagerBanReqVO banReqVO);
222 223  
223 224 /**
224 225 * 【管理后台】解封群
225 226 *
  227 + * @param operatorUserId 操作人用户编号
226 228 * @param id 群编号
227 229 */
228   - void unbanGroup(Long id);
  230 + void unbanGroup(Long operatorUserId, Long id);
229 231  
230 232 }
... ...
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java
... ... @@ -509,25 +509,35 @@ public class ImGroupServiceImpl implements ImGroupService {
509 509  
510 510 @Override
511 511 @CacheEvict(cacheNames = GROUP, key = "#banReqVO.id")
512   - public void banGroup(ImGroupManagerBanReqVO banReqVO) {
  512 + public void banGroup(Long operatorUserId, ImGroupManagerBanReqVO banReqVO) {
513 513 // 1. 校验群存在
514 514 if (getSelf().getGroup(banReqVO.getId()) == null) {
515 515 throw exception(GROUP_NOT_EXISTS);
516 516 }
  517 +
517 518 // 2. 更新封禁状态
518 519 groupMapper.updateById(new ImGroupDO().setId(banReqVO.getId())
519 520 .setBanned(true).setBannedReason(banReqVO.getReason()).setBannedTime(LocalDateTime.now()));
  521 +
  522 + // 3. 广播通知
  523 + groupMessageService.sendGroupMessage(operatorUserId,
  524 + ImGroupMessageSendDTO.ofGroupBanned(banReqVO.getId(), operatorUserId, true));
520 525 }
521 526  
522 527 @Override
523 528 @CacheEvict(cacheNames = GROUP, key = "#id")
524   - public void unbanGroup(Long id) {
  529 + public void unbanGroup(Long operatorUserId, Long id) {
525 530 // 1. 校验群存在
526 531 if (getSelf().getGroup(id) == null) {
527 532 throw exception(GROUP_NOT_EXISTS);
528 533 }
  534 +
529 535 // 2. 解封(保留 bannedReason / bannedTime 作为历史记录)
530 536 groupMapper.updateById(new ImGroupDO().setId(id).setBanned(false));
  537 +
  538 + // 3. 广播通知
  539 + groupMessageService.sendGroupMessage(operatorUserId,
  540 + ImGroupMessageSendDTO.ofGroupBanned(id, operatorUserId, false));
531 541 }
532 542  
533 543 // ==================== 群禁言 ====================
... ...
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/dto/ImGroupMessageSendDTO.java
... ... @@ -207,4 +207,12 @@ public class ImGroupMessageSendDTO {
207 207 .setType(ImMessageTypeEnum.GROUP_CANCEL_MUTED.getType()).setContent(notification);
208 208 }
209 209  
  210 + public static ImGroupMessageSendDTO ofGroupBanned(Long groupId, Long operatorUserId, boolean banned) {
  211 + GroupBannedNotification notification = new GroupBannedNotification();
  212 + notification.setOperatorUserId(operatorUserId);
  213 + notification.setBanned(banned);
  214 + return new ImGroupMessageSendDTO().setGroupId(groupId)
  215 + .setType(ImMessageTypeEnum.GROUP_BANNED.getType()).setContent(notification);
  216 + }
  217 +
210 218 }
... ...
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupBannedNotification.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group;
  2 +
  3 +import lombok.Data;
  4 +
  5 +/**
  6 + * 群封禁 / 解封通知
  7 + */
  8 +@Data
  9 +public class GroupBannedNotification extends BaseGroupNotification {
  10 +
  11 + /**
  12 + * 是否封禁
  13 + */
  14 + private Boolean banned;
  15 +
  16 +}
... ...