diff --git a/yudao-module-im/pom.xml b/yudao-module-im/pom.xml index d5f3d10151..c3e5327381 100644 --- a/yudao-module-im/pom.xml +++ b/yudao-module-im/pom.xml @@ -17,6 +17,7 @@ ${project.artifactId} + im 模块,主要提供能力: 1. 通讯能力,例如:消息发送、消息接收、消息撤回、消息已读等。 2. 通讯会话,例如:单聊、群聊、聊天室等。 diff --git a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/api/package-info.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/api/package-info.java index 5722d74f0c..cfe63d8bb6 100644 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/api/package-info.java +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/api/package-info.java @@ -1,5 +1,5 @@ /** * @author anhaohao - * @date 2024/3/9 下午8:59 + * @date 2024/3/9 下午8:59 TODO @hao:没有 @date 这个,应该是 @since 哈 */ package cn.iocoder.yudao.module.im.api; \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/ErrorCodeConstants.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/ErrorCodeConstants.java index 9e7d3b0114..c56f5dae7a 100644 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/ErrorCodeConstants.java +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/ErrorCodeConstants.java @@ -23,4 +23,5 @@ public interface ErrorCodeConstants { // ========== 群成员 (1-040-500-000) ========== ErrorCode GROUP_MEMBER_NOT_EXISTS = new ErrorCode(1_040_500_000, "群成员不存在"); + } diff --git a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java index 09fa280a25..984f62b517 100644 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java @@ -6,6 +6,7 @@ import lombok.Getter; import java.util.Arrays; +// TODO @hao:类型保持和 openim 一致 /** * IM 消息的类型枚举 *

@@ -42,4 +43,5 @@ public enum ImMessageTypeEnum implements IntArrayValuable { public int[] array() { return ARRAYS; } + } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/package-info.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/package-info.java deleted file mode 100644 index f7571fbf0a..0000000000 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * @author anhaohao - * @date 2024/3/9 下午8:59 - */ -package cn.iocoder.yudao.module.im.enums; \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/pom.xml b/yudao-module-im/yudao-module-im-biz/pom.xml index 9c6eba3d16..a6d1bffad2 100644 --- a/yudao-module-im/yudao-module-im-biz/pom.xml +++ b/yudao-module-im/yudao-module-im-biz/pom.xml @@ -5,7 +5,7 @@ yudao-module-im cn.iocoder.boot - ${revision} + ${revision} 4.0.0 jar @@ -52,6 +52,9 @@ cn.iocoder.boot yudao-spring-boot-starter-test + + + cn.iocoder.boot yudao-spring-boot-starter-excel @@ -61,6 +64,7 @@ yudao-spring-boot-starter-websocket + org.redisson redisson-spring-boot-starter diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java index 7564ac23f2..c94140b175 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java @@ -18,36 +18,41 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +// TODO @hao: 管理后台 - IM 会话 @Tag(name = "管理后台 - 会话") @RestController @RequestMapping("/im/conversation") @Validated public class ImConversationController { + // TODO @hao: conversationService 即可 @Resource private ImConversationService imConversationService; + // TODO @hao:/list 会话列表;一般 get 是给单个对象,或者 get-count 这种;然后 conversation 已经是模块名了,所以可以简化 @GetMapping("/get-conversation") @Operation(summary = "获得用户的会话列表") - @PreAuthorize("hasAuthority('im:conversation:query')") + @PreAuthorize("hasAuthority('im:conversation:query')") // TODO @hao:不用权限哈 public CommonResult> getConversationList() { List conversationList = imConversationService.getConversationList(); return success(BeanUtils.toBean(conversationList, ImConversationRespVO.class)); } - + // TODO @hao:/update-pinned 保持和 db 字段一致哈; + // TODO @hao:这个接口,需要单独的 VO 哈; @PostMapping("/update-top") @Operation(summary = "置顶会话") - @PreAuthorize("hasAuthority('im:conversation:update')") + @PreAuthorize("hasAuthority('im:conversation:update')") // TODO @hao:不用权限哈;因为肯定会判断是不是自己的 public CommonResult updateTop(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) { imConversationService.updateTop(updateReqVO); return success(true); } + // TODO @hao:这个接口,需要单独的 VO 哈; @PostMapping("/update-last-read-time") @Operation(summary = "更新最后已读时间") - @PreAuthorize("hasAuthority('im:conversation:update')") + @PreAuthorize("hasAuthority('im:conversation:update')") // TODO @hao:不用权限哈;因为肯定会判断是不是自己的 public CommonResult updateLastReadTime(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) { imConversationService.updateLastReadTime(updateReqVO); return success(true); diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationPageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationPageReqVO.java index 68f1416760..c3a24b3a7b 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationPageReqVO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationPageReqVO.java @@ -11,7 +11,8 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(description = "管理后台 - 会话分页 Request VO") +// TODO @hao:这个貌似业务上,暂时用不到,可以考虑删除哈。 +@Schema(description = "管理后台 - IM 会话分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationRespVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationRespVO.java index 6d63dbc421..ee9a7248f3 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationRespVO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationRespVO.java @@ -9,9 +9,11 @@ import java.time.LocalDateTime; @Schema(description = "管理后台 - 会话 Response VO") @Data -@ExcelIgnoreUnannotated +@ExcelIgnoreUnannotated // TODO @hao:excel 的注解可以先删除 public class ImConversationRespVO { + // TODO @hao:example 都写下 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13905") @ExcelProperty("编号") private Long id; @@ -20,18 +22,22 @@ public class ImConversationRespVO { @ExcelProperty("所属用户") private Long userId; + // TODO @hao:@Schema 可以改成“会话类型”,不用把具体的数字写在上面哈。这样后续改动,会比较难改 @Schema(description = "类型:1 单聊;2 群聊;4 通知会话(预留)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @ExcelProperty("类型:1 单聊;2 群聊;4 通知会话(预留)") private Integer conversationType; + // TODO @hao:只写,聊天对象编号 @Schema(description = "单聊时,用户编号;群聊时,群编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21454") @ExcelProperty("单聊时,用户编号;群聊时,群编号") private Long targetId; + // TODO @hao:只写 no 即可。 @Schema(description = "会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId") private String no; + // TODO @hao:只写 是否置顶;0 1 是数据库的结果哈; @Schema(description = "是否置顶 0否 1是", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("是否置顶 0否 1是") private Boolean pinned; diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationSaveReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationSaveReqVO.java index c2aaa8f1ce..58d71233ea 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationSaveReqVO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationSaveReqVO.java @@ -7,6 +7,7 @@ import lombok.Data; import java.time.LocalDateTime; +// TODO @hao:这个貌似业务上,暂时用不到,可以考虑删除哈。 @Schema(description = "管理后台 - 会话新增/修改 Request VO") @Data public class ImConversationSaveReqVO { diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationDO.java index f41f274ce6..5a6fabd912 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationDO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationDO.java @@ -9,7 +9,7 @@ import lombok.*; import java.time.LocalDateTime; /** - * 会话 DO + * IM 会话 DO * * @author 芋道源码 */ @@ -32,12 +32,21 @@ public class ImConversationDO extends BaseDO { * 所属用户 */ private Long userId; + // TODO @hao:注释可以改成,如下 + /** + * 会话类型 + * + * 枚举 {@link cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum} + */ /** * 类型:1 单聊;2 群聊;4 通知会话(预留) */ + // TODO @hao:conversationType 改成 type private Integer conversationType; /** - * 单聊时,用户编号;群聊时,群编号 + * 聊天对象编号 + * + * 1. 单聊时,用户编号;群聊时,群编号 */ private Long targetId; /** diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupDO.java index 654709e801..edd2b33211 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupDO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupDO.java @@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.annotation.*; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; /** - * 群 DO + * IM 群信息 DO * * @author 芋道源码 */ @@ -24,14 +24,17 @@ public class ImGroupDO extends BaseDO { */ @TableId private Long id; + // TODO @hao:name,如果这个表已经是 group 了,不用在带额外的 /** * 群名字 */ private String groupName; + // TODO @hao:关联字段; /** - * 群主id + * 群主编号 */ private Long ownerId; + // TODO @hao:头像使用 avatar 好了,整个项目统一;然后 Thumb 是不是不用存,这个更多是文件服务做裁剪 /** * 群头像 */ diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/groupmember/GroupMemberDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/groupmember/GroupMemberDO.java index 8bc7b13d6f..dc97b94fd1 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/groupmember/GroupMemberDO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/groupmember/GroupMemberDO.java @@ -7,8 +7,9 @@ import java.time.LocalDateTime; import com.baomidou.mybatisplus.annotation.*; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +// TODO @hao:这个挪到 group 包下; /** - * 群成员 DO + * IM 群成员 DO * * @author 芋道源码 */ @@ -27,14 +28,16 @@ public class GroupMemberDO extends BaseDO { */ @TableId private Long id; + // TODO @hao:groupId 和 userId 都写下关联字段哈 /** - * 群 id + * 群编号 */ private Long groupId; /** - * 用户id + * 用户编号 */ private Long userId; + // TODO @hao:nickname 和 avatar 是不是不用存储哈; /** * 昵称 */ diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/ImInboxDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/ImInboxDO.java index 20dd94c77a..6f92474d53 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/ImInboxDO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/ImInboxDO.java @@ -6,8 +6,9 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; +// TODO 我们要不要改成 ImMessageQueue 队列?从理解上,概念上,可能都更清晰一点哈。每个用户一个消息队列; /** - * 收件箱 DO + * IM 收件箱 DO * * @author 芋道源码 */ @@ -28,6 +29,8 @@ public class ImInboxDO extends BaseDO { private Long id; /** * 用户编号 + * + * TODO @hao:写下 userId 和 messageId 的关联字段 */ private Long userId; /** diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImMessageDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImMessageDO.java index becf06be41..2b1646cc8e 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImMessageDO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImMessageDO.java @@ -9,7 +9,7 @@ import lombok.*; import java.time.LocalDateTime; /** - * 消息 DO + * IM 消息 DO * * @author 芋道源码 */ @@ -32,6 +32,7 @@ public class ImMessageDO extends BaseDO { * 客户端消息编号 uuid,用于排重 */ private String clientMessageId; + // TODO @hao:senderId、receiverId 存储的具体值写下,对应的群之类的 /** * 发送人编号 */ @@ -40,18 +41,23 @@ public class ImMessageDO extends BaseDO { * 接收人编号 */ private Long receiverId; + // TODO @hao:冗余字段,要说明下的。例如说 /** * 发送人昵称 + * + * 冗余 AdminUserDO 的 nickname 字段 */ private String senderNickname; /** * 发送人头像 */ private String senderAvatar; + // TODO @hao:关联枚举 /** * 会话类型 */ private Integer conversationType; + // TODO @hao:关联字段 /** * 会话标志 */ @@ -60,6 +66,7 @@ public class ImMessageDO extends BaseDO { * 消息类型 */ private Integer contentType; + // TODO @hao:说明下是 json 格式,在哪个包看具体的格式 /** * 消息内容 */ @@ -68,11 +75,12 @@ public class ImMessageDO extends BaseDO { * 发送时间 */ private LocalDateTime sendTime; + // TODO @hao:搞个枚举,然后代码里注释说明下 /** * 消息来源 100-用户发送;200-系统发送(一般是通知); */ private Integer sendFrom; - + // TODO @hao:搞个枚举,然后代码里注释说明下 /** * 消息状态 1 发送中、2 发送成功、3 发送失败、4 已删除、5 已撤回 */ diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/jackson/ImMessageBodyDeserializer.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/jackson/ImMessageBodyDeserializer.java index 7df70ce4c1..2f7c4f8803 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/jackson/ImMessageBodyDeserializer.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/jackson/ImMessageBodyDeserializer.java @@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; +// TODO @hao:可以讨论下:是不是前端传递 type + content,后端根据 type 判断后,直接 jsonutil 解析到对应的 body 就 ok 了 public class ImMessageBodyDeserializer extends JsonDeserializer { @Override @@ -33,4 +34,5 @@ public class ImMessageBodyDeserializer extends JsonDeserializer { // 如果没有匹配的属性,抛出异常 throw ctxt.mappingException("Cannot deserialize to an instance of ImMessageBody"); } + } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImplTest.java b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImplTest.java index 482a4d4ee0..7b97605647 100755 --- a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImplTest.java +++ b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImplTest.java @@ -21,6 +21,7 @@ import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; import static org.junit.jupiter.api.Assertions.*; +// TODO @hao:单测可以先都删除,等后面搞了在弄 /** * {@link ImConversationServiceImpl} 的单元测试类 *