diff --git a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ConversationTypeEnum.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ImConversationTypeEnum.java similarity index 68% rename from yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ConversationTypeEnum.java rename to yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ImConversationTypeEnum.java index bc128243a1..a72ae7b3ea 100644 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ConversationTypeEnum.java +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ImConversationTypeEnum.java @@ -6,7 +6,6 @@ import lombok.Getter; import java.util.Arrays; -// TODO @anhaohao:IM 前缀还是要的哈 /** * IM 会话类型枚举 * 参考 “会话类型” 文档 @@ -15,13 +14,13 @@ import java.util.Arrays; */ @Getter @AllArgsConstructor -public enum ConversationTypeEnum implements IntArrayValuable { +public enum ImConversationTypeEnum implements IntArrayValuable { SINGLE(1, "单聊"), GROUP(3, "群聊"), NOTIFICATION(4, "通知会话"); - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ConversationTypeEnum::getType).toArray(); + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ImConversationTypeEnum::getType).toArray(); /** * 类型 @@ -33,25 +32,26 @@ public enum ConversationTypeEnum implements IntArrayValuable { */ private final String name; - @Override - public int[] array() { - return ARRAYS; - } - /** - * 生成会话编号 TODO @anhaohao:方法注释,和下面参数之间,要有空格 - * @param fromUserId 发送者编号 - * @param receiverId 接收者编号 + * 生成会话编号 + * + * @param fromUserId 发送者编号 + * @param receiverId 接收者编号 * @param conversationType 会话类型 * @return 会话编号 */ public static String generateConversationNo(Long fromUserId, Long receiverId, Integer conversationType) { - if (conversationType.equals(ConversationTypeEnum.SINGLE.getType())) { + if (conversationType.equals(ImConversationTypeEnum.SINGLE.getType())) { return "s_" + fromUserId + "_" + receiverId; - } else if (conversationType.equals(ConversationTypeEnum.GROUP.getType())) { + } else if (conversationType.equals(ImConversationTypeEnum.GROUP.getType())) { return "g_" + receiverId; } return null; } + @Override + 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/message/MessageContentTypeEnum.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageContentTypeEnum.java similarity index 93% rename from yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageContentTypeEnum.java rename to yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageContentTypeEnum.java index f0e756987d..6d5c96f60a 100644 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageContentTypeEnum.java +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageContentTypeEnum.java @@ -6,7 +6,6 @@ import lombok.Getter; import java.util.Arrays; -// TODO @anhaohao:IM 前缀还是要的哈 /** * IM 消息的类型枚举 *

