diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/ImFriendController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/ImFriendController.java index 629ab35..146cb54 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/ImFriendController.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/ImFriendController.java @@ -84,7 +84,7 @@ public class ImFriendController { // ========== 私有方法:VO 组装 ========== private List buildFriendRespVOList(Collection friends) { - if (CollUtil.isNotEmpty(friends)) { + if (CollUtil.isEmpty(friends)) { return Collections.emptyList(); } // 批量聚合 AdminUser 信息(昵称 / 头像),避免 N+1 diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java index 9bb1c07..f05335d 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java @@ -1,25 +1,27 @@ package cn.iocoder.yudao.module.im.controller.admin.group; -import org.springframework.web.bind.annotation.*; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupPageReqVO; +import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupRespVO; +import cn.iocoder.yudao.module.im.controller.admin.group.vo.ImGroupSaveReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; +import cn.iocoder.yudao.module.im.service.group.ImGroupService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; -import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; -import jakarta.validation.*; +import java.util.List; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; -import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; -import cn.iocoder.yudao.module.im.service.group.ImGroupService; - -// DONE @芋艿:create/update/delete/get/page 全部保留,管理后台群管理需要 @Tag(name = "管理后台 - 群") @RestController @RequestMapping("/im/group") @@ -62,6 +64,7 @@ public class ImGroupController { return success(BeanUtils.toBean(group, ImGroupRespVO.class)); } + // TODO @AI:去掉这个接口; @GetMapping("/page") @Operation(summary = "获得群分页") @PreAuthorize("@ss.hasPermission('im:group:query')") @@ -70,4 +73,26 @@ public class ImGroupController { return success(BeanUtils.toBean(pageResult, ImGroupRespVO.class)); } -} \ No newline at end of file + // ========== 用户侧接口(登录用户自己的群,无需后台权限) ========== + + // TODO @AI:直接 list; + @GetMapping("/list-my") + @Operation(summary = "获得当前登录用户的群列表") + public CommonResult> getMyGroupList() { + Long userId = SecurityFrameworkUtils.getLoginUserId(); + List groups = imGroupService.getMyGroupList(userId); + return success(BeanUtils.toBean(groups, ImGroupRespVO.class)); + } + + // TODO @芋艿:【对齐】/group/create、/group/modify、/group/invite、/group/quit、/group/delete/{id} + // 这些用户侧接口第一期暂未实现。需要: + // 1. createGroup(vo):需同时插入 im_group + 批量插入 im_group_member;还要给群成员推送 FRIEND_INVITE 类消息 + // 2. modifyGroup(vo):允许修改 name / notice / avatar / remarkGroupName / remarkNickName + // (其中 remarkGroupName / remarkNickName 是 im_group_member 的字段,不是 im_group 的) + // 3. invite(groupId, userIds):批量插入 im_group_member 为 ENABLE;给被邀请人推送入群通知 + // 4. quitGroup(groupId):校验非群主才能退,然后把自己的 im_group_member 标为 DISABLE + quitTime + // 5. removeGroupMembers(groupId, userIds):群主权限校验 + 把成员标为 DISABLE + // 以上都需要 WebSocket 推送对应事件(FRIEND_INVITE / MEMBER_QUIT / MEMBER_REMOVE 等), + // 涉及 `ImWsEventType` 扩展 + `ImWebSocketPusher` 新增事件推送方法,待统一设计后补上。 + +} diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupMemberController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupMemberController.java index 0c92f48..0a5a2d4 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupMemberController.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupMemberController.java @@ -2,12 +2,15 @@ package cn.iocoder.yudao.module.im.controller.admin.group; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberPageReqVO; import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberRespVO; import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberSaveReqVO; import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -17,9 +20,12 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.Collections; +import java.util.List; +import java.util.Map; + import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -// DONE @芋艿:create/update/delete/get/page 全部保留,管理后台群成员管理需要 @Tag(name = "管理后台 - 群成员") @RestController @RequestMapping("/im/group-member") @@ -29,6 +35,10 @@ public class ImGroupMemberController { @Resource private ImGroupMemberService imGroupMemberService; + @Resource + private AdminUserApi adminUserApi; + + // TODO @AI:add 加人; @PostMapping("/create") @Operation(summary = "创建群成员") @PreAuthorize("@ss.hasPermission('im:group-member:create')") @@ -36,6 +46,10 @@ public class ImGroupMemberController { return success(imGroupMemberService.createGroupMember(createReqVO)); } + // TODO @AI:踢人; + + // TODO @AI:退群;放在这里;避免 group 里面逻辑太多; + @PutMapping("/update") @Operation(summary = "更新群成员") @PreAuthorize("@ss.hasPermission('im:group-member:update')") @@ -70,4 +84,37 @@ public class ImGroupMemberController { return success(BeanUtils.toBean(pageResult, ImGroupMemberRespVO.class)); } -} \ No newline at end of file + // ========== 用户侧接口(登录用户自己看群成员,无需后台权限) ========== + + @GetMapping("/list") + @Operation(summary = "获得指定群的成员列表") + @Parameter(name = "groupId", description = "群编号", required = true, example = "1024") + public CommonResult> getGroupMemberList(@RequestParam("groupId") Long groupId) { + List members = imGroupMemberService.getGroupMemberListByGroupId(groupId); + if (members.isEmpty()) { + return success(Collections.emptyList()); + } + // 聚合 AdminUser 的昵称 + 头像 + List userIds = CollectionUtils.convertList(members, ImGroupMemberDO::getUserId); + Map userMap = adminUserApi.getUserMap(userIds); + return success(CollectionUtils.convertList(members, m -> { + ImGroupMemberRespVO vo = BeanUtils.toBean(m, ImGroupMemberRespVO.class); + AdminUserRespDTO user = userMap.get(m.getUserId()); + if (user != null) { + vo.setNickname(user.getNickname()); + vo.setAvatar(user.getAvatar()); + } + // showNickname 回落:优先群内备注 displayUserName,否则用用户昵称 + if (m.getDisplayUserName() != null && !m.getDisplayUserName().isEmpty()) { + vo.setShowNickname(m.getDisplayUserName()); + } else if (user != null) { + vo.setShowNickname(user.getNickname()); + } + return vo; + })); + } + + // TODO @芋艿:【对齐】/group/members/remove 批量踢人接口第一期未实现。 + // 需要:校验群主权限、批量更新 im_group_member 为 DISABLE + 设置 quitTime、通过 WebSocket 推送给被踢成员。 + +} diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/ImGroupRespVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/ImGroupRespVO.java index 6d2c763..8eebe81 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/ImGroupRespVO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/ImGroupRespVO.java @@ -27,9 +27,15 @@ public class ImGroupRespVO { @Schema(description = "是否封禁") private Boolean banned; + @Schema(description = "封禁时间") + private LocalDateTime bannedTime; + @Schema(description = "是否解散") private Boolean dissolved; + @Schema(description = "解散时间") + private LocalDateTime dissolvedTime; + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/member/ImGroupMemberRespVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/member/ImGroupMemberRespVO.java index 51945df..884c620 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/member/ImGroupMemberRespVO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/member/ImGroupMemberRespVO.java @@ -39,4 +39,15 @@ public class ImGroupMemberRespVO { @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; + // ========== 聚合字段:用户侧接口按需填充(admin CRUD 查询不填) ========== + + @Schema(description = "用户昵称(聚合自 AdminUser,用户侧接口返回)", example = "芋道") + private String nickname; + + @Schema(description = "用户头像(聚合自 AdminUser,用户侧接口返回)") + private String avatar; + + @Schema(description = "展示昵称:优先 displayUserName,回落 nickname", example = "芋道") + private String showNickname; + } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/ImGroupMemberMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/ImGroupMemberMapper.java index c07e94e..afa1fdb 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/ImGroupMemberMapper.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/ImGroupMemberMapper.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.im.dal.mysql.group; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; @@ -7,6 +8,7 @@ import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMember import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; import org.apache.ibatis.annotations.Mapper; +import java.time.LocalDateTime; import java.util.List; /** @@ -39,4 +41,35 @@ public interface ImGroupMemberMapper extends BaseMapperX { default List selectListByUserId(Long userId) { return selectList(new LambdaQueryWrapperX().eq(ImGroupMemberDO::getUserId, userId)); } + + // TODO @AI:selectListByXXX;enabled 传入进来 + default List selectEnabledListByGroupId(Long groupId) { + return selectList(new LambdaQueryWrapperX() + .eq(ImGroupMemberDO::getGroupId, groupId) + .eq(ImGroupMemberDO::getStatus, CommonStatusEnum.ENABLE.getStatus())); + } + + // TODO @AI:selectListByXXX;enabled 传入进来 + default List selectEnabledListByUserId(Long userId) { + return selectList(new LambdaQueryWrapperX() + .eq(ImGroupMemberDO::getUserId, userId) + .eq(ImGroupMemberDO::getStatus, CommonStatusEnum.ENABLE.getStatus())); + } + + /** + * 查询用户已退群的成员记录 + *

+ * 当 {@code minQuitTime} 非空时额外按 {@code quitTime ≥ minQuitTime} 过滤。 + * + * @param userId 用户编号 + * @param minQuitTime 最早退群时间(含),可空 + * @return 已退群成员记录列表 + */ + default List selectQuitListByUserId(Long userId, LocalDateTime minQuitTime) { + return selectList(new LambdaQueryWrapperX() + .eq(ImGroupMemberDO::getUserId, userId) + .eq(ImGroupMemberDO::getStatus, CommonStatusEnum.DISABLE.getStatus()) + .geIfPresent(ImGroupMemberDO::getQuitTime, minQuitTime)); + } + } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImpl.java index d149c90..726c8b9 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImpl.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImpl.java @@ -11,8 +11,10 @@ import cn.iocoder.yudao.module.im.service.websocket.dto.friend.FriendUpdateMessa import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; +import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberService.java index fb418af..123d9cb 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberService.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberService.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMember import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; import jakarta.validation.Valid; +import java.time.LocalDateTime; import java.util.List; /** @@ -54,12 +55,12 @@ public interface ImGroupMemberService { PageResult getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO); /** - * 根据群组id查询群成员 + * 根据群组 id 查询群成员(包含所有状态) * * @param groupId 群组id * @return 群成员列表 */ - List selectByGroupId(Long groupId); + List getGroupMemberListByGroupId(Long groupId); /** * 根据群编号和用户编号查询群成员 @@ -76,5 +77,39 @@ public interface ImGroupMemberService { * @param userId 用户编号 * @return 群成员记录列表 */ - List getGroupMembersByUserId(Long userId); + List getGroupMemberListByUserId(Long userId); + + /** + * 根据群编号查询有效成员列表(仅 ENABLE 状态) + * + * @param groupId 群编号 + * @return 有效群成员列表 + */ + List getActiveGroupMemberListByGroupId(Long groupId); + + /** + * 查询用户所在的所有群的有效成员记录(仅 ENABLE 状态) + * + * @param userId 用户编号 + * @return 有效群成员记录列表 + */ + List getActiveGroupMemberListByUserId(Long userId); + + /** + * 查询用户已退群的群成员记录(DISABLE 状态) + * + * @param userId 用户编号,必传 + * @param minQuitTime 最早退群时间(含),可空 + * @return 已退群成员记录列表 + */ + List getQuitGroupMemberListByUserId(Long userId, LocalDateTime minQuitTime); + + /** + * 校验用户是否为群的有效成员 + * + * @param groupId 群编号 + * @param userId 用户编号 + * @return 群成员记录 + */ + ImGroupMemberDO validateMemberInGroup(Long groupId, Long userId); } diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImpl.java index cf53e64..111c0e4 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImpl.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.im.service.group; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberPageReqVO; import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberSaveReqVO; import org.springframework.stereotype.Service; @@ -12,6 +13,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMemberMapper; +import java.time.LocalDateTime; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -72,7 +74,7 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { } @Override - public List selectByGroupId(Long groupId) { + public List getGroupMemberListByGroupId(Long groupId) { return imGroupMemberMapper.selectListByGroupId(groupId); } @@ -82,8 +84,32 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { } @Override - public List getGroupMembersByUserId(Long userId) { + public List getGroupMemberListByUserId(Long userId) { return imGroupMemberMapper.selectListByUserId(userId); } + @Override + public List getActiveGroupMemberListByGroupId(Long groupId) { + return imGroupMemberMapper.selectEnabledListByGroupId(groupId); + } + + @Override + public List getActiveGroupMemberListByUserId(Long userId) { + return imGroupMemberMapper.selectEnabledListByUserId(userId); + } + + @Override + public List getQuitGroupMemberListByUserId(Long userId, LocalDateTime minQuitTime) { + return imGroupMemberMapper.selectQuitListByUserId(userId, minQuitTime); + } + + @Override + public ImGroupMemberDO validateMemberInGroup(Long groupId, Long userId) { + ImGroupMemberDO member = imGroupMemberMapper.selectByGroupIdAndUserId(groupId, userId); + if (member == null || CommonStatusEnum.DISABLE.getStatus().equals(member.getStatus())) { + throw exception(GROUP_MEMBER_NOT_IN_GROUP); + } + return member; + } + } diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java index a85e9b2..8fddb7b 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java @@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import java.util.List; + /** * 群 Service 接口 * @@ -58,4 +60,14 @@ public interface ImGroupService { */ ImGroupDO validateGroupExists(Long groupId); -} \ No newline at end of file + /** + * 获取指定用户加入的所有"有效"群(未退群且未封禁/解散) + *

+ * 返回当前登录用户在群内身份仍有效的所有群。 + * + * @param userId 用户编号 + * @return 群列表 + */ + List getMyGroupList(Long userId); + +} diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java index bf26a85..6bcc40e 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.im.service.group; +import cn.hutool.core.collection.CollUtil; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; import org.springframework.validation.annotation.Validated; @@ -22,6 +23,7 @@ import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; +// TODO @芋艿:群主的调整,暂时不考虑。后续在弄; /** * 群 Service 实现类 * @@ -37,32 +39,53 @@ public class ImGroupServiceImpl implements ImGroupService { @Resource private ImGroupMemberMapper imGroupMemberMapper; + // TODO @AI:返回对象; + // TODO @AI:要不要拆分 VO;ImGroupCreateReqVO(name) @Override public Long createGroup(ImGroupSaveReqVO createReqVO) { // 插入 ImGroupDO group = BeanUtils.toBean(createReqVO, ImGroupDO.class); imGroupMapper.insert(group); - // 返回 + + // TODO @AI:群主 GroupMember; + + // TODO 多终端推送消息(group message) return group.getId(); } + // TODO @AI:要不要拆分 VO;ImGroupUpdateReqVO(name、avatar、notice);我在本群的昵称/群名备注; + // TODO 1. 需要校验群主:name、avatar、notice;如果修改群信息,是不是要群发消息?(群信息变更消息); + // TODO 2. 需要校验群成员:我在本群的昵称/群名备注 + // TODO @AI:返回 返回对象; @Override public void updateGroup(ImGroupSaveReqVO updateReqVO) { // 校验存在 validateGroupExists(updateReqVO.getId()); + // 更新 ImGroupDO updateObj = BeanUtils.toBean(updateReqVO, ImGroupDO.class); imGroupMapper.updateById(updateObj); } + // TODO @AI:dissolve 解散群; @Override public void deleteGroup(Long id) { // 校验存在 validateGroupExists(id); + // TODO @AI:群主才可以; + + // TODO @AI:清理已读缓存; + + // TODO @AI:推送群解散的提示; + + // TODO @AI:推送群信息变化; + // 删除 imGroupMapper.deleteById(id); } + // TODO @AI:quit 退群; + @Override public ImGroupDO validateGroupExists(Long id) { ImGroupDO group = imGroupMapper.selectById(id); @@ -78,6 +101,10 @@ public class ImGroupServiceImpl implements ImGroupService { return group; } + // TODO @AI:add 加群; + + // TODO @AI:remove 踢人; + @Override public ImGroupDO getGroup(Long id) { return imGroupMapper.selectById(id); @@ -92,14 +119,15 @@ public class ImGroupServiceImpl implements ImGroupService { public List getMyGroupList(Long userId) { // 1. 查用户所在的、仍有效的群成员记录(仅 ENABLE 状态) List members = imGroupMemberMapper.selectEnabledListByUserId(userId); - if (members.isEmpty()) { + if (CollUtil.isNotEmpty(members)) { return Collections.emptyList(); } Set groupIds = CollectionUtils.convertSet(members, ImGroupMemberDO::getGroupId); - if (groupIds.isEmpty()) { + if (CollUtil.isEmpty(groupIds)) { return Collections.emptyList(); } // 2. 查群并过滤掉已封禁/解散的 + // TODO @AI:查询的时候,就过滤掉!不要内存过滤; List groups = imGroupMapper.selectByIds(groupIds); groups.removeIf(g -> Boolean.TRUE.equals(g.getBanned()) || Boolean.TRUE.equals(g.getDissolved())); return groups;