Commit 43b5de5192bef52a4c3c68edb5e432da90d1e1c5
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()
Showing
8 changed files
with
56 additions
and
7 deletions
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<Integer> { | @@ -227,7 +227,13 @@ public enum ImMessageTypeEnum implements ArrayValuable<Integer> { | ||
| 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