Commit 2b891cb4321ae3bb42dad7ffc30c4269413cba47
1 parent
84cea037
IM:code review 消息发送的实现
Showing
32 changed files
with
99 additions
and
90 deletions
yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ConversationTypeEnum.java
| @@ -6,6 +6,7 @@ import lombok.Getter; | @@ -6,6 +6,7 @@ import lombok.Getter; | ||
| 6 | 6 | ||
| 7 | import java.util.Arrays; | 7 | import java.util.Arrays; |
| 8 | 8 | ||
| 9 | +// TODO @anhaohao:IM 前缀还是要的哈 | ||
| 9 | /** | 10 | /** |
| 10 | * IM 会话类型枚举 | 11 | * IM 会话类型枚举 |
| 11 | * 参考 <a href="https://doc.rentsoft.cn/zh-Hans/sdks/enum/conversationType">“会话类型”</a> 文档 | 12 | * 参考 <a href="https://doc.rentsoft.cn/zh-Hans/sdks/enum/conversationType">“会话类型”</a> 文档 |
| @@ -38,7 +39,7 @@ public enum ConversationTypeEnum implements IntArrayValuable { | @@ -38,7 +39,7 @@ public enum ConversationTypeEnum implements IntArrayValuable { | ||
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | /** | 41 | /** |
| 41 | - * 生成会话编号 | 42 | + * 生成会话编号 TODO @anhaohao:方法注释,和下面参数之间,要有空格 |
| 42 | * @param fromUserId 发送者编号 | 43 | * @param fromUserId 发送者编号 |
| 43 | * @param receiverId 接收者编号 | 44 | * @param receiverId 接收者编号 |
| 44 | * @param conversationType 会话类型 | 45 | * @param conversationType 会话类型 |
yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageContentTypeEnum.java
| @@ -6,7 +6,7 @@ import lombok.Getter; | @@ -6,7 +6,7 @@ import lombok.Getter; | ||
| 6 | 6 | ||
| 7 | import java.util.Arrays; | 7 | import java.util.Arrays; |
| 8 | 8 | ||
| 9 | - | 9 | +// TODO @anhaohao:IM 前缀还是要的哈 |
| 10 | /** | 10 | /** |
| 11 | * IM 消息的类型枚举 | 11 | * IM 消息的类型枚举 |
| 12 | * <p> | 12 | * <p> |
| @@ -34,11 +34,11 @@ public enum MessageContentTypeEnum implements IntArrayValuable { | @@ -34,11 +34,11 @@ public enum MessageContentTypeEnum implements IntArrayValuable { | ||
| 34 | QUOTE(114, "引用消息"), | 34 | QUOTE(114, "引用消息"), |
| 35 | FACE(115, "表情消息"), | 35 | FACE(115, "表情消息"), |
| 36 | ADVANCED_REVOKE(118, "高级撤回消息"), | 36 | ADVANCED_REVOKE(118, "高级撤回消息"), |
| 37 | - //好友通知 1200-1299 | 37 | + // ========== 好友通知 1200-1299 =========== |
| 38 | FRIEND_ADDED(1201, "双方成为好友通知"), | 38 | FRIEND_ADDED(1201, "双方成为好友通知"), |
| 39 | - //系统通知 1400 | 39 | + // ========== 系统通知 1400 ========== |
| 40 | OA_NOTIFICATION(1400, "系统通知"), | 40 | OA_NOTIFICATION(1400, "系统通知"), |
| 41 | - //群相关 1500-1599 | 41 | + // ========== 群相关 1500-1599 ========== |
| 42 | GROUP_CREATED(1501, "群创建通知"), | 42 | GROUP_CREATED(1501, "群创建通知"), |
| 43 | GROUP_INFO_CHANGED(1502, "群信息改变通知"), | 43 | GROUP_INFO_CHANGED(1502, "群信息改变通知"), |
| 44 | MEMBER_QUIT(1504, "群成员退出通知"), | 44 | MEMBER_QUIT(1504, "群成员退出通知"), |
yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageSourceEnum.java
| @@ -6,8 +6,9 @@ import lombok.RequiredArgsConstructor; | @@ -6,8 +6,9 @@ import lombok.RequiredArgsConstructor; | ||
| 6 | 6 | ||
| 7 | import java.util.Arrays; | 7 | import java.util.Arrays; |
| 8 | 8 | ||
| 9 | +// TODO @anhaohao:IM 前缀还是要的哈 | ||
| 9 | /** | 10 | /** |
| 10 | - * IM 消息的消息来源 100-用户发送;200-系统发送(一般是通知);不能为空 | 11 | + * IM 消息的消息来源 |
| 11 | */ | 12 | */ |
| 12 | @RequiredArgsConstructor | 13 | @RequiredArgsConstructor |
| 13 | @Getter | 14 | @Getter |
| @@ -18,11 +19,11 @@ public enum MessageSourceEnum implements IntArrayValuable { | @@ -18,11 +19,11 @@ public enum MessageSourceEnum implements IntArrayValuable { | ||
| 18 | 19 | ||
| 19 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MessageSourceEnum::getStatus).toArray(); | 20 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MessageSourceEnum::getStatus).toArray(); |
| 20 | 21 | ||
| 22 | + // TODO @anhaohao:应该是 source | ||
| 21 | /** | 23 | /** |
| 22 | * 状态 | 24 | * 状态 |
| 23 | */ | 25 | */ |
| 24 | private final Integer status; | 26 | private final Integer status; |
| 25 | - | ||
| 26 | /** | 27 | /** |
| 27 | * 名字 | 28 | * 名字 |
| 28 | */ | 29 | */ |
yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageStatusEnum.java
| @@ -6,6 +6,15 @@ import lombok.RequiredArgsConstructor; | @@ -6,6 +6,15 @@ import lombok.RequiredArgsConstructor; | ||
| 6 | 6 | ||
| 7 | import java.util.Arrays; | 7 | import java.util.Arrays; |
| 8 | 8 | ||
| 9 | +// TODO @anhaohao:IM 前缀还是要的哈 | ||
| 10 | +// TODO TODO 状态是这些哈,客户端的视角: | ||
| 11 | +// | ||
| 12 | +//- 草稿(预留) 0 | ||
| 13 | +//- 发送中 1 | ||
| 14 | +//- 发送成功 2 | ||
| 15 | +//- 发送失败 3 | ||
| 16 | +//- 已删除 4 | ||
| 17 | +//- 已撤回 5 | ||
| 9 | /** | 18 | /** |
| 10 | * IM 消息的状态枚举 | 19 | * IM 消息的状态枚举 |
| 11 | */ | 20 | */ |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ConversationController.java
| @@ -18,6 +18,7 @@ import java.util.List; | @@ -18,6 +18,7 @@ import java.util.List; | ||
| 18 | 18 | ||
| 19 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 19 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 20 | 20 | ||
| 21 | +// TODO @anhaohao:im 前缀少啦 | ||
| 21 | @Tag(name = "管理后台 - IM 会话") | 22 | @Tag(name = "管理后台 - IM 会话") |
| 22 | @RestController | 23 | @RestController |
| 23 | @RequestMapping("/im/conversation") | 24 | @RequestMapping("/im/conversation") |
| @@ -42,7 +43,6 @@ public class ConversationController { | @@ -42,7 +43,6 @@ public class ConversationController { | ||
| 42 | return success(true); | 43 | return success(true); |
| 43 | } | 44 | } |
| 44 | 45 | ||
| 45 | - | ||
| 46 | // TODO @hao:这个接口,需要单独的 VO 哈; | 46 | // TODO @hao:这个接口,需要单独的 VO 哈; |
| 47 | @PostMapping("/update-last-read-time") | 47 | @PostMapping("/update-last-read-time") |
| 48 | @Operation(summary = "更新最后已读时间") | 48 | @Operation(summary = "更新最后已读时间") |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ConversationLastTimeReqVO.java
| @@ -7,10 +7,12 @@ import lombok.Data; | @@ -7,10 +7,12 @@ import lombok.Data; | ||
| 7 | 7 | ||
| 8 | import java.time.LocalDateTime; | 8 | import java.time.LocalDateTime; |
| 9 | 9 | ||
| 10 | +// TODO @anhaohao:改成 ConversationUpdateLastReadTimeReqVO,项目目前都是动名词哈。更新置顶 | ||
| 10 | @Schema(description = "管理后台 - 会话最后已读时间 Request VO") | 11 | @Schema(description = "管理后台 - 会话最后已读时间 Request VO") |
| 11 | @Data | 12 | @Data |
| 12 | public class ConversationLastTimeReqVO { | 13 | public class ConversationLastTimeReqVO { |
| 13 | 14 | ||
| 15 | + // TODO @anhaohao:no 不用传递哈。因为 userId + targetId 可以推出来 | ||
| 14 | @Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "s_1_2") | 16 | @Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "s_1_2") |
| 15 | @NotEmpty(message = "会话标志不能为空") | 17 | @NotEmpty(message = "会话标志不能为空") |
| 16 | private String no; | 18 | private String no; |
| @@ -19,6 +21,7 @@ public class ConversationLastTimeReqVO { | @@ -19,6 +21,7 @@ public class ConversationLastTimeReqVO { | ||
| 19 | @NotNull(message = "最后已读时间不能为空") | 21 | @NotNull(message = "最后已读时间不能为空") |
| 20 | private LocalDateTime lastReadTime; | 22 | private LocalDateTime lastReadTime; |
| 21 | 23 | ||
| 24 | + // TODO @anhaohao:userId 不用传递,因为 token 已经能解析出当前用户 | ||
| 22 | @Schema(description = "所属用户", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 25 | @Schema(description = "所属用户", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 23 | private Long userId; | 26 | private Long userId; |
| 24 | 27 | ||
| @@ -26,6 +29,6 @@ public class ConversationLastTimeReqVO { | @@ -26,6 +29,6 @@ public class ConversationLastTimeReqVO { | ||
| 26 | private Long targetId; | 29 | private Long targetId; |
| 27 | 30 | ||
| 28 | @Schema(description = "会话类型",requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 31 | @Schema(description = "会话类型",requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 29 | - private Integer type; //枚举 ConversationTypeEnum | 32 | + private Integer type; // 枚举 ConversationTypeEnum TODO ,这里可以使用 @InEnum 校验,这样这个注释就不用写了 |
| 30 | 33 | ||
| 31 | } | 34 | } |
| 32 | \ No newline at end of file | 35 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ConversationPinnedReqVO.java
| @@ -8,10 +8,12 @@ import lombok.Data; | @@ -8,10 +8,12 @@ import lombok.Data; | ||
| 8 | 8 | ||
| 9 | import java.time.LocalDateTime; | 9 | import java.time.LocalDateTime; |
| 10 | 10 | ||
| 11 | +// TODO @anhaohao:改成 ConversationUpdatePinnedReqVO,项目目前都是动名词哈。更新置顶 | ||
| 11 | @Schema(description = "管理后台 - 会话置顶 Request VO") | 12 | @Schema(description = "管理后台 - 会话置顶 Request VO") |
| 12 | @Data | 13 | @Data |
| 13 | public class ConversationPinnedReqVO { | 14 | public class ConversationPinnedReqVO { |
| 14 | 15 | ||
| 16 | + // TODO @anhaohao:no 不用传递哈。因为 userId + targetId 可以推出来 | ||
| 15 | @Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "s_1_2") | 17 | @Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "s_1_2") |
| 16 | @NotEmpty(message = "会话标志不能为空") | 18 | @NotEmpty(message = "会话标志不能为空") |
| 17 | private String no; | 19 | private String no; |
| @@ -20,6 +22,7 @@ public class ConversationPinnedReqVO { | @@ -20,6 +22,7 @@ public class ConversationPinnedReqVO { | ||
| 20 | @NotNull(message = "是否置顶不能为空") | 22 | @NotNull(message = "是否置顶不能为空") |
| 21 | private Boolean pinned; | 23 | private Boolean pinned; |
| 22 | 24 | ||
| 25 | + // TODO @anhaohao:userId 不用传递,因为 token 已经能解析出当前用户 | ||
| 23 | @Schema(description = "所属用户", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 26 | @Schema(description = "所属用户", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 24 | private Long userId; | 27 | private Long userId; |
| 25 | 28 | ||
| @@ -27,8 +30,6 @@ public class ConversationPinnedReqVO { | @@ -27,8 +30,6 @@ public class ConversationPinnedReqVO { | ||
| 27 | private Long targetId; | 30 | private Long targetId; |
| 28 | 31 | ||
| 29 | @Schema(description = "会话类型",requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 32 | @Schema(description = "会话类型",requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 30 | - private Integer type; //枚举 ConversationTypeEnum | ||
| 31 | - | ||
| 32 | - | 33 | + private Integer type; // 枚举 ConversationTypeEnum TODO ,这里可以使用 @InEnum 校验,这样这个注释就不用写了 |
| 33 | 34 | ||
| 34 | } | 35 | } |
| 35 | \ No newline at end of file | 36 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java
| @@ -28,6 +28,7 @@ import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; | @@ -28,6 +28,7 @@ import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; | ||
| 28 | import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO; | 28 | import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO; |
| 29 | import cn.iocoder.yudao.module.im.service.group.ImGroupService; | 29 | import cn.iocoder.yudao.module.im.service.group.ImGroupService; |
| 30 | 30 | ||
| 31 | +// TODO @芋艿:得看看 create、update、delete、get、page 这几个接口,要保留哪些 | ||
| 31 | @Tag(name = "管理后台 - 群") | 32 | @Tag(name = "管理后台 - 群") |
| 32 | @RestController | 33 | @RestController |
| 33 | @RequestMapping("/im/group") | 34 | @RequestMapping("/im/group") |
| @@ -78,6 +79,7 @@ public class ImGroupController { | @@ -78,6 +79,7 @@ public class ImGroupController { | ||
| 78 | return success(BeanUtils.toBean(pageResult, ImGroupRespVO.class)); | 79 | return success(BeanUtils.toBean(pageResult, ImGroupRespVO.class)); |
| 79 | } | 80 | } |
| 80 | 81 | ||
| 82 | + // TODO @anhaohao:导出可以先不做哈; | ||
| 81 | @GetMapping("/export-excel") | 83 | @GetMapping("/export-excel") |
| 82 | @Operation(summary = "导出群 Excel") | 84 | @Operation(summary = "导出群 Excel") |
| 83 | @PreAuthorize("@ss.hasPermission('im:group:export')") | 85 | @PreAuthorize("@ss.hasPermission('im:group:export')") |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/groupmember/ImGroupMemberController.java
| @@ -27,6 +27,7 @@ import java.util.List; | @@ -27,6 +27,7 @@ import java.util.List; | ||
| 27 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 27 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 28 | import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; | 28 | import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; |
| 29 | 29 | ||
| 30 | +// TODO @芋艿:得看看 create、update、delete、get、page 这几个接口,要保留哪些 | ||
| 30 | @Tag(name = "管理后台 - 群成员") | 31 | @Tag(name = "管理后台 - 群成员") |
| 31 | @RestController | 32 | @RestController |
| 32 | @RequestMapping("/im/group-member") | 33 | @RequestMapping("/im/group-member") |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSaveMessageReqVO.java
| @@ -5,6 +5,7 @@ import lombok.Data; | @@ -5,6 +5,7 @@ import lombok.Data; | ||
| 5 | 5 | ||
| 6 | import java.time.LocalDateTime; | 6 | import java.time.LocalDateTime; |
| 7 | 7 | ||
| 8 | +// TODO @anhaohao:im 前缀哈 | ||
| 8 | @Schema(description = "管理后台 - 收件箱保存消息 Request VO") | 9 | @Schema(description = "管理后台 - 收件箱保存消息 Request VO") |
| 9 | @Data | 10 | @Data |
| 10 | public class InboxSaveMessageReqVO { | 11 | public class InboxSaveMessageReqVO { |
| @@ -20,7 +21,7 @@ public class InboxSaveMessageReqVO { | @@ -20,7 +21,7 @@ public class InboxSaveMessageReqVO { | ||
| 20 | 21 | ||
| 21 | @Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED) | 22 | @Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED) |
| 22 | private String senderAvatar; | 23 | private String senderAvatar; |
| 23 | - | 24 | + |
| 24 | @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") | 25 | @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") |
| 25 | private Long receiverId; | 26 | private Long receiverId; |
| 26 | 27 |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/MessageController.java
| @@ -36,6 +36,7 @@ public class MessageController { | @@ -36,6 +36,7 @@ public class MessageController { | ||
| 36 | return success(messageService.sendMessage(getLoginUserId(), message)); | 36 | return success(messageService.sendMessage(getLoginUserId(), message)); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | + // TODO @anhaohao:我在想,这个接口,改成叫 pullMessageList,会不会更好理解?拉取消息列表 | ||
| 39 | @GetMapping("/list-by-sequence") | 40 | @GetMapping("/list-by-sequence") |
| 40 | @Operation(summary = "拉取大于 sequence 的消息列表") | 41 | @Operation(summary = "拉取大于 sequence 的消息列表") |
| 41 | @Parameter(name = "sequence", description = "序号", required = true, example = "1") | 42 | @Parameter(name = "sequence", description = "序号", required = true, example = "1") |
| @@ -46,6 +47,7 @@ public class MessageController { | @@ -46,6 +47,7 @@ public class MessageController { | ||
| 46 | return success(BeanUtils.toBean(messages, MessageReqVO.class)); | 47 | return success(BeanUtils.toBean(messages, MessageReqVO.class)); |
| 47 | } | 48 | } |
| 48 | 49 | ||
| 50 | + // TODO @anhaohao:直接叫 getMessageList,不叫历史哈;因为它只是给用户叫历史,对系统来说,就是消息列表 | ||
| 49 | @GetMapping("/history") | 51 | @GetMapping("/history") |
| 50 | @Operation(summary = "查询聊天记录-根据会话标志和发送时间进行分页查询") | 52 | @Operation(summary = "查询聊天记录-根据会话标志和发送时间进行分页查询") |
| 51 | public CommonResult<List<MessageReqVO>> getHistoryMessage(@Valid MessagePageReqVO pageReqVO) { | 53 | public CommonResult<List<MessageReqVO>> getHistoryMessage(@Valid MessagePageReqVO pageReqVO) { |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/MessagePageReqVO.java
| @@ -10,14 +10,19 @@ import java.time.LocalDateTime; | @@ -10,14 +10,19 @@ import java.time.LocalDateTime; | ||
| 10 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; | 10 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; |
| 11 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | 11 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| 12 | 12 | ||
| 13 | +// TODO @anhaohao:这个类,不要交 Page,而是消息列表,MessageListReqVO | ||
| 13 | @Schema(description = "管理后台 - 消息分页 Request VO") | 14 | @Schema(description = "管理后台 - 消息分页 Request VO") |
| 14 | @Data | 15 | @Data |
| 15 | @ToString(callSuper = true) | 16 | @ToString(callSuper = true) |
| 16 | public class MessagePageReqVO { | 17 | public class MessagePageReqVO { |
| 17 | 18 | ||
| 19 | + // TODO @anhaohao:还是传递 targetId 和 conversationType,我们要弱化 no 的概念; | ||
| 20 | + | ||
| 18 | @Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "g_1000") | 21 | @Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "g_1000") |
| 19 | private String conversationNo; | 22 | private String conversationNo; |
| 20 | 23 | ||
| 24 | + // TODO @anhaohao:应该不传递时间范围,而是传递分页的时间,然后根据时间,查询消息 | ||
| 25 | + | ||
| 21 | @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27") | 26 | @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27") |
| 22 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | 27 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 23 | private LocalDateTime[] sendTime; | 28 | private LocalDateTime[] sendTime; |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/MessageReqVO.java
| @@ -12,6 +12,8 @@ import java.time.LocalDateTime; | @@ -12,6 +12,8 @@ import java.time.LocalDateTime; | ||
| 12 | 12 | ||
| 13 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | 13 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| 14 | 14 | ||
| 15 | +// TODO @anhaohao:MessageRespVO 消息响应 Response VO | ||
| 16 | +// TODO @anahaohao:每个 example 都写下;啊哈,漏了地方,要补下;因为 http mock 的时候,可以根据它去生成 | ||
| 15 | @Schema(description = "管理后台 - 消息 Request VO") | 17 | @Schema(description = "管理后台 - 消息 Request VO") |
| 16 | @Data | 18 | @Data |
| 17 | public class MessageReqVO { | 19 | public class MessageReqVO { |
| @@ -22,6 +24,7 @@ public class MessageReqVO { | @@ -22,6 +24,7 @@ public class MessageReqVO { | ||
| 22 | @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 24 | @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 23 | private Integer conversationType; // 对应 ImConversationTypeEnum 枚举 | 25 | private Integer conversationType; // 对应 ImConversationTypeEnum 枚举 |
| 24 | 26 | ||
| 27 | + // TODO @anhaohao:这个应该是 senderId | ||
| 25 | @Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | 28 | @Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 26 | private Long fromId; // 根据 conversationType 区分 | 29 | private Long fromId; // 根据 conversationType 区分 |
| 27 | 30 |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageReqVO.java
| @@ -7,6 +7,10 @@ import com.alibaba.excel.annotation.ExcelProperty; | @@ -7,6 +7,10 @@ import com.alibaba.excel.annotation.ExcelProperty; | ||
| 7 | import io.swagger.v3.oas.annotations.media.Schema; | 7 | import io.swagger.v3.oas.annotations.media.Schema; |
| 8 | import lombok.Data; | 8 | import lombok.Data; |
| 9 | 9 | ||
| 10 | +// TODO @anhaohao:MessageSendReqVO,消息发送 | ||
| 11 | + | ||
| 12 | +// TODO @anhaohao:不应该有 excel 相关的注解 | ||
| 13 | + | ||
| 10 | @Schema(description = "管理后台 - 发送消息 Request VO") | 14 | @Schema(description = "管理后台 - 发送消息 Request VO") |
| 11 | @Data | 15 | @Data |
| 12 | @ExcelIgnoreUnannotated | 16 | @ExcelIgnoreUnannotated |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageRespVO.java
| @@ -10,6 +10,8 @@ import java.time.LocalDateTime; | @@ -10,6 +10,8 @@ import java.time.LocalDateTime; | ||
| 10 | 10 | ||
| 11 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | 11 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| 12 | 12 | ||
| 13 | +// TODO @anhaohao:MessageSendRespVO,消息发送结果 | ||
| 14 | + | ||
| 13 | @Schema(description = "管理后台 - 发送消息 Response VO") | 15 | @Schema(description = "管理后台 - 发送消息 Response VO") |
| 14 | @Data | 16 | @Data |
| 15 | @AllArgsConstructor | 17 | @AllArgsConstructor |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ConversationDO.java
| @@ -9,6 +9,7 @@ import lombok.*; | @@ -9,6 +9,7 @@ import lombok.*; | ||
| 9 | 9 | ||
| 10 | import java.time.LocalDateTime; | 10 | import java.time.LocalDateTime; |
| 11 | 11 | ||
| 12 | +// TODO @anhaohao:还是有 IM 前缀哈 | ||
| 12 | /** | 13 | /** |
| 13 | * IM 会话 DO | 14 | * IM 会话 DO |
| 14 | * | 15 | * |
| @@ -44,15 +45,19 @@ public class ConversationDO extends BaseDO { | @@ -44,15 +45,19 @@ public class ConversationDO extends BaseDO { | ||
| 44 | /** | 45 | /** |
| 45 | * 聊天对象编号 | 46 | * 聊天对象编号 |
| 46 | * <p> | 47 | * <p> |
| 47 | - * 1. 单聊时,用户编号;群聊时,群编号 | 48 | + * 1. 单聊时,用户编号; |
| 49 | + * 2. 群聊时,群编号 | ||
| 48 | */ | 50 | */ |
| 49 | private Long targetId; | 51 | private Long targetId; |
| 50 | /** | 52 | /** |
| 51 | - * 会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId | 53 | + * 会话标志 |
| 54 | + * | ||
| 55 | + * 1. 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId | ||
| 56 | + * 2. 群聊:g_groupId | ||
| 52 | */ | 57 | */ |
| 53 | private String no; | 58 | private String no; |
| 54 | /** | 59 | /** |
| 55 | - * 是否置顶 0否 1是 | 60 | + * 是否置顶 |
| 56 | */ | 61 | */ |
| 57 | private Boolean pinned; | 62 | private Boolean pinned; |
| 58 | /** | 63 | /** |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupDO.java
| @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId; | @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId; | ||
| 6 | import com.baomidou.mybatisplus.annotation.TableName; | 6 | import com.baomidou.mybatisplus.annotation.TableName; |
| 7 | import lombok.*; | 7 | import lombok.*; |
| 8 | 8 | ||
| 9 | +// TODO @anhaohao:还是要有 IM | ||
| 9 | /** | 10 | /** |
| 10 | * IM 群信息 DO | 11 | * IM 群信息 DO |
| 11 | * | 12 | * |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupMemberDO.java
| @@ -4,6 +4,7 @@ import lombok.*; | @@ -4,6 +4,7 @@ import lombok.*; | ||
| 4 | import com.baomidou.mybatisplus.annotation.*; | 4 | import com.baomidou.mybatisplus.annotation.*; |
| 5 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 5 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 6 | 6 | ||
| 7 | +// TODO @anhaohao:还是要有 IM | ||
| 7 | /** | 8 | /** |
| 8 | * IM 群成员 DO | 9 | * IM 群成员 DO |
| 9 | * | 10 | * |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/InboxDO.java
| 1 | package cn.iocoder.yudao.module.im.dal.dataobject.inbox; | 1 | package cn.iocoder.yudao.module.im.dal.dataobject.inbox; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | +import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; | ||
| 4 | import com.baomidou.mybatisplus.annotation.KeySequence; | 5 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 5 | import com.baomidou.mybatisplus.annotation.TableId; | 6 | import com.baomidou.mybatisplus.annotation.TableId; |
| 6 | import com.baomidou.mybatisplus.annotation.TableName; | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
| 7 | import lombok.*; | 8 | import lombok.*; |
| 8 | 9 | ||
| 10 | +// TODO @anhaohao:还是要有 IM | ||
| 9 | // TODO 我们要不要改成 ImMessageQueue 队列?从理解上,概念上,可能都更清晰一点哈。每个用户一个消息队列; | 11 | // TODO 我们要不要改成 ImMessageQueue 队列?从理解上,概念上,可能都更清晰一点哈。每个用户一个消息队列; |
| 10 | /** | 12 | /** |
| 11 | * IM 收件箱 DO | 13 | * IM 收件箱 DO |
| @@ -35,6 +37,8 @@ public class InboxDO extends BaseDO { | @@ -35,6 +37,8 @@ public class InboxDO extends BaseDO { | ||
| 35 | private Long userId; | 37 | private Long userId; |
| 36 | /** | 38 | /** |
| 37 | * 消息编号 | 39 | * 消息编号 |
| 40 | + * | ||
| 41 | + * 关联 {@link MessageDO#getId()} | ||
| 38 | */ | 42 | */ |
| 39 | private Long messageId; | 43 | private Long messageId; |
| 40 | /** | 44 | /** |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/MessageDO.java
| @@ -12,6 +12,7 @@ import lombok.*; | @@ -12,6 +12,7 @@ import lombok.*; | ||
| 12 | 12 | ||
| 13 | import java.time.LocalDateTime; | 13 | import java.time.LocalDateTime; |
| 14 | 14 | ||
| 15 | +// TODO @anhaohao:还是要有 IM | ||
| 15 | /** | 16 | /** |
| 16 | * IM 消息 DO | 17 | * IM 消息 DO |
| 17 | * | 18 | * |
| @@ -63,15 +64,21 @@ public class MessageDO extends BaseDO { | @@ -63,15 +64,21 @@ public class MessageDO extends BaseDO { | ||
| 63 | */ | 64 | */ |
| 64 | private Integer conversationType; | 65 | private Integer conversationType; |
| 65 | /** | 66 | /** |
| 66 | - * 会话标志 {@link ConversationTypeEnum} 的generateConversationNo() 方法生成 | 67 | + * 会话标志 |
| 68 | + * | ||
| 69 | + * 生成规则:{@link ConversationTypeEnum#generateConversationNo(Long, Long, Integer)} 方法 | ||
| 67 | */ | 70 | */ |
| 68 | private String conversationNo; | 71 | private String conversationNo; |
| 69 | /** | 72 | /** |
| 70 | - * 消息类型 枚举 {@link MessageContentTypeEnum} | 73 | + * 消息类型 |
| 74 | + * | ||
| 75 | + * 枚举 {@link MessageContentTypeEnum} | ||
| 71 | */ | 76 | */ |
| 72 | private Integer contentType; | 77 | private Integer contentType; |
| 73 | /** | 78 | /** |
| 74 | - * 消息内容 JSON 格式 对应 dal/dataobject/message/content 包 | 79 | + * 消息内容 |
| 80 | + * | ||
| 81 | + * JSON 格式 对应 dal/dataobject/message/content 包 | ||
| 75 | */ | 82 | */ |
| 76 | private String content; | 83 | private String content; |
| 77 | /** | 84 | /** |
| @@ -79,11 +86,15 @@ public class MessageDO extends BaseDO { | @@ -79,11 +86,15 @@ public class MessageDO extends BaseDO { | ||
| 79 | */ | 86 | */ |
| 80 | private LocalDateTime sendTime; | 87 | private LocalDateTime sendTime; |
| 81 | /** | 88 | /** |
| 82 | - * 消息来源 枚举 {@link MessageSourceEnum} | 89 | + * 消息来源 |
| 90 | + * | ||
| 91 | + * 枚举 {@link MessageSourceEnum} | ||
| 83 | */ | 92 | */ |
| 84 | private Integer sendFrom; | 93 | private Integer sendFrom; |
| 85 | /** | 94 | /** |
| 86 | - * 消息状态 枚举 {@link MessageStatusEnum} | 95 | + * 消息状态 |
| 96 | + * | ||
| 97 | + * 枚举 {@link MessageStatusEnum} | ||
| 87 | */ | 98 | */ |
| 88 | private Integer messageStatus; | 99 | private Integer messageStatus; |
| 89 | 100 |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/AudioMessage.java
| @@ -5,6 +5,8 @@ import lombok.AllArgsConstructor; | @@ -5,6 +5,8 @@ import lombok.AllArgsConstructor; | ||
| 5 | import lombok.Data; | 5 | import lombok.Data; |
| 6 | import lombok.NoArgsConstructor; | 6 | import lombok.NoArgsConstructor; |
| 7 | 7 | ||
| 8 | +// TODO @anhaohao:要有 IM; | ||
| 9 | +// TODO @芋艿:后续要挪到 api 包下,主要是给外部接口使用 | ||
| 8 | /** | 10 | /** |
| 9 | * 语音消息的 {@link MessageDO 字段 content} 的内容 | 11 | * 语音消息的 {@link MessageDO 字段 content} 的内容 |
| 10 | * | 12 | * |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/inbox/InboxMapper.java
| @@ -15,12 +15,13 @@ import java.util.List; | @@ -15,12 +15,13 @@ import java.util.List; | ||
| 15 | @Mapper | 15 | @Mapper |
| 16 | public interface InboxMapper extends BaseMapperX<InboxDO> { | 16 | public interface InboxMapper extends BaseMapperX<InboxDO> { |
| 17 | 17 | ||
| 18 | + // TODO @anhaohao:返回 List<InboxDO> ,转换成 messageId 交给上层;dao 尽量通用 | ||
| 18 | default List<Long> selectMessageIdsByUserIdAndSequence(Long userId, Long sequence, Integer size) { | 19 | default List<Long> selectMessageIdsByUserIdAndSequence(Long userId, Long sequence, Integer size) { |
| 19 | return selectList(new LambdaQueryWrapperX<InboxDO>() | 20 | return selectList(new LambdaQueryWrapperX<InboxDO>() |
| 20 | .gt(InboxDO::getUserId, userId) | 21 | .gt(InboxDO::getUserId, userId) |
| 21 | .gt(InboxDO::getSequence, sequence) | 22 | .gt(InboxDO::getSequence, sequence) |
| 22 | .orderByAsc(InboxDO::getSequence) | 23 | .orderByAsc(InboxDO::getSequence) |
| 23 | - .last("limit 0," + size)) | 24 | + .last("limit 0," + size)) // TODO @anhaohao:这里 limit 就可以了,不用从 limit 0 开始; |
| 24 | .stream() | 25 | .stream() |
| 25 | .map(InboxDO::getMessageId) | 26 | .map(InboxDO::getMessageId) |
| 26 | .toList(); | 27 | .toList(); |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationServiceImpl.java
| @@ -12,8 +12,6 @@ import org.springframework.validation.annotation.Validated; | @@ -12,8 +12,6 @@ import org.springframework.validation.annotation.Validated; | ||
| 12 | 12 | ||
| 13 | import java.util.List; | 13 | import java.util.List; |
| 14 | 14 | ||
| 15 | -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 16 | - | ||
| 17 | /** | 15 | /** |
| 18 | * IM 会话 Service 实现类 | 16 | * IM 会话 Service 实现类 |
| 19 | * | 17 | * |
| @@ -43,6 +41,7 @@ public class ConversationServiceImpl implements ConversationService { | @@ -43,6 +41,7 @@ public class ConversationServiceImpl implements ConversationService { | ||
| 43 | ConversationDO conversation = conversationMapper.selectByNo(updateReqVO.getNo()); | 41 | ConversationDO conversation = conversationMapper.selectByNo(updateReqVO.getNo()); |
| 44 | if (conversation == null) { | 42 | if (conversation == null) { |
| 45 | ConversationDO conversationDO = new ConversationDO(); | 43 | ConversationDO conversationDO = new ConversationDO(); |
| 44 | + // TODO @hao:no 不是前端传递哈,后端生成;另外,其实可以把 insert 写成一个公用方法;get会话,拿不到就 insert;接着处理 update 操作;首次多 update 一次,无所谓的;没多少量的 | ||
| 46 | conversationDO.setNo(updateReqVO.getNo()); | 45 | conversationDO.setNo(updateReqVO.getNo()); |
| 47 | conversationDO.setPinned(updateReqVO.getPinned()); | 46 | conversationDO.setPinned(updateReqVO.getPinned()); |
| 48 | conversationDO.setUserId(updateReqVO.getUserId()); | 47 | conversationDO.setUserId(updateReqVO.getUserId()); |
| @@ -50,11 +49,10 @@ public class ConversationServiceImpl implements ConversationService { | @@ -50,11 +49,10 @@ public class ConversationServiceImpl implements ConversationService { | ||
| 50 | conversationDO.setType(updateReqVO.getType()); | 49 | conversationDO.setType(updateReqVO.getType()); |
| 51 | conversationMapper.insert(conversationDO); | 50 | conversationMapper.insert(conversationDO); |
| 52 | } else { | 51 | } else { |
| 53 | - // 更新 | 52 | + // 更新 TODO @anhaohao:这里不要 toBean,因为这里逻辑偏 toc,new ConversationDO 对象,然后逐个 set 需要的值; |
| 54 | ConversationDO updateObj = BeanUtils.toBean(updateReqVO, ConversationDO.class); | 53 | ConversationDO updateObj = BeanUtils.toBean(updateReqVO, ConversationDO.class); |
| 55 | conversationMapper.updateById(updateObj); | 54 | conversationMapper.updateById(updateObj); |
| 56 | } | 55 | } |
| 57 | - | ||
| 58 | } | 56 | } |
| 59 | 57 | ||
| 60 | @Override | 58 | @Override |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/InboxService.java
| @@ -27,4 +27,5 @@ public interface InboxService { | @@ -27,4 +27,5 @@ public interface InboxService { | ||
| 27 | * @return 消息编号列表 | 27 | * @return 消息编号列表 |
| 28 | */ | 28 | */ |
| 29 | List<Long> selectMessageIdsByUserIdAndSequence(Long userId, Long sequence, Integer size); | 29 | List<Long> selectMessageIdsByUserIdAndSequence(Long userId, Long sequence, Integer size); |
| 30 | + | ||
| 30 | } | 31 | } |
| 31 | \ No newline at end of file | 32 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/InboxServiceImpl.java
| @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.im.service.inbox; | @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.im.service.inbox; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | -import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; | ||
| 6 | import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveMessageReqVO; | 5 | import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveMessageReqVO; |
| 7 | import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSendMessageReqVO; | 6 | import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSendMessageReqVO; |
| 8 | import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO; | 7 | import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO; |
| @@ -43,6 +42,7 @@ public class InboxServiceImpl implements InboxService { | @@ -43,6 +42,7 @@ public class InboxServiceImpl implements InboxService { | ||
| 43 | @Resource | 42 | @Resource |
| 44 | private GroupMemberService groupMemberService; | 43 | private GroupMemberService groupMemberService; |
| 45 | 44 | ||
| 45 | + // TODO @anhaohao:下面的逻辑,最好是,1. 保存收件箱 + 发送消息给用户; 2. xxx;这样看的人,会更有感觉哈; | ||
| 46 | @Override | 46 | @Override |
| 47 | public void saveInboxAndSendMessage(InboxSaveMessageReqVO inboxSaveMessage) { | 47 | public void saveInboxAndSendMessage(InboxSaveMessageReqVO inboxSaveMessage) { |
| 48 | // 保存收件箱 + 发送消息给用户 | 48 | // 保存收件箱 + 发送消息给用户 |
| @@ -64,12 +64,15 @@ public class InboxServiceImpl implements InboxService { | @@ -64,12 +64,15 @@ public class InboxServiceImpl implements InboxService { | ||
| 64 | private void saveInboxAndSendMessageForUser(Long userId, InboxSaveMessageReqVO inboxSaveMessage) { | 64 | private void saveInboxAndSendMessageForUser(Long userId, InboxSaveMessageReqVO inboxSaveMessage) { |
| 65 | inboxLockRedisDAO.lock(userId, INBOX_LOCK_TIMEOUT, () -> { | 65 | inboxLockRedisDAO.lock(userId, INBOX_LOCK_TIMEOUT, () -> { |
| 66 | Long userSequence = sequenceRedisDao.generateSequence(userId); | 66 | Long userSequence = sequenceRedisDao.generateSequence(userId); |
| 67 | + // TODO @anhaohao:链式调用; | ||
| 67 | InboxDO inbox = new InboxDO(); | 68 | InboxDO inbox = new InboxDO(); |
| 68 | inbox.setUserId(userId); | 69 | inbox.setUserId(userId); |
| 69 | inbox.setMessageId(inboxSaveMessage.getMessageId()); | 70 | inbox.setMessageId(inboxSaveMessage.getMessageId()); |
| 70 | inbox.setSequence(userSequence); | 71 | inbox.setSequence(userSequence); |
| 71 | inboxMapper.insert(inbox); | 72 | inboxMapper.insert(inbox); |
| 72 | 73 | ||
| 74 | + // TODO @anhaohao:是不是 send 不用在加锁里面哈?! | ||
| 75 | + // TODO @anhaohao:再进一步,是不是用 spring @async 可以并发推送噢 | ||
| 73 | InboxSendMessageReqVO message = BeanUtils.toBean(inboxSaveMessage, InboxSendMessageReqVO.class); | 76 | InboxSendMessageReqVO message = BeanUtils.toBean(inboxSaveMessage, InboxSendMessageReqVO.class); |
| 74 | message.setSequence(userSequence); | 77 | message.setSequence(userSequence); |
| 75 | webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, IM_MESSAGE_RECEIVE, message); | 78 | webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, IM_MESSAGE_RECEIVE, message); |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageServiceImpl.java
| @@ -58,20 +58,25 @@ public class MessageServiceImpl implements MessageService { | @@ -58,20 +58,25 @@ public class MessageServiceImpl implements MessageService { | ||
| 58 | @Override | 58 | @Override |
| 59 | public SendMessageRespVO sendMessage(Long fromUserId, SendMessageReqVO message) { | 59 | public SendMessageRespVO sendMessage(Long fromUserId, SendMessageReqVO message) { |
| 60 | // 保存消息 | 60 | // 保存消息 |
| 61 | + // TODO @anhaohao:InboxSaveMessageReqVO 不用 new 出来传递到 saveMessage 方法里; | ||
| 61 | InboxSaveMessageReqVO inboxSaveMessageReqVO = new InboxSaveMessageReqVO(); | 62 | InboxSaveMessageReqVO inboxSaveMessageReqVO = new InboxSaveMessageReqVO(); |
| 62 | SendMessageRespVO sendMessageRespVO = saveMessage(fromUserId, message, inboxSaveMessageReqVO); | 63 | SendMessageRespVO sendMessageRespVO = saveMessage(fromUserId, message, inboxSaveMessageReqVO); |
| 63 | 64 | ||
| 64 | // 保存收件箱 + 发送消息给用户 | 65 | // 保存收件箱 + 发送消息给用户 |
| 66 | + // TODO @anhaohao:考虑到少定义一些 VO,直接传递 MessageDO 就完事了;反正这两者也是强耦合的; | ||
| 65 | inboxService.saveInboxAndSendMessage(inboxSaveMessageReqVO); | 67 | inboxService.saveInboxAndSendMessage(inboxSaveMessageReqVO); |
| 66 | return sendMessageRespVO; | 68 | return sendMessageRespVO; |
| 67 | } | 69 | } |
| 68 | 70 | ||
| 71 | + // TODO @anhaohao:这个方法,是不是定义成 private 哈;然后返回是 MessageDO 对象,设置最上面的 sendMessage 也是这个。最终 controller 转成 SendMessageRespVO | ||
| 69 | public SendMessageRespVO saveMessage(Long fromUserId, SendMessageReqVO message, InboxSaveMessageReqVO inboxSaveMessageReqVO) { | 72 | public SendMessageRespVO saveMessage(Long fromUserId, SendMessageReqVO message, InboxSaveMessageReqVO inboxSaveMessageReqVO) { |
| 70 | - //需要校验 receiverId 存在 | 73 | + // 需要校验 receiverId 存在 |
| 71 | validateReceiverIdExists(message); | 74 | validateReceiverIdExists(message); |
| 72 | // 查询发送人昵称和发送人头像 | 75 | // 查询发送人昵称和发送人头像 |
| 73 | AdminUserRespDTO fromUser = adminUserApi.getUser(fromUserId); | 76 | AdminUserRespDTO fromUser = adminUserApi.getUser(fromUserId); |
| 74 | // 使用链式调用创建 MessageDO 对象 | 77 | // 使用链式调用创建 MessageDO 对象 |
| 78 | + // TODO @anhaohao:一部分字段,可以 beanutils tobean 搞定; | ||
| 79 | + // TODO @anhaohao:链式 set 的时候,要把相同的放在一行;例如说,setSenderNickname、setSenderAvatar;本质上,就是为了“同类”在一行,阅读起来简单; | ||
| 75 | MessageDO messageDO = new MessageDO() | 80 | MessageDO messageDO = new MessageDO() |
| 76 | .setClientMessageId(message.getClientMessageId()) | 81 | .setClientMessageId(message.getClientMessageId()) |
| 77 | .setSenderId(fromUserId) | 82 | .setSenderId(fromUserId) |
| @@ -102,17 +107,19 @@ public class MessageServiceImpl implements MessageService { | @@ -102,17 +107,19 @@ public class MessageServiceImpl implements MessageService { | ||
| 102 | return new SendMessageRespVO(messageDO.getId(), messageDO.getSendTime()); | 107 | return new SendMessageRespVO(messageDO.getId(), messageDO.getSendTime()); |
| 103 | } | 108 | } |
| 104 | 109 | ||
| 110 | + // TODO @anhaohao:validateReceiver,更简单一点哈;不仅仅校验存在,未来还可以校验,自己是不是有好友关系、群聊是否在群聊里面等等 | ||
| 105 | private void validateReceiverIdExists(SendMessageReqVO message) { | 111 | private void validateReceiverIdExists(SendMessageReqVO message) { |
| 112 | + // TODO @anhaohao:这个不要这里校验,交给 validator 校验掉 | ||
| 106 | if (message.getReceiverId() == null) { | 113 | if (message.getReceiverId() == null) { |
| 107 | throw exception(MESSAGE_RECEIVER_NOT_EXISTS); | 114 | throw exception(MESSAGE_RECEIVER_NOT_EXISTS); |
| 108 | } | 115 | } |
| 109 | if (message.getConversationType().equals(ConversationTypeEnum.SINGLE.getType())) { | 116 | if (message.getConversationType().equals(ConversationTypeEnum.SINGLE.getType())) { |
| 117 | + // TODO @anhaohao:// 之后要空一个空格,中英文协作习惯,中文和英文之间,不能连着;最后也不用 ;哈 | ||
| 110 | //校验用户是否存在; | 118 | //校验用户是否存在; |
| 111 | AdminUserRespDTO receiverUser = adminUserApi.getUser(message.getReceiverId()); | 119 | AdminUserRespDTO receiverUser = adminUserApi.getUser(message.getReceiverId()); |
| 112 | if (receiverUser == null) { | 120 | if (receiverUser == null) { |
| 113 | throw exception(MESSAGE_RECEIVER_NOT_EXISTS); | 121 | throw exception(MESSAGE_RECEIVER_NOT_EXISTS); |
| 114 | } | 122 | } |
| 115 | - | ||
| 116 | } else if (message.getConversationType().equals(ConversationTypeEnum.GROUP.getType())) { | 123 | } else if (message.getConversationType().equals(ConversationTypeEnum.GROUP.getType())) { |
| 117 | //校验群聊是否存在; | 124 | //校验群聊是否存在; |
| 118 | List<GroupMemberDO> groupMemberDOS = groupMemberService.selectByGroupId(message.getReceiverId()); | 125 | List<GroupMemberDO> groupMemberDOS = groupMemberService.selectByGroupId(message.getReceiverId()); |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImReceiveMessage.java
| @@ -15,6 +15,7 @@ public class ImReceiveMessage { | @@ -15,6 +15,7 @@ public class ImReceiveMessage { | ||
| 15 | @InEnum(ConversationTypeEnum.class) | 15 | @InEnum(ConversationTypeEnum.class) |
| 16 | private Integer conversationType; | 16 | private Integer conversationType; |
| 17 | 17 | ||
| 18 | + // TODO @anhaohao:我们应该是 senderId;因为它和 receiverId 是相对应的哈。 | ||
| 18 | @Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | 19 | @Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 19 | private Long fromId; // 根据 conversationType 区分 | 20 | private Long fromId; // 根据 conversationType 区分 |
| 20 | 21 |
yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/conversation/ConversationMapper.xml deleted
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||
| 3 | -<mapper namespace="cn.iocoder.yudao.module.im.dal.mysql.conversation.ConversationMapper"> | ||
| 4 | - | ||
| 5 | - <!-- TODO @hao:xml 如果用不到,可以先删除哈 --> | ||
| 6 | - <!-- | ||
| 7 | - 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。 | ||
| 8 | - 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。 | ||
| 9 | - 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。 | ||
| 10 | - 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ | ||
| 11 | - --> | ||
| 12 | - | ||
| 13 | -</mapper> | ||
| 14 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/group/ImGroupMapper.xml deleted
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||
| 3 | -<mapper namespace="cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMapper"> | ||
| 4 | - | ||
| 5 | - <!-- | ||
| 6 | - 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。 | ||
| 7 | - 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。 | ||
| 8 | - 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。 | ||
| 9 | - 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ | ||
| 10 | - --> | ||
| 11 | - | ||
| 12 | -</mapper> | ||
| 13 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/groupmember/ImGroupMemberMapper.xml deleted
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||
| 3 | -<mapper namespace="cn.iocoder.yudao.module.im.dal.mysql.groupmember.ImGroupMemberMapper"> | ||
| 4 | - | ||
| 5 | - <!-- | ||
| 6 | - 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。 | ||
| 7 | - 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。 | ||
| 8 | - 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。 | ||
| 9 | - 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ | ||
| 10 | - --> | ||
| 11 | - | ||
| 12 | -</mapper> | ||
| 13 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/inbox/InboxMapper.xml deleted
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||
| 3 | -<mapper namespace="cn.iocoder.yudao.module.im.dal.mysql.inbox.InboxMapper"> | ||
| 4 | - | ||
| 5 | - <!-- | ||
| 6 | - 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。 | ||
| 7 | - 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。 | ||
| 8 | - 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。 | ||
| 9 | - 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ | ||
| 10 | - --> | ||
| 11 | - | ||
| 12 | -</mapper> | ||
| 13 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/message/MessageMapper.xml deleted
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||
| 3 | -<mapper namespace="cn.iocoder.yudao.module.im.dal.mysql.message.MessageMapper"> | ||
| 4 | - | ||
| 5 | - <!-- | ||
| 6 | - 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。 | ||
| 7 | - 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。 | ||
| 8 | - 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。 | ||
| 9 | - 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ | ||
| 10 | - --> | ||
| 11 | - | ||
| 12 | -</mapper> | ||
| 13 | \ No newline at end of file | 0 | \ No newline at end of file |