@@ -16,7 +15,7 @@ import java.util.Arrays; */ @Getter @AllArgsConstructor -public enum MessageContentTypeEnum implements IntArrayValuable { +public enum ImMessageContentTypeEnum implements IntArrayValuable { TEXT(101, "文本消息"), PICTURE(102, "图片消息"), @@ -57,7 +56,7 @@ public enum MessageContentTypeEnum implements IntArrayValuable { BURN_CHANGE(1701, "阅后即焚开启或关闭通知"), REVOKE(2101, "撤回消息通知");; - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MessageContentTypeEnum::getType).toArray(); + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ImMessageContentTypeEnum::getType).toArray(); /** * 类型 diff --git a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageSourceEnum.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageSourceEnum.java similarity index 71% rename from yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageSourceEnum.java rename to yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageSourceEnum.java index caa81ab4d7..c1f2393d6a 100644 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageSourceEnum.java +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageSourceEnum.java @@ -6,24 +6,22 @@ import lombok.RequiredArgsConstructor; import java.util.Arrays; -// TODO @anhaohao:IM 前缀还是要的哈 /** * IM 消息的消息来源 */ @RequiredArgsConstructor @Getter -public enum MessageSourceEnum implements IntArrayValuable { +public enum ImMessageSourceEnum implements IntArrayValuable { USER_SEND(100, "用户发送"), SYSTEM_SEND(200, "系统发送"); - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MessageSourceEnum::getStatus).toArray(); + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ImMessageSourceEnum::getSource).toArray(); - // TODO @anhaohao:应该是 source /** * 状态 */ - private final Integer status; + private final Integer source; /** * 名字 */ diff --git a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageStatusEnum.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageStatusEnum.java similarity index 59% rename from yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageStatusEnum.java rename to yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageStatusEnum.java index fc7092040c..e9d8b9a040 100644 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageStatusEnum.java +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageStatusEnum.java @@ -6,27 +6,21 @@ import lombok.RequiredArgsConstructor; import java.util.Arrays; -// TODO @anhaohao:IM 前缀还是要的哈 -// TODO TODO 状态是这些哈,客户端的视角: -// -//- 草稿(预留) 0 -//- 发送中 1 -//- 发送成功 2 -//- 发送失败 3 -//- 已删除 4 -//- 已撤回 5 /** * IM 消息的状态枚举 */ @RequiredArgsConstructor @Getter -public enum MessageStatusEnum implements IntArrayValuable { +public enum ImMessageStatusEnum implements IntArrayValuable { + DRAFT(0, "草稿"), SENDING(1, "发送中"), - SUCCEED(2, "发送成功"), - FAILED(3, "发送失败"); + SUCCESS(2, "发送成功"), + FAILURE(3, "发送失败"), + DELETED(4, "已删除"), + RECALL(5, "已撤回"); - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MessageStatusEnum::getStatus).toArray(); + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ImMessageStatusEnum::getStatus).toArray(); /** * 状态 diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ConversationController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java similarity index 71% rename from yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ConversationController.java rename to yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java index 33cb85765c..ea83761a53 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ConversationController.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java @@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.im.controller.admin.conversation; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ConversationLastTimeReqVO; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdateLastReadTimeReqVO; import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationRespVO; -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ConversationPinnedReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ConversationDO; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdatePinnedReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; import cn.iocoder.yudao.module.im.service.conversation.ConversationService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -17,13 +17,13 @@ import org.springframework.web.bind.annotation.*; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -// TODO @anhaohao:im 前缀少啦 @Tag(name = "管理后台 - IM 会话") @RestController @RequestMapping("/im/conversation") @Validated -public class ConversationController { +public class ImConversationController { @Resource private ConversationService conversationService; @@ -31,23 +31,21 @@ public class ConversationController { @GetMapping("/list") @Operation(summary = "获得用户的会话列表") public CommonResult> getConversationList() { - List conversationList = conversationService.getConversationList(); + List conversationList = conversationService.getConversationList(); return success(BeanUtils.toBean(conversationList, ImConversationRespVO.class)); } - // TODO @hao:这个接口,需要单独的 VO 哈; @PostMapping("/update-pinned") @Operation(summary = "置顶会话") - public CommonResult updatePinned(@Valid @RequestBody ConversationPinnedReqVO updateReqVO) { - conversationService.updatePinned(updateReqVO); + public CommonResult updatePinned(@Valid @RequestBody ImConversationUpdatePinnedReqVO updateReqVO) { + conversationService.updatePinned(getLoginUserId(),updateReqVO); return success(true); } - // TODO @hao:这个接口,需要单独的 VO 哈; @PostMapping("/update-last-read-time") @Operation(summary = "更新最后已读时间") - public CommonResult updateLastReadTime(@Valid @RequestBody ConversationLastTimeReqVO updateReqVO) { - conversationService.updateLastReadTime(updateReqVO); + public CommonResult updateLastReadTime(@Valid @RequestBody ImConversationUpdateLastReadTimeReqVO updateReqVO) { + conversationService.updateLastReadTime(getLoginUserId(),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/ConversationLastTimeReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ConversationLastTimeReqVO.java deleted file mode 100755 index dfd05a0692..0000000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ConversationLastTimeReqVO.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.module.im.controller.admin.conversation.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.Data; - -import java.time.LocalDateTime; - -// TODO @anhaohao:改成 ConversationUpdateLastReadTimeReqVO,项目目前都是动名词哈。更新置顶 -@Schema(description = "管理后台 - 会话最后已读时间 Request VO") -@Data -public class ConversationLastTimeReqVO { - - // TODO @anhaohao:no 不用传递哈。因为 userId + targetId 可以推出来 - @Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "s_1_2") - @NotEmpty(message = "会话标志不能为空") - private String no; - - @Schema(description = "最后已读时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-01 00:00:00") - @NotNull(message = "最后已读时间不能为空") - private LocalDateTime lastReadTime; - - // TODO @anhaohao:userId 不用传递,因为 token 已经能解析出当前用户 - @Schema(description = "所属用户", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Long userId; - - @Schema(description = "聊天对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Long targetId; - - @Schema(description = "会话类型",requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer type; // 枚举 ConversationTypeEnum TODO ,这里可以使用 @InEnum 校验,这样这个注释就不用写了 - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ConversationPinnedReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ConversationPinnedReqVO.java deleted file mode 100755 index f10ae27f99..0000000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ConversationPinnedReqVO.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.im.controller.admin.conversation.vo; - -import com.alibaba.excel.annotation.ExcelProperty; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.Data; - -import java.time.LocalDateTime; - -// TODO @anhaohao:改成 ConversationUpdatePinnedReqVO,项目目前都是动名词哈。更新置顶 -@Schema(description = "管理后台 - 会话置顶 Request VO") -@Data -public class ConversationPinnedReqVO { - - // TODO @anhaohao:no 不用传递哈。因为 userId + targetId 可以推出来 - @Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "s_1_2") - @NotEmpty(message = "会话标志不能为空") - private String no; - - @Schema(description = "是否置顶", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "是否置顶不能为空") - private Boolean pinned; - - // TODO @anhaohao:userId 不用传递,因为 token 已经能解析出当前用户 - @Schema(description = "所属用户", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Long userId; - - @Schema(description = "聊天对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Long targetId; - - @Schema(description = "会话类型",requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer type; // 枚举 ConversationTypeEnum TODO ,这里可以使用 @InEnum 校验,这样这个注释就不用写了 - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationUpdateLastReadTimeReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationUpdateLastReadTimeReqVO.java new file mode 100755 index 0000000000..cec9ad5a6e --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationUpdateLastReadTimeReqVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.im.controller.admin.conversation.vo; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 会话最后已读时间 Request VO") +@Data +public class ImConversationUpdateLastReadTimeReqVO { + + @Schema(description = "最后已读时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-01 00:00:00") + @NotNull(message = "最后已读时间不能为空") + private LocalDateTime lastReadTime; + + @Schema(description = "聊天对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + private Long targetId; + + @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @InEnum(value = ImConversationTypeEnum.class, message = "会话类型必须是 {value}") + private Integer type; + +} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationUpdatePinnedReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationUpdatePinnedReqVO.java new file mode 100755 index 0000000000..8c1e5264de --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationUpdatePinnedReqVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.im.controller.admin.conversation.vo; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Schema(description = "管理后台 - 会话置顶 Request VO") +@Data +public class ImConversationUpdatePinnedReqVO { + + @Schema(description = "是否置顶", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "是否置顶不能为空") + private Boolean pinned; + + @Schema(description = "聊天对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + private Long targetId; + + @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @InEnum(value = ImConversationTypeEnum.class, message = "会话类型必须是 {value}") + private Integer type; + +} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java index 778b94098d..807093ae45 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java @@ -25,8 +25,8 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; -import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO; -import cn.iocoder.yudao.module.im.service.group.ImGroupService; +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; +import cn.iocoder.yudao.module.im.service.group.GroupService; // TODO @芋艿:得看看 create、update、delete、get、page 这几个接口,要保留哪些 @Tag(name = "管理后台 - 群") @@ -36,20 +36,20 @@ import cn.iocoder.yudao.module.im.service.group.ImGroupService; public class ImGroupController { @Resource - private ImGroupService imGroupService; + private GroupService groupService; @PostMapping("/create") @Operation(summary = "创建群") @PreAuthorize("@ss.hasPermission('im:group:create')") public CommonResult createGroup(@Valid @RequestBody ImGroupSaveReqVO createReqVO) { - return success(imGroupService.createGroup(createReqVO)); + return success(groupService.createGroup(createReqVO)); } @PutMapping("/update") @Operation(summary = "更新群") @PreAuthorize("@ss.hasPermission('im:group:update')") public CommonResult updateGroup(@Valid @RequestBody ImGroupSaveReqVO updateReqVO) { - imGroupService.updateGroup(updateReqVO); + groupService.updateGroup(updateReqVO); return success(true); } @@ -58,7 +58,7 @@ public class ImGroupController { @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('im:group:delete')") public CommonResult deleteGroup(@RequestParam("id") Long id) { - imGroupService.deleteGroup(id); + groupService.deleteGroup(id); return success(true); } @@ -67,7 +67,7 @@ public class ImGroupController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('im:group:query')") public CommonResult getGroup(@RequestParam("id") Long id) { - GroupDO group = imGroupService.getGroup(id); + ImGroupDO group = groupService.getGroup(id); return success(BeanUtils.toBean(group, ImGroupRespVO.class)); } @@ -75,22 +75,8 @@ public class ImGroupController { @Operation(summary = "获得群分页") @PreAuthorize("@ss.hasPermission('im:group:query')") public CommonResult> getGroupPage(@Valid ImGroupPageReqVO pageReqVO) { - PageResult pageResult = imGroupService.getGroupPage(pageReqVO); + PageResult pageResult = groupService.getGroupPage(pageReqVO); return success(BeanUtils.toBean(pageResult, ImGroupRespVO.class)); } - // TODO @anhaohao:导出可以先不做哈; - @GetMapping("/export-excel") - @Operation(summary = "导出群 Excel") - @PreAuthorize("@ss.hasPermission('im:group:export')") - @OperateLog(type = EXPORT) - public void exportGroupExcel(@Valid ImGroupPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = imGroupService.getGroupPage(pageReqVO).getList(); - // 导出 Excel - ExcelUtils.write(response, "群.xls", "数据", ImGroupRespVO.class, - BeanUtils.toBean(list, ImGroupRespVO.class)); - } - } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/groupmember/ImGroupMemberController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/groupmember/ImGroupMemberController.java index 285ea422bb..319031e590 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/groupmember/ImGroupMemberController.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/groupmember/ImGroupMemberController.java @@ -9,7 +9,7 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberPageReqVO; import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberRespVO; import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberSaveReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; import cn.iocoder.yudao.module.im.service.groupmember.GroupMemberService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -66,7 +66,7 @@ public class ImGroupMemberController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('im:group-member:query')") public CommonResult getGroupMember(@RequestParam("id") Long id) { - GroupMemberDO groupMember = groupMemberService.getGroupMember(id); + ImGroupMemberDO groupMember = groupMemberService.getGroupMember(id); return success(BeanUtils.toBean(groupMember, ImGroupMemberRespVO.class)); } @@ -74,7 +74,7 @@ public class ImGroupMemberController { @Operation(summary = "获得群成员分页") @PreAuthorize("@ss.hasPermission('im:group-member:query')") public CommonResult> getGroupMemberPage(@Valid ImGroupMemberPageReqVO pageReqVO) { - PageResult pageResult = groupMemberService.getGroupMemberPage(pageReqVO); + PageResult pageResult = groupMemberService.getGroupMemberPage(pageReqVO); return success(BeanUtils.toBean(pageResult, ImGroupMemberRespVO.class)); } @@ -85,7 +85,7 @@ public class ImGroupMemberController { public void exportGroupMemberExcel(@Valid ImGroupMemberPageReqVO pageReqVO, HttpServletResponse response) throws IOException { pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = groupMemberService.getGroupMemberPage(pageReqVO).getList(); + List list = groupMemberService.getGroupMemberPage(pageReqVO).getList(); // 导出 Excel ExcelUtils.write(response, "群成员.xls", "数据", ImGroupMemberRespVO.class, BeanUtils.toBean(list, ImGroupMemberRespVO.class)); diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSaveMessageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSaveMessageReqVO.java deleted file mode 100644 index 35691cbfb9..0000000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSaveMessageReqVO.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.iocoder.yudao.module.im.controller.admin.inbox.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; - -// TODO @anhaohao:im 前缀哈 -@Schema(description = "管理后台 - 收件箱保存消息 Request VO") -@Data -public class InboxSaveMessageReqVO { - - @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer conversationType; // 对应 ImConversationTypeEnum 枚举 - - @Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long fromId; // 根据 conversationType 区分 - - @Schema(description = "发送人昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") - private String senderNickname; - - @Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED) - private String senderAvatar; - - @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") - private Long receiverId; - - @Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454") - private Long messageId; - - @Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer contentType; // 参见 ImMessageTypeEnum 枚举 - - @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED) - private String content; - - @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime sendTime; - -// @Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED) -// private Long sequence; - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/package-info.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/package-info.java new file mode 100644 index 0000000000..2ec90868b8 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/package-info.java @@ -0,0 +1,5 @@ +/** + * @author anhaohao + * @since 2024/3/31 下午10:41 + */ +package cn.iocoder.yudao.module.im.controller.admin.inbox.vo; \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImMessageController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImMessageController.java new file mode 100755 index 0000000000..b246df07c3 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImMessageController.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.module.im.controller.admin.message; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListReqVO; +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageRespVO; +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendReqVO; +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendRespVO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; +import cn.iocoder.yudao.module.im.service.message.MessageService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Tag(name = "管理后台 - IM 消息") +@RestController +@RequestMapping("/im/message") +@Validated +public class ImMessageController { + + @Resource + private MessageService messageService; + + @PostMapping("/send") + @Operation(summary = "发送消息") + public CommonResult sendMessage(@Valid @RequestBody ImMessageSendReqVO imMessageSendReqVO) { + ImMessageDO message = messageService.sendMessage(getLoginUserId(), imMessageSendReqVO); + return success(BeanUtils.toBean(message, ImMessageSendRespVO.class)); + } + + @GetMapping("/pull") + @Operation(summary = "消息列表-拉取大于 sequence 的消息列表") + @Parameter(name = "sequence", description = "序号", required = true, example = "1") + @Parameter(name = "size", description = "条数", required = true, example = "10") + public CommonResult> pullMessageList(@RequestParam("sequence") Long sequence, + @RequestParam("size") Integer size) { + List messages = messageService.pullMessageList(getLoginUserId(), sequence, size); + return success(BeanUtils.toBean(messages, ImMessageRespVO.class)); + } + + @GetMapping("/list") + @Operation(summary = "消息列表-根据接收人和发送时间进行分页查询") + public CommonResult> getMessageList(@Valid ImMessageListReqVO listReqVO) { + List messagePage = messageService.getMessageList(getLoginUserId(), listReqVO); + return success(BeanUtils.toBean(messagePage, ImMessageRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/MessageController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/MessageController.java deleted file mode 100755 index 5923a93799..0000000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/MessageController.java +++ /dev/null @@ -1,59 +0,0 @@ -package cn.iocoder.yudao.module.im.controller.admin.message; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.MessagePageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.MessageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.SendMessageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.SendMessageRespVO; -import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; -import cn.iocoder.yudao.module.im.service.message.MessageService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.annotation.Resource; -import jakarta.validation.Valid; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; - -@Tag(name = "管理后台 - IM 消息") -@RestController -@RequestMapping("/im/message") -@Validated -public class MessageController { - - @Resource - private MessageService messageService; - - @PostMapping("/send") - @Operation(summary = "发送消息") - public CommonResult sendMessage(@Valid @RequestBody SendMessageReqVO message) { - return success(messageService.sendMessage(getLoginUserId(), message)); - } - - // TODO @anhaohao:我在想,这个接口,改成叫 pullMessageList,会不会更好理解?拉取消息列表 - @GetMapping("/list-by-sequence") - @Operation(summary = "拉取大于 sequence 的消息列表") - @Parameter(name = "sequence", description = "序号", required = true, example = "1") - @Parameter(name = "size", description = "条数", required = true, example = "10") - public CommonResult> getMessageListBySequence(@RequestParam("sequence") Long sequence, - @RequestParam("size") Integer size) { - List messages = messageService.getMessageListBySequence(getLoginUserId(), sequence, size); - return success(BeanUtils.toBean(messages, MessageReqVO.class)); - } - - // TODO @anhaohao:直接叫 getMessageList,不叫历史哈;因为它只是给用户叫历史,对系统来说,就是消息列表 - @GetMapping("/history") - @Operation(summary = "查询聊天记录-根据会话标志和发送时间进行分页查询") - public CommonResult> getHistoryMessage(@Valid MessagePageReqVO pageReqVO) { - //根据会话标志和发送时间进行分页查询 - List messagePage = messageService.getHistoryMessage(pageReqVO); - return success(BeanUtils.toBean(messagePage, MessageReqVO.class)); - } - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageListReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageListReqVO.java new file mode 100755 index 0000000000..ee21ed0eaa --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageListReqVO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.im.controller.admin.message.vo; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; + +@Schema(description = "管理后台 - 消息列表 Request VO") +@Data +@ToString(callSuper = true) +public class ImMessageListReqVO { + + @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") + @NotNull(message = "接收人编号不能为空") + private Long receiverId; + + @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + @InEnum(value = ImConversationTypeEnum.class,message = "会话类型必须是 {value}") + @NotNull(message = "会话类型不能为空") + private Integer conversationType; + + @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27 12:00:00") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDateTime sendTime; + +} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSendMessageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageRespVO.java old mode 100644 new mode 100755 similarity index 56% rename from yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSendMessageReqVO.java rename to yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageRespVO.java index ae58c5e741..10f099624c --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSendMessageReqVO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageRespVO.java @@ -1,42 +1,47 @@ -package cn.iocoder.yudao.module.im.controller.admin.inbox.vo; +package cn.iocoder.yudao.module.im.controller.admin.message.vo; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; +import cn.iocoder.yudao.module.im.enums.message.ImMessageContentTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; -@Schema(description = "管理后台 - 收件箱保存消息 Request VO") +@Schema(description = "管理后台 - 消息 Response VO") @Data -public class InboxSendMessageReqVO { +public class ImMessageRespVO { + + @Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454") + private Long id; @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer conversationType; // 对应 ImConversationTypeEnum 枚举 + @InEnum(value = ImConversationTypeEnum.class) + private Integer conversationType; - @Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long fromId; // 根据 conversationType 区分 + @Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long senderId; @Schema(description = "发送人昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") private String senderNickname; - @Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://www.iocoder.cn/xxx.jpg") private String senderAvatar; - - @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") + + @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") private Long receiverId; - @Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454") - private Long messageId; - @Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer contentType; // 参见 ImMessageTypeEnum 枚举 + @InEnum(value = ImMessageContentTypeEnum.class) + private Integer contentType; - @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好") private String content; - @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27 12:00:00") private LocalDateTime sendTime; - @Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Long sequence; } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageSendReqVO.java similarity index 59% rename from yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageReqVO.java rename to yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageSendReqVO.java index 15f6e909c9..fd04053544 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageReqVO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageSendReqVO.java @@ -1,40 +1,36 @@ package cn.iocoder.yudao.module.im.controller.admin.message.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.im.enums.message.MessageContentTypeEnum; -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; +import cn.iocoder.yudao.module.im.enums.message.ImMessageContentTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import lombok.Data; -// TODO @anhaohao:MessageSendReqVO,消息发送 - -// TODO @anhaohao:不应该有 excel 相关的注解 - @Schema(description = "管理后台 - 发送消息 Request VO") @Data -@ExcelIgnoreUnannotated -public class SendMessageReqVO { +public class ImMessageSendReqVO { @Schema(description = "客户端消息编号 uuid,用于排重", requiredMode = Schema.RequiredMode.REQUIRED, example = "3331") - @ExcelProperty("客户端消息编号 uuid,用于排重") + @NotNull(message = "客户端消息编号不能为空") private String clientMessageId; @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") - @ExcelProperty("接收人编号") + @NotNull(message = "接收人编号不能为空") private Long receiverId; @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - @ExcelProperty("会话类型") + @InEnum(value = ImConversationTypeEnum.class) + @NotNull(message = "会话类型不能为空") private Integer conversationType; @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @ExcelProperty("消息类型") - @InEnum(MessageContentTypeEnum.class) + @InEnum(ImMessageContentTypeEnum.class) + @NotNull(message = "消息类型不能为空") private Integer contentType; - @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("消息内容") + @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好") + @NotNull(message = "消息内容不能为空") private String content; } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageRespVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageSendRespVO.java similarity index 90% rename from yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageRespVO.java rename to yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageSendRespVO.java index 534cf254b5..188cddc893 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageRespVO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageSendRespVO.java @@ -10,13 +10,11 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -// TODO @anhaohao:MessageSendRespVO,消息发送结果 - @Schema(description = "管理后台 - 发送消息 Response VO") @Data @AllArgsConstructor @NoArgsConstructor -public class SendMessageRespVO { +public class ImMessageSendRespVO { @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12") private Long id; diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/MessagePageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/MessagePageReqVO.java deleted file mode 100755 index 2bac34409a..0000000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/MessagePageReqVO.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.im.controller.admin.message.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -// TODO @anhaohao:这个类,不要交 Page,而是消息列表,MessageListReqVO -@Schema(description = "管理后台 - 消息分页 Request VO") -@Data -@ToString(callSuper = true) -public class MessagePageReqVO { - - // TODO @anhaohao:还是传递 targetId 和 conversationType,我们要弱化 no 的概念; - - @Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "g_1000") - private String conversationNo; - - // TODO @anhaohao:应该不传递时间范围,而是传递分页的时间,然后根据时间,查询消息 - - @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] sendTime; - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/MessageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/MessageReqVO.java deleted file mode 100755 index 8dac88ce28..0000000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/MessageReqVO.java +++ /dev/null @@ -1,52 +0,0 @@ -package cn.iocoder.yudao.module.im.controller.admin.message.vo; - -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.im.enums.message.MessageContentTypeEnum; -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -// TODO @anhaohao:MessageRespVO 消息响应 Response VO -// TODO @anahaohao:每个 example 都写下;啊哈,漏了地方,要补下;因为 http mock 的时候,可以根据它去生成 -@Schema(description = "管理后台 - 消息 Request VO") -@Data -public class MessageReqVO { - - @Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454") - private Long id; - - @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer conversationType; // 对应 ImConversationTypeEnum 枚举 - - // TODO @anhaohao:这个应该是 senderId - @Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long fromId; // 根据 conversationType 区分 - - @Schema(description = "发送人昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") - private String senderNickname; - - @Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED) - private String senderAvatar; - - @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") - private Long receiverId; - - @Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer contentType; // 参见 ImMessageTypeEnum 枚举 - - @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED) - private String content; - - @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime sendTime; - - @Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED) - private Long sequence; - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ConversationDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationDO.java similarity index 86% rename from yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ConversationDO.java rename to yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationDO.java index 4342179cdc..273b99a4bf 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ConversationDO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationDO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.im.dal.dataobject.conversation; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.im.enums.conversation.ConversationTypeEnum; +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -9,7 +9,6 @@ import lombok.*; import java.time.LocalDateTime; -// TODO @anhaohao:还是有 IM 前缀哈 /** * IM 会话 DO * @@ -23,7 +22,7 @@ import java.time.LocalDateTime; @Builder @NoArgsConstructor @AllArgsConstructor -public class ConversationDO extends BaseDO { +public class ImConversationDO extends BaseDO { /** * 编号 @@ -39,7 +38,7 @@ public class ConversationDO extends BaseDO { /** * 会话类型 *

- * 枚举 {@link ConversationTypeEnum} + * 枚举 {@link ImConversationTypeEnum} */ private Integer type; /** diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupDO.java similarity index 94% rename from yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupDO.java rename to yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupDO.java index 8f846933dd..727f1aa27f 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupDO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupDO.java @@ -6,7 +6,6 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; -// TODO @anhaohao:还是要有 IM /** * IM 群信息 DO * @@ -20,7 +19,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class GroupDO extends BaseDO { +public class ImGroupDO extends BaseDO { /** * 编号 diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupMemberDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupMemberDO.java similarity index 93% rename from yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupMemberDO.java rename to yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupMemberDO.java index 87db7ec4f1..6d7ada16e1 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupMemberDO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupMemberDO.java @@ -4,7 +4,6 @@ import lombok.*; import com.baomidou.mybatisplus.annotation.*; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -// TODO @anhaohao:还是要有 IM /** * IM 群成员 DO * @@ -18,7 +17,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; @Builder @NoArgsConstructor @AllArgsConstructor -public class GroupMemberDO extends BaseDO { +public class ImGroupMemberDO extends BaseDO { /** * 编号 diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/InboxDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/ImInboxDO.java similarity index 79% rename from yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/InboxDO.java rename to yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/ImInboxDO.java index 11b8c090bf..bea1f44953 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/InboxDO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/ImInboxDO.java @@ -1,14 +1,14 @@ package cn.iocoder.yudao.module.im.dal.dataobject.inbox; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; -// TODO @anhaohao:还是要有 IM // TODO 我们要不要改成 ImMessageQueue 队列?从理解上,概念上,可能都更清晰一点哈。每个用户一个消息队列; + /** * IM 收件箱 DO * @@ -22,7 +22,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class InboxDO extends BaseDO { +public class ImInboxDO extends BaseDO { /** * 编号 @@ -31,14 +31,14 @@ public class InboxDO extends BaseDO { private Long id; /** * 用户编号 - * - * TODO @hao:写下 userId 和 messageId 的关联字段 + *

+ * 关联 {@link ImMessageDO#getSenderId()} 或者 {@link ImMessageDO#getReceiverId()} */ private Long userId; /** * 消息编号 - * - * 关联 {@link MessageDO#getId()} + *

+ * 关联 {@link ImMessageDO#getId()} */ private Long messageId; /** diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/MessageDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImMessageDO.java similarity index 73% rename from yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/MessageDO.java rename to yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImMessageDO.java index d6b3f6728a..93b4acf6d7 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/MessageDO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImMessageDO.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.module.im.dal.dataobject.message; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.im.enums.conversation.ConversationTypeEnum; -import cn.iocoder.yudao.module.im.enums.message.MessageContentTypeEnum; -import cn.iocoder.yudao.module.im.enums.message.MessageSourceEnum; -import cn.iocoder.yudao.module.im.enums.message.MessageStatusEnum; +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; +import cn.iocoder.yudao.module.im.enums.message.ImMessageContentTypeEnum; +import cn.iocoder.yudao.module.im.enums.message.ImMessageSourceEnum; +import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -12,7 +12,6 @@ import lombok.*; import java.time.LocalDateTime; -// TODO @anhaohao:还是要有 IM /** * IM 消息 DO * @@ -26,7 +25,7 @@ import java.time.LocalDateTime; @Builder @NoArgsConstructor @AllArgsConstructor -public class MessageDO extends BaseDO { +public class ImMessageDO extends BaseDO { /** * 编号 @@ -60,24 +59,24 @@ public class MessageDO extends BaseDO { */ private String senderAvatar; /** - * 会话类型 枚举 {@link ConversationTypeEnum} + * 会话类型 枚举 {@link ImConversationTypeEnum} */ private Integer conversationType; /** * 会话标志 - * - * 生成规则:{@link ConversationTypeEnum#generateConversationNo(Long, Long, Integer)} 方法 + *

+ * 生成规则:{@link ImConversationTypeEnum#generateConversationNo(Long, Long, Integer)} 方法 */ private String conversationNo; /** * 消息类型 - * - * 枚举 {@link MessageContentTypeEnum} + *

+ * 枚举 {@link ImMessageContentTypeEnum} */ private Integer contentType; /** * 消息内容 - * + *

* JSON 格式 对应 dal/dataobject/message/content 包 */ private String content; @@ -87,14 +86,14 @@ public class MessageDO extends BaseDO { private LocalDateTime sendTime; /** * 消息来源 - * - * 枚举 {@link MessageSourceEnum} + *

+ * 枚举 {@link ImMessageSourceEnum} */ private Integer sendFrom; /** * 消息状态 - * - * 枚举 {@link MessageStatusEnum} + *

+ * 枚举 {@link ImMessageStatusEnum} */ private Integer messageStatus; diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/AudioMessage.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/AudioMessage.java index 9258ce7342..e6f6cfbf1f 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/AudioMessage.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/AudioMessage.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.im.dal.dataobject.message.content; -import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -8,7 +8,7 @@ import lombok.NoArgsConstructor; // TODO @anhaohao:要有 IM; // TODO @芋艿:后续要挪到 api 包下,主要是给外部接口使用 /** - * 语音消息的 {@link MessageDO 字段 content} 的内容 + * 语音消息的 {@link ImMessageDO 字段 content} 的内容 * * @author 芋道源码 */ diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/CardMessage.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/CardMessage.java index 3eff9bf43d..4199f79b0d 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/CardMessage.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/CardMessage.java @@ -1,12 +1,12 @@ package cn.iocoder.yudao.module.im.dal.dataobject.message.content; -import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** - * 名片消息的 {@link MessageDO 字段 content} 的内容 + * 名片消息的 {@link ImMessageDO 字段 content} 的内容 * * @author anhaohao * @since 2024/3/23 下午5:53 diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/FileMessage.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/FileMessage.java index 2dd2b6b0a3..0cb112e6bf 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/FileMessage.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/FileMessage.java @@ -1,12 +1,12 @@ package cn.iocoder.yudao.module.im.dal.dataobject.message.content; -import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** - * 文件消息的 {@link MessageDO 字段 content} 的内容 + * 文件消息的 {@link ImMessageDO 字段 content} 的内容 * * @author 芋道源码 */ diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/ImageMessage.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/ImageMessage.java index cfdfcb1e68..2cd0dfbc2f 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/ImageMessage.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/ImageMessage.java @@ -1,12 +1,12 @@ package cn.iocoder.yudao.module.im.dal.dataobject.message.content; -import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** - * 图片消息的 {@link MessageDO 字段 content} 的内容 + * 图片消息的 {@link ImMessageDO 字段 content} 的内容 * * @author 芋道源码 */ diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/LocationMessage.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/LocationMessage.java index a95c2d8005..439b18f910 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/LocationMessage.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/LocationMessage.java @@ -1,12 +1,12 @@ package cn.iocoder.yudao.module.im.dal.dataobject.message.content; -import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** - * 地址位置消息的 {@link MessageDO 字段 content} 的内容 + * 地址位置消息的 {@link ImMessageDO 字段 content} 的内容 * * @author 芋道源码 */ diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/TextMessage.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/TextMessage.java index b7f13a4e90..35edffff4d 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/TextMessage.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/TextMessage.java @@ -1,12 +1,12 @@ package cn.iocoder.yudao.module.im.dal.dataobject.message.content; -import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** - * 文本消息的 {@link MessageDO 字段 content} 的内容 + * 文本消息的 {@link ImMessageDO 字段 content} 的内容 * * @author 芋道源码 */ diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/VideoMessage.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/VideoMessage.java index e757e5074c..166954c19a 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/VideoMessage.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/VideoMessage.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.module.im.dal.dataobject.message.content; -import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import lombok.Data; /** - * 视频消息的 {@link MessageDO 字段 content} 的内容 + * 视频消息的 {@link ImMessageDO 字段 content} 的内容 * * @author 芋道源码 */ diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/conversation/ConversationMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/conversation/ConversationMapper.java index 0121470a87..ed6fe155c4 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/conversation/ConversationMapper.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/conversation/ConversationMapper.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.im.dal.mysql.conversation; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ConversationDO; +import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; import org.apache.ibatis.annotations.Mapper; /** @@ -11,9 +10,9 @@ import org.apache.ibatis.annotations.Mapper; * @author 芋道源码 */ @Mapper -public interface ConversationMapper extends BaseMapperX { +public interface ConversationMapper extends BaseMapperX { - default ConversationDO selectByNo(String no){ - return selectOne(ConversationDO::getNo, no); + default ImConversationDO selectByNo(String no){ + return selectOne(ImConversationDO::getNo, no); } } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/GroupMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/GroupMapper.java new file mode 100644 index 0000000000..1e01de47d0 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/GroupMapper.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.im.dal.mysql.group; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; + +/** + * 群 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface GroupMapper extends BaseMapperX { + + default PageResult selectPage(ImGroupPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(ImGroupDO::getGroupName, reqVO.getGroupName()) + .eqIfPresent(ImGroupDO::getOwnerId, reqVO.getOwnerId()) + .eqIfPresent(ImGroupDO::getHeadImage, reqVO.getHeadImage()) + .eqIfPresent(ImGroupDO::getHeadImageThumb, reqVO.getHeadImageThumb()) + .eqIfPresent(ImGroupDO::getNotice, reqVO.getNotice()) + .eqIfPresent(ImGroupDO::getRemark, reqVO.getRemark()) + .betweenIfPresent(ImGroupDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(ImGroupDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/ImGroupMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/ImGroupMapper.java deleted file mode 100644 index 6049550fca..0000000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/ImGroupMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.mysql.group; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO; -import org.apache.ibatis.annotations.Mapper; -import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; - -/** - * 群 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface ImGroupMapper extends BaseMapperX { - - default PageResult selectPage(ImGroupPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(GroupDO::getGroupName, reqVO.getGroupName()) - .eqIfPresent(GroupDO::getOwnerId, reqVO.getOwnerId()) - .eqIfPresent(GroupDO::getHeadImage, reqVO.getHeadImage()) - .eqIfPresent(GroupDO::getHeadImageThumb, reqVO.getHeadImageThumb()) - .eqIfPresent(GroupDO::getNotice, reqVO.getNotice()) - .eqIfPresent(GroupDO::getRemark, reqVO.getRemark()) - .betweenIfPresent(GroupDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(GroupDO::getId)); - } - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/groupmember/GroupMemberMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/groupmember/GroupMemberMapper.java new file mode 100644 index 0000000000..1ebf494844 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/groupmember/GroupMemberMapper.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.im.dal.mysql.groupmember; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberPageReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 群成员 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface GroupMemberMapper extends BaseMapperX { + + default PageResult selectPage(ImGroupMemberPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(ImGroupMemberDO::getGroupId, reqVO.getGroupId()) + .eqIfPresent(ImGroupMemberDO::getUserId, reqVO.getUserId()) + .likeIfPresent(ImGroupMemberDO::getNickname, reqVO.getNickname()) + .eqIfPresent(ImGroupMemberDO::getAvatar, reqVO.getAvatar()) + .likeIfPresent(ImGroupMemberDO::getAliasName, reqVO.getAliasName()) + .eqIfPresent(ImGroupMemberDO::getRemark, reqVO.getRemark()) + .betweenIfPresent(ImGroupMemberDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(ImGroupMemberDO::getId)); + } + + default List selectListByGroupId(Long groupId) { + return selectList(new LambdaQueryWrapperX().eq(ImGroupMemberDO::getGroupId, groupId)); + } +} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/groupmember/ImGroupMemberMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/groupmember/ImGroupMemberMapper.java deleted file mode 100644 index 505459af0f..0000000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/groupmember/ImGroupMemberMapper.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.mysql.groupmember; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberPageReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -/** - * 群成员 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface ImGroupMemberMapper extends BaseMapperX { - - default PageResult selectPage(ImGroupMemberPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eqIfPresent(GroupMemberDO::getGroupId, reqVO.getGroupId()) - .eqIfPresent(GroupMemberDO::getUserId, reqVO.getUserId()) - .likeIfPresent(GroupMemberDO::getNickname, reqVO.getNickname()) - .eqIfPresent(GroupMemberDO::getAvatar, reqVO.getAvatar()) - .likeIfPresent(GroupMemberDO::getAliasName, reqVO.getAliasName()) - .eqIfPresent(GroupMemberDO::getRemark, reqVO.getRemark()) - .betweenIfPresent(GroupMemberDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(GroupMemberDO::getId)); - } - - default List selectListByGroupId(Long groupId) { - return selectList(new LambdaQueryWrapperX().eq(GroupMemberDO::getGroupId, groupId)); - } -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/inbox/InboxMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/inbox/InboxMapper.java index 73921fca21..0f5ff07ab2 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/inbox/InboxMapper.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/inbox/InboxMapper.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.im.dal.mysql.inbox; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.im.dal.dataobject.inbox.InboxDO; +import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO; import org.apache.ibatis.annotations.Mapper; import java.util.List; @@ -13,27 +13,14 @@ import java.util.List; * @author 芋道源码 */ @Mapper -public interface InboxMapper extends BaseMapperX { +public interface InboxMapper extends BaseMapperX { - // TODO @anhaohao:返回 List ,转换成 messageId 交给上层;dao 尽量通用 - default List selectMessageIdsByUserIdAndSequence(Long userId, Long sequence, Integer size) { - return selectList(new LambdaQueryWrapperX() - .gt(InboxDO::getUserId, userId) - .gt(InboxDO::getSequence, sequence) - .orderByAsc(InboxDO::getSequence) - .last("limit 0," + size)) // TODO @anhaohao:这里 limit 就可以了,不用从 limit 0 开始; - .stream() - .map(InboxDO::getMessageId) - .toList(); + default List selectListByUserIdAndSequence(Long userId, Long sequence, Integer size) { + return selectList(new LambdaQueryWrapperX() + .gt(ImInboxDO::getUserId, userId) + .gt(ImInboxDO::getSequence, sequence) + .orderByAsc(ImInboxDO::getSequence) + .last("LIMIT " + size)); } -// default PageResult selectPage(ImInboxPageReqVO reqVO) { -// return selectPage(reqVO, new LambdaQueryWrapperX() -// .eqIfPresent(InboxDO::getUserId, reqVO.getUserId()) -// .eqIfPresent(InboxDO::getMessageId, reqVO.getMessageId()) -// .eqIfPresent(InboxDO::getSequence, reqVO.getSequence()) -// .betweenIfPresent(InboxDO::getCreateTime, reqVO.getCreateTime()) -// .orderByDesc(InboxDO::getId)); -// } - } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/MessageMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/MessageMapper.java index bd99fb661e..a90b63ecaf 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/MessageMapper.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/MessageMapper.java @@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.im.dal.mysql.message; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.MessagePageReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.inbox.InboxDO; -import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; -import com.github.yulichang.wrapper.MPJLambdaWrapper; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import org.apache.ibatis.annotations.Mapper; import java.util.List; @@ -16,13 +13,12 @@ import java.util.List; * @author 芋道源码 */ @Mapper -public interface MessageMapper extends BaseMapperX { +public interface MessageMapper extends BaseMapperX { - default List getHistoryMessage(MessagePageReqVO pageReqVO) { - return selectList(new LambdaQueryWrapperX() - .eqIfPresent(MessageDO::getConversationNo, pageReqVO.getConversationNo()) - .betweenIfPresent(MessageDO::getSendTime, pageReqVO.getSendTime()) - .orderByAsc(MessageDO::getSendTime)); + default List selectMessageList(ImMessageDO message) { + return selectList(new LambdaQueryWrapperX() + .eqIfPresent(ImMessageDO::getConversationNo, message.getConversationNo()) + .eqIfPresent(ImMessageDO::getSendTime, message.getSendTime()) + .orderByAsc(ImMessageDO::getSendTime)); } - } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceRedisDao.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceRedisDAO.java similarity index 91% rename from yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceRedisDao.java rename to yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceRedisDAO.java index ddbab25fb7..e3bd8fdbbe 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceRedisDao.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceRedisDAO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.im.dal.redis.inbox; import jakarta.annotation.Resource; -import org.redisson.api.RedissonClient; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Repository; @@ -15,7 +14,7 @@ import static cn.iocoder.yudao.module.im.dal.redis.RedisKeyConstants.INBOX_SEQUE * @author anhaohao */ @Repository -public class SequenceRedisDao { +public class SequenceRedisDAO { @Resource private RedisTemplate redisTemplate; diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationService.java index 200ae695f1..e76a793da5 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationService.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationService.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.im.service.conversation; -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ConversationLastTimeReqVO; -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ConversationPinnedReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ConversationDO; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdateLastReadTimeReqVO; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdatePinnedReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; import java.util.List; @@ -18,20 +18,22 @@ public interface ConversationService { * * @return 会话列表 */ - List getConversationList(); + List getConversationList(); /** * 置顶会话 * + * @param loginUserId 登录用户编号 * @param updateReqVO 更新信息 */ - void updatePinned(ConversationPinnedReqVO updateReqVO); + void updatePinned(Long loginUserId, ImConversationUpdatePinnedReqVO updateReqVO); /** * 更新最后已读时间 * + * @param loginUserId 登录用户编号 * @param updateReqVO 更新信息 */ - void updateLastReadTime(ConversationLastTimeReqVO updateReqVO); + void updateLastReadTime(Long loginUserId, ImConversationUpdateLastReadTimeReqVO updateReqVO); } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationServiceImpl.java index 14c498a93a..49fd8b9383 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationServiceImpl.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationServiceImpl.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.module.im.service.conversation; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ConversationLastTimeReqVO; -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ConversationPinnedReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ConversationDO; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdateLastReadTimeReqVO; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdatePinnedReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; import cn.iocoder.yudao.module.im.dal.mysql.conversation.ConversationMapper; +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; import cn.iocoder.yudao.module.im.service.inbox.InboxService; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -27,50 +27,50 @@ public class ConversationServiceImpl implements ConversationService { private InboxService inboxService; @Override - public List getConversationList() { + public List getConversationList() { return conversationMapper.selectList(); } @Override - public void updatePinned(ConversationPinnedReqVO updateReqVO) { - // TODO @hao:updateTop 和 updateLastReadTime 使用独立的逻辑实现,不使用统一的 ImConversationSaveReqVO; - // TODO 大体步骤建议: - // 1. 先 getOrderCreateConversation,查询会话,不存在则插入; - // 2. 更新对应的字段 - // 3. 做对应更新的 notify 推送 - ConversationDO conversation = conversationMapper.selectByNo(updateReqVO.getNo()); + public void updatePinned(Long loginUserId, ImConversationUpdatePinnedReqVO updateReqVO) { + // 1. 获得会话编号 + String no = ImConversationTypeEnum.generateConversationNo(loginUserId, updateReqVO.getTargetId(), updateReqVO.getType()); + // 2. 查询会话 + ImConversationDO conversation = conversationMapper.selectByNo(no); if (conversation == null) { - ConversationDO conversationDO = new ConversationDO(); - // TODO @hao:no 不是前端传递哈,后端生成;另外,其实可以把 insert 写成一个公用方法;get会话,拿不到就 insert;接着处理 update 操作;首次多 update 一次,无所谓的;没多少量的 - conversationDO.setNo(updateReqVO.getNo()); - conversationDO.setPinned(updateReqVO.getPinned()); - conversationDO.setUserId(updateReqVO.getUserId()); - conversationDO.setTargetId(updateReqVO.getTargetId()); - conversationDO.setType(updateReqVO.getType()); - conversationMapper.insert(conversationDO); - } else { - // 更新 TODO @anhaohao:这里不要 toBean,因为这里逻辑偏 toc,new ConversationDO 对象,然后逐个 set 需要的值; - ConversationDO updateObj = BeanUtils.toBean(updateReqVO, ConversationDO.class); - conversationMapper.updateById(updateObj); + // 2.1. 不存在,则插入 + conversation = insertConversation(no, loginUserId, updateReqVO.getTargetId(), updateReqVO.getType()); } + // 3. 更新会话 + conversation.setPinned(updateReqVO.getPinned()); + conversationMapper.updateById(conversation); + // 4. 做对应更新的 notify 推送 + } + + private ImConversationDO insertConversation(String no, Long userId, Long targetId, Integer type) { + ImConversationDO imConversationDO = new ImConversationDO(); + imConversationDO.setNo(no); + imConversationDO.setUserId(userId); + imConversationDO.setTargetId(targetId); + imConversationDO.setType(type); + conversationMapper.insert(imConversationDO); + return imConversationDO; } @Override - public void updateLastReadTime(ConversationLastTimeReqVO updateReqVO) { - ConversationDO conversation = conversationMapper.selectByNo(updateReqVO.getNo()); + public void updateLastReadTime(Long loginUserId, ImConversationUpdateLastReadTimeReqVO updateReqVO) { + // 1. 获得会话编号 + String no = ImConversationTypeEnum.generateConversationNo(loginUserId, updateReqVO.getTargetId(), updateReqVO.getType()); + // 2. 查询会话 + ImConversationDO conversation = conversationMapper.selectByNo(no); if (conversation == null) { - ConversationDO conversationDO = new ConversationDO(); - conversationDO.setNo(updateReqVO.getNo()); - conversationDO.setLastReadTime(updateReqVO.getLastReadTime()); - conversationDO.setUserId(updateReqVO.getUserId()); - conversationDO.setTargetId(updateReqVO.getTargetId()); - conversationDO.setType(updateReqVO.getType()); - conversationMapper.insert(conversationDO); - } else { - // 更新 - ConversationDO updateObj = BeanUtils.toBean(updateReqVO, ConversationDO.class); - conversationMapper.updateById(updateObj); + // 2.1. 不存在,则插入 + conversation = insertConversation(no, loginUserId, updateReqVO.getTargetId(), updateReqVO.getType()); } + // 3. 更新会话 + conversation.setLastReadTime(updateReqVO.getLastReadTime()); + conversationMapper.updateById(conversation); + // 4. 做对应更新的 notify 推送 } } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/GroupService.java similarity index 81% rename from yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java rename to yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/GroupService.java index cd395b8afc..233af0273c 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/GroupService.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.im.service.group; import jakarta.validation.*; import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; -import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; /** @@ -10,7 +10,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; * * @author 芋道源码 */ -public interface ImGroupService { +public interface GroupService { /** * 创建群 @@ -40,7 +40,7 @@ public interface ImGroupService { * @param id 编号 * @return 群 */ - GroupDO getGroup(Long id); + ImGroupDO getGroup(Long id); /** * 获得群分页 @@ -48,6 +48,6 @@ public interface ImGroupService { * @param pageReqVO 分页查询 * @return 群分页 */ - PageResult getGroupPage(ImGroupPageReqVO pageReqVO); + PageResult getGroupPage(ImGroupPageReqVO pageReqVO); } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/GroupServiceImpl.java similarity index 62% rename from yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java rename to yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/GroupServiceImpl.java index 5cc2e1b098..13d5c526c5 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/GroupServiceImpl.java @@ -5,11 +5,11 @@ import jakarta.annotation.Resource; import org.springframework.validation.annotation.Validated; import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; -import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMapper; +import cn.iocoder.yudao.module.im.dal.mysql.group.GroupMapper; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; @@ -21,16 +21,16 @@ import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; */ @Service @Validated -public class ImGroupServiceImpl implements ImGroupService { +public class GroupServiceImpl implements GroupService { @Resource - private ImGroupMapper imGroupMapper; + private GroupMapper groupMapper; @Override public Long createGroup(ImGroupSaveReqVO createReqVO) { // 插入 - GroupDO group = BeanUtils.toBean(createReqVO, GroupDO.class); - imGroupMapper.insert(group); + ImGroupDO group = BeanUtils.toBean(createReqVO, ImGroupDO.class); + groupMapper.insert(group); // 返回 return group.getId(); } @@ -40,8 +40,8 @@ public class ImGroupServiceImpl implements ImGroupService { // 校验存在 validateGroupExists(updateReqVO.getId()); // 更新 - GroupDO updateObj = BeanUtils.toBean(updateReqVO, GroupDO.class); - imGroupMapper.updateById(updateObj); + ImGroupDO updateObj = BeanUtils.toBean(updateReqVO, ImGroupDO.class); + groupMapper.updateById(updateObj); } @Override @@ -49,23 +49,23 @@ public class ImGroupServiceImpl implements ImGroupService { // 校验存在 validateGroupExists(id); // 删除 - imGroupMapper.deleteById(id); + groupMapper.deleteById(id); } private void validateGroupExists(Long id) { - if (imGroupMapper.selectById(id) == null) { + if (groupMapper.selectById(id) == null) { throw exception(GROUP_NOT_EXISTS); } } @Override - public GroupDO getGroup(Long id) { - return imGroupMapper.selectById(id); + public ImGroupDO getGroup(Long id) { + return groupMapper.selectById(id); } @Override - public PageResult getGroupPage(ImGroupPageReqVO pageReqVO) { - return imGroupMapper.selectPage(pageReqVO); + public PageResult getGroupPage(ImGroupPageReqVO pageReqVO) { + return groupMapper.selectPage(pageReqVO); } } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/GroupMemberService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/GroupMemberService.java index e003a23eb1..3188c2e3fe 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/GroupMemberService.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/GroupMemberService.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.im.service.groupmember; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberPageReqVO; import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberSaveReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; import jakarta.validation.Valid; import java.util.List; @@ -43,7 +43,7 @@ public interface GroupMemberService { * @param id 编号 * @return 群成员 */ - GroupMemberDO getGroupMember(Long id); + ImGroupMemberDO getGroupMember(Long id); /** * 获得群成员分页 @@ -51,7 +51,7 @@ public interface GroupMemberService { * @param pageReqVO 分页查询 * @return 群成员分页 */ - PageResult getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO); + PageResult getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO); /** * 根据群组id查询群成员 @@ -59,5 +59,5 @@ public interface GroupMemberService { * @param groupId 群组id * @return 群成员列表 */ - List selectByGroupId(Long groupId); + List selectByGroupId(Long groupId); } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/GroupMemberServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/GroupMemberServiceImpl.java index def340012d..43df1b9ac4 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/GroupMemberServiceImpl.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/GroupMemberServiceImpl.java @@ -5,11 +5,11 @@ import jakarta.annotation.Resource; import org.springframework.validation.annotation.Validated; import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.*; -import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.im.dal.mysql.groupmember.ImGroupMemberMapper; +import cn.iocoder.yudao.module.im.dal.mysql.groupmember.GroupMemberMapper; import java.util.List; @@ -26,13 +26,13 @@ import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; public class GroupMemberServiceImpl implements GroupMemberService { @Resource - private ImGroupMemberMapper imGroupMemberMapper; + private GroupMemberMapper groupMemberMapper; @Override public Long createGroupMember(ImGroupMemberSaveReqVO createReqVO) { // 插入 - GroupMemberDO groupMember = BeanUtils.toBean(createReqVO, GroupMemberDO.class); - imGroupMemberMapper.insert(groupMember); + ImGroupMemberDO groupMember = BeanUtils.toBean(createReqVO, ImGroupMemberDO.class); + groupMemberMapper.insert(groupMember); // 返回 return groupMember.getId(); } @@ -42,8 +42,8 @@ public class GroupMemberServiceImpl implements GroupMemberService { // 校验存在 validateGroupMemberExists(updateReqVO.getId()); // 更新 - GroupMemberDO updateObj = BeanUtils.toBean(updateReqVO, GroupMemberDO.class); - imGroupMemberMapper.updateById(updateObj); + ImGroupMemberDO updateObj = BeanUtils.toBean(updateReqVO, ImGroupMemberDO.class); + groupMemberMapper.updateById(updateObj); } @Override @@ -51,28 +51,28 @@ public class GroupMemberServiceImpl implements GroupMemberService { // 校验存在 validateGroupMemberExists(id); // 删除 - imGroupMemberMapper.deleteById(id); + groupMemberMapper.deleteById(id); } private void validateGroupMemberExists(Long id) { - if (imGroupMemberMapper.selectById(id) == null) { + if (groupMemberMapper.selectById(id) == null) { throw exception(GROUP_MEMBER_NOT_EXISTS); } } @Override - public GroupMemberDO getGroupMember(Long id) { - return imGroupMemberMapper.selectById(id); + public ImGroupMemberDO getGroupMember(Long id) { + return groupMemberMapper.selectById(id); } @Override - public PageResult getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO) { - return imGroupMemberMapper.selectPage(pageReqVO); + public PageResult getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO) { + return groupMemberMapper.selectPage(pageReqVO); } @Override - public List selectByGroupId(Long groupId) { - return imGroupMemberMapper.selectListByGroupId(groupId); + public List selectByGroupId(Long groupId) { + return groupMemberMapper.selectListByGroupId(groupId); } } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/InboxService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/InboxService.java index e03db6321c..97b6b63c6c 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/InboxService.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/InboxService.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.im.service.inbox; -import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveMessageReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import java.util.List; @@ -14,9 +14,9 @@ public interface InboxService { /** * 保存收件箱和发送消息 * - * @param inboxSaveMessageReqVO 收件箱保存消息 Request VO + * @param imMessageDO 收件箱保存消息 Request VO */ - void saveInboxAndSendMessage(InboxSaveMessageReqVO inboxSaveMessageReqVO); + void saveInboxAndSendMessage(ImMessageDO imMessageDO); /** * 获得大于 sequence 的消息ids diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/InboxServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/InboxServiceImpl.java index d7a43a0cc6..537e427122 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/InboxServiceImpl.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/InboxServiceImpl.java @@ -2,18 +2,19 @@ package cn.iocoder.yudao.module.im.service.inbox; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveMessageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSendMessageReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO; -import cn.iocoder.yudao.module.im.dal.dataobject.inbox.InboxDO; +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageRespVO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; +import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import cn.iocoder.yudao.module.im.dal.mysql.inbox.InboxMapper; import cn.iocoder.yudao.module.im.dal.redis.inbox.InboxLockRedisDAO; -import cn.iocoder.yudao.module.im.dal.redis.inbox.SequenceRedisDao; -import cn.iocoder.yudao.module.im.enums.conversation.ConversationTypeEnum; +import cn.iocoder.yudao.module.im.dal.redis.inbox.SequenceRedisDAO; +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; import cn.iocoder.yudao.module.im.service.groupmember.GroupMemberService; import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; import jakarta.annotation.Resource; import org.dromara.hutool.core.date.DateUnit; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -33,50 +34,60 @@ public class InboxServiceImpl implements InboxService { @Resource private InboxMapper inboxMapper; + @Resource - private SequenceRedisDao sequenceRedisDao; // 序列生成器Redis DAO + private SequenceRedisDAO sequenceRedisDAO; @Resource - private InboxLockRedisDAO inboxLockRedisDAO; // 收件箱的锁 Redis DAO + private InboxLockRedisDAO inboxLockRedisDAO; + @Resource private WebSocketSenderApi webSocketSenderApi; @Resource private GroupMemberService groupMemberService; - // TODO @anhaohao:下面的逻辑,最好是,1. 保存收件箱 + 发送消息给用户; 2. xxx;这样看的人,会更有感觉哈; @Override - public void saveInboxAndSendMessage(InboxSaveMessageReqVO inboxSaveMessage) { - // 保存收件箱 + 发送消息给用户 - saveInboxAndSendMessageForUser(inboxSaveMessage.getFromId(), inboxSaveMessage); - - if (inboxSaveMessage.getConversationType().equals(ConversationTypeEnum.SINGLE.getType())) { - saveInboxAndSendMessageForUser(inboxSaveMessage.getReceiverId(), inboxSaveMessage); - } else if (inboxSaveMessage.getConversationType().equals(ConversationTypeEnum.GROUP.getType())) { - List groupMembers = groupMemberService.selectByGroupId(inboxSaveMessage.getReceiverId()); - groupMembers.forEach(groupMemberDO -> saveInboxAndSendMessageForUser(groupMemberDO.getUserId(), inboxSaveMessage)); + public void saveInboxAndSendMessage(ImMessageDO message) { + // 1. 保存收件箱 + 发送消息给发送人 + saveInboxAndSendMessageForUser(message.getSenderId(), message); + // 2. 保存收件箱 + 发送消息给接收人 + if (message.getConversationType().equals(ImConversationTypeEnum.SINGLE.getType())) { + // 2.1 如果是单聊,直接发送给接收人 + saveInboxAndSendMessageForUser(message.getReceiverId(), message); + } else if (message.getConversationType().equals(ImConversationTypeEnum.GROUP.getType())) { + // 2.2 如果是群聊,发送给群聊的所有人 + List groupMembers = groupMemberService.selectByGroupId(message.getReceiverId()); + groupMembers.forEach(groupMemberDO -> saveInboxAndSendMessageForUser(groupMemberDO.getUserId(), message)); } } @Override public List selectMessageIdsByUserIdAndSequence(Long userId, Long sequence, Integer size) { - return inboxMapper.selectMessageIdsByUserIdAndSequence(userId, sequence, size); + List imInboxDOS = inboxMapper.selectListByUserIdAndSequence(userId, sequence, size); + return imInboxDOS.stream().map(ImInboxDO::getMessageId).toList(); } - private void saveInboxAndSendMessageForUser(Long userId, InboxSaveMessageReqVO inboxSaveMessage) { - inboxLockRedisDAO.lock(userId, INBOX_LOCK_TIMEOUT, () -> { - Long userSequence = sequenceRedisDao.generateSequence(userId); - // TODO @anhaohao:链式调用; - InboxDO inbox = new InboxDO(); - inbox.setUserId(userId); - inbox.setMessageId(inboxSaveMessage.getMessageId()); - inbox.setSequence(userSequence); - inboxMapper.insert(inbox); - // TODO @anhaohao:是不是 send 不用在加锁里面哈?! - // TODO @anhaohao:再进一步,是不是用 spring @async 可以并发推送噢 - InboxSendMessageReqVO message = BeanUtils.toBean(inboxSaveMessage, InboxSendMessageReqVO.class); - message.setSequence(userSequence); - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, IM_MESSAGE_RECEIVE, message); + //TODO 多线程处理 + public void saveInboxAndSendMessageForUser(Long userId, ImMessageDO message) { + inboxLockRedisDAO.lock(userId, INBOX_LOCK_TIMEOUT, () -> { + // 1. 生成序列号 + Long userSequence = sequenceRedisDAO.generateSequence(userId); + // 2. 保存收件箱 + ImInboxDO inbox = new ImInboxDO() + .setUserId(userId) + .setMessageId(message.getId()) + .setSequence(userSequence); + inboxMapper.insert(inbox); + // 3. 发送消息 + sendAsyncMessage(userId, message, userSequence); }); } + @Async + public void sendAsyncMessage(Long userId, ImMessageDO message, Long userSequence) { + ImMessageRespVO messageRespVO = BeanUtils.toBean(message, ImMessageRespVO.class); + messageRespVO.setSequence(userSequence); + webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, IM_MESSAGE_RECEIVE, messageRespVO); + } + } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageService.java index ee58f42cbe..63277da9b6 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageService.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageService.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.im.service.message; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.MessagePageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.SendMessageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.SendMessageRespVO; -import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListReqVO; +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import java.util.List; @@ -17,26 +16,28 @@ public interface MessageService { /** * 获得历史消息 * - * @param pageReqVO 分页查询 + * @param loginUserId 登录用户编号 + * @param listReqVO 分页查询 * @return 消息分页 */ - List getHistoryMessage(MessagePageReqVO pageReqVO); + List getMessageList(Long loginUserId, ImMessageListReqVO listReqVO); /** * 拉取消息-大于 seq 的消息 * - * @param userId 用户id - * @param sequence 序列号 - * @param size 数量 + * @param loginUserId 登录用户编号 + * @param sequence 序列号 + * @param size 数量 * @return 消息列表 */ - List getMessageListBySequence(Long userId, Long sequence, Integer size); + List pullMessageList(Long loginUserId, Long sequence, Integer size); /** * 发送消息 + * * @param loginUserId 登录用户编号 - * @param message 消息 + * @param message 消息 * @return 消息编号 */ - SendMessageRespVO sendMessage(Long loginUserId, SendMessageReqVO message); + ImMessageDO sendMessage(Long loginUserId, ImMessageSendReqVO message); } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageServiceImpl.java index 1203fa0924..364e3942d4 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageServiceImpl.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageServiceImpl.java @@ -1,15 +1,14 @@ package cn.iocoder.yudao.module.im.service.message; -import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveMessageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.MessagePageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.SendMessageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.SendMessageRespVO; -import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO; -import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import cn.hutool.core.bean.BeanUtil; +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListReqVO; +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; import cn.iocoder.yudao.module.im.dal.mysql.message.MessageMapper; -import cn.iocoder.yudao.module.im.enums.conversation.ConversationTypeEnum; -import cn.iocoder.yudao.module.im.enums.message.MessageSourceEnum; -import cn.iocoder.yudao.module.im.enums.message.MessageStatusEnum; +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; +import cn.iocoder.yudao.module.im.enums.message.ImMessageSourceEnum; +import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; import cn.iocoder.yudao.module.im.service.groupmember.GroupMemberService; import cn.iocoder.yudao.module.im.service.inbox.InboxService; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; @@ -38,92 +37,66 @@ public class MessageServiceImpl implements MessageService { @Resource private MessageMapper messageMapper; @Resource - private InboxService inboxService; - @Resource private AdminUserApi adminUserApi; @Resource + private InboxService inboxService; + @Resource private GroupMemberService groupMemberService; @Override - public List getHistoryMessage(MessagePageReqVO pageReqVO) { - return messageMapper.getHistoryMessage(pageReqVO); + public List getMessageList(Long loginUserId, ImMessageListReqVO listReqVO) { + // 1. 获得会话编号 + String no = ImConversationTypeEnum.generateConversationNo(loginUserId, listReqVO.getReceiverId(), listReqVO.getConversationType()); + // 2. 查询历史消息 + ImMessageDO message = new ImMessageDO() + .setSendTime(listReqVO.getSendTime()) + .setConversationNo(no); + return messageMapper.selectMessageList(message); } @Override - public List getMessageListBySequence(Long userId, Long sequence, Integer size) { + public List pullMessageList(Long userId, Long sequence, Integer size) { List messageIds = inboxService.selectMessageIdsByUserIdAndSequence(userId, sequence, size); return messageMapper.selectBatchIds(messageIds); } @Override - public SendMessageRespVO sendMessage(Long fromUserId, SendMessageReqVO message) { - // 保存消息 - // TODO @anhaohao:InboxSaveMessageReqVO 不用 new 出来传递到 saveMessage 方法里; - InboxSaveMessageReqVO inboxSaveMessageReqVO = new InboxSaveMessageReqVO(); - SendMessageRespVO sendMessageRespVO = saveMessage(fromUserId, message, inboxSaveMessageReqVO); - - // 保存收件箱 + 发送消息给用户 - // TODO @anhaohao:考虑到少定义一些 VO,直接传递 MessageDO 就完事了;反正这两者也是强耦合的; - inboxService.saveInboxAndSendMessage(inboxSaveMessageReqVO); - return sendMessageRespVO; + public ImMessageDO sendMessage(Long fromUserId, ImMessageSendReqVO imMessageSendReqVO) { + // 1. 保存消息 + ImMessageDO message = saveMessage(fromUserId, imMessageSendReqVO); + // 2. 保存到收件箱,并发送消息 + inboxService.saveInboxAndSendMessage(message); + return message; } - // TODO @anhaohao:这个方法,是不是定义成 private 哈;然后返回是 MessageDO 对象,设置最上面的 sendMessage 也是这个。最终 controller 转成 SendMessageRespVO - public SendMessageRespVO saveMessage(Long fromUserId, SendMessageReqVO message, InboxSaveMessageReqVO inboxSaveMessageReqVO) { - // 需要校验 receiverId 存在 + private ImMessageDO saveMessage(Long fromUserId, ImMessageSendReqVO message) { + // 1. 校验接收人是否存在 validateReceiverIdExists(message); - // 查询发送人昵称和发送人头像 + // 2. 查询发送人信息 AdminUserRespDTO fromUser = adminUserApi.getUser(fromUserId); - // 使用链式调用创建 MessageDO 对象 - // TODO @anhaohao:一部分字段,可以 beanutils tobean 搞定; - // TODO @anhaohao:链式 set 的时候,要把相同的放在一行;例如说,setSenderNickname、setSenderAvatar;本质上,就是为了“同类”在一行,阅读起来简单; - MessageDO messageDO = new MessageDO() - .setClientMessageId(message.getClientMessageId()) + // 3. 保存消息 + ImMessageDO imMessageDO = BeanUtil.copyProperties(message, ImMessageDO.class) + .setSenderNickname(fromUser.getNickname()).setSenderAvatar(fromUser.getAvatar()) .setSenderId(fromUserId) - .setReceiverId(message.getReceiverId()) - .setSenderNickname(fromUser.getNickname()) - .setSenderAvatar(fromUser.getAvatar()) - .setConversationType(message.getConversationType()) - .setContentType(message.getContentType()) - .setConversationNo(ConversationTypeEnum.generateConversationNo(fromUserId, message.getReceiverId(), message.getConversationType())) - .setContent(message.getContent()) - .setSendFrom(MessageSourceEnum.USER_SEND.getStatus()) - .setSendTime(TimeUtil.now()) - .setMessageStatus(MessageStatusEnum.SENDING.getStatus()); - messageMapper.insert(messageDO); - - // 设置 InboxSaveMessageReqVO 对象 - inboxSaveMessageReqVO.setConversationType(message.getConversationType()) - .setFromId(fromUserId) - .setReceiverId(message.getReceiverId()) - .setMessageId(messageDO.getId()) - .setContentType(message.getContentType()) - .setContent(message.getContent()) - .setSendTime(messageDO.getSendTime()) - .setSenderNickname(fromUser.getNickname()) - .setSenderAvatar(fromUser.getAvatar()); - - // 返回 SendMessageRespVO 对象 - return new SendMessageRespVO(messageDO.getId(), messageDO.getSendTime()); + .setConversationNo(ImConversationTypeEnum.generateConversationNo(fromUserId, message.getReceiverId(), message.getConversationType())) + .setSendFrom(ImMessageSourceEnum.USER_SEND.getSource()) + .setMessageStatus(ImMessageStatusEnum.SENDING.getStatus()) + .setSendTime(TimeUtil.now()); + messageMapper.insert(imMessageDO); + return imMessageDO; } - // TODO @anhaohao:validateReceiver,更简单一点哈;不仅仅校验存在,未来还可以校验,自己是不是有好友关系、群聊是否在群聊里面等等 - private void validateReceiverIdExists(SendMessageReqVO message) { - // TODO @anhaohao:这个不要这里校验,交给 validator 校验掉 - if (message.getReceiverId() == null) { - throw exception(MESSAGE_RECEIVER_NOT_EXISTS); - } - if (message.getConversationType().equals(ConversationTypeEnum.SINGLE.getType())) { - // TODO @anhaohao:// 之后要空一个空格,中英文协作习惯,中文和英文之间,不能连着;最后也不用 ;哈 - //校验用户是否存在; + private void validateReceiverIdExists(ImMessageSendReqVO message) { + if (message.getConversationType().equals(ImConversationTypeEnum.SINGLE.getType())) { + // 校验用户是否存在 AdminUserRespDTO receiverUser = adminUserApi.getUser(message.getReceiverId()); if (receiverUser == null) { throw exception(MESSAGE_RECEIVER_NOT_EXISTS); } - } else if (message.getConversationType().equals(ConversationTypeEnum.GROUP.getType())) { - //校验群聊是否存在; - List groupMemberDOS = groupMemberService.selectByGroupId(message.getReceiverId()); - if (groupMemberDOS.isEmpty()) { + } else if (message.getConversationType().equals(ImConversationTypeEnum.GROUP.getType())) { + // 校验群聊是否存在 + List imGroupMemberDOS = groupMemberService.selectByGroupId(message.getReceiverId()); + if (imGroupMemberDOS.isEmpty()) { throw exception(MESSAGE_RECEIVER_NOT_EXISTS); } } diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/ImWebSocketMessageListener.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/ImWebSocketMessageListener.java deleted file mode 100644 index 21cbdbc27e..0000000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/ImWebSocketMessageListener.java +++ /dev/null @@ -1,49 +0,0 @@ -package cn.iocoder.yudao.module.im.websocket; - -import cn.iocoder.yudao.framework.websocket.core.listener.WebSocketMessageListener; -import cn.iocoder.yudao.framework.websocket.core.util.WebSocketFrameworkUtils; -import cn.iocoder.yudao.module.im.websocket.message.ImSendMessage; -import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import org.springframework.web.socket.WebSocketSession; - -// TODO @hao:消息发送,使用 http 上行。因为在 cloud 框架下,我们比较难去 Listener。因为 im-server 不会自己启动 websocket 路径 - -/** - * WebSocket im - * - * @author 芋道源码 - */ -@Component -@Slf4j -public class ImWebSocketMessageListener implements WebSocketMessageListener { - - public static final String IM_MESSAGE_RECEIVE = "im-message-receive"; - @Resource - private WebSocketSenderApi webSocketSenderApi; // WebSocket消息发送器 - - /** - * 处理WebSocket消息 - * - * @param session WebSocket会话 - * @param message 发送的IM消息 - */ - @Override - public void onMessage(WebSocketSession session, ImSendMessage message) { - Long fromUserId = WebSocketFrameworkUtils.getLoginUserId(session); // 获取登录用户ID - log.info(message.toString()); - } - - /** - * 获取类型 - * - * @return 类型 - */ - @Override - public String getType() { - return "im-message-send"; - } - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImReceiveMessage.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImReceiveMessage.java deleted file mode 100644 index d270102a48..0000000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImReceiveMessage.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.module.im.websocket.message; - -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.im.enums.conversation.ConversationTypeEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 消息发送 receive") -@Data -public class ImReceiveMessage { - - @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @InEnum(ConversationTypeEnum.class) - private Integer conversationType; - - // TODO @anhaohao:我们应该是 senderId;因为它和 receiverId 是相对应的哈。 - @Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long fromId; // 根据 conversationType 区分 - - // TODO @hao:昵称和头像,也直接发给接收人好了; - - @Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454") - private Long messageId; - - @Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer contentType; // 参见 ImMessageTypeEnum 枚举 - - @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED) - private String content; - - @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime sendTime; - - @Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED) - private Long sequence; - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImSendMessage.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImSendMessage.java deleted file mode 100644 index 77e37a3cb5..0000000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImSendMessage.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.im.websocket.message; - -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.im.enums.conversation.ConversationTypeEnum; -import cn.iocoder.yudao.module.im.enums.message.MessageContentTypeEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - IM 消息发送 send") -@Data -public class ImSendMessage { - - @Schema(description = "客户端消息编号 uuid,用于排重", requiredMode = Schema.RequiredMode.REQUIRED, example = "3331") - private String clientMessageId; - - @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @InEnum(ConversationTypeEnum.class) - private Integer conversationType; - - @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long receiverId; // 根据 conversationType 区分 - - @Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @InEnum(MessageContentTypeEnum.class) - private Integer contentType; - - @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED) - private String content; - -} \ No newline at end of file