Commit 2b891cb4321ae3bb42dad7ffc30c4269413cba47

Authored by YunaiV
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