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,6 +26,7 @@ import java.util.Map;
26 26
27 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 27 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
28 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 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 @Tag(name = "管理后台 - IM 群聊管理") 31 @Tag(name = "管理后台 - IM 群聊管理")
31 @RestController 32 @RestController
@@ -76,7 +77,7 @@ public class ImGroupManagerController { @@ -76,7 +77,7 @@ public class ImGroupManagerController {
76 @Operation(summary = "封禁群") 77 @Operation(summary = "封禁群")
77 @PreAuthorize("@ss.hasPermission('im:manager:group:ban')") 78 @PreAuthorize("@ss.hasPermission('im:manager:group:ban')")
78 public CommonResult<Boolean> banGroup(@Valid @RequestBody ImGroupManagerBanReqVO reqVO) { 79 public CommonResult<Boolean> banGroup(@Valid @RequestBody ImGroupManagerBanReqVO reqVO) {
79 - groupService.banGroup(reqVO); 80 + groupService.banGroup(getLoginUserId(), reqVO);
80 return success(true); 81 return success(true);
81 } 82 }
82 83
@@ -85,7 +86,7 @@ public class ImGroupManagerController { @@ -85,7 +86,7 @@ public class ImGroupManagerController {
85 @Parameter(name = "id", description = "群编号", required = true, example = "1024") 86 @Parameter(name = "id", description = "群编号", required = true, example = "1024")
86 @PreAuthorize("@ss.hasPermission('im:manager:group:ban')") 87 @PreAuthorize("@ss.hasPermission('im:manager:group:ban')")
87 public CommonResult<Boolean> unbanGroup(@RequestParam("id") Long id) { 88 public CommonResult<Boolean> unbanGroup(@RequestParam("id") Long id) {
88 - groupService.unbanGroup(id); 89 + groupService.unbanGroup(getLoginUserId(), id);
89 return success(true); 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,6 +39,9 @@ public class ImGroupManagerRespVO {
39 @Schema(description = "是否封禁", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") 39 @Schema(description = "是否封禁", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
40 private Boolean banned; 40 private Boolean banned;
41 41
  42 + @Schema(description = "是否全群禁言")
  43 + private Boolean mutedAll;
  44 +
42 @Schema(description = "封禁原因") 45 @Schema(description = "封禁原因")
43 private String bannedReason; 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,4 +39,7 @@ public class ImGroupMemberManagerRespVO {
39 @Schema(description = "退群时间") 39 @Schema(description = "退群时间")
40 private LocalDateTime quitTime; 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,7 +227,13 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; {
227 * 对应自己的类:GroupMessageUnpinNotification 227 * 对应自己的类:GroupMessageUnpinNotification
228 * 场景:群主 / 管理员取消置顶,全员广播;前端按 messageId 从 group.pinnedMessages 移除 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 public static final Integer[] ARRAYS = Arrays.stream(values()).map(ImMessageTypeEnum::getType).toArray(Integer[]::new); 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,15 +216,17 @@ public interface ImGroupService {
216 /** 216 /**
217 * 【管理后台】封禁群 217 * 【管理后台】封禁群
218 * 218 *
  219 + * @param operatorUserId 操作人用户编号
219 * @param banReqVO 封禁信息(含群编号、封禁原因) 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 * @param id 群编号 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,25 +509,35 @@ public class ImGroupServiceImpl implements ImGroupService {
509 509
510 @Override 510 @Override
511 @CacheEvict(cacheNames = GROUP, key = "#banReqVO.id") 511 @CacheEvict(cacheNames = GROUP, key = "#banReqVO.id")
512 - public void banGroup(ImGroupManagerBanReqVO banReqVO) { 512 + public void banGroup(Long operatorUserId, ImGroupManagerBanReqVO banReqVO) {
513 // 1. 校验群存在 513 // 1. 校验群存在
514 if (getSelf().getGroup(banReqVO.getId()) == null) { 514 if (getSelf().getGroup(banReqVO.getId()) == null) {
515 throw exception(GROUP_NOT_EXISTS); 515 throw exception(GROUP_NOT_EXISTS);
516 } 516 }
  517 +
517 // 2. 更新封禁状态 518 // 2. 更新封禁状态
518 groupMapper.updateById(new ImGroupDO().setId(banReqVO.getId()) 519 groupMapper.updateById(new ImGroupDO().setId(banReqVO.getId())
519 .setBanned(true).setBannedReason(banReqVO.getReason()).setBannedTime(LocalDateTime.now())); 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 @Override 527 @Override
523 @CacheEvict(cacheNames = GROUP, key = "#id") 528 @CacheEvict(cacheNames = GROUP, key = "#id")
524 - public void unbanGroup(Long id) { 529 + public void unbanGroup(Long operatorUserId, Long id) {
525 // 1. 校验群存在 530 // 1. 校验群存在
526 if (getSelf().getGroup(id) == null) { 531 if (getSelf().getGroup(id) == null) {
527 throw exception(GROUP_NOT_EXISTS); 532 throw exception(GROUP_NOT_EXISTS);
528 } 533 }
  534 +
529 // 2. 解封(保留 bannedReason / bannedTime 作为历史记录) 535 // 2. 解封(保留 bannedReason / bannedTime 作为历史记录)
530 groupMapper.updateById(new ImGroupDO().setId(id).setBanned(false)); 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,4 +207,12 @@ public class ImGroupMessageSendDTO {
207 .setType(ImMessageTypeEnum.GROUP_CANCEL_MUTED.getType()).setContent(notification); 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 +}