Commit 84304718dc19627516fab687d7c010c9eade9b81
1 parent
b814a873
✨ feat(group): 支持批量邀请和移除群成员
Showing
11 changed files
with
213 additions
and
49 deletions
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java
| @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupCreateReqVO; | @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupCreateReqVO; | ||
| 6 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupRespVO; | 6 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupRespVO; |
| 7 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupUpdateReqVO; | 7 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupUpdateReqVO; |
| 8 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberInviteReqVO; | 8 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberInviteReqVO; |
| 9 | +import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberRemoveReqVO; | ||
| 9 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; | 10 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; |
| 10 | import cn.iocoder.yudao.module.im.service.group.ImGroupService; | 11 | import cn.iocoder.yudao.module.im.service.group.ImGroupService; |
| 11 | import io.swagger.v3.oas.annotations.Operation; | 12 | import io.swagger.v3.oas.annotations.Operation; |
| @@ -29,7 +30,7 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLogi | @@ -29,7 +30,7 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLogi | ||
| 29 | public class ImGroupController { | 30 | public class ImGroupController { |
| 30 | 31 | ||
| 31 | @Resource | 32 | @Resource |
| 32 | - private ImGroupService imGroupService; | 33 | + private ImGroupService groupService; |
| 33 | 34 | ||
| 34 | // ==================== 群的写操作 ==================== | 35 | // ==================== 群的写操作 ==================== |
| 35 | 36 | ||
| @@ -37,7 +38,7 @@ public class ImGroupController { | @@ -37,7 +38,7 @@ public class ImGroupController { | ||
| 37 | @Operation(summary = "创建群") | 38 | @Operation(summary = "创建群") |
| 38 | @PreAuthorize("@ss.hasPermission('im:group:create')") | 39 | @PreAuthorize("@ss.hasPermission('im:group:create')") |
| 39 | public CommonResult<ImGroupRespVO> createGroup(@Valid @RequestBody ImGroupCreateReqVO createReqVO) { | 40 | public CommonResult<ImGroupRespVO> createGroup(@Valid @RequestBody ImGroupCreateReqVO createReqVO) { |
| 40 | - ImGroupDO group = imGroupService.createGroup(createReqVO, getLoginUserId()); | 41 | + ImGroupDO group = groupService.createGroup(createReqVO, getLoginUserId()); |
| 41 | return success(BeanUtils.toBean(group, ImGroupRespVO.class)); | 42 | return success(BeanUtils.toBean(group, ImGroupRespVO.class)); |
| 42 | } | 43 | } |
| 43 | 44 | ||
| @@ -45,7 +46,7 @@ public class ImGroupController { | @@ -45,7 +46,7 @@ public class ImGroupController { | ||
| 45 | @Operation(summary = "更新群") | 46 | @Operation(summary = "更新群") |
| 46 | @PreAuthorize("@ss.hasPermission('im:group:update')") | 47 | @PreAuthorize("@ss.hasPermission('im:group:update')") |
| 47 | public CommonResult<ImGroupRespVO> updateGroup(@Valid @RequestBody ImGroupUpdateReqVO updateReqVO) { | 48 | public CommonResult<ImGroupRespVO> updateGroup(@Valid @RequestBody ImGroupUpdateReqVO updateReqVO) { |
| 48 | - ImGroupDO group = imGroupService.updateGroup(updateReqVO, getLoginUserId()); | 49 | + ImGroupDO group = groupService.updateGroup(updateReqVO, getLoginUserId()); |
| 49 | return success(BeanUtils.toBean(group, ImGroupRespVO.class)); | 50 | return success(BeanUtils.toBean(group, ImGroupRespVO.class)); |
| 50 | } | 51 | } |
| 51 | 52 | ||
| @@ -54,7 +55,7 @@ public class ImGroupController { | @@ -54,7 +55,7 @@ public class ImGroupController { | ||
| 54 | @Parameter(name = "id", description = "群编号", required = true) | 55 | @Parameter(name = "id", description = "群编号", required = true) |
| 55 | @PreAuthorize("@ss.hasPermission('im:group:delete')") | 56 | @PreAuthorize("@ss.hasPermission('im:group:delete')") |
| 56 | public CommonResult<Boolean> dissolveGroup(@RequestParam("id") Long id) { | 57 | public CommonResult<Boolean> dissolveGroup(@RequestParam("id") Long id) { |
| 57 | - imGroupService.dissolveGroup(id, getLoginUserId()); | 58 | + groupService.dissolveGroup(id, getLoginUserId()); |
| 58 | return success(true); | 59 | return success(true); |
| 59 | } | 60 | } |
| 60 | 61 | ||
| @@ -65,14 +66,14 @@ public class ImGroupController { | @@ -65,14 +66,14 @@ public class ImGroupController { | ||
| 65 | @Parameter(name = "id", description = "编号", required = true, example = "1024") | 66 | @Parameter(name = "id", description = "编号", required = true, example = "1024") |
| 66 | @PreAuthorize("@ss.hasPermission('im:group:query')") | 67 | @PreAuthorize("@ss.hasPermission('im:group:query')") |
| 67 | public CommonResult<ImGroupRespVO> getGroup(@RequestParam("id") Long id) { | 68 | public CommonResult<ImGroupRespVO> getGroup(@RequestParam("id") Long id) { |
| 68 | - ImGroupDO group = imGroupService.getGroup(id); | 69 | + ImGroupDO group = groupService.getGroup(id); |
| 69 | return success(BeanUtils.toBean(group, ImGroupRespVO.class)); | 70 | return success(BeanUtils.toBean(group, ImGroupRespVO.class)); |
| 70 | } | 71 | } |
| 71 | 72 | ||
| 72 | @GetMapping("/list") | 73 | @GetMapping("/list") |
| 73 | @Operation(summary = "获得当前登录用户的群列表") | 74 | @Operation(summary = "获得当前登录用户的群列表") |
| 74 | public CommonResult<List<ImGroupRespVO>> getMyGroupList() { | 75 | public CommonResult<List<ImGroupRespVO>> getMyGroupList() { |
| 75 | - List<ImGroupDO> groups = imGroupService.getActiveGroupList(getLoginUserId()); | 76 | + List<ImGroupDO> groups = groupService.getActiveGroupList(getLoginUserId()); |
| 76 | return success(BeanUtils.toBean(groups, ImGroupRespVO.class)); | 77 | return success(BeanUtils.toBean(groups, ImGroupRespVO.class)); |
| 77 | } | 78 | } |
| 78 | 79 | ||
| @@ -81,8 +82,9 @@ public class ImGroupController { | @@ -81,8 +82,9 @@ public class ImGroupController { | ||
| 81 | @PostMapping("/invite") | 82 | @PostMapping("/invite") |
| 82 | @Operation(summary = "邀请用户加入群") | 83 | @Operation(summary = "邀请用户加入群") |
| 83 | @PreAuthorize("@ss.hasPermission('im:group:update')") | 84 | @PreAuthorize("@ss.hasPermission('im:group:update')") |
| 84 | - public CommonResult<Long> inviteGroupMember(@Valid @RequestBody ImGroupMemberInviteReqVO inviteReqVO) { | ||
| 85 | - return success(imGroupService.inviteGroupMember(getLoginUserId(), inviteReqVO)); | 85 | + public CommonResult<Boolean> inviteGroupMember(@Valid @RequestBody ImGroupMemberInviteReqVO inviteReqVO) { |
| 86 | + groupService.inviteGroupMember(getLoginUserId(), inviteReqVO); | ||
| 87 | + return success(true); | ||
| 86 | } | 88 | } |
| 87 | 89 | ||
| 88 | @DeleteMapping("/quit") | 90 | @DeleteMapping("/quit") |
| @@ -90,16 +92,15 @@ public class ImGroupController { | @@ -90,16 +92,15 @@ public class ImGroupController { | ||
| 90 | @Parameter(name = "groupId", description = "群编号", required = true) | 92 | @Parameter(name = "groupId", description = "群编号", required = true) |
| 91 | @PreAuthorize("@ss.hasPermission('im:group:update')") | 93 | @PreAuthorize("@ss.hasPermission('im:group:update')") |
| 92 | public CommonResult<Boolean> quitGroup(@RequestParam("groupId") Long groupId) { | 94 | public CommonResult<Boolean> quitGroup(@RequestParam("groupId") Long groupId) { |
| 93 | - imGroupService.quitGroup(groupId, getLoginUserId()); | 95 | + groupService.quitGroup(groupId, getLoginUserId()); |
| 94 | return success(true); | 96 | return success(true); |
| 95 | } | 97 | } |
| 96 | 98 | ||
| 97 | @DeleteMapping("/kicking") | 99 | @DeleteMapping("/kicking") |
| 98 | @Operation(summary = "移除群成员") | 100 | @Operation(summary = "移除群成员") |
| 99 | @PreAuthorize("@ss.hasPermission('im:group:update')") | 101 | @PreAuthorize("@ss.hasPermission('im:group:update')") |
| 100 | - public CommonResult<Boolean> removeGroupMember(@RequestParam("groupId") Long groupId, | ||
| 101 | - @RequestParam("memberUserId") Long memberUserId) { | ||
| 102 | - imGroupService.removeGroupMember(groupId, memberUserId, getLoginUserId()); | 102 | + public CommonResult<Boolean> removeGroupMember(@Valid @RequestBody ImGroupMemberRemoveReqVO removeReqVO) { |
| 103 | + groupService.removeGroupMember(getLoginUserId(), removeReqVO); | ||
| 103 | return success(true); | 104 | return success(true); |
| 104 | } | 105 | } |
| 105 | 106 |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/member/ImGroupMemberInviteReqVO.java
| 1 | package cn.iocoder.yudao.module.im.controller.admin.group.vo.member; | 1 | package cn.iocoder.yudao.module.im.controller.admin.group.vo.member; |
| 2 | 2 | ||
| 3 | import io.swagger.v3.oas.annotations.media.Schema; | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | +import jakarta.validation.constraints.NotEmpty; | ||
| 4 | import jakarta.validation.constraints.NotNull; | 5 | import jakarta.validation.constraints.NotNull; |
| 5 | import lombok.Data; | 6 | import lombok.Data; |
| 6 | 7 | ||
| 8 | +import java.util.List; | ||
| 9 | + | ||
| 7 | @Schema(description = "管理后台 - 群成员邀请 Request VO") | 10 | @Schema(description = "管理后台 - 群成员邀请 Request VO") |
| 8 | @Data | 11 | @Data |
| 9 | public class ImGroupMemberInviteReqVO { | 12 | public class ImGroupMemberInviteReqVO { |
| @@ -12,8 +15,8 @@ public class ImGroupMemberInviteReqVO { | @@ -12,8 +15,8 @@ public class ImGroupMemberInviteReqVO { | ||
| 12 | @NotNull(message = "群编号不能为空") | 15 | @NotNull(message = "群编号不能为空") |
| 13 | private Long groupId; | 16 | private Long groupId; |
| 14 | 17 | ||
| 15 | - @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21730") | ||
| 16 | - @NotNull(message = "用户编号不能为空") | ||
| 17 | - private Long userId; | 18 | + @Schema(description = "被邀请的用户编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2, 3]") |
| 19 | + @NotEmpty(message = "被邀请的用户编号列表不能为空") | ||
| 20 | + private List<Long> memberUserIds; | ||
| 18 | 21 | ||
| 19 | } | 22 | } |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/member/ImGroupMemberRemoveReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.im.controller.admin.group.vo.member; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import jakarta.validation.constraints.NotEmpty; | ||
| 5 | +import jakarta.validation.constraints.NotNull; | ||
| 6 | +import lombok.Data; | ||
| 7 | + | ||
| 8 | +import java.util.List; | ||
| 9 | + | ||
| 10 | +@Schema(description = "管理后台 - 群成员移除 Request VO") | ||
| 11 | +@Data | ||
| 12 | +public class ImGroupMemberRemoveReqVO { | ||
| 13 | + | ||
| 14 | + @Schema(description = "群编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 15 | + @NotNull(message = "群编号不能为空") | ||
| 16 | + private Long groupId; | ||
| 17 | + | ||
| 18 | + @Schema(description = "被移除的用户编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2, 3]") | ||
| 19 | + @NotEmpty(message = "被移除的用户编号列表不能为空") | ||
| 20 | + private List<Long> memberUserIds; | ||
| 21 | + | ||
| 22 | +} |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/ImGroupMemberMapper.java
| @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; | @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; | ||
| 7 | import org.apache.ibatis.annotations.Mapper; | 7 | import org.apache.ibatis.annotations.Mapper; |
| 8 | 8 | ||
| 9 | import java.time.LocalDateTime; | 9 | import java.time.LocalDateTime; |
| 10 | +import java.util.Collection; | ||
| 10 | import java.util.List; | 11 | import java.util.List; |
| 11 | 12 | ||
| 12 | /** | 13 | /** |
| @@ -27,6 +28,12 @@ public interface ImGroupMemberMapper extends BaseMapperX<ImGroupMemberDO> { | @@ -27,6 +28,12 @@ public interface ImGroupMemberMapper extends BaseMapperX<ImGroupMemberDO> { | ||
| 27 | .eq(ImGroupMemberDO::getUserId, userId)); | 28 | .eq(ImGroupMemberDO::getUserId, userId)); |
| 28 | } | 29 | } |
| 29 | 30 | ||
| 31 | + default List<ImGroupMemberDO> selectListByGroupIdAndUserIds(Long groupId, Collection<Long> userIds) { | ||
| 32 | + return selectList(new LambdaQueryWrapperX<ImGroupMemberDO>() | ||
| 33 | + .eq(ImGroupMemberDO::getGroupId, groupId) | ||
| 34 | + .in(ImGroupMemberDO::getUserId, userIds)); | ||
| 35 | + } | ||
| 36 | + | ||
| 30 | default List<ImGroupMemberDO> selectListByGroupIdAndStatus(Long groupId, Integer status) { | 37 | default List<ImGroupMemberDO> selectListByGroupIdAndStatus(Long groupId, Integer status) { |
| 31 | return selectList(new LambdaQueryWrapperX<ImGroupMemberDO>() | 38 | return selectList(new LambdaQueryWrapperX<ImGroupMemberDO>() |
| 32 | .eq(ImGroupMemberDO::getGroupId, groupId) | 39 | .eq(ImGroupMemberDO::getGroupId, groupId) |
| @@ -62,4 +69,13 @@ public interface ImGroupMemberMapper extends BaseMapperX<ImGroupMemberDO> { | @@ -62,4 +69,13 @@ public interface ImGroupMemberMapper extends BaseMapperX<ImGroupMemberDO> { | ||
| 62 | .eq(ImGroupMemberDO::getStatus, oldStatus)); | 69 | .eq(ImGroupMemberDO::getStatus, oldStatus)); |
| 63 | } | 70 | } |
| 64 | 71 | ||
| 72 | + @SuppressWarnings("UnusedReturnValue") | ||
| 73 | + default int updateByGroupIdAndUserIdsAndStatus(Long groupId, Collection<Long> userIds, | ||
| 74 | + Integer oldStatus, ImGroupMemberDO updateObj) { | ||
| 75 | + return update(updateObj, new LambdaQueryWrapperX<ImGroupMemberDO>() | ||
| 76 | + .eq(ImGroupMemberDO::getGroupId, groupId) | ||
| 77 | + .in(ImGroupMemberDO::getUserId, userIds) | ||
| 78 | + .eq(ImGroupMemberDO::getStatus, oldStatus)); | ||
| 79 | + } | ||
| 80 | + | ||
| 65 | } | 81 | } |
| 66 | \ No newline at end of file | 82 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/message/GroupMessageReadRedisDAO.java
| @@ -5,6 +5,7 @@ import jakarta.annotation.Resource; | @@ -5,6 +5,7 @@ import jakarta.annotation.Resource; | ||
| 5 | import org.springframework.data.redis.core.StringRedisTemplate; | 5 | import org.springframework.data.redis.core.StringRedisTemplate; |
| 6 | import org.springframework.stereotype.Repository; | 6 | import org.springframework.stereotype.Repository; |
| 7 | 7 | ||
| 8 | +import java.util.Collection; | ||
| 8 | import java.util.HashMap; | 9 | import java.util.HashMap; |
| 9 | import java.util.Map; | 10 | import java.util.Map; |
| 10 | 11 | ||
| @@ -73,6 +74,18 @@ public class GroupMessageReadRedisDAO { | @@ -73,6 +74,18 @@ public class GroupMessageReadRedisDAO { | ||
| 73 | } | 74 | } |
| 74 | 75 | ||
| 75 | /** | 76 | /** |
| 77 | + * 批量删除用户在某群的已读位置 | ||
| 78 | + * | ||
| 79 | + * @param groupId 群编号 | ||
| 80 | + * @param userIds 用户编号集合 | ||
| 81 | + */ | ||
| 82 | + public void deleteReadMaxMessageIds(Long groupId, Collection<Long> userIds) { | ||
| 83 | + String key = formatKey(groupId); | ||
| 84 | + Object[] hashKeys = userIds.stream().map(String::valueOf).toArray(); | ||
| 85 | + stringRedisTemplate.opsForHash().delete(key, hashKeys); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + /** | ||
| 76 | * 删除某群所有用户的已读位置(整个 Hash Key) | 89 | * 删除某群所有用户的已读位置(整个 Hash Key) |
| 77 | * | 90 | * |
| 78 | * @param groupId 群编号 | 91 | * @param groupId 群编号 |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberService.java
| @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; | @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; | ||
| 5 | import jakarta.validation.Valid; | 5 | import jakarta.validation.Valid; |
| 6 | 6 | ||
| 7 | import java.time.LocalDateTime; | 7 | import java.time.LocalDateTime; |
| 8 | +import java.util.Collection; | ||
| 8 | import java.util.List; | 9 | import java.util.List; |
| 9 | 10 | ||
| 10 | /** | 11 | /** |
| @@ -69,6 +70,14 @@ public interface ImGroupMemberService { | @@ -69,6 +70,14 @@ public interface ImGroupMemberService { | ||
| 69 | ImGroupMemberDO addGroupMember(Long groupId, Long userId); | 70 | ImGroupMemberDO addGroupMember(Long groupId, Long userId); |
| 70 | 71 | ||
| 71 | /** | 72 | /** |
| 73 | + * 批量添加群成员(入群) | ||
| 74 | + * | ||
| 75 | + * @param groupId 群编号 | ||
| 76 | + * @param userIds 用户编号集合 | ||
| 77 | + */ | ||
| 78 | + void addGroupMembers(Long groupId, Collection<Long> userIds); | ||
| 79 | + | ||
| 80 | + /** | ||
| 72 | * 校验用户是否为群的有效成员 | 81 | * 校验用户是否为群的有效成员 |
| 73 | * | 82 | * |
| 74 | * @param groupId 群编号 | 83 | * @param groupId 群编号 |
| @@ -98,6 +107,16 @@ public interface ImGroupMemberService { | @@ -98,6 +107,16 @@ public interface ImGroupMemberService { | ||
| 98 | void removeGroupMember(Long groupId, Long userId); | 107 | void removeGroupMember(Long groupId, Long userId); |
| 99 | 108 | ||
| 100 | /** | 109 | /** |
| 110 | + * 批量移除指定群成员(设置为 DISABLE 状态) | ||
| 111 | + * <p> | ||
| 112 | + * 用于批量踢出场景 | ||
| 113 | + * | ||
| 114 | + * @param groupId 群编号 | ||
| 115 | + * @param userIds 用户编号集合 | ||
| 116 | + */ | ||
| 117 | + void removeGroupMembers(Long groupId, Collection<Long> userIds); | ||
| 118 | + | ||
| 119 | + /** | ||
| 101 | * 移除群的全部成员(设置为 DISABLE 状态) | 120 | * 移除群的全部成员(设置为 DISABLE 状态) |
| 102 | * <p> | 121 | * <p> |
| 103 | * 用于群解散场景 | 122 | * 用于群解散场景 |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImpl.java
| 1 | package cn.iocoder.yudao.module.im.service.group; | 1 | package cn.iocoder.yudao.module.im.service.group; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 3 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberUpdateReqVO; | 6 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberUpdateReqVO; |
| @@ -10,9 +11,13 @@ import org.springframework.stereotype.Service; | @@ -10,9 +11,13 @@ import org.springframework.stereotype.Service; | ||
| 10 | import org.springframework.validation.annotation.Validated; | 11 | import org.springframework.validation.annotation.Validated; |
| 11 | 12 | ||
| 12 | import java.time.LocalDateTime; | 13 | import java.time.LocalDateTime; |
| 14 | +import java.util.ArrayList; | ||
| 15 | +import java.util.Collection; | ||
| 13 | import java.util.List; | 16 | import java.util.List; |
| 17 | +import java.util.Map; | ||
| 14 | 18 | ||
| 15 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 19 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 20 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | ||
| 16 | import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.GROUP_MEMBER_NOT_IN_GROUP; | 21 | import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.GROUP_MEMBER_NOT_IN_GROUP; |
| 17 | 22 | ||
| 18 | /** | 23 | /** |
| @@ -25,31 +30,31 @@ import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.GROUP_MEMBER_N | @@ -25,31 +30,31 @@ import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.GROUP_MEMBER_N | ||
| 25 | public class ImGroupMemberServiceImpl implements ImGroupMemberService { | 30 | public class ImGroupMemberServiceImpl implements ImGroupMemberService { |
| 26 | 31 | ||
| 27 | @Resource | 32 | @Resource |
| 28 | - private ImGroupMemberMapper imGroupMemberMapper; | 33 | + private ImGroupMemberMapper groupMemberMapper; |
| 29 | 34 | ||
| 30 | @Override | 35 | @Override |
| 31 | public ImGroupMemberDO getGroupMember(Long id) { | 36 | public ImGroupMemberDO getGroupMember(Long id) { |
| 32 | - return imGroupMemberMapper.selectById(id); | 37 | + return groupMemberMapper.selectById(id); |
| 33 | } | 38 | } |
| 34 | 39 | ||
| 35 | @Override | 40 | @Override |
| 36 | public List<ImGroupMemberDO> getGroupMemberListByGroupId(Long groupId) { | 41 | public List<ImGroupMemberDO> getGroupMemberListByGroupId(Long groupId) { |
| 37 | - return imGroupMemberMapper.selectListByGroupId(groupId); | 42 | + return groupMemberMapper.selectListByGroupId(groupId); |
| 38 | } | 43 | } |
| 39 | 44 | ||
| 40 | @Override | 45 | @Override |
| 41 | public List<ImGroupMemberDO> getActiveGroupMemberListByGroupId(Long groupId) { | 46 | public List<ImGroupMemberDO> getActiveGroupMemberListByGroupId(Long groupId) { |
| 42 | - return imGroupMemberMapper.selectListByGroupIdAndStatus(groupId, CommonStatusEnum.ENABLE.getStatus()); | 47 | + return groupMemberMapper.selectListByGroupIdAndStatus(groupId, CommonStatusEnum.ENABLE.getStatus()); |
| 43 | } | 48 | } |
| 44 | 49 | ||
| 45 | @Override | 50 | @Override |
| 46 | public List<ImGroupMemberDO> getActiveGroupMemberListByUserId(Long userId) { | 51 | public List<ImGroupMemberDO> getActiveGroupMemberListByUserId(Long userId) { |
| 47 | - return imGroupMemberMapper.selectListByUserIdAndStatus(userId, CommonStatusEnum.ENABLE.getStatus()); | 52 | + return groupMemberMapper.selectListByUserIdAndStatus(userId, CommonStatusEnum.ENABLE.getStatus()); |
| 48 | } | 53 | } |
| 49 | 54 | ||
| 50 | @Override | 55 | @Override |
| 51 | public List<ImGroupMemberDO> getQuitGroupMemberListByUserId(Long userId, LocalDateTime minQuitTime) { | 56 | public List<ImGroupMemberDO> getQuitGroupMemberListByUserId(Long userId, LocalDateTime minQuitTime) { |
| 52 | - return imGroupMemberMapper.selectQuitListByUserId(userId, minQuitTime); | 57 | + return groupMemberMapper.selectQuitListByUserId(userId, minQuitTime); |
| 53 | } | 58 | } |
| 54 | 59 | ||
| 55 | @Override | 60 | @Override |
| @@ -57,13 +62,42 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { | @@ -57,13 +62,42 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { | ||
| 57 | ImGroupMemberDO member = new ImGroupMemberDO() | 62 | ImGroupMemberDO member = new ImGroupMemberDO() |
| 58 | .setGroupId(groupId).setUserId(userId) | 63 | .setGroupId(groupId).setUserId(userId) |
| 59 | .setStatus(CommonStatusEnum.ENABLE.getStatus()).setJoinTime(LocalDateTime.now()); | 64 | .setStatus(CommonStatusEnum.ENABLE.getStatus()).setJoinTime(LocalDateTime.now()); |
| 60 | - imGroupMemberMapper.insert(member); | 65 | + groupMemberMapper.insert(member); |
| 61 | return member; | 66 | return member; |
| 62 | } | 67 | } |
| 63 | 68 | ||
| 64 | @Override | 69 | @Override |
| 70 | + public void addGroupMembers(Long groupId, Collection<Long> userIds) { | ||
| 71 | + LocalDateTime now = LocalDateTime.now(); | ||
| 72 | + // 1.1 查询已有记录(含已退群的 DISABLE 记录) | ||
| 73 | + List<ImGroupMemberDO> existMembers = groupMemberMapper.selectListByGroupIdAndUserIds(groupId, userIds); | ||
| 74 | + Map<Long, ImGroupMemberDO> existMap = convertMap(existMembers, ImGroupMemberDO::getUserId); | ||
| 75 | + // 1.2 分类:已有记录 → UPDATE,新成员 → INSERT | ||
| 76 | + List<ImGroupMemberDO> inserts = new ArrayList<>(); | ||
| 77 | + List<ImGroupMemberDO> updates = new ArrayList<>(); | ||
| 78 | + for (Long userId : userIds) { | ||
| 79 | + ImGroupMemberDO exist = existMap.get(userId); | ||
| 80 | + if (exist == null) { | ||
| 81 | + inserts.add(new ImGroupMemberDO().setGroupId(groupId).setUserId(userId) | ||
| 82 | + .setStatus(CommonStatusEnum.ENABLE.getStatus()).setJoinTime(now)); | ||
| 83 | + } else if (CommonStatusEnum.DISABLE.getStatus().equals(exist.getStatus())) { | ||
| 84 | + updates.add(new ImGroupMemberDO().setId(exist.getId()) | ||
| 85 | + .setStatus(CommonStatusEnum.ENABLE.getStatus()).setJoinTime(now)); | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + // 2. 执行 | ||
| 90 | + if (CollUtil.isNotEmpty(inserts)) { | ||
| 91 | + groupMemberMapper.insertBatch(inserts); | ||
| 92 | + } | ||
| 93 | + if (CollUtil.isNotEmpty(updates)) { | ||
| 94 | + groupMemberMapper.updateBatch(updates); | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + @Override | ||
| 65 | public ImGroupMemberDO validateMemberInGroup(Long groupId, Long userId) { | 99 | public ImGroupMemberDO validateMemberInGroup(Long groupId, Long userId) { |
| 66 | - ImGroupMemberDO member = imGroupMemberMapper.selectByGroupIdAndUserId(groupId, userId); | 100 | + ImGroupMemberDO member = groupMemberMapper.selectByGroupIdAndUserId(groupId, userId); |
| 67 | if (member == null || CommonStatusEnum.DISABLE.getStatus().equals(member.getStatus())) { | 101 | if (member == null || CommonStatusEnum.DISABLE.getStatus().equals(member.getStatus())) { |
| 68 | throw exception(GROUP_MEMBER_NOT_IN_GROUP); | 102 | throw exception(GROUP_MEMBER_NOT_IN_GROUP); |
| 69 | } | 103 | } |
| @@ -77,7 +111,7 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { | @@ -77,7 +111,7 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { | ||
| 77 | // 2. 更新群成员信息 | 111 | // 2. 更新群成员信息 |
| 78 | ImGroupMemberDO updateObj = BeanUtils.toBean(updateReqVO, ImGroupMemberDO.class) | 112 | ImGroupMemberDO updateObj = BeanUtils.toBean(updateReqVO, ImGroupMemberDO.class) |
| 79 | .setId(member.getId()); | 113 | .setId(member.getId()); |
| 80 | - imGroupMemberMapper.updateById(updateObj); | 114 | + groupMemberMapper.updateById(updateObj); |
| 81 | } | 115 | } |
| 82 | 116 | ||
| 83 | @Override | 117 | @Override |
| @@ -85,14 +119,22 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { | @@ -85,14 +119,22 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { | ||
| 85 | // 1. 校验是群的有效成员 | 119 | // 1. 校验是群的有效成员 |
| 86 | ImGroupMemberDO member = validateMemberInGroup(groupId, userId); | 120 | ImGroupMemberDO member = validateMemberInGroup(groupId, userId); |
| 87 | // 2. 更新为退群状态 | 121 | // 2. 更新为退群状态 |
| 88 | - imGroupMemberMapper.updateById(new ImGroupMemberDO().setId(member.getId()) | 122 | + groupMemberMapper.updateById(new ImGroupMemberDO().setId(member.getId()) |
| 89 | .setStatus(CommonStatusEnum.DISABLE.getStatus()) | 123 | .setStatus(CommonStatusEnum.DISABLE.getStatus()) |
| 90 | .setQuitTime(LocalDateTime.now())); | 124 | .setQuitTime(LocalDateTime.now())); |
| 91 | } | 125 | } |
| 92 | 126 | ||
| 93 | @Override | 127 | @Override |
| 128 | + public void removeGroupMembers(Long groupId, Collection<Long> userIds) { | ||
| 129 | + groupMemberMapper.updateByGroupIdAndUserIdsAndStatus(groupId, userIds, | ||
| 130 | + CommonStatusEnum.ENABLE.getStatus(), | ||
| 131 | + new ImGroupMemberDO().setStatus(CommonStatusEnum.DISABLE.getStatus()) | ||
| 132 | + .setQuitTime(LocalDateTime.now())); | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + @Override | ||
| 94 | public void removeGroupMembersByGroupId(Long groupId) { | 136 | public void removeGroupMembersByGroupId(Long groupId) { |
| 95 | - imGroupMemberMapper.updateByGroupIdAndStatus(groupId, CommonStatusEnum.ENABLE.getStatus(), | 137 | + groupMemberMapper.updateByGroupIdAndStatus(groupId, CommonStatusEnum.ENABLE.getStatus(), |
| 96 | new ImGroupMemberDO().setStatus(CommonStatusEnum.DISABLE.getStatus()) | 138 | new ImGroupMemberDO().setStatus(CommonStatusEnum.DISABLE.getStatus()) |
| 97 | .setQuitTime(LocalDateTime.now())); | 139 | .setQuitTime(LocalDateTime.now())); |
| 98 | } | 140 | } |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.im.service.group; | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.im.service.group; | ||
| 3 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupCreateReqVO; | 3 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupCreateReqVO; |
| 4 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupUpdateReqVO; | 4 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupUpdateReqVO; |
| 5 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberInviteReqVO; | 5 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberInviteReqVO; |
| 6 | +import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberRemoveReqVO; | ||
| 6 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; | 7 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; |
| 7 | import jakarta.validation.Valid; | 8 | import jakarta.validation.Valid; |
| 8 | 9 | ||
| @@ -92,13 +93,13 @@ public interface ImGroupService { | @@ -92,13 +93,13 @@ public interface ImGroupService { | ||
| 92 | /** | 93 | /** |
| 93 | * 邀请用户加入群 | 94 | * 邀请用户加入群 |
| 94 | * <p> | 95 | * <p> |
| 95 | - * 仅群主可执行 | 96 | + * 群成员即可执行,支持批量。 |
| 97 | + * 校验群人数上限,邀请后推送提示消息和群创建事件给被邀请人。 | ||
| 96 | * | 98 | * |
| 97 | - * @param userId 当前登录用户编号(群主) | 99 | + * @param userId 当前登录用户编号 |
| 98 | * @param inviteReqVO 邀请信息 | 100 | * @param inviteReqVO 邀请信息 |
| 99 | - * @return 群成员编号 | ||
| 100 | */ | 101 | */ |
| 101 | - Long inviteGroupMember(Long userId, @Valid ImGroupMemberInviteReqVO inviteReqVO); | 102 | + void inviteGroupMember(Long userId, @Valid ImGroupMemberInviteReqVO inviteReqVO); |
| 102 | 103 | ||
| 103 | /** | 104 | /** |
| 104 | * 退群 | 105 | * 退群 |
| @@ -113,12 +114,11 @@ public interface ImGroupService { | @@ -113,12 +114,11 @@ public interface ImGroupService { | ||
| 113 | /** | 114 | /** |
| 114 | * 移除群成员(踢人) | 115 | * 移除群成员(踢人) |
| 115 | * <p> | 116 | * <p> |
| 116 | - * 仅群主可执行,且不能移除自己 | 117 | + * 仅群主可执行,且不能移除自己,支持批量 |
| 117 | * | 118 | * |
| 118 | - * @param groupId 群编号 | ||
| 119 | - * @param memberUserId 被移除的用户编号 | ||
| 120 | - * @param userId 当前登录用户编号(群主) | 119 | + * @param userId 当前登录用户编号(群主) |
| 120 | + * @param removeReqVO 移除信息 | ||
| 121 | */ | 121 | */ |
| 122 | - void removeGroupMember(Long groupId, Long memberUserId, Long userId); | 122 | + void removeGroupMember(Long userId, @Valid ImGroupMemberRemoveReqVO removeReqVO); |
| 123 | 123 | ||
| 124 | } | 124 | } |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java
| @@ -11,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | @@ -11,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 11 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupCreateReqVO; | 11 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupCreateReqVO; |
| 12 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupUpdateReqVO; | 12 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupUpdateReqVO; |
| 13 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberInviteReqVO; | 13 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberInviteReqVO; |
| 14 | +import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberRemoveReqVO; | ||
| 14 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberUpdateReqVO; | 15 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberUpdateReqVO; |
| 15 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; | 16 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; |
| 16 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; | 17 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; |
| @@ -30,8 +31,11 @@ import org.springframework.validation.annotation.Validated; | @@ -30,8 +31,11 @@ import org.springframework.validation.annotation.Validated; | ||
| 30 | 31 | ||
| 31 | import java.time.LocalDateTime; | 32 | import java.time.LocalDateTime; |
| 32 | import java.util.Collections; | 33 | import java.util.Collections; |
| 34 | +import java.util.HashSet; | ||
| 33 | import java.util.List; | 35 | import java.util.List; |
| 36 | +import java.util.Map; | ||
| 34 | import java.util.Set; | 37 | import java.util.Set; |
| 38 | +import java.util.stream.Collectors; | ||
| 35 | 39 | ||
| 36 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 40 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 37 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | 41 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| @@ -149,13 +153,39 @@ public class ImGroupServiceImpl implements ImGroupService { | @@ -149,13 +153,39 @@ public class ImGroupServiceImpl implements ImGroupService { | ||
| 149 | // ==================== 群成员的写操作 ==================== | 153 | // ==================== 群成员的写操作 ==================== |
| 150 | 154 | ||
| 151 | @Override | 155 | @Override |
| 152 | - public Long inviteGroupMember(Long userId, ImGroupMemberInviteReqVO inviteReqVO) { | ||
| 153 | - // 1. 校验群存在 + 当前用户是群主 | ||
| 154 | - validateGroupOwner(inviteReqVO.getGroupId(), userId); | 156 | + public void inviteGroupMember(Long userId, ImGroupMemberInviteReqVO inviteReqVO) { |
| 157 | + Long groupId = inviteReqVO.getGroupId(); | ||
| 158 | + // 1.1 校验群存在 + 当前用户是群成员 | ||
| 159 | + validateGroupExists(groupId); | ||
| 160 | + groupMemberService.validateMemberInGroup(groupId, userId); | ||
| 161 | + // 1.2 排除已在群中的用户 | ||
| 162 | + List<ImGroupMemberDO> activeMembers = groupMemberService.getActiveGroupMemberListByGroupId(groupId); | ||
| 163 | + activeMembers.forEach(member -> inviteReqVO.getMemberUserIds().remove(member.getUserId())); | ||
| 164 | + if (CollUtil.isEmpty(inviteReqVO.getMemberUserIds())) { | ||
| 165 | + return; | ||
| 166 | + } | ||
| 167 | + // 1.3 校验群人数上限 | ||
| 168 | + List<Long> memberUserIds = inviteReqVO.getMemberUserIds(); | ||
| 169 | + if (activeMembers.size() + memberUserIds.size() > MAX_GROUP_MEMBER) { | ||
| 170 | + throw exception(GROUP_MEMBER_EXCEED, MAX_GROUP_MEMBER); | ||
| 171 | + } | ||
| 155 | 172 | ||
| 156 | - // 2. 添加群成员 | ||
| 157 | - ImGroupMemberDO member = groupMemberService.addGroupMember(inviteReqVO.getGroupId(), inviteReqVO.getUserId()); | ||
| 158 | - return member.getId(); | 173 | + // 2. 批量添加群成员 |
| 174 | + groupMemberService.addGroupMembers(groupId, memberUserIds); | ||
| 175 | + | ||
| 176 | + // 3.1 推送群创建事件给被邀请人(让客户端新增群会话) | ||
| 177 | + webSocketService.sendGroupMessageAsync(new HashSet<>(memberUserIds), | ||
| 178 | + ImGroupMessageDTO.ofGroupCreate(userId, groupId)); | ||
| 179 | + // 3.2 发送邀请提示消息给所有群成员 | ||
| 180 | + AdminUserRespDTO inviter = adminUserApi.getUser(userId); | ||
| 181 | + Map<Long, AdminUserRespDTO> invitedUserMap = adminUserApi.getUserMap(memberUserIds); | ||
| 182 | + String invitedNames = memberUserIds.stream() | ||
| 183 | + .map(id -> invitedUserMap.containsKey(id) ? invitedUserMap.get(id).getNickname() : String.valueOf(id)) | ||
| 184 | + .collect(Collectors.joining(",")); | ||
| 185 | + String tipContent = StrUtil.format(GROUP_INVITE_TIP_MESSAGE, inviter.getNickname(), invitedNames); | ||
| 186 | + List<ImGroupMemberDO> allMembers = groupMemberService.getActiveGroupMemberListByGroupId(groupId); | ||
| 187 | + Set<Long> allMemberUserIds = convertSet(allMembers, ImGroupMemberDO::getUserId); | ||
| 188 | + groupMessageService.sendTipGroupMessage(userId, groupId, allMemberUserIds, tipContent); | ||
| 159 | } | 189 | } |
| 160 | 190 | ||
| 161 | @Override | 191 | @Override |
| @@ -180,23 +210,25 @@ public class ImGroupServiceImpl implements ImGroupService { | @@ -180,23 +210,25 @@ public class ImGroupServiceImpl implements ImGroupService { | ||
| 180 | } | 210 | } |
| 181 | 211 | ||
| 182 | @Override | 212 | @Override |
| 183 | - public void removeGroupMember(Long groupId, Long memberUserId, Long userId) { | 213 | + public void removeGroupMember(Long userId, ImGroupMemberRemoveReqVO removeReqVO) { |
| 214 | + Long groupId = removeReqVO.getGroupId(); | ||
| 184 | // 1. 校验群存在 + 当前用户是群主 | 215 | // 1. 校验群存在 + 当前用户是群主 |
| 185 | validateGroupOwner(groupId, userId); | 216 | validateGroupOwner(groupId, userId); |
| 186 | // 2. 不能移除自己 | 217 | // 2. 不能移除自己 |
| 187 | - if (ObjUtil.equal(memberUserId, userId)) { | 218 | + if (removeReqVO.getMemberUserIds().contains(userId)) { |
| 188 | throw exception(GROUP_CANNOT_REMOVE_SELF); | 219 | throw exception(GROUP_CANNOT_REMOVE_SELF); |
| 189 | } | 220 | } |
| 190 | 221 | ||
| 191 | - // 3.1 移除群成员 | ||
| 192 | - groupMemberService.removeGroupMember(groupId, memberUserId); | ||
| 193 | - // 3.2 清理已读缓存 | ||
| 194 | - groupMessageService.deleteReadMaxMessageId(groupId, memberUserId); | 222 | + // 3.1 批量移除群成员 |
| 223 | + Set<Long> memberUserIds = new HashSet<>(removeReqVO.getMemberUserIds()); | ||
| 224 | + groupMemberService.removeGroupMembers(groupId, memberUserIds); | ||
| 225 | + // 3.2 批量清理已读缓存 | ||
| 226 | + groupMessageService.deleteReadMaxMessageIds(groupId, memberUserIds); | ||
| 195 | 227 | ||
| 196 | // 4.1 发送踢出提示消息(TIP_TEXT) | 228 | // 4.1 发送踢出提示消息(TIP_TEXT) |
| 197 | - groupMessageService.sendTipGroupMessage(userId, groupId, Set.of(memberUserId), GROUP_REMOVE_TIP_MESSAGE); | 229 | + groupMessageService.sendTipGroupMessage(userId, groupId, memberUserIds, GROUP_REMOVE_TIP_MESSAGE); |
| 198 | // 4.2 推送群删除事件 | 230 | // 4.2 推送群删除事件 |
| 199 | - webSocketService.sendGroupMessageAsync(Set.of(memberUserId), | 231 | + webSocketService.sendGroupMessageAsync(memberUserIds, |
| 200 | ImGroupMessageDTO.ofGroupDelete(userId, groupId)); | 232 | ImGroupMessageDTO.ofGroupDelete(userId, groupId)); |
| 201 | } | 233 | } |
| 202 | 234 |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageService.java
| @@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.im.controller.admin.message.vo.group.ImGroupMessa | @@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.im.controller.admin.message.vo.group.ImGroupMessa | ||
| 4 | import cn.iocoder.yudao.module.im.controller.admin.message.vo.group.ImGroupMessageSendReqVO; | 4 | import cn.iocoder.yudao.module.im.controller.admin.message.vo.group.ImGroupMessageSendReqVO; |
| 5 | import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO; | 5 | import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO; |
| 6 | 6 | ||
| 7 | +import java.util.Collection; | ||
| 7 | import java.util.List; | 8 | import java.util.List; |
| 8 | import java.util.Set; | 9 | import java.util.Set; |
| 9 | 10 | ||
| @@ -81,6 +82,16 @@ public interface ImGroupMessageService { | @@ -81,6 +82,16 @@ public interface ImGroupMessageService { | ||
| 81 | void deleteReadMaxMessageId(Long groupId, Long userId); | 82 | void deleteReadMaxMessageId(Long groupId, Long userId); |
| 82 | 83 | ||
| 83 | /** | 84 | /** |
| 85 | + * 批量清理用户在某群的已读位置缓存 | ||
| 86 | + * <p> | ||
| 87 | + * 用于批量踢出场景 | ||
| 88 | + * | ||
| 89 | + * @param groupId 群编号 | ||
| 90 | + * @param userIds 用户编号集合 | ||
| 91 | + */ | ||
| 92 | + void deleteReadMaxMessageIds(Long groupId, Collection<Long> userIds); | ||
| 93 | + | ||
| 94 | + /** | ||
| 84 | * 清理某群所有用户的已读位置缓存 | 95 | * 清理某群所有用户的已读位置缓存 |
| 85 | * <p> | 96 | * <p> |
| 86 | * 用于群解散场景 | 97 | * 用于群解散场景 |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImpl.java
| @@ -477,6 +477,11 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { | @@ -477,6 +477,11 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { | ||
| 477 | } | 477 | } |
| 478 | 478 | ||
| 479 | @Override | 479 | @Override |
| 480 | + public void deleteReadMaxMessageIds(Long groupId, Collection<Long> userIds) { | ||
| 481 | + groupMessageReadRedisDAO.deleteReadMaxMessageIds(groupId, userIds); | ||
| 482 | + } | ||
| 483 | + | ||
| 484 | + @Override | ||
| 480 | public void deleteReadMaxMessageIdMap(Long groupId) { | 485 | public void deleteReadMaxMessageIdMap(Long groupId) { |
| 481 | groupMessageReadRedisDAO.deleteReadMaxMessageIdMap(groupId); | 486 | groupMessageReadRedisDAO.deleteReadMaxMessageIdMap(groupId); |
| 482 | } | 487 | } |