Commit ba5b7dbd0aeb4db8ddf6b6d4d64cbd2844fb0a0f
1 parent
f6a29e53
📝 refactor(messages): 重构消息类,简化字段命名和结构,增强可读性
Showing
14 changed files
with
295 additions
and
143 deletions
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/AudioMessage.java
| 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; | 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | ||
| 4 | -import lombok.AllArgsConstructor; | ||
| 5 | import lombok.Data; | 3 | import lombok.Data; |
| 6 | -import lombok.NoArgsConstructor; | ||
| 7 | 4 | ||
| 8 | -// TODO @anhaohao:要有 IM; | ||
| 9 | -// TODO @芋艿:后续要挪到 api 包下,主要是给外部接口使用 | ||
| 10 | /** | 5 | /** |
| 11 | - * 语音消息的 {@link ImMessageDO 字段 content} 的内容 | ||
| 12 | - * | ||
| 13 | - * @author 芋道源码 | 6 | + * 语音消息内容 |
| 14 | */ | 7 | */ |
| 15 | @Data | 8 | @Data |
| 16 | -@AllArgsConstructor | ||
| 17 | -@NoArgsConstructor | ||
| 18 | public class AudioMessage { | 9 | public class AudioMessage { |
| 19 | 10 | ||
| 20 | /** | 11 | /** |
| 21 | - * 语音文件唯一 ID | 12 | + * 语音文件 URL |
| 22 | */ | 13 | */ |
| 23 | - private String uuid; | ||
| 24 | - | ||
| 25 | - /** | ||
| 26 | - * 语音文件的本地路径 | ||
| 27 | - */ | ||
| 28 | - private String soundPath; | ||
| 29 | - | 14 | + private String url; |
| 30 | /** | 15 | /** |
| 31 | - * 语音文件下载地址 | 16 | + * 语音时长(秒) |
| 32 | */ | 17 | */ |
| 33 | - private String sourceUrl; | ||
| 34 | - | ||
| 35 | - /** | ||
| 36 | - * 语音文件大小 | ||
| 37 | - */ | ||
| 38 | - private int dataSize; | ||
| 39 | - | ||
| 40 | - /** | ||
| 41 | - * 语音时长 | ||
| 42 | - */ | ||
| 43 | - private int duration; | ||
| 44 | - | 18 | + private Integer duration; |
| 45 | /** | 19 | /** |
| 46 | - * 语音文件类型 | 20 | + * 文件大小(字节) |
| 47 | */ | 21 | */ |
| 48 | - private String soundType; | 22 | + private Long size; |
| 49 | 23 | ||
| 50 | -} | ||
| 51 | \ No newline at end of file | 24 | \ No newline at end of file |
| 25 | +} |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/CardMessage.java
| 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; | 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | ||
| 4 | -import lombok.AllArgsConstructor; | ||
| 5 | import lombok.Data; | 3 | import lombok.Data; |
| 6 | -import lombok.NoArgsConstructor; | ||
| 7 | 4 | ||
| 8 | /** | 5 | /** |
| 9 | - * 名片消息的 {@link ImMessageDO 字段 content} 的内容 | ||
| 10 | - * | ||
| 11 | - * @author anhaohao | ||
| 12 | - * @since 2024/3/23 下午5:53 | 6 | + * 名片消息内容 |
| 13 | */ | 7 | */ |
| 14 | @Data | 8 | @Data |
| 15 | -@AllArgsConstructor | ||
| 16 | -@NoArgsConstructor | ||
| 17 | public class CardMessage { | 9 | public class CardMessage { |
| 18 | 10 | ||
| 19 | /** | 11 | /** |
| 20 | - * 用户 ID | 12 | + * 用户编号 |
| 21 | */ | 13 | */ |
| 22 | - private String userID; | ||
| 23 | - | 14 | + private Long userId; |
| 24 | /** | 15 | /** |
| 25 | - * 用户名 | 16 | + * 用户昵称 |
| 26 | */ | 17 | */ |
| 27 | private String nickname; | 18 | private String nickname; |
| 28 | - | ||
| 29 | /** | 19 | /** |
| 30 | * 用户头像 | 20 | * 用户头像 |
| 31 | */ | 21 | */ |
| 32 | - private int faceURL; | 22 | + private String avatar; |
| 33 | 23 | ||
| 34 | - /** | ||
| 35 | - * 扩展字段 | ||
| 36 | - */ | ||
| 37 | - private String ex; | ||
| 38 | } | 24 | } |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/FileMessage.java
| 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; | 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | ||
| 4 | -import lombok.AllArgsConstructor; | ||
| 5 | import lombok.Data; | 3 | import lombok.Data; |
| 6 | -import lombok.NoArgsConstructor; | ||
| 7 | 4 | ||
| 8 | /** | 5 | /** |
| 9 | - * 文件消息的 {@link ImMessageDO 字段 content} 的内容 | ||
| 10 | - * | ||
| 11 | - * @author 芋道源码 | 6 | + * 文件消息内容 |
| 12 | */ | 7 | */ |
| 13 | @Data | 8 | @Data |
| 14 | -@AllArgsConstructor | ||
| 15 | -@NoArgsConstructor | ||
| 16 | public class FileMessage { | 9 | public class FileMessage { |
| 17 | 10 | ||
| 18 | /** | 11 | /** |
| 12 | + * 文件 URL | ||
| 13 | + */ | ||
| 14 | + private String url; | ||
| 15 | + /** | ||
| 19 | * 文件名 | 16 | * 文件名 |
| 20 | */ | 17 | */ |
| 21 | private String name; | 18 | private String name; |
| 22 | /** | 19 | /** |
| 23 | - * 文件 URL | 20 | + * 文件大小(字节) |
| 24 | */ | 21 | */ |
| 25 | - private String url; | 22 | + private Long size; |
| 23 | + /** | ||
| 24 | + * 文件类型(扩展名) | ||
| 25 | + */ | ||
| 26 | + private String type; | ||
| 26 | 27 | ||
| 27 | -} | ||
| 28 | \ No newline at end of file | 28 | \ No newline at end of file |
| 29 | +} |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/ImageMessage.java
| 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; | 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | ||
| 4 | -import lombok.AllArgsConstructor; | ||
| 5 | import lombok.Data; | 3 | import lombok.Data; |
| 6 | -import lombok.NoArgsConstructor; | ||
| 7 | 4 | ||
| 8 | /** | 5 | /** |
| 9 | - * 图片消息的 {@link ImMessageDO 字段 content} 的内容 | ||
| 10 | - * | ||
| 11 | - * @author 芋道源码 | 6 | + * 图片消息内容 |
| 12 | */ | 7 | */ |
| 13 | @Data | 8 | @Data |
| 14 | -@AllArgsConstructor | ||
| 15 | -@NoArgsConstructor | ||
| 16 | public class ImageMessage { | 9 | public class ImageMessage { |
| 17 | 10 | ||
| 18 | /** | 11 | /** |
| 19 | - * 图片地址 | 12 | + * 图片 URL |
| 20 | */ | 13 | */ |
| 21 | private String url; | 14 | private String url; |
| 15 | + /** | ||
| 16 | + * 缩略图 URL | ||
| 17 | + */ | ||
| 18 | + private String thumbnailUrl; | ||
| 19 | + /** | ||
| 20 | + * 图片宽度 | ||
| 21 | + */ | ||
| 22 | + private Integer width; | ||
| 23 | + /** | ||
| 24 | + * 图片高度 | ||
| 25 | + */ | ||
| 26 | + private Integer height; | ||
| 27 | + /** | ||
| 28 | + * 图片大小(字节) | ||
| 29 | + */ | ||
| 30 | + private Long size; | ||
| 22 | 31 | ||
| 23 | } | 32 | } |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/LocationMessage.java
| 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; | 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | ||
| 4 | -import lombok.AllArgsConstructor; | ||
| 5 | import lombok.Data; | 3 | import lombok.Data; |
| 6 | -import lombok.NoArgsConstructor; | ||
| 7 | 4 | ||
| 8 | /** | 5 | /** |
| 9 | - * 地址位置消息的 {@link ImMessageDO 字段 content} 的内容 | ||
| 10 | - * | ||
| 11 | - * @author 芋道源码 | 6 | + * 位置消息内容 |
| 12 | */ | 7 | */ |
| 13 | @Data | 8 | @Data |
| 14 | -@AllArgsConstructor | ||
| 15 | -@NoArgsConstructor | ||
| 16 | public class LocationMessage { | 9 | public class LocationMessage { |
| 17 | 10 | ||
| 18 | /** | 11 | /** |
| 19 | - * 地理位置 | ||
| 20 | - * <p> | ||
| 21 | - * 例如说:中国 浙江省 杭州市 网商路 599号 | 12 | + * 位置描述 |
| 22 | */ | 13 | */ |
| 23 | - private String address; | 14 | + private String description; |
| 24 | /** | 15 | /** |
| 25 | * 经度 | 16 | * 经度 |
| 26 | */ | 17 | */ |
| @@ -30,4 +21,4 @@ public class LocationMessage { | @@ -30,4 +21,4 @@ public class LocationMessage { | ||
| 30 | */ | 21 | */ |
| 31 | private Double latitude; | 22 | private Double latitude; |
| 32 | 23 | ||
| 33 | -} | ||
| 34 | \ No newline at end of file | 24 | \ No newline at end of file |
| 25 | +} |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/TextMessage.java
| 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; | 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | ||
| 4 | -import lombok.AllArgsConstructor; | ||
| 5 | import lombok.Data; | 3 | import lombok.Data; |
| 6 | -import lombok.NoArgsConstructor; | ||
| 7 | 4 | ||
| 8 | /** | 5 | /** |
| 9 | - * 文本消息的 {@link ImMessageDO 字段 content} 的内容 | ||
| 10 | - * | ||
| 11 | - * @author 芋道源码 | 6 | + * 文本消息内容 |
| 12 | */ | 7 | */ |
| 13 | @Data | 8 | @Data |
| 14 | -@AllArgsConstructor | ||
| 15 | -@NoArgsConstructor | ||
| 16 | public class TextMessage { | 9 | public class TextMessage { |
| 17 | 10 | ||
| 18 | /** | 11 | /** |
| 19 | - * 文本消息的具体内容 | 12 | + * 文本内容 |
| 20 | */ | 13 | */ |
| 21 | private String content; | 14 | private String content; |
| 22 | 15 | ||
| 23 | -} | ||
| 24 | \ No newline at end of file | 16 | \ No newline at end of file |
| 17 | +} |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/VideoMessage.java
| 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; | 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message.content; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | ||
| 4 | import lombok.Data; | 3 | import lombok.Data; |
| 5 | 4 | ||
| 6 | /** | 5 | /** |
| 7 | - * 视频消息的 {@link ImMessageDO 字段 content} 的内容 | ||
| 8 | - * | ||
| 9 | - * @author 芋道源码 | 6 | + * 视频消息内容 |
| 10 | */ | 7 | */ |
| 11 | @Data | 8 | @Data |
| 12 | public class VideoMessage { | 9 | public class VideoMessage { |
| 13 | 10 | ||
| 14 | /** | 11 | /** |
| 15 | - * 视频地址 | 12 | + * 视频文件 URL |
| 16 | */ | 13 | */ |
| 17 | private String url; | 14 | private String url; |
| 15 | + /** | ||
| 16 | + * 视频封面 URL | ||
| 17 | + */ | ||
| 18 | + private String coverUrl; | ||
| 19 | + /** | ||
| 20 | + * 视频时长(秒) | ||
| 21 | + */ | ||
| 22 | + private Integer duration; | ||
| 23 | + /** | ||
| 24 | + * 视频宽度 | ||
| 25 | + */ | ||
| 26 | + private Integer width; | ||
| 27 | + /** | ||
| 28 | + * 视频高度 | ||
| 29 | + */ | ||
| 30 | + private Integer height; | ||
| 31 | + /** | ||
| 32 | + * 文件大小(字节) | ||
| 33 | + */ | ||
| 34 | + private Long size; | ||
| 18 | 35 | ||
| 19 | -} | ||
| 20 | \ No newline at end of file | 36 | \ No newline at end of file |
| 37 | +} |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.im.service.group; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | +import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberPageReqVO; | ||
| 5 | +import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberSaveReqVO; | ||
| 6 | +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; | ||
| 7 | +import jakarta.validation.Valid; | ||
| 8 | + | ||
| 9 | +import java.util.List; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * 群成员 Service 接口 | ||
| 13 | + * | ||
| 14 | + * @author 芋道源码 | ||
| 15 | + */ | ||
| 16 | +public interface ImGroupMemberService { | ||
| 17 | + | ||
| 18 | + /** | ||
| 19 | + * 创建群成员 | ||
| 20 | + * | ||
| 21 | + * @param createReqVO 创建信息 | ||
| 22 | + * @return 编号 | ||
| 23 | + */ | ||
| 24 | + Long createGroupMember(@Valid ImGroupMemberSaveReqVO createReqVO); | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 更新群成员 | ||
| 28 | + * | ||
| 29 | + * @param updateReqVO 更新信息 | ||
| 30 | + */ | ||
| 31 | + void updateGroupMember(@Valid ImGroupMemberSaveReqVO updateReqVO); | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * 删除群成员 | ||
| 35 | + * | ||
| 36 | + * @param id 编号 | ||
| 37 | + */ | ||
| 38 | + void deleteGroupMember(Long id); | ||
| 39 | + | ||
| 40 | + /** | ||
| 41 | + * 获得群成员 | ||
| 42 | + * | ||
| 43 | + * @param id 编号 | ||
| 44 | + * @return 群成员 | ||
| 45 | + */ | ||
| 46 | + ImGroupMemberDO getGroupMember(Long id); | ||
| 47 | + | ||
| 48 | + /** | ||
| 49 | + * 获得群成员分页 | ||
| 50 | + * | ||
| 51 | + * @param pageReqVO 分页查询 | ||
| 52 | + * @return 群成员分页 | ||
| 53 | + */ | ||
| 54 | + PageResult<ImGroupMemberDO> getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO); | ||
| 55 | + | ||
| 56 | + /** | ||
| 57 | + * 根据群组id查询群成员 | ||
| 58 | + * | ||
| 59 | + * @param groupId 群组id | ||
| 60 | + * @return 群成员列表 | ||
| 61 | + */ | ||
| 62 | + List<ImGroupMemberDO> selectByGroupId(Long groupId); | ||
| 63 | + | ||
| 64 | + /** | ||
| 65 | + * 根据群编号和用户编号查询群成员 | ||
| 66 | + * | ||
| 67 | + * @param groupId 群编号 | ||
| 68 | + * @param userId 用户编号 | ||
| 69 | + * @return 群成员 | ||
| 70 | + */ | ||
| 71 | + ImGroupMemberDO getGroupMember(Long groupId, Long userId); | ||
| 72 | + | ||
| 73 | + /** | ||
| 74 | + * 查询用户所在的所有群的成员记录 | ||
| 75 | + * | ||
| 76 | + * @param userId 用户编号 | ||
| 77 | + * @return 群成员记录列表 | ||
| 78 | + */ | ||
| 79 | + List<ImGroupMemberDO> getGroupMembersByUserId(Long userId); | ||
| 80 | +} |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.im.service.group; | ||
| 2 | + | ||
| 3 | +import org.springframework.stereotype.Service; | ||
| 4 | +import jakarta.annotation.Resource; | ||
| 5 | +import org.springframework.validation.annotation.Validated; | ||
| 6 | + | ||
| 7 | +import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.*; | ||
| 8 | +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; | ||
| 9 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 10 | +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 11 | + | ||
| 12 | +import cn.iocoder.yudao.module.im.dal.mysql.groupmember.ImGroupMemberMapper; | ||
| 13 | + | ||
| 14 | +import java.util.List; | ||
| 15 | + | ||
| 16 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 17 | +import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * 群成员 Service 实现类 | ||
| 21 | + * | ||
| 22 | + * @author 芋道源码 | ||
| 23 | + */ | ||
| 24 | +@Service | ||
| 25 | +@Validated | ||
| 26 | +public class ImGroupMemberServiceImpl implements ImGroupMemberService { | ||
| 27 | + | ||
| 28 | + @Resource | ||
| 29 | + private ImGroupMemberMapper imGroupMemberMapper; | ||
| 30 | + | ||
| 31 | + @Override | ||
| 32 | + public Long createGroupMember(ImGroupMemberSaveReqVO createReqVO) { | ||
| 33 | + // 插入 | ||
| 34 | + ImGroupMemberDO groupMember = BeanUtils.toBean(createReqVO, ImGroupMemberDO.class); | ||
| 35 | + imGroupMemberMapper.insert(groupMember); | ||
| 36 | + // 返回 | ||
| 37 | + return groupMember.getId(); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + @Override | ||
| 41 | + public void updateGroupMember(ImGroupMemberSaveReqVO updateReqVO) { | ||
| 42 | + // 校验存在 | ||
| 43 | + validateGroupMemberExists(updateReqVO.getId()); | ||
| 44 | + // 更新 | ||
| 45 | + ImGroupMemberDO updateObj = BeanUtils.toBean(updateReqVO, ImGroupMemberDO.class); | ||
| 46 | + imGroupMemberMapper.updateById(updateObj); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + @Override | ||
| 50 | + public void deleteGroupMember(Long id) { | ||
| 51 | + // 校验存在 | ||
| 52 | + validateGroupMemberExists(id); | ||
| 53 | + // 删除 | ||
| 54 | + imGroupMemberMapper.deleteById(id); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + private void validateGroupMemberExists(Long id) { | ||
| 58 | + if (imGroupMemberMapper.selectById(id) == null) { | ||
| 59 | + throw exception(GROUP_MEMBER_NOT_EXISTS); | ||
| 60 | + } | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + @Override | ||
| 64 | + public ImGroupMemberDO getGroupMember(Long id) { | ||
| 65 | + return imGroupMemberMapper.selectById(id); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + @Override | ||
| 69 | + public PageResult<ImGroupMemberDO> getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO) { | ||
| 70 | + return imGroupMemberMapper.selectPage(pageReqVO); | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + @Override | ||
| 74 | + public List<ImGroupMemberDO> selectByGroupId(Long groupId) { | ||
| 75 | + return imGroupMemberMapper.selectListByGroupId(groupId); | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + @Override | ||
| 79 | + public ImGroupMemberDO getGroupMember(Long groupId, Long userId) { | ||
| 80 | + return imGroupMemberMapper.selectByGroupIdAndUserId(groupId, userId); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + @Override | ||
| 84 | + public List<ImGroupMemberDO> getGroupMembersByUserId(Long userId) { | ||
| 85 | + return imGroupMemberMapper.selectListByUserId(userId); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | +} |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImpl.java
| @@ -15,9 +15,9 @@ import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; | @@ -15,9 +15,9 @@ import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; | ||
| 15 | import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; | 15 | import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; |
| 16 | import cn.iocoder.yudao.module.im.enums.message.ImWebSocketTypeConstants; | 16 | import cn.iocoder.yudao.module.im.enums.message.ImWebSocketTypeConstants; |
| 17 | import cn.iocoder.yudao.module.im.service.group.ImGroupService; | 17 | import cn.iocoder.yudao.module.im.service.group.ImGroupService; |
| 18 | -import cn.iocoder.yudao.module.im.service.groupmember.ImGroupMemberService; | 18 | +import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService; |
| 19 | import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; | 19 | import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; |
| 20 | -import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; | 20 | +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; |
| 21 | import jakarta.annotation.Resource; | 21 | import jakarta.annotation.Resource; |
| 22 | import lombok.extern.slf4j.Slf4j; | 22 | import lombok.extern.slf4j.Slf4j; |
| 23 | import org.springframework.stereotype.Service; | 23 | import org.springframework.stereotype.Service; |
| @@ -54,7 +54,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { | @@ -54,7 +54,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { | ||
| 54 | @Resource | 54 | @Resource |
| 55 | private GroupReadPositionRedisDAO groupReadPositionRedisDAO; | 55 | private GroupReadPositionRedisDAO groupReadPositionRedisDAO; |
| 56 | @Resource | 56 | @Resource |
| 57 | - private WebSocketSenderApi webSocketSenderApi; | 57 | + private WebSocketMessageSender webSocketMessageSender; |
| 58 | 58 | ||
| 59 | @Override | 59 | @Override |
| 60 | public ImGroupMessageDO sendMessage(Long senderId, ImGroupMessageSendReqVO reqVO) { | 60 | public ImGroupMessageDO sendMessage(Long senderId, ImGroupMessageSendReqVO reqVO) { |
| @@ -170,7 +170,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { | @@ -170,7 +170,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { | ||
| 170 | Map<String, Object> readEvent = new HashMap<>(); | 170 | Map<String, Object> readEvent = new HashMap<>(); |
| 171 | readEvent.put("groupId", groupId.toString()); | 171 | readEvent.put("groupId", groupId.toString()); |
| 172 | readEvent.put("messageScene", "group"); | 172 | readEvent.put("messageScene", "group"); |
| 173 | - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, | 173 | + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), userId, |
| 174 | ImWebSocketTypeConstants.READ, readEvent); | 174 | ImWebSocketTypeConstants.READ, readEvent); |
| 175 | 175 | ||
| 176 | // 5. 刷新群回执 | 176 | // 5. 刷新群回执 |
| @@ -209,7 +209,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { | @@ -209,7 +209,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { | ||
| 209 | if (ImGroupMemberStatusEnum.QUIT.getStatus().equals(m.getStatus())) { | 209 | if (ImGroupMemberStatusEnum.QUIT.getStatus().equals(m.getStatus())) { |
| 210 | continue; | 210 | continue; |
| 211 | } | 211 | } |
| 212 | - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), m.getUserId(), | 212 | + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), m.getUserId(), |
| 213 | ImWebSocketTypeConstants.RECALL, recallEvent); | 213 | ImWebSocketTypeConstants.RECALL, recallEvent); |
| 214 | } | 214 | } |
| 215 | } | 215 | } |
| @@ -302,7 +302,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { | @@ -302,7 +302,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { | ||
| 302 | if (ImGroupMemberStatusEnum.QUIT.getStatus().equals(m.getStatus())) { | 302 | if (ImGroupMemberStatusEnum.QUIT.getStatus().equals(m.getStatus())) { |
| 303 | continue; | 303 | continue; |
| 304 | } | 304 | } |
| 305 | - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), m.getUserId(), | 305 | + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), m.getUserId(), |
| 306 | ImWebSocketTypeConstants.RECEIPT, receiptEvent); | 306 | ImWebSocketTypeConstants.RECEIPT, receiptEvent); |
| 307 | } | 307 | } |
| 308 | } | 308 | } |
| @@ -382,7 +382,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { | @@ -382,7 +382,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { | ||
| 382 | && !member.getUserId().equals(message.getSenderId())) { | 382 | && !member.getUserId().equals(message.getSenderId())) { |
| 383 | continue; | 383 | continue; |
| 384 | } | 384 | } |
| 385 | - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), member.getUserId(), | 385 | + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), member.getUserId(), |
| 386 | ImWebSocketTypeConstants.GROUP_MESSAGE, event); | 386 | ImWebSocketTypeConstants.GROUP_MESSAGE, event); |
| 387 | } | 387 | } |
| 388 | } | 388 | } |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImpl.java
| @@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; | @@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; | ||
| 9 | import cn.iocoder.yudao.module.im.enums.message.ImWebSocketTypeConstants; | 9 | import cn.iocoder.yudao.module.im.enums.message.ImWebSocketTypeConstants; |
| 10 | import cn.iocoder.yudao.module.im.service.friend.ImFriendService; | 10 | import cn.iocoder.yudao.module.im.service.friend.ImFriendService; |
| 11 | import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; | 11 | import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; |
| 12 | -import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; | 12 | +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; |
| 13 | import jakarta.annotation.Resource; | 13 | import jakarta.annotation.Resource; |
| 14 | import lombok.extern.slf4j.Slf4j; | 14 | import lombok.extern.slf4j.Slf4j; |
| 15 | import org.springframework.stereotype.Service; | 15 | import org.springframework.stereotype.Service; |
| @@ -48,7 +48,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { | @@ -48,7 +48,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { | ||
| 48 | 48 | ||
| 49 | // TODO @AI:这个类貌似路径不对?! | 49 | // TODO @AI:这个类貌似路径不对?! |
| 50 | @Resource | 50 | @Resource |
| 51 | - private WebSocketSenderApi webSocketSenderApi; | 51 | + private WebSocketMessageSender webSocketMessageSender; |
| 52 | 52 | ||
| 53 | @Override | 53 | @Override |
| 54 | public ImPrivateMessageDO sendMessage(Long senderId, ImPrivateMessageSendReqVO reqVO) { | 54 | public ImPrivateMessageDO sendMessage(Long senderId, ImPrivateMessageSendReqVO reqVO) { |
| @@ -107,7 +107,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { | @@ -107,7 +107,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { | ||
| 107 | // TODO @AI:需要整理下,相关的 websocket DTO;可维护性变强! | 107 | // TODO @AI:需要整理下,相关的 websocket DTO;可维护性变强! |
| 108 | readEvent.put("friendId", friendId.toString()); | 108 | readEvent.put("friendId", friendId.toString()); |
| 109 | readEvent.put("messageScene", "private"); | 109 | readEvent.put("messageScene", "private"); |
| 110 | - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, | 110 | + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), userId, |
| 111 | ImWebSocketTypeConstants.READ, readEvent); | 111 | ImWebSocketTypeConstants.READ, readEvent); |
| 112 | 112 | ||
| 113 | // 3. 发送 RECEIPT 事件给对方(已读回执) | 113 | // 3. 发送 RECEIPT 事件给对方(已读回执) |
| @@ -115,7 +115,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { | @@ -115,7 +115,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { | ||
| 115 | // TODO @AI:需要整理下,相关的 websocket DTO;可维护性变强! | 115 | // TODO @AI:需要整理下,相关的 websocket DTO;可维护性变强! |
| 116 | receiptEvent.put("userId", userId.toString()); | 116 | receiptEvent.put("userId", userId.toString()); |
| 117 | receiptEvent.put("messageScene", "private"); | 117 | receiptEvent.put("messageScene", "private"); |
| 118 | - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), friendId, | 118 | + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), friendId, |
| 119 | ImWebSocketTypeConstants.RECEIPT, receiptEvent); | 119 | ImWebSocketTypeConstants.RECEIPT, receiptEvent); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| @@ -147,11 +147,11 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { | @@ -147,11 +147,11 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { | ||
| 147 | recallEvent.put("messageId", messageId.toString()); | 147 | recallEvent.put("messageId", messageId.toString()); |
| 148 | recallEvent.put("messageScene", "private"); | 148 | recallEvent.put("messageScene", "private"); |
| 149 | recallEvent.put("senderId", userId.toString()); | 149 | recallEvent.put("senderId", userId.toString()); |
| 150 | - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), message.getReceiverId(), | 150 | + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), message.getReceiverId(), |
| 151 | ImWebSocketTypeConstants.RECALL, recallEvent); | 151 | ImWebSocketTypeConstants.RECALL, recallEvent); |
| 152 | // 3.2 也通知发送方自己的其他终端 | 152 | // 3.2 也通知发送方自己的其他终端 |
| 153 | // TODO @AI:需要整理下,相关的 websocket DTO;可维护性变强! | 153 | // TODO @AI:需要整理下,相关的 websocket DTO;可维护性变强! |
| 154 | - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, | 154 | + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), userId, |
| 155 | ImWebSocketTypeConstants.RECALL, recallEvent); | 155 | ImWebSocketTypeConstants.RECALL, recallEvent); |
| 156 | } | 156 | } |
| 157 | 157 | ||
| @@ -171,10 +171,10 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { | @@ -171,10 +171,10 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { | ||
| 171 | event.put("sendTime", message.getSendTime().toString()); | 171 | event.put("sendTime", message.getSendTime().toString()); |
| 172 | event.put("messageScene", "private"); | 172 | event.put("messageScene", "private"); |
| 173 | // 推送给接收方 | 173 | // 推送给接收方 |
| 174 | - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), message.getReceiverId(), | 174 | + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), message.getReceiverId(), |
| 175 | ImWebSocketTypeConstants.PRIVATE_MESSAGE, event); | 175 | ImWebSocketTypeConstants.PRIVATE_MESSAGE, event); |
| 176 | // 推送给发送方自己的其他终端(多端同步) | 176 | // 推送给发送方自己的其他终端(多端同步) |
| 177 | - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), message.getSenderId(), | 177 | + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), message.getSenderId(), |
| 178 | ImWebSocketTypeConstants.PRIVATE_MESSAGE, event); | 178 | ImWebSocketTypeConstants.PRIVATE_MESSAGE, event); |
| 179 | } | 179 | } |
| 180 | 180 |
yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImplTest.java
| 1 | package cn.iocoder.yudao.module.im.service.message; | 1 | package cn.iocoder.yudao.module.im.service.message; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.exception.ServiceException; | 3 | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| 4 | -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImGroupMessageSendReqVO; | 4 | +import cn.iocoder.yudao.module.im.controller.admin.message.vo.group.ImGroupMessageSendReqVO; |
| 5 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; | 5 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; |
| 6 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; | 6 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; |
| 7 | import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO; | 7 | import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO; |
| @@ -11,9 +11,9 @@ import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberStatusEnum; | @@ -11,9 +11,9 @@ import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberStatusEnum; | ||
| 11 | import cn.iocoder.yudao.module.im.enums.message.ImGroupMessageReceiptStatusEnum; | 11 | import cn.iocoder.yudao.module.im.enums.message.ImGroupMessageReceiptStatusEnum; |
| 12 | import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; | 12 | import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; |
| 13 | import cn.iocoder.yudao.module.im.service.group.ImGroupService; | 13 | import cn.iocoder.yudao.module.im.service.group.ImGroupService; |
| 14 | -import cn.iocoder.yudao.module.im.service.groupmember.ImGroupMemberService; | 14 | +import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService; |
| 15 | import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; | 15 | import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; |
| 16 | -import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; | 16 | +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; |
| 17 | import org.junit.jupiter.api.Test; | 17 | import org.junit.jupiter.api.Test; |
| 18 | import org.junit.jupiter.api.extension.ExtendWith; | 18 | import org.junit.jupiter.api.extension.ExtendWith; |
| 19 | import org.mockito.InjectMocks; | 19 | import org.mockito.InjectMocks; |
| @@ -51,7 +51,7 @@ public class ImGroupMessageServiceImplTest { | @@ -51,7 +51,7 @@ public class ImGroupMessageServiceImplTest { | ||
| 51 | @Mock | 51 | @Mock |
| 52 | private GroupReadPositionRedisDAO groupReadPositionRedisDAO; | 52 | private GroupReadPositionRedisDAO groupReadPositionRedisDAO; |
| 53 | @Mock | 53 | @Mock |
| 54 | - private WebSocketSenderApi webSocketSenderApi; | 54 | + private WebSocketMessageSender webSocketMessageSender; |
| 55 | 55 | ||
| 56 | private ImGroupMessageSendReqVO buildSendReqVO() { | 56 | private ImGroupMessageSendReqVO buildSendReqVO() { |
| 57 | ImGroupMessageSendReqVO reqVO = new ImGroupMessageSendReqVO(); | 57 | ImGroupMessageSendReqVO reqVO = new ImGroupMessageSendReqVO(); |
| @@ -89,7 +89,11 @@ public class ImGroupMessageServiceImplTest { | @@ -89,7 +89,11 @@ public class ImGroupMessageServiceImplTest { | ||
| 89 | .status(ImGroupMemberStatusEnum.NORMAL.getStatus()).build() | 89 | .status(ImGroupMemberStatusEnum.NORMAL.getStatus()).build() |
| 90 | ); | 90 | ); |
| 91 | when(imGroupMemberService.selectByGroupId(10L)).thenReturn(allMembers); | 91 | when(imGroupMemberService.selectByGroupId(10L)).thenReturn(allMembers); |
| 92 | - when(imGroupMessageMapper.insert(any())).thenReturn(1); | 92 | + when(imGroupMessageMapper.insert(any(ImGroupMessageDO.class))).thenAnswer(invocation -> { |
| 93 | + ImGroupMessageDO msg = invocation.getArgument(0); | ||
| 94 | + msg.setId(99L); | ||
| 95 | + return 1; | ||
| 96 | + }); | ||
| 93 | 97 | ||
| 94 | // 调用 | 98 | // 调用 |
| 95 | ImGroupMessageDO result = groupMessageService.sendMessage(1L, reqVO); | 99 | ImGroupMessageDO result = groupMessageService.sendMessage(1L, reqVO); |
| @@ -102,7 +106,7 @@ public class ImGroupMessageServiceImplTest { | @@ -102,7 +106,7 @@ public class ImGroupMessageServiceImplTest { | ||
| 102 | assertEquals(ImGroupMessageReceiptStatusEnum.NO_RECEIPT.getStatus(), result.getReceiptStatus()); | 106 | assertEquals(ImGroupMessageReceiptStatusEnum.NO_RECEIPT.getStatus(), result.getReceiptStatus()); |
| 103 | 107 | ||
| 104 | // 验证推送给 3 个群成员 | 108 | // 验证推送给 3 个群成员 |
| 105 | - verify(webSocketSenderApi, times(3)).sendObject(anyInt(), anyLong(), anyString(), any()); | 109 | + verify(webSocketMessageSender, times(3)).sendObject(anyInt(), anyLong(), anyString(), any()); |
| 106 | } | 110 | } |
| 107 | 111 | ||
| 108 | @Test | 112 | @Test |
| @@ -121,7 +125,7 @@ public class ImGroupMessageServiceImplTest { | @@ -121,7 +125,7 @@ public class ImGroupMessageServiceImplTest { | ||
| 121 | 125 | ||
| 122 | // 断言 | 126 | // 断言 |
| 123 | assertEquals(100L, result.getId()); | 127 | assertEquals(100L, result.getId()); |
| 124 | - verify(imGroupMessageMapper, never()).insert(any()); | 128 | + verify(imGroupMessageMapper, never()).insert(any(ImGroupMessageDO.class)); |
| 125 | } | 129 | } |
| 126 | 130 | ||
| 127 | @Test | 131 | @Test |
| @@ -262,7 +266,7 @@ public class ImGroupMessageServiceImplTest { | @@ -262,7 +266,7 @@ public class ImGroupMessageServiceImplTest { | ||
| 262 | .id(50L).senderId(1L).groupId(10L) | 266 | .id(50L).senderId(1L).groupId(10L) |
| 263 | .status(ImMessageStatusEnum.NORMAL).build(); | 267 | .status(ImMessageStatusEnum.NORMAL).build(); |
| 264 | when(imGroupMessageMapper.selectById(50L)).thenReturn(message); | 268 | when(imGroupMessageMapper.selectById(50L)).thenReturn(message); |
| 265 | - when(imGroupMessageMapper.updateById(any())).thenReturn(1); | 269 | + when(imGroupMessageMapper.updateById(any(ImGroupMessageDO.class))).thenReturn(1); |
| 266 | 270 | ||
| 267 | List<ImGroupMemberDO> members = List.of( | 271 | List<ImGroupMemberDO> members = List.of( |
| 268 | ImGroupMemberDO.builder().groupId(10L).userId(1L) | 272 | ImGroupMemberDO.builder().groupId(10L).userId(1L) |
| @@ -278,7 +282,7 @@ public class ImGroupMessageServiceImplTest { | @@ -278,7 +282,7 @@ public class ImGroupMessageServiceImplTest { | ||
| 278 | groupMessageService.recallMessage(1L, 50L); | 282 | groupMessageService.recallMessage(1L, 50L); |
| 279 | 283 | ||
| 280 | // 断言:只给 2 个活跃成员发送 RECALL 事件(userId=3 已退群) | 284 | // 断言:只给 2 个活跃成员发送 RECALL 事件(userId=3 已退群) |
| 281 | - verify(webSocketSenderApi, times(2)).sendObject(anyInt(), anyLong(), anyString(), any()); | 285 | + verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), anyString(), any()); |
| 282 | } | 286 | } |
| 283 | 287 | ||
| 284 | // ========== 群已读测试 ========== | 288 | // ========== 群已读测试 ========== |
yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImplTest.java
| @@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper; | @@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper; | ||
| 7 | import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; | 7 | import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; |
| 8 | import cn.iocoder.yudao.module.im.service.friend.ImFriendService; | 8 | import cn.iocoder.yudao.module.im.service.friend.ImFriendService; |
| 9 | import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; | 9 | import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; |
| 10 | -import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; | 10 | +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; |
| 11 | import org.junit.jupiter.api.Test; | 11 | import org.junit.jupiter.api.Test; |
| 12 | import org.junit.jupiter.api.extension.ExtendWith; | 12 | import org.junit.jupiter.api.extension.ExtendWith; |
| 13 | import org.mockito.InjectMocks; | 13 | import org.mockito.InjectMocks; |
| @@ -40,7 +40,7 @@ public class ImPrivateMessageServiceImplTest { | @@ -40,7 +40,7 @@ public class ImPrivateMessageServiceImplTest { | ||
| 40 | @Mock | 40 | @Mock |
| 41 | private ImSensitiveWordService imSensitiveWordService; | 41 | private ImSensitiveWordService imSensitiveWordService; |
| 42 | @Mock | 42 | @Mock |
| 43 | - private WebSocketSenderApi webSocketSenderApi; | 43 | + private WebSocketMessageSender webSocketMessageSender; |
| 44 | 44 | ||
| 45 | private ImPrivateMessageSendReqVO buildSendReqVO() { | 45 | private ImPrivateMessageSendReqVO buildSendReqVO() { |
| 46 | ImPrivateMessageSendReqVO reqVO = new ImPrivateMessageSendReqVO(); | 46 | ImPrivateMessageSendReqVO reqVO = new ImPrivateMessageSendReqVO(); |
| @@ -59,7 +59,11 @@ public class ImPrivateMessageServiceImplTest { | @@ -59,7 +59,11 @@ public class ImPrivateMessageServiceImplTest { | ||
| 59 | ImPrivateMessageSendReqVO reqVO = buildSendReqVO(); | 59 | ImPrivateMessageSendReqVO reqVO = buildSendReqVO(); |
| 60 | when(imPrivateMessageMapper.selectBySenderIdAndClientMessageId(1L, "test-uuid-001")) | 60 | when(imPrivateMessageMapper.selectBySenderIdAndClientMessageId(1L, "test-uuid-001")) |
| 61 | .thenReturn(null); | 61 | .thenReturn(null); |
| 62 | - when(imPrivateMessageMapper.insert(any())).thenReturn(1); | 62 | + when(imPrivateMessageMapper.insert(any(ImPrivateMessageDO.class))).thenAnswer(invocation -> { |
| 63 | + ImPrivateMessageDO msg = invocation.getArgument(0); | ||
| 64 | + msg.setId(99L); | ||
| 65 | + return 1; | ||
| 66 | + }); | ||
| 63 | 67 | ||
| 64 | // 调用 | 68 | // 调用 |
| 65 | ImPrivateMessageDO result = privateMessageService.sendMessage(1L, reqVO); | 69 | ImPrivateMessageDO result = privateMessageService.sendMessage(1L, reqVO); |
| @@ -75,8 +79,8 @@ public class ImPrivateMessageServiceImplTest { | @@ -75,8 +79,8 @@ public class ImPrivateMessageServiceImplTest { | ||
| 75 | // 验证调用 | 79 | // 验证调用 |
| 76 | verify(imFriendService).validateIsFriend(1L, 2L); | 80 | verify(imFriendService).validateIsFriend(1L, 2L); |
| 77 | verify(imSensitiveWordService).validateText(reqVO.getContent()); | 81 | verify(imSensitiveWordService).validateText(reqVO.getContent()); |
| 78 | - verify(imPrivateMessageMapper).insert(any()); | ||
| 79 | - verify(webSocketSenderApi, times(2)).sendObject(anyInt(), anyLong(), anyString(), any()); | 82 | + verify(imPrivateMessageMapper).insert(any(ImPrivateMessageDO.class)); |
| 83 | + verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), anyString(), any()); | ||
| 80 | } | 84 | } |
| 81 | 85 | ||
| 82 | @Test | 86 | @Test |
| @@ -96,7 +100,7 @@ public class ImPrivateMessageServiceImplTest { | @@ -96,7 +100,7 @@ public class ImPrivateMessageServiceImplTest { | ||
| 96 | // 断言:返回已存在的消息 | 100 | // 断言:返回已存在的消息 |
| 97 | assertEquals(100L, result.getId()); | 101 | assertEquals(100L, result.getId()); |
| 98 | // 验证不会重复插入 | 102 | // 验证不会重复插入 |
| 99 | - verify(imPrivateMessageMapper, never()).insert(any()); | 103 | + verify(imPrivateMessageMapper, never()).insert(any(ImPrivateMessageDO.class)); |
| 100 | } | 104 | } |
| 101 | 105 | ||
| 102 | @Test | 106 | @Test |
| @@ -151,7 +155,7 @@ public class ImPrivateMessageServiceImplTest { | @@ -151,7 +155,7 @@ public class ImPrivateMessageServiceImplTest { | ||
| 151 | privateMessageService.readMessages(1L, 2L); | 155 | privateMessageService.readMessages(1L, 2L); |
| 152 | 156 | ||
| 153 | // 断言:发送了 READ 和 RECEIPT 事件 | 157 | // 断言:发送了 READ 和 RECEIPT 事件 |
| 154 | - verify(webSocketSenderApi, times(2)).sendObject(anyInt(), anyLong(), anyString(), any()); | 158 | + verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), anyString(), any()); |
| 155 | } | 159 | } |
| 156 | 160 | ||
| 157 | // ========== 撤回测试 ========== | 161 | // ========== 撤回测试 ========== |
| @@ -163,15 +167,15 @@ public class ImPrivateMessageServiceImplTest { | @@ -163,15 +167,15 @@ public class ImPrivateMessageServiceImplTest { | ||
| 163 | .id(10L).senderId(1L).receiverId(2L) | 167 | .id(10L).senderId(1L).receiverId(2L) |
| 164 | .status(ImMessageStatusEnum.UNREAD.getStatus()).build(); | 168 | .status(ImMessageStatusEnum.UNREAD.getStatus()).build(); |
| 165 | when(imPrivateMessageMapper.selectById(10L)).thenReturn(message); | 169 | when(imPrivateMessageMapper.selectById(10L)).thenReturn(message); |
| 166 | - when(imPrivateMessageMapper.updateById(any())).thenReturn(1); | 170 | + when(imPrivateMessageMapper.updateById(any(ImPrivateMessageDO.class))).thenReturn(1); |
| 167 | 171 | ||
| 168 | // 调用 | 172 | // 调用 |
| 169 | privateMessageService.recallMessage(1L, 10L); | 173 | privateMessageService.recallMessage(1L, 10L); |
| 170 | 174 | ||
| 171 | // 断言 | 175 | // 断言 |
| 172 | - verify(imPrivateMessageMapper).updateById(any()); | 176 | + verify(imPrivateMessageMapper).updateById(any(ImPrivateMessageDO.class)); |
| 173 | // 验证推送了 RECALL 事件(给接收方和发送方) | 177 | // 验证推送了 RECALL 事件(给接收方和发送方) |
| 174 | - verify(webSocketSenderApi, times(2)).sendObject(anyInt(), anyLong(), anyString(), any()); | 178 | + verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), anyString(), any()); |
| 175 | } | 179 | } |
| 176 | 180 | ||
| 177 | @Test | 181 | @Test |
yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImWebSocketEventTest.java
| @@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper; | @@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper; | ||
| 6 | import cn.iocoder.yudao.module.im.enums.message.ImWebSocketTypeConstants; | 6 | import cn.iocoder.yudao.module.im.enums.message.ImWebSocketTypeConstants; |
| 7 | import cn.iocoder.yudao.module.im.service.friend.ImFriendService; | 7 | import cn.iocoder.yudao.module.im.service.friend.ImFriendService; |
| 8 | import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; | 8 | import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; |
| 9 | -import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; | 9 | +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; |
| 10 | import org.junit.jupiter.api.Test; | 10 | import org.junit.jupiter.api.Test; |
| 11 | import org.junit.jupiter.api.extension.ExtendWith; | 11 | import org.junit.jupiter.api.extension.ExtendWith; |
| 12 | import org.mockito.ArgumentCaptor; | 12 | import org.mockito.ArgumentCaptor; |
| @@ -40,7 +40,7 @@ public class ImWebSocketEventTest { | @@ -40,7 +40,7 @@ public class ImWebSocketEventTest { | ||
| 40 | @Mock | 40 | @Mock |
| 41 | private ImSensitiveWordService imSensitiveWordService; | 41 | private ImSensitiveWordService imSensitiveWordService; |
| 42 | @Mock | 42 | @Mock |
| 43 | - private WebSocketSenderApi webSocketSenderApi; | 43 | + private WebSocketMessageSender webSocketMessageSender; |
| 44 | 44 | ||
| 45 | @Test | 45 | @Test |
| 46 | public void testSendMessage_websocketEvent() { | 46 | public void testSendMessage_websocketEvent() { |
| @@ -52,7 +52,12 @@ public class ImWebSocketEventTest { | @@ -52,7 +52,12 @@ public class ImWebSocketEventTest { | ||
| 52 | reqVO.setContent("{\"content\":\"事件测试\"}"); | 52 | reqVO.setContent("{\"content\":\"事件测试\"}"); |
| 53 | 53 | ||
| 54 | when(imPrivateMessageMapper.selectBySenderIdAndClientMessageId(1L, "evt-uuid")).thenReturn(null); | 54 | when(imPrivateMessageMapper.selectBySenderIdAndClientMessageId(1L, "evt-uuid")).thenReturn(null); |
| 55 | - when(imPrivateMessageMapper.insert(any())).thenReturn(1); | 55 | + // mock insert:通过 doAnswer 模拟 MyBatis-Plus 设置 ID |
| 56 | + when(imPrivateMessageMapper.insert(any(ImPrivateMessageDO.class))).thenAnswer(invocation -> { | ||
| 57 | + ImPrivateMessageDO msg = invocation.getArgument(0); | ||
| 58 | + msg.setId(99L); | ||
| 59 | + return 1; | ||
| 60 | + }); | ||
| 56 | 61 | ||
| 57 | // 调用 | 62 | // 调用 |
| 58 | privateMessageService.sendMessage(1L, reqVO); | 63 | privateMessageService.sendMessage(1L, reqVO); |
| @@ -60,7 +65,7 @@ public class ImWebSocketEventTest { | @@ -60,7 +65,7 @@ public class ImWebSocketEventTest { | ||
| 60 | // 捕获 WebSocket 调用 | 65 | // 捕获 WebSocket 调用 |
| 61 | ArgumentCaptor<String> typeCaptor = ArgumentCaptor.forClass(String.class); | 66 | ArgumentCaptor<String> typeCaptor = ArgumentCaptor.forClass(String.class); |
| 62 | ArgumentCaptor<Object> contentCaptor = ArgumentCaptor.forClass(Object.class); | 67 | ArgumentCaptor<Object> contentCaptor = ArgumentCaptor.forClass(Object.class); |
| 63 | - verify(webSocketSenderApi, times(2)).sendObject(anyInt(), anyLong(), | 68 | + verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), |
| 64 | typeCaptor.capture(), contentCaptor.capture()); | 69 | typeCaptor.capture(), contentCaptor.capture()); |
| 65 | 70 | ||
| 66 | // 验证消息事件类型 | 71 | // 验证消息事件类型 |
| @@ -87,7 +92,7 @@ public class ImWebSocketEventTest { | @@ -87,7 +92,7 @@ public class ImWebSocketEventTest { | ||
| 87 | // 捕获 | 92 | // 捕获 |
| 88 | ArgumentCaptor<String> typeCaptor = ArgumentCaptor.forClass(String.class); | 93 | ArgumentCaptor<String> typeCaptor = ArgumentCaptor.forClass(String.class); |
| 89 | ArgumentCaptor<Long> userCaptor = ArgumentCaptor.forClass(Long.class); | 94 | ArgumentCaptor<Long> userCaptor = ArgumentCaptor.forClass(Long.class); |
| 90 | - verify(webSocketSenderApi, times(2)).sendObject(anyInt(), userCaptor.capture(), | 95 | + verify(webSocketMessageSender, times(2)).sendObject(anyInt(), userCaptor.capture(), |
| 91 | typeCaptor.capture(), any()); | 96 | typeCaptor.capture(), any()); |
| 92 | 97 | ||
| 93 | // 第一次:发给自己的 READ 事件 | 98 | // 第一次:发给自己的 READ 事件 |
| @@ -104,7 +109,7 @@ public class ImWebSocketEventTest { | @@ -104,7 +109,7 @@ public class ImWebSocketEventTest { | ||
| 104 | ImPrivateMessageDO message = ImPrivateMessageDO.builder() | 109 | ImPrivateMessageDO message = ImPrivateMessageDO.builder() |
| 105 | .id(10L).senderId(1L).receiverId(2L).status(0).build(); | 110 | .id(10L).senderId(1L).receiverId(2L).status(0).build(); |
| 106 | when(imPrivateMessageMapper.selectById(10L)).thenReturn(message); | 111 | when(imPrivateMessageMapper.selectById(10L)).thenReturn(message); |
| 107 | - when(imPrivateMessageMapper.updateById(any())).thenReturn(1); | 112 | + when(imPrivateMessageMapper.updateById(any(ImPrivateMessageDO.class))).thenReturn(1); |
| 108 | 113 | ||
| 109 | // 调用 | 114 | // 调用 |
| 110 | privateMessageService.recallMessage(1L, 10L); | 115 | privateMessageService.recallMessage(1L, 10L); |
| @@ -112,7 +117,7 @@ public class ImWebSocketEventTest { | @@ -112,7 +117,7 @@ public class ImWebSocketEventTest { | ||
| 112 | // 捕获 | 117 | // 捕获 |
| 113 | ArgumentCaptor<String> typeCaptor = ArgumentCaptor.forClass(String.class); | 118 | ArgumentCaptor<String> typeCaptor = ArgumentCaptor.forClass(String.class); |
| 114 | ArgumentCaptor<Object> contentCaptor = ArgumentCaptor.forClass(Object.class); | 119 | ArgumentCaptor<Object> contentCaptor = ArgumentCaptor.forClass(Object.class); |
| 115 | - verify(webSocketSenderApi, times(2)).sendObject(anyInt(), anyLong(), | 120 | + verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), |
| 116 | typeCaptor.capture(), contentCaptor.capture()); | 121 | typeCaptor.capture(), contentCaptor.capture()); |
| 117 | 122 | ||
| 118 | // 验证 RECALL 事件类型 | 123 | // 验证 RECALL 事件类型 |