From 4015b2f213daf1713d711a640dd8a5908ef93ae6 Mon Sep 17 00:00:00 2001 From: 安浩浩 <1036606149@qq.com> Date: Wed, 27 Mar 2024 23:28:00 +0800 Subject: [PATCH] 新增:消息发送和代码优化 --- yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/api/package-info.java | 2 +- yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/ErrorCodeConstants.java | 1 + yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ConversationTypeEnum.java | 46 ++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ImConversationTypeEnum.java | 29 ----------------------------- yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageStatusEnum.java | 31 ------------------------------- yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java | 47 ----------------------------------------------- yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageContentTypeEnum.java | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageSourceEnum.java | 36 ++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageStatusEnum.java | 37 +++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/pom.xml | 30 +++++++++++++++--------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ConversationController.java | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java | 61 ------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationPageReqVO.java | 2 +- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationSaveReqVO.java | 2 +- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java | 8 ++++---- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/groupmember/ImGroupMemberController.java | 2 +- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/ImInboxController.java | 14 +++++++------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/ImInboxSaveReqVO.java | 37 ------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSaveMessageReqVO.java | 42 ++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSaveReqVO.java | 37 +++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSendMessageReqVO.java | 42 ++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImMessageController.java | 68 -------------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/MessageController.java | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessagePageReqVO.java | 62 -------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageReqVO.java | 36 ++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageRespVO.java | 77 ----------------------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/MessagePageReqVO.java | 25 +++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageReqVO.java | 36 ++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageRespVO.java | 26 ++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ConversationDO.java | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationDO.java | 65 ----------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupDO.java | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupMemberDO.java | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupDO.java | 55 ------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/groupmember/GroupMemberDO.java | 58 ---------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/ImInboxDO.java | 45 --------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/InboxDO.java | 45 +++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImMessageDO.java | 89 ----------------------------------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/MessageDO.java | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImAudioMessageBody.java | 31 ------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImFileMessageBody.java | 31 ------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImImageMessageBody.java | 30 ------------------------------ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImLocationMessageBody.java | 32 -------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImMessageBody.java | 12 ------------ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImTextMessageBody.java | 22 ---------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImVideoMessageBody.java | 27 --------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/AudioMessage.java | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/CardMessage.java | 38 ++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/FileMessage.java | 27 +++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/ImageMessage.java | 23 +++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/LocationMessage.java | 33 +++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/TextMessage.java | 23 +++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/VideoMessage.java | 19 +++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/conversation/ConversationMapper.java | 34 ++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/conversation/ImConversationMapper.java | 36 ------------------------------------ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/ImGroupMapper.java | 24 ++++++++++++------------ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/groupmember/ImGroupMemberMapper.java | 2 +- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/inbox/ImInboxMapper.java | 18 +++++++++--------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImMessageMapper.java | 62 -------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/MessageMapper.java | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/RedisKeyConstants.java | 7 +++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/InboxLockRedisDAO.java | 39 +++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceGeneratorRedisDao.java | 29 ----------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceRedisDao.java | 37 +++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/jackson/ImMessageBodyDeserializer.java | 38 -------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationService.java | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationServiceImpl.java | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationService.java | 78 ------------------------------------------------------------------------------ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImpl.java | 115 ------------------------------------------------------------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupService.java | 6 +++--- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java | 10 +++++----- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberService.java | 2 +- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberServiceImpl.java | 2 +- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxService.java | 18 ++++++++++++------ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxServiceImpl.java | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageService.java | 103 ------------------------------------------------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImpl.java | 143 ----------------------------------------------------------------------------------------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageService.java | 43 +++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageServiceImpl.java | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/ImWebSocketMessageListener.java | 184 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImReceiveMessage.java | 39 --------------------------------------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImSendMessage.java | 26 -------------------------- yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/conversation/ConversationMapper.xml | 13 +++++++++++++ yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/conversation/ImConversationMapper.xml | 13 ------------- yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/message/ImMessageMapper.xml | 12 ------------ yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/message/MessageMapper.xml | 12 ++++++++++++ yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImplTest.java | 148 ---------------------------------------------------------------------------------------------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImplTest.java | 147 --------------------------------------------------------------------------------------------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberServiceImplTest.java | 147 --------------------------------------------------------------------------------------------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxServiceImplTest.java | 135 --------------------------------------------------------------------------------------------------------------------------------------- yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImplTest.java | 167 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- 91 files changed, 1767 insertions(+), 2607 deletions(-) create mode 100644 yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ConversationTypeEnum.java delete mode 100644 yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ImConversationTypeEnum.java delete mode 100644 yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageStatusEnum.java delete mode 100644 yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java create mode 100644 yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageContentTypeEnum.java create mode 100644 yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageSourceEnum.java create mode 100644 yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageStatusEnum.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ConversationController.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/ImInboxSaveReqVO.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSaveMessageReqVO.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSaveReqVO.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSendMessageReqVO.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImMessageController.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/MessageController.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessagePageReqVO.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageReqVO.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageRespVO.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/MessagePageReqVO.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageReqVO.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageRespVO.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ConversationDO.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationDO.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupDO.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupMemberDO.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupDO.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/groupmember/GroupMemberDO.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/ImInboxDO.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/InboxDO.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImMessageDO.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/MessageDO.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImAudioMessageBody.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImFileMessageBody.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImImageMessageBody.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImLocationMessageBody.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImMessageBody.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImTextMessageBody.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImVideoMessageBody.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/AudioMessage.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/CardMessage.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/FileMessage.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/ImageMessage.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/LocationMessage.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/TextMessage.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/VideoMessage.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/conversation/ConversationMapper.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/conversation/ImConversationMapper.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImMessageMapper.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/MessageMapper.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/InboxLockRedisDAO.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceGeneratorRedisDao.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceRedisDao.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/jackson/ImMessageBodyDeserializer.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationService.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationServiceImpl.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationService.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImpl.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageService.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImpl.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageService.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageServiceImpl.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/ImWebSocketMessageListener.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImReceiveMessage.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImSendMessage.java create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/conversation/ConversationMapper.xml delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/conversation/ImConversationMapper.xml delete mode 100755 yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/message/ImMessageMapper.xml create mode 100755 yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/message/MessageMapper.xml delete mode 100755 yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImplTest.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImplTest.java delete mode 100644 yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberServiceImplTest.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxServiceImplTest.java delete mode 100755 yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImplTest.java diff --git a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/api/package-info.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/api/package-info.java index cfe63d8..4938097 100644 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/api/package-info.java +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/api/package-info.java @@ -1,5 +1,5 @@ /** * @author anhaohao - * @date 2024/3/9 下午8:59 TODO @hao:没有 @date 这个,应该是 @since 哈 + * @since 2024/3/9 下午8:59 */ package cn.iocoder.yudao.module.im.api; \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/ErrorCodeConstants.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/ErrorCodeConstants.java index c56f5da..3232338 100644 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/ErrorCodeConstants.java +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/ErrorCodeConstants.java @@ -17,6 +17,7 @@ public interface ErrorCodeConstants { // ========== 消息 (1-040-300-000) ========== ErrorCode MESSAGE_NOT_EXISTS = new ErrorCode(1_040_300_000, "消息不存在"); + ErrorCode MESSAGE_RECEIVER_NOT_EXISTS = new ErrorCode(1_040_300_001, "接收人不存在"); // ========== 群 (1-040-400-000) ========== ErrorCode GROUP_NOT_EXISTS = new ErrorCode(1_040_400_000, "群不存在"); 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/ConversationTypeEnum.java new file mode 100644 index 0000000..afd6bfe --- /dev/null +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ConversationTypeEnum.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.im.enums.conversation; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * IM 会话类型枚举 + * 参考 “会话类型” 文档 + * + * @author anhaohao + */ +@Getter +@AllArgsConstructor +public enum ConversationTypeEnum { + + SINGLE(1, "单聊"), + GROUP(3, "群聊"), + NOTIFICATION(4, "通知会话"); + + /** + * 类型 + */ + private final Integer type; + + /** + * 名字 + */ + private final String name; + + /** + * 生成会话编号 + * @param fromUserId 发送者编号 + * @param receiverId 接收者编号 + * @param conversationType 会话类型 + * @return 会话编号 + */ + public static String generateConversationNo(Long fromUserId, Long receiverId, Integer conversationType) { + if (conversationType.equals(ConversationTypeEnum.SINGLE.getType())) { + return "s_" + fromUserId + "_" + receiverId; + } else if (conversationType.equals(ConversationTypeEnum.GROUP.getType())) { + return "g_" + receiverId; + } + return null; + } + +} \ 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/conversation/ImConversationTypeEnum.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ImConversationTypeEnum.java deleted file mode 100644 index bef578a..0000000 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ImConversationTypeEnum.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.module.im.enums.conversation; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * IM 会话的类型枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum ImConversationTypeEnum { - - // TODO @hao:单聊,我们使用 SINGLE,主要 private 这个单词在 java 里太特殊了; - PRIVATE(1, "单聊"), - GROUP(2, "群聊"), - NOTICE(4, "通知会话"); - - /** - * 类型 - */ - private final Integer type; - /** - * 名字 - */ - private final String name; - -} \ 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/ImMessageStatusEnum.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageStatusEnum.java deleted file mode 100644 index d2ce4e4..0000000 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageStatusEnum.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.module.im.enums.message; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -import java.util.Arrays; - -// TODO @hao:注释哈; -@RequiredArgsConstructor -@Getter -public enum ImMessageStatusEnum implements IntArrayValuable { - - SENDING(1, "发送中"), - SUCCESS(2, "发送成功"), - FAILURE(3, "发送失败"), - DELETED(4, "已删除"), - RECALL(5, "已撤回"); - - // TODO @hao:静态变量,和普通变量,最好空一行; - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ImMessageStatusEnum::getStatus).toArray(); - // TODO @hao:注释哈; - private final Integer status; - private final String name; - - @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/ImMessageTypeEnum.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java deleted file mode 100644 index 984f62b..0000000 --- a/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java +++ /dev/null @@ -1,47 +0,0 @@ -package cn.iocoder.yudao.module.im.enums.message; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -// TODO @hao:类型保持和 openim 一致 -/** - * IM 消息的类型枚举 - *

- * 参考 “消息类型” 文档 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum ImMessageTypeEnum implements IntArrayValuable { - - TEXT(1, "文本"), // 消息内容为普通文本 - IMAGE(2, "图片"), // 消息内容为图片 URL 地址、尺寸、图片大小等信息 - AUDIO(3, "语音"), // 消息内容为语音文件的 URL 地址、时长、大小、格式等信息 - VIDEO(4, "视频"), // 消息内容为视频文件的 URL 地址、时长、大小、格式等信息 - FILE(5, "文件"), // 消息内容为文件的 URL 地址、大小、格式等信息 - LOCATION(6, "地理位置"), // 消息内容为地理位置标题、经度、纬度信息 - // TODO @芋艿:下面两种,貌似企业微信设计的更好:https://developer.work.weixin.qq.com/document/path/90240 - TIP(7, "提示"), // 又叫做 Tip 消息,没有推送和通知栏提醒,主要用于会话内的通知提醒,例如进入会话时出现的欢迎消息,或是会话过程中命中敏感词后的提示消息等场景 - NOTIFICATION(8, "通知"), // 主要用于群组、聊天室和超大群的事件通知,由服务端下发,客户端无法发送事件通知消息。通知类消息有在线、离线、漫游机制;没有通知栏提醒 - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ImMessageTypeEnum::getType).toArray(); - /** - * 类型 - */ - private final Integer type; - /** - * 名字 - */ - private final String name; - - @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/MessageContentTypeEnum.java new file mode 100644 index 0000000..580ed21 --- /dev/null +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageContentTypeEnum.java @@ -0,0 +1,77 @@ +package cn.iocoder.yudao.module.im.enums.message; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + + +/** + * IM 消息的类型枚举 + *

+ * 参考 “消息类型” 文档 + * + * @author anhaohao + */ +@Getter +@AllArgsConstructor +public enum MessageContentTypeEnum implements IntArrayValuable { + + TEXT(101, "文本消息"), + PICTURE(102, "图片消息"), + VOICE(103, "语音消息"), + VIDEO(104, "视频消息"), + FILE(105, "文件消息"), + AT_TEXT(106, "@消息"), + MERGE(107, "合并消息"), + CARD(108, "名片消息"), + LOCATION(109, "位置消息"), + CUSTOM(110, "自定义消息"), + REVOKE_RECEIPT(111, "撤回消息回执"), + C2C_RECEIPT(112, "单聊消息回执"), + TYPING(113, "输入状态"), + QUOTE(114, "引用消息"), + FACE(115, "表情消息"), + ADVANCED_REVOKE(118, "高级撤回消息"), + //好友通知 1200-1299 + FRIEND_ADDED(1201, "双方成为好友通知"), + //系统通知 1400 + OA_NOTIFICATION(1400, "系统通知"), + //群相关 1500-1599 + GROUP_CREATED(1501, "群创建通知"), + GROUP_INFO_CHANGED(1502, "群信息改变通知"), + MEMBER_QUIT(1504, "群成员退出通知"), + GROUP_OWNER_CHANGED(1507, "群主更换通知"), + MEMBER_KICKED(1508, "群成员被踢通知"), + MEMBER_INVITED(1509, "邀请群成员通知"), + MEMBER_ENTER(1510, "群成员进群通知"), + GROUP_DISMISSED(1511, "解散群通知"), + GROUP_MEMBER_MUTED(1512, "群成员禁言通知"), + GROUP_MEMBER_CANCEL_MUTED(1513, "取消群成员禁言通知"), + GROUP_MUTED(1514, "群禁言通知"), + GROUP_CANCEL_MUTED(1515, "取消群禁言通知"), + GROUP_ANNOUNCEMENT_UPDATED(1519, "群公告改变通知"), + GROUP_NAME_UPDATED(1520, "群名称改变通知"), + + BURN_CHANGE(1701, "阅后即焚开启或关闭通知"), + REVOKE(2101, "撤回消息通知");; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MessageContentTypeEnum::getType).toArray(); + + /** + * 类型 + */ + private final Integer type; + + /** + * 名字 + */ + private final String name; + + @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/MessageSourceEnum.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageSourceEnum.java new file mode 100644 index 0000000..3b04c97 --- /dev/null +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageSourceEnum.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.im.enums.message; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +/** + * IM 消息的消息来源 100-用户发送;200-系统发送(一般是通知);不能为空 + */ +@RequiredArgsConstructor +@Getter +public enum MessageSourceEnum implements IntArrayValuable { + + USER_SEND(100, "用户发送"), + SYSTEM_SEND(200, "系统发送"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MessageSourceEnum::getStatus).toArray(); + + /** + * 状态 + */ + private final Integer status; + + /** + * 名字 + */ + private final String name; + + @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/MessageStatusEnum.java b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageStatusEnum.java new file mode 100644 index 0000000..389d9fd --- /dev/null +++ b/yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/message/MessageStatusEnum.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.im.enums.message; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +/** + * IM 消息的状态枚举 + */ +@RequiredArgsConstructor +@Getter +public enum MessageStatusEnum implements IntArrayValuable { + + SENDING(1, "发送中"), + SUCCEED(2, "发送成功"), + FAILED(3, "发送失败"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MessageStatusEnum::getStatus).toArray(); + + /** + * 状态 + */ + private final Integer status; + + /** + * 名字 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/pom.xml b/yudao-module-im/yudao-module-im-biz/pom.xml index a6d1bff..058c10a 100644 --- a/yudao-module-im/yudao-module-im-biz/pom.xml +++ b/yudao-module-im/yudao-module-im-biz/pom.xml @@ -5,19 +5,19 @@ yudao-module-im cn.iocoder.boot - ${revision} + ${revision} 4.0.0 - jar + jar yudao-module-im-biz - ${project.artifactId} - + ${project.artifactId} + im 模块,主要实现 im 模块的业务逻辑。 - + cn.iocoder.boot yudao-module-im-api @@ -41,34 +41,34 @@ yudao-spring-boot-starter-security + + cn.iocoder.boot + yudao-spring-boot-starter-websocket + + cn.iocoder.boot yudao-spring-boot-starter-mybatis - cn.iocoder.boot - yudao-spring-boot-starter-test + yudao-spring-boot-starter-redis - - + cn.iocoder.boot yudao-spring-boot-starter-excel + + cn.iocoder.boot - yudao-spring-boot-starter-websocket + yudao-spring-boot-starter-test - - - org.redisson - redisson-spring-boot-starter - \ 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/ConversationController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ConversationController.java new file mode 100755 index 0000000..6276c15 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ConversationController.java @@ -0,0 +1,61 @@ +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.ImConversationRespVO; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationSaveReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ConversationDO; +import cn.iocoder.yudao.module.im.service.conversation.ConversationService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +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; + +// TODO @hao: 管理后台 - IM 会话 +@Tag(name = "管理后台 - IM 会话") +@RestController +@RequestMapping("/im/conversation") +@Validated +public class ConversationController { + + // TODO @hao: conversationService 即可 + @Resource + private ConversationService conversationService; + + // TODO @hao:/list 会话列表;一般 get 是给单个对象,或者 get-count 这种;然后 conversation 已经是模块名了,所以可以简化 + @GetMapping("/get-conversation") + @Operation(summary = "获得用户的会话列表") + @PreAuthorize("hasAuthority('im:conversation:query')") // TODO @hao:不用权限哈 + public CommonResult> getConversationList() { + List conversationList = conversationService.getConversationList(); + return success(BeanUtils.toBean(conversationList, ImConversationRespVO.class)); + } + + // TODO @hao:/update-pinned 保持和 db 字段一致哈; + // TODO @hao:这个接口,需要单独的 VO 哈; + @PostMapping("/update-top") + @Operation(summary = "置顶会话") + @PreAuthorize("hasAuthority('im:conversation:update')") // TODO @hao:不用权限哈;因为肯定会判断是不是自己的 + public CommonResult updateTop(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) { + conversationService.updateTop(updateReqVO); + return success(true); + } + + + // TODO @hao:这个接口,需要单独的 VO 哈; + @PostMapping("/update-last-read-time") + @Operation(summary = "更新最后已读时间") + @PreAuthorize("hasAuthority('im:conversation:update')") // TODO @hao:不用权限哈;因为肯定会判断是不是自己的 + public CommonResult updateLastReadTime(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) { + conversationService.updateLastReadTime(updateReqVO); + return success(true); + } + +} \ 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/ImConversationController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java deleted file mode 100755 index c94140b..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java +++ /dev/null @@ -1,61 +0,0 @@ -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.ImConversationRespVO; -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationSaveReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; -import cn.iocoder.yudao.module.im.service.conversation.ImConversationService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.annotation.Resource; -import jakarta.validation.Valid; -import org.springframework.security.access.prepost.PreAuthorize; -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; - -// TODO @hao: 管理后台 - IM 会话 -@Tag(name = "管理后台 - 会话") -@RestController -@RequestMapping("/im/conversation") -@Validated -public class ImConversationController { - - // TODO @hao: conversationService 即可 - @Resource - private ImConversationService imConversationService; - - // TODO @hao:/list 会话列表;一般 get 是给单个对象,或者 get-count 这种;然后 conversation 已经是模块名了,所以可以简化 - @GetMapping("/get-conversation") - @Operation(summary = "获得用户的会话列表") - @PreAuthorize("hasAuthority('im:conversation:query')") // TODO @hao:不用权限哈 - public CommonResult> getConversationList() { - List conversationList = imConversationService.getConversationList(); - return success(BeanUtils.toBean(conversationList, ImConversationRespVO.class)); - } - - // TODO @hao:/update-pinned 保持和 db 字段一致哈; - // TODO @hao:这个接口,需要单独的 VO 哈; - @PostMapping("/update-top") - @Operation(summary = "置顶会话") - @PreAuthorize("hasAuthority('im:conversation:update')") // TODO @hao:不用权限哈;因为肯定会判断是不是自己的 - public CommonResult updateTop(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) { - imConversationService.updateTop(updateReqVO); - return success(true); - } - - - // TODO @hao:这个接口,需要单独的 VO 哈; - @PostMapping("/update-last-read-time") - @Operation(summary = "更新最后已读时间") - @PreAuthorize("hasAuthority('im:conversation:update')") // TODO @hao:不用权限哈;因为肯定会判断是不是自己的 - public CommonResult updateLastReadTime(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) { - imConversationService.updateLastReadTime(updateReqVO); - return success(true); - } - -} \ 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/ImConversationPageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationPageReqVO.java index c3a24b3..e1308d8 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationPageReqVO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationPageReqVO.java @@ -22,7 +22,7 @@ public class ImConversationPageReqVO extends PageParam { private Long userId; @Schema(description = "类型:1 单聊;2 群聊;4 通知会话(预留)", example = "1") - private Integer conversationType; + private Integer type; @Schema(description = "单聊时,用户编号;群聊时,群编号", example = "21454") private Long targetId; diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationSaveReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationSaveReqVO.java index 58d7123..b226f16 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationSaveReqVO.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationSaveReqVO.java @@ -21,7 +21,7 @@ public class ImConversationSaveReqVO { @Schema(description = "类型:1 单聊;2 群聊;4 通知会话(预留)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotNull(message = "类型:1 单聊;2 群聊;4 通知会话(预留)不能为空") - private Integer conversationType; + private Integer type; @Schema(description = "单聊时,用户编号;群聊时,群编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21454") @NotEmpty(message = "单聊时,用户编号;群聊时,群编号不能为空") 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 a1afcc9..abd97bf 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,7 +25,7 @@ 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.ImGroupDO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO; import cn.iocoder.yudao.module.im.service.group.ImGroupService; @Tag(name = "管理后台 - 群") @@ -66,7 +66,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) { - ImGroupDO group = imGroupService.getGroup(id); + GroupDO group = imGroupService.getGroup(id); return success(BeanUtils.toBean(group, ImGroupRespVO.class)); } @@ -74,7 +74,7 @@ public class ImGroupController { @Operation(summary = "获得群分页") @PreAuthorize("@ss.hasPermission('im:group:query')") public CommonResult> getGroupPage(@Valid ImGroupPageReqVO pageReqVO) { - PageResult pageResult = imGroupService.getGroupPage(pageReqVO); + PageResult pageResult = imGroupService.getGroupPage(pageReqVO); return success(BeanUtils.toBean(pageResult, ImGroupRespVO.class)); } @@ -85,7 +85,7 @@ public class ImGroupController { public void exportGroupExcel(@Valid ImGroupPageReqVO pageReqVO, HttpServletResponse response) throws IOException { pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = imGroupService.getGroupPage(pageReqVO).getList(); + List list = imGroupService.getGroupPage(pageReqVO).getList(); // 导出 Excel ExcelUtils.write(response, "群.xls", "数据", ImGroupRespVO.class, BeanUtils.toBean(list, ImGroupRespVO.class)); 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 c715b63..1a70ebb 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.groupmember.GroupMemberDO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO; import cn.iocoder.yudao.module.im.service.groupmember.ImGroupMemberService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/ImInboxController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/ImInboxController.java index 4912f72..4459d49 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/ImInboxController.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/ImInboxController.java @@ -8,8 +8,8 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.ImInboxPageReqVO; import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.ImInboxRespVO; -import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.ImInboxSaveReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO; +import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.inbox.InboxDO; import cn.iocoder.yudao.module.im.service.inbox.ImInboxService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -39,14 +39,14 @@ public class ImInboxController { @PostMapping("/create") @Operation(summary = "创建收件箱") @PreAuthorize("@ss.hasPermission('im:inbox:create')") - public CommonResult createInbox(@Valid @RequestBody ImInboxSaveReqVO createReqVO) { + public CommonResult createInbox(@Valid @RequestBody InboxSaveReqVO createReqVO) { return success(imInboxService.createInbox(createReqVO)); } @PutMapping("/update") @Operation(summary = "更新收件箱") @PreAuthorize("@ss.hasPermission('im:inbox:update')") - public CommonResult updateInbox(@Valid @RequestBody ImInboxSaveReqVO updateReqVO) { + public CommonResult updateInbox(@Valid @RequestBody InboxSaveReqVO updateReqVO) { imInboxService.updateInbox(updateReqVO); return success(true); } @@ -65,7 +65,7 @@ public class ImInboxController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('im:inbox:query')") public CommonResult getInbox(@RequestParam("id") Long id) { - ImInboxDO inbox = imInboxService.getInbox(id); + InboxDO inbox = imInboxService.getInbox(id); return success(BeanUtils.toBean(inbox, ImInboxRespVO.class)); } @@ -73,7 +73,7 @@ public class ImInboxController { @Operation(summary = "获得收件箱分页") @PreAuthorize("@ss.hasPermission('im:inbox:query')") public CommonResult> getInboxPage(@Valid ImInboxPageReqVO pageReqVO) { - PageResult pageResult = imInboxService.getInboxPage(pageReqVO); + PageResult pageResult = imInboxService.getInboxPage(pageReqVO); return success(BeanUtils.toBean(pageResult, ImInboxRespVO.class)); } @@ -84,7 +84,7 @@ public class ImInboxController { public void exportInboxExcel(@Valid ImInboxPageReqVO pageReqVO, HttpServletResponse response) throws IOException { pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = imInboxService.getInboxPage(pageReqVO).getList(); + List list = imInboxService.getInboxPage(pageReqVO).getList(); // 导出 Excel ExcelUtils.write(response, "收件箱.xls", "数据", ImInboxRespVO.class, BeanUtils.toBean(list, ImInboxRespVO.class)); diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/ImInboxSaveReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/ImInboxSaveReqVO.java deleted file mode 100755 index 678be51..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/ImInboxSaveReqVO.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.im.controller.admin.inbox.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -// TODO @hao:这个是不是删除掉,应该不会有这个 VO 哈 -@Schema(description = "管理后台 - 收件箱新增/修改 Request VO") -@Data -@AllArgsConstructor -@NoArgsConstructor -public class ImInboxSaveReqVO { - - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18389") - private Long id; - - @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3979") - @NotNull(message = "用户编号不能为空") - private Long userId; - - @Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454") - @NotNull(message = "消息编号不能为空") - private Long messageId; - - @Schema(description = "序号,按照 user 递增", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "序号,按照 user 递增不能为空") - private Long sequence; - - public ImInboxSaveReqVO(Long userId, Long messageId, Long sequence) { - this.userId = userId; - this.messageId = messageId; - this.sequence = 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/InboxSaveMessageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSaveMessageReqVO.java new file mode 100644 index 0000000..f48a002 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSaveMessageReqVO.java @@ -0,0 +1,42 @@ +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; + +@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/InboxSaveReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSaveReqVO.java new file mode 100755 index 0000000..b44a2b7 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSaveReqVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.im.controller.admin.inbox.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +// TODO @hao:这个是不是删除掉,应该不会有这个 VO 哈 +@Schema(description = "管理后台 - 收件箱新增/修改 Request VO") +@Data +@AllArgsConstructor +@NoArgsConstructor +public class InboxSaveReqVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18389") + private Long id; + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3979") + @NotNull(message = "用户编号不能为空") + private Long userId; + + @Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454") + @NotNull(message = "消息编号不能为空") + private Long messageId; + + @Schema(description = "序号,按照 user 递增", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "序号,按照 user 递增不能为空") + private Long sequence; + + public InboxSaveReqVO(Long userId, Long messageId, Long sequence) { + this.userId = userId; + this.messageId = messageId; + this.sequence = 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/InboxSendMessageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSendMessageReqVO.java new file mode 100644 index 0000000..ae58c5e --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/inbox/vo/InboxSendMessageReqVO.java @@ -0,0 +1,42 @@ +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; + +@Schema(description = "管理后台 - 收件箱保存消息 Request VO") +@Data +public class InboxSendMessageReqVO { + + @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/message/ImMessageController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImMessageController.java deleted file mode 100755 index 91026f8..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImMessageController.java +++ /dev/null @@ -1,68 +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.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessagePageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageRespVO; -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; -import cn.iocoder.yudao.module.im.service.message.ImMessageService; -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.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -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 ImMessageService imMessageService; - - @GetMapping("/get-message-by-sequence") // TODO @hao:list-by-sequence - @Operation(summary = "拉取消息-增量拉取大于 seq 的消息") // TODO @hao:可以改成 拉取大于 sequence 的消息列表 - @Parameter(name = "sequence", description = "序号", required = true, example = "1") - @Parameter(name = "size", description = "条数", required = true, example = "10") - @PreAuthorize("@ss.hasPermission('im:message:query')") // TODO @hao:权限可以删除哈; - public CommonResult> loadMessage(@RequestParam("sequence") Long sequence, - @RequestParam("size") Integer size) { - // TODO @hao:方法名,可以改成 getMessageListBySequence - // TODO @hao:如果是返回列表,变量要用 messages, 或者 messageList,体现出是复数 - List message = imMessageService.loadMessage(getLoginUserId(), sequence, size); - return success(BeanUtils.toBean(message, ImMessageRespVO.class)); - } - - // TODO @hao:这个接口的使用场景是哪个哈? - @GetMapping("/get-all-message") - @Operation(summary = "拉取全部消息") - @Parameter(name = "size", description = "条数", required = true, example = "10") - @PreAuthorize("@ss.hasPermission('im:message:query')") - public CommonResult> loadAllMessage(@RequestParam("size") Integer size) { - List message = imMessageService.loadAllMessage(getLoginUserId(), size); - return success(BeanUtils.toBean(message, ImMessageRespVO.class)); - } - - // TODO @hao:是不是分页参数不太对哈?应该只有 conversationNo,sendTime 字段;然后,做链式分页的查询,不太适合传统的 pageSize + number 查询; - @GetMapping("/page") - @Operation(summary = "查询聊天记录-分页") - @PreAuthorize("@ss.hasPermission('im:message:query')") // TODO @hao:权限可以删除哈; - public CommonResult> getMessagePage(@Valid ImMessagePageReqVO pageReqVO) { - PageResult messagePage = imMessageService.getMessagePage(pageReqVO); - 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 new file mode 100755 index 0000000..fc5d33a --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/MessageController.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.MessagePageReqVO; +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageReqVO; +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)); + } + + @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> loadMessage(@RequestParam("sequence") Long sequence, + @RequestParam("size") Integer size) { + List messages = messageService.getMessageListBySequence(getLoginUserId(), sequence, size); + return success(BeanUtils.toBean(messages, ImMessageReqVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "查询聊天记录-分页") + public CommonResult> getMessagePage(@Valid MessagePageReqVO pageReqVO) { + //根据会话标志和发送时间进行分页查询 + List messagePage = messageService.getMessagePage(pageReqVO); + return success(BeanUtils.toBean(messagePage, ImMessageReqVO.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/ImMessagePageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessagePageReqVO.java deleted file mode 100755 index ed8c2db..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessagePageReqVO.java +++ /dev/null @@ -1,62 +0,0 @@ -package cn.iocoder.yudao.module.im.controller.admin.message.vo; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import com.alibaba.excel.annotation.ExcelProperty; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -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_HOUR_MINUTE_SECOND; - -@Schema(description = "管理后台 - 消息分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ImMessagePageReqVO extends PageParam { - - @Schema(description = "客户端消息编号 uuid,用于排重", example = "3331") - private String clientMessageId; - - @Schema(description = "发送人编号", example = "23239") - private Long senderId; - - @Schema(description = "接收人编号", example = "32494") - private Long receiverId; - - @Schema(description = "发送人昵称", example = "李四") - private String senderNickname; - - @Schema(description = "发送人头像") - private String senderAvatar; - - @Schema(description = "会话类型", example = "2") - private Integer conversationType; - - @Schema(description = "会话标志") - private String conversationNo; - - @Schema(description = "消息类型", example = "1") - private Integer contentType; - - @Schema(description = "消息内容") - private String content; - - @Schema(description = "发送时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] sendTime; - - @Schema(description = "消息来源 100-用户发送;200-系统发送(一般是通知);") - private Integer sendFrom; - - @Schema(description = "创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] createTime; - - @Schema(description = "消息状态 1 发送中、2 发送成功、3 发送失败、4 已删除、5 已撤回", requiredMode = Schema.RequiredMode.REQUIRED) - private Integer messageStatus; - -} \ 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/ImMessageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageReqVO.java new file mode 100755 index 0000000..0f0d4f2 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageReqVO.java @@ -0,0 +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 io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 消息 Request VO") +@Data +@ExcelIgnoreUnannotated +public class ImMessageReqVO { + + @Schema(description = "客户端消息编号 uuid,用于排重", requiredMode = Schema.RequiredMode.REQUIRED, example = "3331") + @ExcelProperty("客户端消息编号 uuid,用于排重") + private String clientMessageId; + + @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") + @ExcelProperty("接收人编号") + private Long receiverId; + + @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + @ExcelProperty("会话类型") + private Integer conversationType; + + @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty("消息类型") + @InEnum(MessageContentTypeEnum.class) + private Integer contentType; + + @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("消息内容") + 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/ImMessageRespVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageRespVO.java deleted file mode 100755 index 19e3886..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageRespVO.java +++ /dev/null @@ -1,77 +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.ImMessageStatusEnum; -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; -import lombok.Data; - -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 消息 Response VO") -@Data -@ExcelIgnoreUnannotated -public class ImMessageRespVO { - - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30713") - @ExcelProperty("编号") - private Long id; - - @Schema(description = "客户端消息编号 uuid,用于排重", requiredMode = Schema.RequiredMode.REQUIRED, example = "3331") - @ExcelProperty("客户端消息编号 uuid,用于排重") - private String clientMessageId; - - @Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23239") - @ExcelProperty("发送人编号") - private Long senderId; - - @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") - @ExcelProperty("接收人编号") - private Long receiverId; - - @Schema(description = "发送人昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") - @ExcelProperty("发送人昵称") - private String senderNickname; - - @Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("发送人头像") - private String senderAvatar; - - @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - @ExcelProperty("会话类型") - private Integer conversationType; - - @Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("会话标志") - private String conversationNo; - - @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @ExcelProperty("消息类型") - @InEnum(ImMessageTypeEnum.class) - private Integer contentType; - - @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("消息内容") - private String content; - - @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("发送时间") - private LocalDateTime sendTime; - - @Schema(description = "消息来源 100-用户发送;200-系统发送(一般是通知);", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("消息来源 100-用户发送;200-系统发送(一般是通知);") - private Integer sendFrom; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("创建时间") - private LocalDateTime createTime; - - @Schema(description = "消息状态 1 发送中、2 发送成功、3 发送失败、4 已删除、5 已撤回", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("消息状态") - @InEnum(ImMessageStatusEnum.class) - private Integer messageStatus; - -} \ 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/MessagePageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/MessagePageReqVO.java new file mode 100755 index 0000000..01e7b70 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/MessagePageReqVO.java @@ -0,0 +1,25 @@ +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; + +@Schema(description = "管理后台 - 消息分页 Request VO") +@Data +@ToString(callSuper = true) +public class MessagePageReqVO { + + @Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "g_1000") + private String conversationNo; + + @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/SendMessageReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageReqVO.java new file mode 100755 index 0000000..dd97a9c --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageReqVO.java @@ -0,0 +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 io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 发送消息 Request VO") +@Data +@ExcelIgnoreUnannotated +public class SendMessageReqVO { + + @Schema(description = "客户端消息编号 uuid,用于排重", requiredMode = Schema.RequiredMode.REQUIRED, example = "3331") + @ExcelProperty("客户端消息编号 uuid,用于排重") + private String clientMessageId; + + @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") + @ExcelProperty("接收人编号") + private Long receiverId; + + @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + @ExcelProperty("会话类型") + private Integer conversationType; + + @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty("消息类型") + @InEnum(MessageContentTypeEnum.class) + private Integer contentType; + + @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("消息内容") + 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/SendMessageRespVO.java new file mode 100755 index 0000000..79ac757 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/SendMessageRespVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.im.controller.admin.message.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +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; + +@Schema(description = "管理后台 - 发送消息 Response VO") +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SendMessageRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12") + private Long id; + + @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27 12:00:00") + @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/dal/dataobject/conversation/ConversationDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ConversationDO.java new file mode 100755 index 0000000..0f8f22e --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ConversationDO.java @@ -0,0 +1,63 @@ +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 com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.time.LocalDateTime; + +/** + * IM 会话 DO + * + * @author 芋道源码 + */ +@TableName("im_conversation") +@KeySequence("im_conversation_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ConversationDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + + /** + * 所属用户 + */ + private Long userId; + + /** + * 会话类型 + *

+ * 枚举 {@link ConversationTypeEnum} + */ + private Integer type; + /** + * 聊天对象编号 + *

+ * 1. 单聊时,用户编号;群聊时,群编号 + */ + private Long targetId; + /** + * 会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId + */ + private String no; + /** + * 是否置顶 0否 1是 + */ + private Boolean pinned; + /** + * 最后已读时间 + */ + private LocalDateTime lastReadTime; + +} \ 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/ImConversationDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationDO.java deleted file mode 100755 index 5a6fabd..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationDO.java +++ /dev/null @@ -1,65 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.dataobject.conversation; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -import java.time.LocalDateTime; - -/** - * IM 会话 DO - * - * @author 芋道源码 - */ -@TableName("im_conversation") -@KeySequence("im_conversation_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ImConversationDO extends BaseDO { - - /** - * 编号 - */ - @TableId - private Long id; - /** - * 所属用户 - */ - private Long userId; - // TODO @hao:注释可以改成,如下 - /** - * 会话类型 - * - * 枚举 {@link cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum} - */ - /** - * 类型:1 单聊;2 群聊;4 通知会话(预留) - */ - // TODO @hao:conversationType 改成 type - private Integer conversationType; - /** - * 聊天对象编号 - * - * 1. 单聊时,用户编号;群聊时,群编号 - */ - private Long targetId; - /** - * 会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId - */ - private String no; - /** - * 是否置顶 0否 1是 - */ - private Boolean pinned; - /** - * 最后已读时间 - */ - private LocalDateTime lastReadTime; - -} \ 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/group/GroupDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupDO.java new file mode 100644 index 0000000..ce6b1a6 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupDO.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.module.im.dal.dataobject.group; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * IM 群信息 DO + * + * @author 芋道源码 + */ +@TableName("im_group") +@KeySequence("im_group_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class GroupDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + // TODO @hao:name,如果这个表已经是 group 了,不用在带额外的 + /** + * 群名字 + */ + private String groupName; + // TODO @hao:关联字段; + /** + * 群主编号 + */ + private Long ownerId; + // TODO @hao:头像使用 avatar 好了,整个项目统一;然后 Thumb 是不是不用存,这个更多是文件服务做裁剪 + /** + * 群头像 + */ + private String headImage; + /** + * 群头像缩略图 + */ + private String headImageThumb; + /** + * 群公告 + */ + private String notice; + /** + * 群备注 + */ + private String remark; + +} \ 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/group/GroupMemberDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupMemberDO.java new file mode 100644 index 0000000..0ccffee --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/GroupMemberDO.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.module.im.dal.dataobject.group; + +import lombok.*; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * IM 群成员 DO + * + * @author 芋道源码 + */ +@TableName("im_group_member") +@KeySequence("im_group_member_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class GroupMemberDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + // TODO @hao:groupId 和 userId 都写下关联字段哈 + /** + * 群编号 + */ + private Long groupId; + /** + * 用户编号 + */ + private Long userId; + // TODO @hao:nickname 和 avatar 是不是不用存储哈; + /** + * 昵称 + */ + private String nickname; + /** + * 头像 + */ + private String avatar; + /** + * 组内显示名称 + */ + private String aliasName; + /** + * 备注 + */ + private String remark; + +} \ 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/group/ImGroupDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupDO.java deleted file mode 100644 index edd2b33..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupDO.java +++ /dev/null @@ -1,55 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.dataobject.group; - -import lombok.*; -import com.baomidou.mybatisplus.annotation.*; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; - -/** - * IM 群信息 DO - * - * @author 芋道源码 - */ -@TableName("im_group") -@KeySequence("im_group_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ImGroupDO extends BaseDO { - - /** - * 编号 - */ - @TableId - private Long id; - // TODO @hao:name,如果这个表已经是 group 了,不用在带额外的 - /** - * 群名字 - */ - private String groupName; - // TODO @hao:关联字段; - /** - * 群主编号 - */ - private Long ownerId; - // TODO @hao:头像使用 avatar 好了,整个项目统一;然后 Thumb 是不是不用存,这个更多是文件服务做裁剪 - /** - * 群头像 - */ - private String headImage; - /** - * 群头像缩略图 - */ - private String headImageThumb; - /** - * 群公告 - */ - private String notice; - /** - * 群备注 - */ - private String remark; - -} \ 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/groupmember/GroupMemberDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/groupmember/GroupMemberDO.java deleted file mode 100644 index dc97b94..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/groupmember/GroupMemberDO.java +++ /dev/null @@ -1,58 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.dataobject.groupmember; - -import lombok.*; -import java.util.*; -import java.time.LocalDateTime; -import java.time.LocalDateTime; -import com.baomidou.mybatisplus.annotation.*; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; - -// TODO @hao:这个挪到 group 包下; -/** - * IM 群成员 DO - * - * @author 芋道源码 - */ -@TableName("im_group_member") -@KeySequence("im_group_member_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class GroupMemberDO extends BaseDO { - - /** - * 编号 - */ - @TableId - private Long id; - // TODO @hao:groupId 和 userId 都写下关联字段哈 - /** - * 群编号 - */ - private Long groupId; - /** - * 用户编号 - */ - private Long userId; - // TODO @hao:nickname 和 avatar 是不是不用存储哈; - /** - * 昵称 - */ - private String nickname; - /** - * 头像 - */ - private String avatar; - /** - * 组内显示名称 - */ - private String aliasName; - /** - * 备注 - */ - private String remark; - -} \ 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/inbox/ImInboxDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/ImInboxDO.java deleted file mode 100755 index 6f92474..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/ImInboxDO.java +++ /dev/null @@ -1,45 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.dataobject.inbox; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -// TODO 我们要不要改成 ImMessageQueue 队列?从理解上,概念上,可能都更清晰一点哈。每个用户一个消息队列; -/** - * IM 收件箱 DO - * - * @author 芋道源码 - */ -@TableName("im_inbox") -@KeySequence("im_inbox_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ImInboxDO extends BaseDO { - - /** - * 编号 - */ - @TableId - private Long id; - /** - * 用户编号 - * - * TODO @hao:写下 userId 和 messageId 的关联字段 - */ - private Long userId; - /** - * 消息编号 - */ - private Long messageId; - /** - * 序号,按照 user 递增 - */ - 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/inbox/InboxDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/InboxDO.java new file mode 100755 index 0000000..62accc3 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/InboxDO.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.im.dal.dataobject.inbox; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +// TODO 我们要不要改成 ImMessageQueue 队列?从理解上,概念上,可能都更清晰一点哈。每个用户一个消息队列; +/** + * IM 收件箱 DO + * + * @author 芋道源码 + */ +@TableName("im_inbox") +@KeySequence("im_inbox_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class InboxDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 用户编号 + * + * TODO @hao:写下 userId 和 messageId 的关联字段 + */ + private Long userId; + /** + * 消息编号 + */ + private Long messageId; + /** + * 序号,按照 user 递增 + */ + 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/message/ImMessageDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImMessageDO.java deleted file mode 100755 index 2b1646c..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImMessageDO.java +++ /dev/null @@ -1,89 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.dataobject.message; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -import java.time.LocalDateTime; - -/** - * IM 消息 DO - * - * @author 芋道源码 - */ -@TableName("im_message") -@KeySequence("im_message_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ImMessageDO extends BaseDO { - - /** - * 编号 - */ - @TableId - private Long id; - /** - * 客户端消息编号 uuid,用于排重 - */ - private String clientMessageId; - // TODO @hao:senderId、receiverId 存储的具体值写下,对应的群之类的 - /** - * 发送人编号 - */ - private Long senderId; - /** - * 接收人编号 - */ - private Long receiverId; - // TODO @hao:冗余字段,要说明下的。例如说 - /** - * 发送人昵称 - * - * 冗余 AdminUserDO 的 nickname 字段 - */ - private String senderNickname; - /** - * 发送人头像 - */ - private String senderAvatar; - // TODO @hao:关联枚举 - /** - * 会话类型 - */ - private Integer conversationType; - // TODO @hao:关联字段 - /** - * 会话标志 - */ - private String conversationNo; - /** - * 消息类型 - */ - private Integer contentType; - // TODO @hao:说明下是 json 格式,在哪个包看具体的格式 - /** - * 消息内容 - */ - private String content; - /** - * 发送时间 - */ - private LocalDateTime sendTime; - // TODO @hao:搞个枚举,然后代码里注释说明下 - /** - * 消息来源 100-用户发送;200-系统发送(一般是通知); - */ - private Integer sendFrom; - // TODO @hao:搞个枚举,然后代码里注释说明下 - /** - * 消息状态 1 发送中、2 发送成功、3 发送失败、4 已删除、5 已撤回 - */ - private Integer messageStatus; - -} \ 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/message/MessageDO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/MessageDO.java new file mode 100755 index 0000000..7f89a93 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/MessageDO.java @@ -0,0 +1,90 @@ +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 com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.time.LocalDateTime; + +/** + * IM 消息 DO + * + * @author 芋道源码 + */ +@TableName("im_message") +@KeySequence("im_message_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MessageDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 客户端消息编号 uuid,用于排重 + */ + private String clientMessageId; + /** + * 发送人编号 存储的是用户编号 + */ + private Long senderId; + /** + * 接收人编号 + *

+ * 1. 单聊时,用户编号;群聊时,群编号 + */ + private Long receiverId; + /** + * 消息发送者昵称 + *

+ * 冗余 AdminUserDO 的 nickname 字段 + */ + private String senderNickname; + /** + * 消息发送者头像 + *

+ * 冗余 AdminUserDO 的 avatar 字段 + */ + private String senderAvatar; + /** + * 会话类型 枚举 {@link ConversationTypeEnum} + */ + private Integer conversationType; + /** + * 会话标志 {@link ConversationTypeEnum} 的generateConversationNo() 方法生成 + */ + private String conversationNo; + /** + * 消息类型 枚举 {@link MessageContentTypeEnum} + */ + private Integer contentType; + /** + * 消息内容 JSON 格式 对应 dal/dataobject/message/content 包 + */ + private String content; + /** + * 发送时间 + */ + private LocalDateTime sendTime; + /** + * 消息来源 枚举 {@link MessageSourceEnum} + */ + private Integer sendFrom; + /** + * 消息状态 枚举 {@link MessageStatusEnum} + */ + private Integer messageStatus; + +} \ 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/message/body/ImAudioMessageBody.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImAudioMessageBody.java deleted file mode 100644 index acc8d84..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImAudioMessageBody.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.dataobject.message.body; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * 语音消息的 {@link ImMessageBody} - * - * @author 芋道源码 - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -public class ImAudioMessageBody implements ImMessageBody { - - /** - * 语音 URL - */ - private String url; - /** - * 语音格式,例如说 arm、mp3、speex 等 - */ - private String format; - - // TODO 芋艿:要不要以下字段?待定;云信有、企业微信没有 -//"dur":4551, //语音持续时长ms -// "md5":"87b94a090dec5c58f242b7132a530a01", //语音文件的md5值,按照字节流加密 -// "size":16420 //语音文件大小,单位为字节(Byte) - -} \ 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/message/body/ImFileMessageBody.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImFileMessageBody.java deleted file mode 100644 index 2ed2384..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImFileMessageBody.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.dataobject.message.body; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * 文件消息的 {@link ImMessageBody} - * - * @author 芋道源码 - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -public class ImFileMessageBody implements ImMessageBody { - - /** - * 文件名 - */ - private String name; - /** - * 文件 URL - */ - private String url; - - // TODO 芋艿:要不要以下字段?待定;云信有、企业微信没有 -// "md5":"79d62a35fa3d34c367b20c66afc2a500", //文件MD5,按照字节流加密 -// "ext":"ttf", //文件后缀类型 -// "size":91680 //大小,单位为字节(Byte) - -} \ 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/message/body/ImImageMessageBody.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImImageMessageBody.java deleted file mode 100644 index 1a81c28..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImImageMessageBody.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.dataobject.message.body; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * 图片消息的 {@link ImMessageBody} - * - * @author 芋道源码 - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -public class ImImageMessageBody implements ImMessageBody { - - /** - * 图片地址 - */ - private String url; - - // TODO 芋艿:要不要以下字段?待定;云信有、企业微信没有 -// "name":"图片发送于2015-05-07 13:59", //图片name -// "md5":"9894907e4ad9de4678091277509361f7", //图片文件md5,按照字节流加密 -// "ext":"jpg", //图片后缀 -// "w":6814, //宽,单位为像素 -// "h":2332, //高,单位为像素 -// "size":388245 //图片文件大小,单位为字节(Byte) - -} diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImLocationMessageBody.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImLocationMessageBody.java deleted file mode 100644 index 3e9db26..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImLocationMessageBody.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.dataobject.message.body; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * 地址位置消息的 {@link ImMessageBody} - * - * @author 芋道源码 - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -public class ImLocationMessageBody implements ImMessageBody { - - /** - * 地理位置 - * - * 例如说:中国 浙江省 杭州市 网商路 599号 - */ - private String address; - /** - * 经度 - */ - private Double longitude; - /** - * 纬度 - */ - private Double latitude; - -} \ 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/message/body/ImMessageBody.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImMessageBody.java deleted file mode 100644 index e5eddc0..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImMessageBody.java +++ /dev/null @@ -1,12 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.dataobject.message.body; - - -import cn.iocoder.yudao.module.im.jackson.ImMessageBodyDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * IM 消息的 body 内容 - */ -@JsonDeserialize(using = ImMessageBodyDeserializer.class) -public interface ImMessageBody { -} \ 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/message/body/ImTextMessageBody.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImTextMessageBody.java deleted file mode 100644 index 9e6f973..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImTextMessageBody.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.dataobject.message.body; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * 文本消息的 {@link ImMessageBody} - * - * @author 芋道源码 - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -public class ImTextMessageBody implements ImMessageBody { - - /** - * 文本消息内容 - */ - 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/dal/dataobject/message/body/ImVideoMessageBody.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImVideoMessageBody.java deleted file mode 100644 index 5d64347..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/body/ImVideoMessageBody.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.dataobject.message.body; - -import lombok.Data; - -/** - * 视频消息的 {@link ImMessageBody} - * - * @author 芋道源码 - */ -@Data -public class ImVideoMessageBody implements ImMessageBody { - - /** - * 视频地址 - */ - private String url; - - // TODO 芋艿:要不要以下字段?待定;云信有、企业微信没有 -// "dur":8003, //视频持续时长ms -// "md5":"da2cef3e5663ee9c3547ef5d127f7e3e", //视频文件的md5值,按照字节流加密 -// "w":360, //宽,单位为像素 -// "h":480, //高,单位为像素 -// "size":16420 //视频文件大小,单位为字节(Byte)】 -// "ext":"mp4", //视频格式 - - -} \ 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/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 new file mode 100644 index 0000000..41420ac --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/AudioMessage.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.im.dal.dataobject.message.content; + +import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 语音消息的 {@link MessageDO 字段 content} 的内容 + * + * @author 芋道源码 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AudioMessage { + + /** + * 语音文件唯一 ID + */ + private String uuid; + + /** + * 语音文件的本地路径 + */ + private String soundPath; + + /** + * 语音文件下载地址 + */ + private String sourceUrl; + + /** + * 语音文件大小 + */ + private int dataSize; + + /** + * 语音时长 + */ + private int duration; + + /** + * 语音文件类型 + */ + private String soundType; + +} \ 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/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 new file mode 100644 index 0000000..3eff9bf --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/CardMessage.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.im.dal.dataobject.message.content; + +import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 名片消息的 {@link MessageDO 字段 content} 的内容 + * + * @author anhaohao + * @since 2024/3/23 下午5:53 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CardMessage { + + /** + * 用户 ID + */ + private String userID; + + /** + * 用户名 + */ + private String nickname; + + /** + * 用户头像 + */ + private int faceURL; + + /** + * 扩展字段 + */ + private String ex; +} 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 new file mode 100644 index 0000000..2dd2b6b --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/FileMessage.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.im.dal.dataobject.message.content; + +import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 文件消息的 {@link MessageDO 字段 content} 的内容 + * + * @author 芋道源码 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class FileMessage { + + /** + * 文件名 + */ + private String name; + /** + * 文件 URL + */ + private String url; + +} \ 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/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 new file mode 100644 index 0000000..cfdfcb1 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/ImageMessage.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.im.dal.dataobject.message.content; + +import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 图片消息的 {@link MessageDO 字段 content} 的内容 + * + * @author 芋道源码 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ImageMessage { + + /** + * 图片地址 + */ + private String url; + +} 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 new file mode 100644 index 0000000..a95c2d8 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/LocationMessage.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.im.dal.dataobject.message.content; + +import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 地址位置消息的 {@link MessageDO 字段 content} 的内容 + * + * @author 芋道源码 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class LocationMessage { + + /** + * 地理位置 + *

+ * 例如说:中国 浙江省 杭州市 网商路 599号 + */ + private String address; + /** + * 经度 + */ + private Double longitude; + /** + * 纬度 + */ + private Double latitude; + +} \ 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/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 new file mode 100644 index 0000000..b7f13a4 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/TextMessage.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.im.dal.dataobject.message.content; + +import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 文本消息的 {@link MessageDO 字段 content} 的内容 + * + * @author 芋道源码 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class TextMessage { + + /** + * 文本消息的具体内容 + */ + 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/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 new file mode 100644 index 0000000..e757e50 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/VideoMessage.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.im.dal.dataobject.message.content; + +import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO; +import lombok.Data; + +/** + * 视频消息的 {@link MessageDO 字段 content} 的内容 + * + * @author 芋道源码 + */ +@Data +public class VideoMessage { + + /** + * 视频地址 + */ + private String url; + +} \ 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/conversation/ConversationMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/conversation/ConversationMapper.java new file mode 100755 index 0000000..73ade2e --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/conversation/ConversationMapper.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.im.dal.mysql.conversation; + +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.conversation.vo.ImConversationPageReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ConversationDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * IM 会话 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface ConversationMapper extends BaseMapperX { + + default PageResult selectPage(ImConversationPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(ConversationDO::getUserId, reqVO.getUserId()) + .eqIfPresent(ConversationDO::getType, reqVO.getType()) + .eqIfPresent(ConversationDO::getTargetId, reqVO.getTargetId()) + .eqIfPresent(ConversationDO::getNo, reqVO.getNo()) + .eqIfPresent(ConversationDO::getPinned, reqVO.getPinned()) + .betweenIfPresent(ConversationDO::getLastReadTime, reqVO.getLastReadTime()) + .betweenIfPresent(ConversationDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(ConversationDO::getId)); + } + + // TODO @hao:1)no) {,要有空格哈;2)可以直接 selectOne(ImConversationDO::getNo, no) 父类做了封装 + default ConversationDO selectByNo(String no){ + return selectOne(new LambdaQueryWrapperX().eq(ConversationDO::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/conversation/ImConversationMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/conversation/ImConversationMapper.java deleted file mode 100755 index d4bfb0c..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/conversation/ImConversationMapper.java +++ /dev/null @@ -1,36 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.mysql.conversation; - -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.conversation.vo.ImConversationPageReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Optional; - -/** - * IM 会话 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface ImConversationMapper extends BaseMapperX { - - default PageResult selectPage(ImConversationPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eqIfPresent(ImConversationDO::getUserId, reqVO.getUserId()) - .eqIfPresent(ImConversationDO::getConversationType, reqVO.getConversationType()) - .eqIfPresent(ImConversationDO::getTargetId, reqVO.getTargetId()) - .eqIfPresent(ImConversationDO::getNo, reqVO.getNo()) - .eqIfPresent(ImConversationDO::getPinned, reqVO.getPinned()) - .betweenIfPresent(ImConversationDO::getLastReadTime, reqVO.getLastReadTime()) - .betweenIfPresent(ImConversationDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(ImConversationDO::getId)); - } - - // TODO @hao:1)no) {,要有空格哈;2)可以直接 selectOne(ImConversationDO::getNo, no) 父类做了封装 - default ImConversationDO selectByNo(String no){ - return selectOne(new LambdaQueryWrapperX().eq(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/ImGroupMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/ImGroupMapper.java index ac301ee..6049550 100644 --- 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 @@ -3,7 +3,7 @@ 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 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.*; @@ -13,18 +13,18 @@ import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; * @author 芋道源码 */ @Mapper -public interface ImGroupMapper extends BaseMapperX { +public interface ImGroupMapper 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)); + 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/ImGroupMemberMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/groupmember/ImGroupMemberMapper.java index d42d1f9..505459a 100644 --- 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 @@ -4,7 +4,7 @@ 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.groupmember.GroupMemberDO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO; import org.apache.ibatis.annotations.Mapper; import java.util.List; diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/inbox/ImInboxMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/inbox/ImInboxMapper.java index aae03ba..15c427e 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/inbox/ImInboxMapper.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/inbox/ImInboxMapper.java @@ -4,7 +4,7 @@ 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.inbox.vo.ImInboxPageReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO; +import cn.iocoder.yudao.module.im.dal.dataobject.inbox.InboxDO; import org.apache.ibatis.annotations.Mapper; /** @@ -13,15 +13,15 @@ import org.apache.ibatis.annotations.Mapper; * @author 芋道源码 */ @Mapper -public interface ImInboxMapper extends BaseMapperX { +public interface ImInboxMapper extends BaseMapperX { - default PageResult selectPage(ImInboxPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eqIfPresent(ImInboxDO::getUserId, reqVO.getUserId()) - .eqIfPresent(ImInboxDO::getMessageId, reqVO.getMessageId()) - .eqIfPresent(ImInboxDO::getSequence, reqVO.getSequence()) - .betweenIfPresent(ImInboxDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(ImInboxDO::getId)); + 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/ImMessageMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImMessageMapper.java deleted file mode 100755 index 54d53b9..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImMessageMapper.java +++ /dev/null @@ -1,62 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.mysql.message; - -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.message.vo.ImMessagePageReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO; -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; -import com.github.yulichang.wrapper.MPJLambdaWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -/** - * 消息 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface ImMessageMapper extends BaseMapperX { - - default PageResult selectPage(ImMessagePageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eqIfPresent(ImMessageDO::getClientMessageId, reqVO.getClientMessageId()) - .eqIfPresent(ImMessageDO::getSenderId, reqVO.getSenderId()) - .eqIfPresent(ImMessageDO::getReceiverId, reqVO.getReceiverId()) - .likeIfPresent(ImMessageDO::getSenderNickname, reqVO.getSenderNickname()) - .eqIfPresent(ImMessageDO::getSenderAvatar, reqVO.getSenderAvatar()) - .eqIfPresent(ImMessageDO::getConversationType, reqVO.getConversationType()) - .eqIfPresent(ImMessageDO::getConversationNo, reqVO.getConversationNo()) - .eqIfPresent(ImMessageDO::getContentType, reqVO.getContentType()) - .eqIfPresent(ImMessageDO::getContent, reqVO.getContent()) - .betweenIfPresent(ImMessageDO::getSendTime, reqVO.getSendTime()) - .eqIfPresent(ImMessageDO::getSendFrom, reqVO.getSendFrom()) - .betweenIfPresent(ImMessageDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(ImMessageDO::getId)); - } - - // TODO @hao:不链表哈;先从 ImInboxDO 查询出 messageId,然后再到 ImMessageDO 里 IN - default List getGreaterThanSequenceMessage(Long userId, Long sequence, Integer size) { - //查询 inbox 表中,大于 sequence 的消息,关联 message 表,按照 inbox 表 sequence 升序 - return selectJoinList(ImMessageDO.class, new MPJLambdaWrapper() - .selectAll(ImMessageDO.class) - .innerJoin(ImInboxDO.class, ImInboxDO::getMessageId, ImMessageDO::getId) - .eq(ImInboxDO::getUserId, userId) - .gt(ImInboxDO::getSequence, sequence) - .orderByAsc(ImInboxDO::getSequence) - .last("limit 0," + size)); - } - - // TODO @hao:在 dao 里,使用 selectListByUserId,查询用 select,条件用 by,这个算是 spring data 的 method dsl - default List getAllMessage(Long userId, Integer size) { - //查询 inbox 表中,100条消息,关联 message 表,按照 inbox 表 sequence 降序 - return selectJoinList(ImMessageDO.class, new MPJLambdaWrapper() - .selectAll(ImMessageDO.class) - .innerJoin(ImInboxDO.class, ImInboxDO::getMessageId, ImMessageDO::getId) - .eq(ImInboxDO::getUserId, userId) - .orderByDesc(ImInboxDO::getSequence) - .last("limit 0," + size)); - } - -} \ 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 new file mode 100755 index 0000000..90fa620 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/MessageMapper.java @@ -0,0 +1,51 @@ +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 org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 消息 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface MessageMapper extends BaseMapperX { + + // TODO @hao:不链表哈;先从 ImInboxDO 查询出 messageId,然后再到 ImMessageDO 里 IN + default List getGreaterThanSequenceMessage(Long userId, Long sequence, Integer size) { + //查询 inbox 表中,大于 sequence 的消息,关联 message 表,按照 inbox 表 sequence 升序 + return selectJoinList(MessageDO.class, new MPJLambdaWrapper() + .selectAll(MessageDO.class) + .innerJoin(InboxDO.class, InboxDO::getMessageId, MessageDO::getId) + .eq(InboxDO::getUserId, userId) + .gt(InboxDO::getSequence, sequence) + .orderByAsc(InboxDO::getSequence) + .last("limit 0," + size)); + } + + // TODO @hao:在 dao 里,使用 selectListByUserId,查询用 select,条件用 by,这个算是 spring data 的 method dsl + default List getAllMessage(Long userId, Integer size) { + //查询 inbox 表中,100条消息,关联 message 表,按照 inbox 表 sequence 降序 + return selectJoinList(MessageDO.class, new MPJLambdaWrapper() + .selectAll(MessageDO.class) + .innerJoin(InboxDO.class, InboxDO::getMessageId, MessageDO::getId) + .eq(InboxDO::getUserId, userId) + .orderByDesc(InboxDO::getSequence) + .last("limit 0," + size)); + } + + default List getMessagePage(MessagePageReqVO pageReqVO) { + return selectList(new LambdaQueryWrapperX() + .eqIfPresent(MessageDO::getConversationNo, pageReqVO.getConversationNo()) + .betweenIfPresent(MessageDO::getSendTime, pageReqVO.getSendTime()) + .orderByAsc(MessageDO::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/RedisKeyConstants.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/RedisKeyConstants.java index 906c892..76dba12 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/RedisKeyConstants.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/RedisKeyConstants.java @@ -14,4 +14,11 @@ public interface RedisKeyConstants { * VALUE 数据类型: String */ String INBOX_SEQUENCE = "im_inbox_sequence:%s"; + + /** + * 收件箱的分布式锁 + * KEY 格式: im:inbox:lock:{userId} + * VALUE 数据类型: String + */ + String INBOX_LOCK = "im_inbox_lock:%s"; } diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/InboxLockRedisDAO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/InboxLockRedisDAO.java new file mode 100644 index 0000000..a247d09 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/InboxLockRedisDAO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.im.dal.redis.inbox; + +import jakarta.annotation.Resource; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.stereotype.Repository; + +import java.util.concurrent.TimeUnit; + +import static cn.iocoder.yudao.module.im.dal.redis.RedisKeyConstants.INBOX_LOCK; + +/** + * 收件箱的锁 Redis DAO + * + * @author 芋道源码 + */ +@Repository +public class InboxLockRedisDAO { + + @Resource + private RedissonClient redissonClient; + + private static String formatKey(Long id) { + return String.format(INBOX_LOCK, id); + } + + public void lock(Long id, Long timeoutMillis, Runnable runnable) { + String lockKey = formatKey(id); + RLock lock = redissonClient.getLock(lockKey); + try { + lock.lock(timeoutMillis, TimeUnit.MILLISECONDS); + // 执行逻辑 + runnable.run(); + } finally { + lock.unlock(); + } + } + +} diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceGeneratorRedisDao.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceGeneratorRedisDao.java deleted file mode 100644 index d1ceec7..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceGeneratorRedisDao.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.module.im.dal.redis.inbox; - -import jakarta.annotation.Resource; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.stereotype.Repository; - -import static cn.iocoder.yudao.module.im.dal.redis.RedisKeyConstants.INBOX_SEQUENCE; - -// TODO @芋艿:这个名字,需要在考虑下; -/** - * 序号生成器 Redis DAO - * - * @author anhaohao - */ -@Repository -public class SequenceGeneratorRedisDao { - - @Resource - private RedisTemplate redisTemplate; - - private static String formatKey(Long userId) { - return String.format(INBOX_SEQUENCE, userId); - } - - public Long generateSequence(Long userId) { - return redisTemplate.opsForValue().increment(formatKey(userId), 1); - } - -} 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 new file mode 100644 index 0000000..ddbab25 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/redis/inbox/SequenceRedisDao.java @@ -0,0 +1,37 @@ +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; + +import static cn.iocoder.yudao.module.im.dal.redis.RedisKeyConstants.INBOX_SEQUENCE; + +// TODO @芋艿:这个名字,需要在考虑下; + +/** + * 序号生成器 Redis DAO + * + * @author anhaohao + */ +@Repository +public class SequenceRedisDao { + + @Resource + private RedisTemplate redisTemplate; + + private static String formatKey(Long userId) { + return String.format(INBOX_SEQUENCE, userId); + } + + /** + * 生成序号 + * + * @param userId 用户编号 + * @return 序号 + */ + public Long generateSequence(Long userId) { + return redisTemplate.opsForValue().increment(formatKey(userId), 1); + } + +} diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/jackson/ImMessageBodyDeserializer.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/jackson/ImMessageBodyDeserializer.java deleted file mode 100644 index 2f7c4f8..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/jackson/ImMessageBodyDeserializer.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.im.jackson; - -import cn.iocoder.yudao.module.im.dal.dataobject.message.body.*; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; - -import java.io.IOException; - -// TODO @hao:可以讨论下:是不是前端传递 type + content,后端根据 type 判断后,直接 jsonutil 解析到对应的 body 就 ok 了 -public class ImMessageBodyDeserializer extends JsonDeserializer { - - @Override - public ImMessageBody deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - JsonNode node = p.getCodec().readTree(p); - // 根据 node 中的内容来判断应该实例化哪个子类 - if (node.has("content")) { - return new ImTextMessageBody(node.get("content").asText()); - } - if (node.has("url")) { - String url = node.get("url").asText(); - if (node.has("format")) { - return new ImAudioMessageBody(url, node.get("format").asText()); - } - return new ImImageMessageBody(url); - } - if (node.has("name")) { - return new ImFileMessageBody(node.get("name").asText(), node.get("url").asText()); - } - if (node.has("address")) { - return new ImLocationMessageBody(node.get("address").asText(), node.get("longitude").asDouble(), node.get("latitude").asDouble()); - } - // 如果没有匹配的属性,抛出异常 - throw ctxt.mappingException("Cannot deserialize to an instance of ImMessageBody"); - } - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/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 new file mode 100755 index 0000000..0fa3a47 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationService.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.im.service.conversation; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationPageReqVO; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationSaveReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ConversationDO; +import jakarta.validation.Valid; + +import java.util.List; + +/** + * IM 会话 Service 接口 + * + * @author 芋道源码 + */ +public interface ConversationService { + + /** + * 创建会话 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createConversation(@Valid ImConversationSaveReqVO createReqVO); + + /** + * 更新会话 + * + * @param updateReqVO 更新信息 + */ + void updateConversation(@Valid ImConversationSaveReqVO updateReqVO); + + /** + * 删除会话 + * + * @param id 编号 + */ + void deleteConversation(Long id); + + /** + * 获得会话 + * + * @param id 编号 + * @return 会话 + */ + ConversationDO getConversation(Long id); + + /** + * 获得会话分页 + * + * @param pageReqVO 分页查询 + * @return 会话分页 + */ + PageResult getConversationPage(ImConversationPageReqVO pageReqVO); + + + /** + * 获得用户的会话列表 + * + * @return 会话列表 + */ + List getConversationList(); + + /** + * 置顶会话 + * + * @param updateReqVO 更新信息 + */ + void updateTop(ImConversationSaveReqVO updateReqVO); + + /** + * 更新最后已读时间 + * + * @param updateReqVO 更新信息 + */ + void updateLastReadTime(ImConversationSaveReqVO 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 new file mode 100755 index 0000000..7b1bd9a --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ConversationServiceImpl.java @@ -0,0 +1,115 @@ +package cn.iocoder.yudao.module.im.service.conversation; + +import cn.hutool.core.date.DateUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationPageReqVO; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationSaveReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ConversationDO; +import cn.iocoder.yudao.module.im.dal.mysql.conversation.ConversationMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import java.util.Date; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.CONVERSATION_NOT_EXISTS; + +/** + * IM 会话 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class ConversationServiceImpl implements ConversationService { + + // TODO @hao: 自己模块的注入,不用带 im 前缀哈; + @Resource + private ConversationMapper conversationMapper; + + // TODO @hao: 这个方法,是不是不需要哈 + @Override + public Long createConversation(ImConversationSaveReqVO createReqVO) { + ConversationDO conversation = BeanUtils.toBean(createReqVO, ConversationDO.class); + conversationMapper.insert(conversation); + return conversation.getId(); + } + + // TODO @hao: 这个方法,是不是不需要哈 + @Override + public void updateConversation(ImConversationSaveReqVO updateReqVO) { + // 校验存在 + validateConversationExists(updateReqVO.getId()); + // 更新 + ConversationDO updateObj = BeanUtils.toBean(updateReqVO, ConversationDO.class); + conversationMapper.updateById(updateObj); + } + + // TODO @hao: 考虑到可能和端上不同步,可以不校验是不是存储。另外,不基于 id 删除。要基于 no + userId 删除哈。说白了,对端上要屏蔽 id 字段 + @Override + public void deleteConversation(Long id) { + // 校验存在 + validateConversationExists(id); + // 删除 + conversationMapper.deleteById(id); + } + + private void validateConversationExists(Long id) { + if (conversationMapper.selectById(id) == null) { + throw exception(CONVERSATION_NOT_EXISTS); + } + } + + @Override + public ConversationDO getConversation(Long id) { + return conversationMapper.selectById(id); + } + + @Override + public PageResult getConversationPage(ImConversationPageReqVO pageReqVO) { + return conversationMapper.selectPage(pageReqVO); + } + + @Override + public List getConversationList() { + return conversationMapper.selectList(); + } + + @Override + public void updateTop(ImConversationSaveReqVO updateReqVO) { + createOrUpdateConversation(updateReqVO); + } + + @Override + public void updateLastReadTime(ImConversationSaveReqVO updateReqVO) { + createOrUpdateConversation(updateReqVO); + } + + // TODO @hao:updateTop 和 updateLastReadTime 使用独立的逻辑实现,不使用统一的 ImConversationSaveReqVO; + // TODO 大体步骤建议: + // 1. 先 getOrderCreateConversation,查询会话,不存在则插入; + // 2. 更新对应的字段 + // 3. 做对应更新的 notify 推送 + private void createOrUpdateConversation(ImConversationSaveReqVO updateReqVO) { + // 操作会话(已读、置顶)时,才会延迟创建,要先判断是否存在,根据 no 查询是否存在,不存在则新增 + ConversationDO conversation = conversationMapper.selectByNo(updateReqVO.getNo()); + if (conversation == null) { + ConversationDO conversationDO = new ConversationDO(); + conversationDO.setNo(updateReqVO.getNo()); + conversationDO.setUserId(updateReqVO.getUserId()); + conversationDO.setTargetId(updateReqVO.getTargetId()); + conversationDO.setType(updateReqVO.getType()); + conversationDO.setPinned(updateReqVO.getPinned()); + conversationDO.setLastReadTime(DateUtil.toLocalDateTime(new Date())); + conversationMapper.insert(conversationDO); + } else { + // 更新 + ConversationDO updateObj = BeanUtils.toBean(updateReqVO, ConversationDO.class); + conversationMapper.updateById(updateObj); + } + } + +} \ 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/ImConversationService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationService.java deleted file mode 100755 index d235a7e..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationService.java +++ /dev/null @@ -1,78 +0,0 @@ -package cn.iocoder.yudao.module.im.service.conversation; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationPageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationSaveReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; -import jakarta.validation.Valid; - -import java.util.List; - -/** - * IM 会话 Service 接口 - * - * @author 芋道源码 - */ -public interface ImConversationService { - - /** - * 创建会话 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createConversation(@Valid ImConversationSaveReqVO createReqVO); - - /** - * 更新会话 - * - * @param updateReqVO 更新信息 - */ - void updateConversation(@Valid ImConversationSaveReqVO updateReqVO); - - /** - * 删除会话 - * - * @param id 编号 - */ - void deleteConversation(Long id); - - /** - * 获得会话 - * - * @param id 编号 - * @return 会话 - */ - ImConversationDO getConversation(Long id); - - /** - * 获得会话分页 - * - * @param pageReqVO 分页查询 - * @return 会话分页 - */ - PageResult getConversationPage(ImConversationPageReqVO pageReqVO); - - - /** - * 获得用户的会话列表 - * - * @return 会话列表 - */ - List getConversationList(); - - /** - * 置顶会话 - * - * @param updateReqVO 更新信息 - */ - void updateTop(ImConversationSaveReqVO updateReqVO); - - /** - * 更新最后已读时间 - * - * @param updateReqVO 更新信息 - */ - void updateLastReadTime(ImConversationSaveReqVO 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/ImConversationServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImpl.java deleted file mode 100755 index a14a31b..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImpl.java +++ /dev/null @@ -1,115 +0,0 @@ -package cn.iocoder.yudao.module.im.service.conversation; - -import cn.hutool.core.date.DateUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationPageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationSaveReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; -import cn.iocoder.yudao.module.im.dal.mysql.conversation.ImConversationMapper; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import java.util.Date; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.CONVERSATION_NOT_EXISTS; - -/** - * IM 会话 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class ImConversationServiceImpl implements ImConversationService { - - // TODO @hao: 自己模块的注入,不用带 im 前缀哈; - @Resource - private ImConversationMapper imConversationMapper; - - // TODO @hao: 这个方法,是不是不需要哈 - @Override - public Long createConversation(ImConversationSaveReqVO createReqVO) { - ImConversationDO conversation = BeanUtils.toBean(createReqVO, ImConversationDO.class); - imConversationMapper.insert(conversation); - return conversation.getId(); - } - - // TODO @hao: 这个方法,是不是不需要哈 - @Override - public void updateConversation(ImConversationSaveReqVO updateReqVO) { - // 校验存在 - validateConversationExists(updateReqVO.getId()); - // 更新 - ImConversationDO updateObj = BeanUtils.toBean(updateReqVO, ImConversationDO.class); - imConversationMapper.updateById(updateObj); - } - - // TODO @hao: 考虑到可能和端上不同步,可以不校验是不是存储。另外,不基于 id 删除。要基于 no + userId 删除哈。说白了,对端上要屏蔽 id 字段 - @Override - public void deleteConversation(Long id) { - // 校验存在 - validateConversationExists(id); - // 删除 - imConversationMapper.deleteById(id); - } - - private void validateConversationExists(Long id) { - if (imConversationMapper.selectById(id) == null) { - throw exception(CONVERSATION_NOT_EXISTS); - } - } - - @Override - public ImConversationDO getConversation(Long id) { - return imConversationMapper.selectById(id); - } - - @Override - public PageResult getConversationPage(ImConversationPageReqVO pageReqVO) { - return imConversationMapper.selectPage(pageReqVO); - } - - @Override - public List getConversationList() { - return imConversationMapper.selectList(); - } - - @Override - public void updateTop(ImConversationSaveReqVO updateReqVO) { - createOrUpdateConversation(updateReqVO); - } - - @Override - public void updateLastReadTime(ImConversationSaveReqVO updateReqVO) { - createOrUpdateConversation(updateReqVO); - } - - // TODO @hao:updateTop 和 updateLastReadTime 使用独立的逻辑实现,不使用统一的 ImConversationSaveReqVO; - // TODO 大体步骤建议: - // 1. 先 getOrderCreateConversation,查询会话,不存在则插入; - // 2. 更新对应的字段 - // 3. 做对应更新的 notify 推送 - private void createOrUpdateConversation(ImConversationSaveReqVO updateReqVO) { - // 操作会话(已读、置顶)时,才会延迟创建,要先判断是否存在,根据 no 查询是否存在,不存在则新增 - ImConversationDO conversation = imConversationMapper.selectByNo(updateReqVO.getNo()); - if (conversation == null) { - ImConversationDO conversationDO = new ImConversationDO(); - conversationDO.setNo(updateReqVO.getNo()); - conversationDO.setUserId(updateReqVO.getUserId()); - conversationDO.setTargetId(updateReqVO.getTargetId()); - conversationDO.setConversationType(updateReqVO.getConversationType()); - conversationDO.setPinned(updateReqVO.getPinned()); - conversationDO.setLastReadTime(DateUtil.toLocalDateTime(new Date())); - imConversationMapper.insert(conversationDO); - } else { - // 更新 - ImConversationDO updateObj = BeanUtils.toBean(updateReqVO, ImConversationDO.class); - imConversationMapper.updateById(updateObj); - } - } - -} \ 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/ImGroupService.java index 4ebc373..cd395b8 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/ImGroupService.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.ImGroupDO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; /** @@ -40,7 +40,7 @@ public interface ImGroupService { * @param id 编号 * @return 群 */ - ImGroupDO getGroup(Long id); + GroupDO 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/ImGroupServiceImpl.java index e7e20e9..5cc2e1b 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/ImGroupServiceImpl.java @@ -5,7 +5,7 @@ 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.ImGroupDO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -29,7 +29,7 @@ public class ImGroupServiceImpl implements ImGroupService { @Override public Long createGroup(ImGroupSaveReqVO createReqVO) { // 插入 - ImGroupDO group = BeanUtils.toBean(createReqVO, ImGroupDO.class); + GroupDO group = BeanUtils.toBean(createReqVO, GroupDO.class); imGroupMapper.insert(group); // 返回 return group.getId(); @@ -40,7 +40,7 @@ public class ImGroupServiceImpl implements ImGroupService { // 校验存在 validateGroupExists(updateReqVO.getId()); // 更新 - ImGroupDO updateObj = BeanUtils.toBean(updateReqVO, ImGroupDO.class); + GroupDO updateObj = BeanUtils.toBean(updateReqVO, GroupDO.class); imGroupMapper.updateById(updateObj); } @@ -59,12 +59,12 @@ public class ImGroupServiceImpl implements ImGroupService { } @Override - public ImGroupDO getGroup(Long id) { + public GroupDO getGroup(Long id) { return imGroupMapper.selectById(id); } @Override - public PageResult getGroupPage(ImGroupPageReqVO pageReqVO) { + public PageResult getGroupPage(ImGroupPageReqVO pageReqVO) { return imGroupMapper.selectPage(pageReqVO); } diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberService.java index 4ee73ae..4c27936 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberService.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberService.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.groupmember.GroupMemberDO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO; import jakarta.validation.Valid; import java.util.List; diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberServiceImpl.java index 3152f04..f4ebd31 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberServiceImpl.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberServiceImpl.java @@ -5,7 +5,7 @@ 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.groupmember.GroupMemberDO; +import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxService.java index 98c164a..948b554 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxService.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxService.java @@ -2,8 +2,9 @@ package cn.iocoder.yudao.module.im.service.inbox; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.ImInboxPageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.ImInboxSaveReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO; +import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveReqVO; +import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveMessageReqVO; +import cn.iocoder.yudao.module.im.dal.dataobject.inbox.InboxDO; import jakarta.validation.Valid; // TODO @hao:不用的方法,删除下哈; @@ -20,14 +21,14 @@ public interface ImInboxService { * @param createReqVO 创建信息 * @return 编号 */ - Long createInbox(@Valid ImInboxSaveReqVO createReqVO); + Long createInbox(@Valid InboxSaveReqVO createReqVO); /** * 更新收件箱 * * @param updateReqVO 更新信息 */ - void updateInbox(@Valid ImInboxSaveReqVO updateReqVO); + void updateInbox(@Valid InboxSaveReqVO updateReqVO); /** * 删除收件箱 @@ -42,7 +43,7 @@ public interface ImInboxService { * @param id 编号 * @return 收件箱 */ - ImInboxDO getInbox(Long id); + InboxDO getInbox(Long id); /** * 获得收件箱分页 @@ -50,6 +51,11 @@ public interface ImInboxService { * @param pageReqVO 分页查询 * @return 收件箱分页 */ - PageResult getInboxPage(ImInboxPageReqVO pageReqVO); + PageResult getInboxPage(ImInboxPageReqVO pageReqVO); + /** + * 保存收件箱和发送消息 + * @param inboxSaveMessageReqVO 收件箱保存消息 Request VO + */ + void saveInboxAndSendMessage(InboxSaveMessageReqVO inboxSaveMessageReqVO); } \ 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/ImInboxServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxServiceImpl.java index 2168fde..f7bea8c 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxServiceImpl.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxServiceImpl.java @@ -1,15 +1,27 @@ package cn.iocoder.yudao.module.im.service.inbox; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.ImInboxPageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.ImInboxSaveReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO; +import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveMessageReqVO; +import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveReqVO; +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.dal.mysql.inbox.ImInboxMapper; +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.service.groupmember.ImGroupMemberService; import jakarta.annotation.Resource; +import org.dromara.hutool.core.date.DateUnit; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; +import java.util.List; + import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.INBOX_NOT_EXISTS; @@ -22,22 +34,33 @@ import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.INBOX_NOT_EXIS @Validated public class ImInboxServiceImpl implements ImInboxService { + private static final Long INBOX_LOCK_TIMEOUT = 120 * DateUnit.SECOND.getMillis(); + private static final String IM_MESSAGE_RECEIVE = "im-message-receive"; + @Resource private ImInboxMapper imInboxMapper; + @Resource + private SequenceRedisDao sequenceRedisDao; // 序列生成器Redis DAO + @Resource + private InboxLockRedisDAO inboxLockRedisDAO; // 收件箱的锁 Redis DAO + @Resource + private WebSocketMessageSender webSocketMessageSender; // WebSocket消息发送器 + @Resource + private ImGroupMemberService imGroupMemberService; @Override - public Long createInbox(ImInboxSaveReqVO createReqVO) { - ImInboxDO inbox = BeanUtils.toBean(createReqVO, ImInboxDO.class); + public Long createInbox(InboxSaveReqVO createReqVO) { + InboxDO inbox = BeanUtils.toBean(createReqVO, InboxDO.class); imInboxMapper.insert(inbox); return inbox.getId(); } @Override - public void updateInbox(ImInboxSaveReqVO updateReqVO) { + public void updateInbox(InboxSaveReqVO updateReqVO) { // 校验存在 validateInboxExists(updateReqVO.getId()); // 更新 - ImInboxDO updateObj = BeanUtils.toBean(updateReqVO, ImInboxDO.class); + InboxDO updateObj = BeanUtils.toBean(updateReqVO, InboxDO.class); imInboxMapper.updateById(updateObj); } @@ -56,13 +79,45 @@ public class ImInboxServiceImpl implements ImInboxService { } @Override - public ImInboxDO getInbox(Long id) { + public InboxDO getInbox(Long id) { return imInboxMapper.selectById(id); } @Override - public PageResult getInboxPage(ImInboxPageReqVO pageReqVO) { + public PageResult getInboxPage(ImInboxPageReqVO pageReqVO) { return imInboxMapper.selectPage(pageReqVO); } + @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 = imGroupMemberService.selectByGroupId(inboxSaveMessage.getReceiverId()); + groupMembers.forEach(groupMemberDO -> saveInboxAndSendMessageForUser(groupMemberDO.getUserId(), inboxSaveMessage)); + } + } + + private void saveInboxAndSendMessageForUser(Long userId, InboxSaveMessageReqVO inboxSaveMessage) { + inboxLockRedisDAO.lock(userId, INBOX_LOCK_TIMEOUT, () -> { + Long userSequence = sequenceRedisDao.generateSequence(userId); + InboxDO inbox = new InboxDO(); + inbox.setUserId(userId); + inbox.setMessageId(inboxSaveMessage.getMessageId()); + inbox.setSequence(userSequence); + imInboxMapper.insert(inbox); + + //是发送人不发送 + if (userId.equals(inboxSaveMessage.getFromId())) { + return; + } + InboxSendMessageReqVO message = BeanUtils.toBean(inboxSaveMessage, InboxSendMessageReqVO.class); + message.setSequence(userSequence); + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), userId, IM_MESSAGE_RECEIVE, 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/ImMessageService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageService.java deleted file mode 100755 index 061e1d7..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageService.java +++ /dev/null @@ -1,103 +0,0 @@ -package cn.iocoder.yudao.module.im.service.message; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessagePageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSaveReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; -import cn.iocoder.yudao.module.im.websocket.message.ImSendMessage; -import jakarta.validation.Valid; - -import java.util.List; - -/** - * 消息 Service 接口 - * - * @author 芋道源码 - */ -public interface ImMessageService { - - /** - * 创建消息 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createMessage(@Valid ImMessageSaveReqVO createReqVO); - - /** - * 更新消息 - * - * @param updateReqVO 更新信息 - */ - void updateMessage(@Valid ImMessageSaveReqVO updateReqVO); - - /** - * 删除消息 - * - * @param id 编号 - */ - void deleteMessage(Long id); - - /** - * 获得消息 - * - * @param id 编号 - * @return 消息 - */ - ImMessageDO getMessage(Long id); - - /** - * 获得消息分页 - * - * @param pageReqVO 分页查询 - * @return 消息分页 - */ - PageResult getMessagePage(ImMessagePageReqVO pageReqVO); - - - /** - * 保存私聊消息 - * - * @param imSendMessage 消息信息 - * @param fromUserId 发送人编号 - * @return id - */ - ImMessageDO savePrivateMessage(ImSendMessage imSendMessage, Long fromUserId); - - /** - * 更新消息状态 - * - * @param messageId 消息id - * @param messageStatus 消息状态 - */ - void updateMessageStatus(Long messageId, Integer messageStatus); - - /** - * 保存群聊消息 - * - * @param message 消息 - * @param fromUserId 发送者用户ID - * @return id - */ - ImMessageDO saveGroupMessage(ImSendMessage message, Long fromUserId); - - /** - * 拉取消息-大于 seq 的消息 - * - * @param userId 用户id - * @param sequence 序列号 - * @param size 数量 - * @return 消息列表 - */ - List loadMessage(Long userId, Long sequence, Integer size); - - // TODO @hao;这种接口,项目里叫 getMessageListByUserId,尽量保持 getList 获取列表哈; - /** - * 拉取全部消息 - * - * @param userId 登录用户编号 - * @param size 数量 - * @return 消息列表 - */ - List loadAllMessage(Long userId, Integer size); -} \ 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/ImMessageServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImpl.java deleted file mode 100755 index 6c5a98f..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImpl.java +++ /dev/null @@ -1,143 +0,0 @@ -package cn.iocoder.yudao.module.im.service.message; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessagePageReqVO; -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSaveReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; -import cn.iocoder.yudao.module.im.dal.mysql.message.ImMessageMapper; -import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; -import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; -import cn.iocoder.yudao.module.im.websocket.message.ImSendMessage; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; -import jakarta.annotation.Resource; -import org.dromara.hutool.core.date.TimeUtil; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.MESSAGE_NOT_EXISTS; - -/** - * 消息 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class ImMessageServiceImpl implements ImMessageService { - - @Resource - private ImMessageMapper imMessageMapper; - @Resource - private AdminUserApi adminUserApi; - - @Override - public Long createMessage(ImMessageSaveReqVO createReqVO) { - // 插入 - ImMessageDO message = BeanUtils.toBean(createReqVO, ImMessageDO.class); - imMessageMapper.insert(message); - // 返回 - return message.getId(); - } - - @Override - public void updateMessage(ImMessageSaveReqVO updateReqVO) { - // 校验存在 - validateMessageExists(updateReqVO.getId()); - // 更新 - ImMessageDO updateObj = BeanUtils.toBean(updateReqVO, ImMessageDO.class); - imMessageMapper.updateById(updateObj); - } - - @Override - public void deleteMessage(Long id) { - // 校验存在 - validateMessageExists(id); - // 删除 - imMessageMapper.deleteById(id); - } - - private void validateMessageExists(Long id) { - if (imMessageMapper.selectById(id) == null) { - throw exception(MESSAGE_NOT_EXISTS); - } - } - - @Override - public ImMessageDO getMessage(Long id) { - return imMessageMapper.selectById(id); - } - - @Override - public PageResult getMessagePage(ImMessagePageReqVO pageReqVO) { - return imMessageMapper.selectPage(pageReqVO); - } - - - @Override - public ImMessageDO savePrivateMessage(ImSendMessage message, Long fromUserId) { - return saveImMessageDO(message, fromUserId); - } - - private ImMessageDO saveImMessageDO(ImSendMessage message, Long fromUserId) { - // TODO @hao:可以搞成 messageDO - // TODO @hao:链式调用 - ImMessageDO imMessageDO = new ImMessageDO(); - imMessageDO.setClientMessageId(message.getClientMessageId()); - imMessageDO.setSenderId(fromUserId); - imMessageDO.setReceiverId(message.getReceiverId()); - // 查询发送人昵称和发送人头像 - AdminUserRespDTO user = adminUserApi.getUser(fromUserId); - imMessageDO.setSenderNickname(user.getNickname()); - imMessageDO.setSenderAvatar(user.getAvatar()); - imMessageDO.setConversationType(message.getConversationType()); - imMessageDO.setContentType(message.getContentType()); - // 单聊:s_{userId}_{targetId} 群聊:群聊:g_{groupId} - // TODO @hao:这里的 conversationNo 的生成,可以写到工具类里,或者干脆放到 ImConversationTypeEnum 里; - if (message.getConversationType().equals(ImConversationTypeEnum.PRIVATE.getType())) { - imMessageDO.setConversationNo("s_" + fromUserId + "_" + message.getReceiverId()); - } else if (message.getConversationType().equals(ImConversationTypeEnum.GROUP.getType())) { - imMessageDO.setConversationNo("g_" + message.getReceiverId()); - } - imMessageDO.setContent(message.getContent()); - // TODO @hao:枚举哈; - // 消息来源 100-用户发送;200-系统发送(一般是通知);不能为空 - imMessageDO.setSendFrom(100); - imMessageDO.setSendTime(TimeUtil.now()); - // TODO @hao:服务端的消息,就是默认生成哈; - imMessageDO.setMessageStatus(ImMessageStatusEnum.SENDING.getStatus()); - imMessageMapper.insert(imMessageDO); - return imMessageDO; - } - - @Override - public void updateMessageStatus(Long messageId, Integer messageStatus) { - // 校验 id 是否存在 - validateMessageExists(messageId); - //更新消息状态 - ImMessageDO imMessageDO = new ImMessageDO(); - imMessageDO.setId(messageId); - imMessageDO.setMessageStatus(messageStatus); - imMessageMapper.updateById(imMessageDO); - } - - @Override - public ImMessageDO saveGroupMessage(ImSendMessage message, Long fromUserId) { - return saveImMessageDO(message, fromUserId); - } - - @Override - public List loadMessage(Long userId, Long sequence, Integer size) { - return imMessageMapper.getGreaterThanSequenceMessage(userId, sequence, size); - } - - @Override - public List loadAllMessage(Long userId, Integer size) { - return imMessageMapper.getAllMessage(userId, size); - } - -} \ 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 new file mode 100755 index 0000000..82b03dc --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageService.java @@ -0,0 +1,43 @@ +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 java.util.List; + +/** + * 消息 Service 接口 + * + * @author 芋道源码 + */ +public interface MessageService { + + /** + * 获得消息分页 + * + * @param pageReqVO 分页查询 + * @return 消息分页 + */ + List getMessagePage(MessagePageReqVO pageReqVO); + + + /** + * 拉取消息-大于 seq 的消息 + * + * @param userId 用户id + * @param sequence 序列号 + * @param size 数量 + * @return 消息列表 + */ + List getMessageListBySequence(Long userId, Long sequence, Integer size); + + /** + * 发送消息 + * @param loginUserId 登录用户编号 + * @param message 消息 + * @return 消息编号 + */ + SendMessageRespVO sendMessage(Long loginUserId, SendMessageReqVO 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 new file mode 100755 index 0000000..76d2623 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/MessageServiceImpl.java @@ -0,0 +1,122 @@ +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.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.service.groupmember.ImGroupMemberService; +import cn.iocoder.yudao.module.im.service.inbox.ImInboxService; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.dromara.hutool.core.date.TimeUtil; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.MESSAGE_RECEIVER_NOT_EXISTS; + +/** + * 消息 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +@Slf4j +public class MessageServiceImpl implements MessageService { + + @Resource + private MessageMapper messageMapper; + @Resource + private ImInboxService imInboxService; // IM收件箱服务 + @Resource + private AdminUserApi adminUserApi; + @Resource + private ImGroupMemberService imGroupMemberService; + + @Override + public List getMessagePage(MessagePageReqVO pageReqVO) { + return messageMapper.getMessagePage(pageReqVO); + } + + @Override + public List getMessageListBySequence(Long userId, Long sequence, Integer size) { + return messageMapper.getGreaterThanSequenceMessage(userId, sequence, size); + } + + @Override + public SendMessageRespVO sendMessage(Long fromUserId, SendMessageReqVO message) { + // 保存消息 + InboxSaveMessageReqVO inboxSaveMessageReqVO = new InboxSaveMessageReqVO(); + SendMessageRespVO sendMessageRespVO = saveMessage(fromUserId, message, inboxSaveMessageReqVO); + + // 保存收件箱 + 发送消息给用户 + imInboxService.saveInboxAndSendMessage(inboxSaveMessageReqVO); + return sendMessageRespVO; + } + + public SendMessageRespVO saveMessage(Long fromUserId, SendMessageReqVO message, InboxSaveMessageReqVO inboxSaveMessageReqVO) { + //需要校验 receiverId 存在 + validateReceiverIdExists(message); + // 查询发送人昵称和发送人头像 + AdminUserRespDTO fromUser = adminUserApi.getUser(fromUserId); + // 使用链式调用创建 MessageDO 对象 + MessageDO messageDO = new MessageDO() + .setClientMessageId(message.getClientMessageId()) + .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()); + inboxSaveMessageReqVO.setFromId(fromUserId); + inboxSaveMessageReqVO.setReceiverId(message.getReceiverId()); + inboxSaveMessageReqVO.setMessageId(messageDO.getId()); + inboxSaveMessageReqVO.setContentType(message.getContentType()); + inboxSaveMessageReqVO.setContent(message.getContent()); + inboxSaveMessageReqVO.setSendTime(messageDO.getSendTime()); + + // 返回 SendMessageRespVO 对象 + return new SendMessageRespVO(messageDO.getId(), messageDO.getSendTime()); + } + + private void validateReceiverIdExists(SendMessageReqVO message) { + if (message.getReceiverId() == null) { + throw exception(MESSAGE_RECEIVER_NOT_EXISTS); + } + if (message.getConversationType().equals(ConversationTypeEnum.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 = imGroupMemberService.selectByGroupId(message.getReceiverId()); + if (groupMemberDOS.isEmpty()) { + throw exception(MESSAGE_RECEIVER_NOT_EXISTS); + } + } + } + +} \ 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/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 be816f7..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/ImWebSocketMessageListener.java +++ /dev/null @@ -1,184 +0,0 @@ -package cn.iocoder.yudao.module.im.websocket; - -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.websocket.core.listener.WebSocketMessageListener; -import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; -import cn.iocoder.yudao.framework.websocket.core.util.WebSocketFrameworkUtils; -import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.ImInboxSaveReqVO; -import cn.iocoder.yudao.module.im.dal.dataobject.groupmember.GroupMemberDO; -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; -import cn.iocoder.yudao.module.im.dal.redis.inbox.SequenceGeneratorRedisDao; -import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; -import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; -import cn.iocoder.yudao.module.im.service.conversation.ImConversationService; -import cn.iocoder.yudao.module.im.service.groupmember.ImGroupMemberService; -import cn.iocoder.yudao.module.im.service.inbox.ImInboxService; -import cn.iocoder.yudao.module.im.service.message.ImMessageService; -import cn.iocoder.yudao.module.im.websocket.message.ImReceiveMessage; -import cn.iocoder.yudao.module.im.websocket.message.ImSendMessage; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import org.springframework.web.socket.WebSocketSession; - -import java.util.List; - -// 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 WebSocketMessageSender webSocketMessageSender; // WebSocket消息发送器 - @Resource - private ImMessageService imMessageService; // IM消息服务 - @Resource - private ImConversationService imConversationService; // IM会话服务 - @Resource - private ImInboxService imInboxService; // IM收件箱服务 - @Resource - private ImGroupMemberService imGroupMemberService; // 群成员服务 - @Resource - private SequenceGeneratorRedisDao sequenceGeneratorRedisDao; // 序列生成器Redis DAO - - /** - * 处理WebSocket消息 - * - * @param session WebSocket会话 - * @param message 发送的IM消息 - */ - @Override - public void onMessage(WebSocketSession session, ImSendMessage message) { - Long fromUserId = WebSocketFrameworkUtils.getLoginUserId(session); // 获取登录用户ID - - // 如果是私人消息,处理私人消息 - if (message.getConversationType().equals(ImConversationTypeEnum.PRIVATE.getType())) { - handlePrivateMessage(fromUserId, message); - } else if (message.getConversationType().equals(ImConversationTypeEnum.GROUP.getType())) { - // 处理群聊消息 - handleGroupMessage(fromUserId, message); - } else { - // TODO @hao:是不是应该会话类型哈?然后打印这种错误日志,最好把 message 整个打进去,这样更好定位完整的消息; - log.error("[onMessage][消息类型({}) 未支持]", message.getConversationType()); - } - } - - /** - * 处理群聊消息 - * - * @param fromUserId 发送者用户ID - * @param message 发送的IM消息 - */ - private void handleGroupMessage(Long fromUserId, ImSendMessage message) { - // TODO @hao:群存在; - // TODO @hao:发送人在群里; - ImMessageDO imMessageDO = imMessageService.saveGroupMessage(message, fromUserId); // 保存群聊消息 - Long groupId = message.getReceiverId(); - - // 发送消息给群聊成员 - // TODO @hao:变量名可以叫 groupMembers;一般不用 DO 后缀,除非为了区分; - List groupMemberDOList = imGroupMemberService.selectByGroupId(groupId); - groupMemberDOList.forEach(groupMemberDO -> { - // 过滤掉自己 - // TODO @hao:98 到 99 的代码,是不是可以融合到这里来; - if (groupMemberDO.getUserId().equals(fromUserId)) { - return; - } - Long receiverSequence = sequenceGeneratorRedisDao.generateSequence(groupMemberDO.getUserId()); // 生成接收者序列 - Long receiverInboxId = createAndSaveInbox(groupMemberDO.getUserId(), imMessageDO.getId(), receiverSequence); // 创建并保存接收者收件箱 - sendMessage(groupMemberDO.getUserId(), receiverInboxId, imMessageDO, message, receiverSequence); - }); - - Long fromUserSequence = sequenceGeneratorRedisDao.generateSequence(fromUserId); // 生成发送者序列 - Long fromUserInboxId = createAndSaveInbox(fromUserId, imMessageDO.getId(), fromUserSequence); // 创建并保存发送者收件箱 - - // 发送消息给发送者 - sendMessage(fromUserId, fromUserInboxId, imMessageDO, message, fromUserSequence); - - // 更新消息状态为成功 - imMessageService.updateMessageStatus(imMessageDO.getId(), ImMessageStatusEnum.SUCCESS.getStatus()); - } - - /** - * 处理私人消息 - * - * @param fromUserId 发送者用户ID - * @param message 发送的IM消息 - */ - private void handlePrivateMessage(Long fromUserId, ImSendMessage message) { - // TODO @hao:需要校验 receiverId 存在; - ImMessageDO imMessageDO = imMessageService.savePrivateMessage(message, fromUserId); // 保存私人消息 - Long receiverId = message.getReceiverId(); - - // TODO @hao:sequenceGeneratorRedisDao.generateSequence 和 createAndSaveInbox 步骤,要加锁;不然会有并发问题;如果有疑问,可以微信招我沟通哈;另外,创建 seq、保存收件箱、发送,可以统一封装到 imInboxService 里哈;这样,后续要发某个消息,就是丢个 message 对象进去; - Long fromUserSequence = sequenceGeneratorRedisDao.generateSequence(fromUserId); // 生成发送者序列 - Long fromUserInboxId = createAndSaveInbox(fromUserId, imMessageDO.getId(), fromUserSequence); // 创建并保存发送者收件箱 - - Long receiverSequence = sequenceGeneratorRedisDao.generateSequence(message.getReceiverId()); // 生成接收者序列 - Long receiverInboxId = createAndSaveInbox(message.getReceiverId(), imMessageDO.getId(), receiverSequence); // 创建并保存接收者收件箱 - - // 发送消息给接收者和发送者 - sendMessage(fromUserId, fromUserInboxId, imMessageDO, message, fromUserSequence); - sendMessage(receiverId, receiverInboxId, imMessageDO, message, receiverSequence); - - // 更新消息状态为成功 - // TODO @hao:后端消息的发送,默认就是 success 哈,不要区分 status;status 更多是前端使用的; - imMessageService.updateMessageStatus(imMessageDO.getId(), ImMessageStatusEnum.SUCCESS.getStatus()); - // 保存私人会话,只有在 client 操作会话(已读、置顶)时,才会延迟创建 - //imConversationService.savePrivateConversation(fromUserId, receiverId); - } - - /** - * 创建并保存收件箱 - * - * @param userId 用户ID - * @param messageId 消息ID - * @param sequence 序列 - * @return 收件箱ID - */ - private Long createAndSaveInbox(Long userId, Long messageId, Long sequence) { - ImInboxSaveReqVO inboxSaveReqVO = new ImInboxSaveReqVO(userId, messageId, sequence); // 创建收件箱保存请求VO - return imInboxService.createInbox(inboxSaveReqVO); // 创建收件箱 - } - - // TODO @hao:这个使用 WebSocketSenderApi 发送哈; - /** - * 发送消息 - * - * @param fromUserId 发送者用户ID - * @param inboxId 收件箱ID - * @param imMessageDO IM消息数据对象 - * @param message 发送的IM消息 - * @param sequence 序列 - */ - private void sendMessage(Long fromUserId, Long inboxId, ImMessageDO imMessageDO, ImSendMessage message, Long sequence) { - // TODO @hao:不要每个字段 set 占一行;想同类型的字段用一行,然后链式 set,会更简洁干净。 - ImReceiveMessage receiveMessage = new ImReceiveMessage(); // 创建接收消息 - receiveMessage.setFromId(fromUserId); // 设置发送者ID - receiveMessage.setConversationType(message.getConversationType()); // 设置会话类型 - receiveMessage.setContentType(message.getContentType()); // 设置内容类型 - receiveMessage.setContent(message.getContent()); // 设置内容 - receiveMessage.setMessageId(imMessageDO.getId()); // 设置消息ID - receiveMessage.setInboxId(inboxId); // 设置收件箱ID - receiveMessage.setSendTime(imMessageDO.getSendTime()); // 设置发送时间 - receiveMessage.setSequence(sequence); // 设置序列 - webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), fromUserId, ImWebSocketMessageListener.IM_MESSAGE_RECEIVE, receiveMessage); // 发送消息 - } - - /** - * 获取类型 - * - * @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 23a1ad6..0000000 --- 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 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") - private Integer conversationType; // 对应 ImConversationTypeEnum 枚举 - - @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; - - // TODO @hao:inboxId 不需要哈; - @Schema(description = "收件箱编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18389") - private Long inboxId; - - @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 440e308..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImSendMessage.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.im.websocket.message; - -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") - // TODO @hao:用下 InEnum 校验。这样可以少写 15 的注释哈;类似 contentType 也是; - private Integer conversationType; // 对应 ImConversationTypeEnum 枚举 - - @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long receiverId; // 根据 conversationType 区分 - - @Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer contentType; // 参见 ImMessageTypeEnum 枚举 - - @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED) - private String content; - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/conversation/ConversationMapper.xml b/yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/conversation/ConversationMapper.xml new file mode 100755 index 0000000..f6a9d5a --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/conversation/ConversationMapper.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/conversation/ImConversationMapper.xml b/yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/conversation/ImConversationMapper.xml deleted file mode 100755 index 37fd6fb..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/conversation/ImConversationMapper.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/message/ImMessageMapper.xml b/yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/message/ImMessageMapper.xml deleted file mode 100755 index 73bf7eb..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/message/ImMessageMapper.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/message/MessageMapper.xml b/yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/message/MessageMapper.xml new file mode 100755 index 0000000..46521ed --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/resources/mapper/message/MessageMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImplTest.java b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImplTest.java deleted file mode 100755 index 7b97605..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImplTest.java +++ /dev/null @@ -1,148 +0,0 @@ -package cn.iocoder.yudao.module.im.service.conversation; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import jakarta.annotation.Resource; - -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; - -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.*; -import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; -import cn.iocoder.yudao.module.im.dal.mysql.conversation.ImConversationMapper; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import org.springframework.context.annotation.Import; - -import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; -import static org.junit.jupiter.api.Assertions.*; - -// TODO @hao:单测可以先都删除,等后面搞了在弄 -/** - * {@link ImConversationServiceImpl} 的单元测试类 - * - * @author 芋道源码 - */ -@Import(ImConversationServiceImpl.class) -public class ImConversationServiceImplTest extends BaseDbUnitTest { - - @Resource - private ImConversationServiceImpl conversationService; - - @Resource - private ImConversationMapper imConversationMapper; - - @Test - public void testCreateConversation_success() { - // 准备参数 - ImConversationSaveReqVO createReqVO = randomPojo(ImConversationSaveReqVO.class).setId(null); - - // 调用 - Long conversationId = conversationService.createConversation(createReqVO); - // 断言 - assertNotNull(conversationId); - // 校验记录的属性是否正确 - ImConversationDO conversation = imConversationMapper.selectById(conversationId); - assertPojoEquals(createReqVO, conversation, "id"); - } - - @Test - public void testUpdateConversation_success() { - // mock 数据 - ImConversationDO dbConversation = randomPojo(ImConversationDO.class); - imConversationMapper.insert(dbConversation);// @Sql: 先插入出一条存在的数据 - // 准备参数 - ImConversationSaveReqVO updateReqVO = randomPojo(ImConversationSaveReqVO.class, o -> { - o.setId(dbConversation.getId()); // 设置更新的 ID - }); - - // 调用 - conversationService.updateConversation(updateReqVO); - // 校验是否更新正确 - ImConversationDO conversation = imConversationMapper.selectById(updateReqVO.getId()); // 获取最新的 - assertPojoEquals(updateReqVO, conversation); - } - - @Test - public void testUpdateConversation_notExists() { - // 准备参数 - ImConversationSaveReqVO updateReqVO = randomPojo(ImConversationSaveReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> conversationService.updateConversation(updateReqVO), CONVERSATION_NOT_EXISTS); - } - - @Test - public void testDeleteConversation_success() { - // mock 数据 - ImConversationDO dbConversation = randomPojo(ImConversationDO.class); - imConversationMapper.insert(dbConversation);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbConversation.getId(); - - // 调用 - conversationService.deleteConversation(id); - // 校验数据不存在了 - assertNull(imConversationMapper.selectById(id)); - } - - @Test - public void testDeleteConversation_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> conversationService.deleteConversation(id), CONVERSATION_NOT_EXISTS); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetConversationPage() { - // mock 数据 - ImConversationDO dbConversation = randomPojo(ImConversationDO.class, o -> { // 等会查询到 - o.setUserId(null); - o.setConversationType(null); - o.setTargetId(null); - o.setNo(null); - o.setPinned(null); - o.setLastReadTime(null); - o.setCreateTime(null); - }); - imConversationMapper.insert(dbConversation); - // 测试 userId 不匹配 - imConversationMapper.insert(cloneIgnoreId(dbConversation, o -> o.setUserId(null))); - // 测试 conversationType 不匹配 - imConversationMapper.insert(cloneIgnoreId(dbConversation, o -> o.setConversationType(null))); - // 测试 targetId 不匹配 - imConversationMapper.insert(cloneIgnoreId(dbConversation, o -> o.setTargetId(null))); - // 测试 no 不匹配 - imConversationMapper.insert(cloneIgnoreId(dbConversation, o -> o.setNo(null))); - // 测试 pinned 不匹配 - imConversationMapper.insert(cloneIgnoreId(dbConversation, o -> o.setPinned(null))); - // 测试 lastReadTime 不匹配 - imConversationMapper.insert(cloneIgnoreId(dbConversation, o -> o.setLastReadTime(null))); - // 测试 createTime 不匹配 - imConversationMapper.insert(cloneIgnoreId(dbConversation, o -> o.setCreateTime(null))); - // 准备参数 - ImConversationPageReqVO reqVO = new ImConversationPageReqVO(); - reqVO.setUserId(null); - reqVO.setConversationType(null); - reqVO.setTargetId(null); - reqVO.setNo(null); - reqVO.setPinned(null); - reqVO.setLastReadTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); - reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); - - // 调用 - PageResult pageResult = conversationService.getConversationPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbConversation, pageResult.getList().get(0)); - } - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImplTest.java b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImplTest.java deleted file mode 100644 index 4876a52..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImplTest.java +++ /dev/null @@ -1,147 +0,0 @@ -package cn.iocoder.yudao.module.im.service.group; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import jakarta.annotation.Resource; - -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; - -import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; -import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; -import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMapper; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import org.springframework.context.annotation.Import; - -import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; -import static org.junit.jupiter.api.Assertions.*; - -/** - * {@link ImGroupServiceImpl} 的单元测试类 - * - * @author 芋道源码 - */ -@Import(ImGroupServiceImpl.class) -public class ImGroupServiceImplTest extends BaseDbUnitTest { - - @Resource - private ImGroupServiceImpl groupService; - - @Resource - private ImGroupMapper imGroupMapper; - - @Test - public void testCreateGroup_success() { - // 准备参数 - ImGroupSaveReqVO createReqVO = randomPojo(ImGroupSaveReqVO.class).setId(null); - - // 调用 - Long groupId = groupService.createGroup(createReqVO); - // 断言 - assertNotNull(groupId); - // 校验记录的属性是否正确 - ImGroupDO group = imGroupMapper.selectById(groupId); - assertPojoEquals(createReqVO, group, "id"); - } - - @Test - public void testUpdateGroup_success() { - // mock 数据 - ImGroupDO dbGroup = randomPojo(ImGroupDO.class); - imGroupMapper.insert(dbGroup);// @Sql: 先插入出一条存在的数据 - // 准备参数 - ImGroupSaveReqVO updateReqVO = randomPojo(ImGroupSaveReqVO.class, o -> { - o.setId(dbGroup.getId()); // 设置更新的 ID - }); - - // 调用 - groupService.updateGroup(updateReqVO); - // 校验是否更新正确 - ImGroupDO group = imGroupMapper.selectById(updateReqVO.getId()); // 获取最新的 - assertPojoEquals(updateReqVO, group); - } - - @Test - public void testUpdateGroup_notExists() { - // 准备参数 - ImGroupSaveReqVO updateReqVO = randomPojo(ImGroupSaveReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> groupService.updateGroup(updateReqVO), GROUP_NOT_EXISTS); - } - - @Test - public void testDeleteGroup_success() { - // mock 数据 - ImGroupDO dbGroup = randomPojo(ImGroupDO.class); - imGroupMapper.insert(dbGroup);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbGroup.getId(); - - // 调用 - groupService.deleteGroup(id); - // 校验数据不存在了 - assertNull(imGroupMapper.selectById(id)); - } - - @Test - public void testDeleteGroup_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> groupService.deleteGroup(id), GROUP_NOT_EXISTS); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetGroupPage() { - // mock 数据 - ImGroupDO dbGroup = randomPojo(ImGroupDO.class, o -> { // 等会查询到 - o.setGroupName(null); - o.setOwnerId(null); - o.setHeadImage(null); - o.setHeadImageThumb(null); - o.setNotice(null); - o.setRemark(null); - o.setCreateTime(null); - }); - imGroupMapper.insert(dbGroup); - // 测试 groupName 不匹配 - imGroupMapper.insert(cloneIgnoreId(dbGroup, o -> o.setGroupName(null))); - // 测试 ownerId 不匹配 - imGroupMapper.insert(cloneIgnoreId(dbGroup, o -> o.setOwnerId(null))); - // 测试 headImage 不匹配 - imGroupMapper.insert(cloneIgnoreId(dbGroup, o -> o.setHeadImage(null))); - // 测试 headImageThumb 不匹配 - imGroupMapper.insert(cloneIgnoreId(dbGroup, o -> o.setHeadImageThumb(null))); - // 测试 notice 不匹配 - imGroupMapper.insert(cloneIgnoreId(dbGroup, o -> o.setNotice(null))); - // 测试 remark 不匹配 - imGroupMapper.insert(cloneIgnoreId(dbGroup, o -> o.setRemark(null))); - // 测试 createTime 不匹配 - imGroupMapper.insert(cloneIgnoreId(dbGroup, o -> o.setCreateTime(null))); - // 准备参数 - ImGroupPageReqVO reqVO = new ImGroupPageReqVO(); - reqVO.setGroupName(null); - reqVO.setOwnerId(null); - reqVO.setHeadImage(null); - reqVO.setHeadImageThumb(null); - reqVO.setNotice(null); - reqVO.setRemark(null); - reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); - - // 调用 - PageResult pageResult = groupService.getGroupPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbGroup, pageResult.getList().get(0)); - } - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberServiceImplTest.java b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberServiceImplTest.java deleted file mode 100644 index 394807c..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberServiceImplTest.java +++ /dev/null @@ -1,147 +0,0 @@ -package cn.iocoder.yudao.module.im.service.groupmember; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import jakarta.annotation.Resource; - -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; - -import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.*; -import cn.iocoder.yudao.module.im.dal.dataobject.groupmember.GroupMemberDO; -import cn.iocoder.yudao.module.im.dal.mysql.groupmember.ImGroupMemberMapper; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import org.springframework.context.annotation.Import; - -import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; -import static org.junit.jupiter.api.Assertions.*; - -/** - * {@link ImGroupMemberServiceImpl} 的单元测试类 - * - * @author 芋道源码 - */ -@Import(ImGroupMemberServiceImpl.class) -public class ImGroupMemberServiceImplTest extends BaseDbUnitTest { - - @Resource - private ImGroupMemberServiceImpl groupMemberService; - - @Resource - private ImGroupMemberMapper imGroupMemberMapper; - - @Test - public void testCreateGroupMember_success() { - // 准备参数 - ImGroupMemberSaveReqVO createReqVO = randomPojo(ImGroupMemberSaveReqVO.class).setId(null); - - // 调用 - Long groupMemberId = groupMemberService.createGroupMember(createReqVO); - // 断言 - assertNotNull(groupMemberId); - // 校验记录的属性是否正确 - GroupMemberDO groupMember = imGroupMemberMapper.selectById(groupMemberId); - assertPojoEquals(createReqVO, groupMember, "id"); - } - - @Test - public void testUpdateGroupMember_success() { - // mock 数据 - GroupMemberDO dbGroupMember = randomPojo(GroupMemberDO.class); - imGroupMemberMapper.insert(dbGroupMember);// @Sql: 先插入出一条存在的数据 - // 准备参数 - ImGroupMemberSaveReqVO updateReqVO = randomPojo(ImGroupMemberSaveReqVO.class, o -> { - o.setId(dbGroupMember.getId()); // 设置更新的 ID - }); - - // 调用 - groupMemberService.updateGroupMember(updateReqVO); - // 校验是否更新正确 - GroupMemberDO groupMember = imGroupMemberMapper.selectById(updateReqVO.getId()); // 获取最新的 - assertPojoEquals(updateReqVO, groupMember); - } - - @Test - public void testUpdateGroupMember_notExists() { - // 准备参数 - ImGroupMemberSaveReqVO updateReqVO = randomPojo(ImGroupMemberSaveReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> groupMemberService.updateGroupMember(updateReqVO), GROUP_MEMBER_NOT_EXISTS); - } - - @Test - public void testDeleteGroupMember_success() { - // mock 数据 - GroupMemberDO dbGroupMember = randomPojo(GroupMemberDO.class); - imGroupMemberMapper.insert(dbGroupMember);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbGroupMember.getId(); - - // 调用 - groupMemberService.deleteGroupMember(id); - // 校验数据不存在了 - assertNull(imGroupMemberMapper.selectById(id)); - } - - @Test - public void testDeleteGroupMember_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> groupMemberService.deleteGroupMember(id), GROUP_MEMBER_NOT_EXISTS); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetGroupMemberPage() { - // mock 数据 - GroupMemberDO dbGroupMember = randomPojo(GroupMemberDO.class, o -> { // 等会查询到 - o.setGroupId(null); - o.setUserId(null); - o.setNickname(null); - o.setAvatar(null); - o.setAliasName(null); - o.setRemark(null); - o.setCreateTime(null); - }); - imGroupMemberMapper.insert(dbGroupMember); - // 测试 groupId 不匹配 - imGroupMemberMapper.insert(cloneIgnoreId(dbGroupMember, o -> o.setGroupId(null))); - // 测试 userId 不匹配 - imGroupMemberMapper.insert(cloneIgnoreId(dbGroupMember, o -> o.setUserId(null))); - // 测试 nickname 不匹配 - imGroupMemberMapper.insert(cloneIgnoreId(dbGroupMember, o -> o.setNickname(null))); - // 测试 avatar 不匹配 - imGroupMemberMapper.insert(cloneIgnoreId(dbGroupMember, o -> o.setAvatar(null))); - // 测试 aliasName 不匹配 - imGroupMemberMapper.insert(cloneIgnoreId(dbGroupMember, o -> o.setAliasName(null))); - // 测试 remark 不匹配 - imGroupMemberMapper.insert(cloneIgnoreId(dbGroupMember, o -> o.setRemark(null))); - // 测试 createTime 不匹配 - imGroupMemberMapper.insert(cloneIgnoreId(dbGroupMember, o -> o.setCreateTime(null))); - // 准备参数 - ImGroupMemberPageReqVO reqVO = new ImGroupMemberPageReqVO(); - reqVO.setGroupId(null); - reqVO.setUserId(null); - reqVO.setNickname(null); - reqVO.setAvatar(null); - reqVO.setAliasName(null); - reqVO.setRemark(null); - reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); - - // 调用 - PageResult pageResult = groupMemberService.getGroupMemberPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbGroupMember, pageResult.getList().get(0)); - } - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxServiceImplTest.java b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxServiceImplTest.java deleted file mode 100755 index 8224429..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxServiceImplTest.java +++ /dev/null @@ -1,135 +0,0 @@ -package cn.iocoder.yudao.module.im.service.inbox; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import jakarta.annotation.Resource; - -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; - -import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.*; -import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO; -import cn.iocoder.yudao.module.im.dal.mysql.inbox.ImInboxMapper; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import org.springframework.context.annotation.Import; - -import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; -import static org.junit.jupiter.api.Assertions.*; - -/** - * {@link ImInboxServiceImpl} 的单元测试类 - * - * @author 芋道源码 - */ -@Import(ImInboxServiceImpl.class) -public class ImInboxServiceImplTest extends BaseDbUnitTest { - - @Resource - private ImInboxServiceImpl inboxService; - - @Resource - private ImInboxMapper imInboxMapper; - - @Test - public void testCreateInbox_success() { - // 准备参数 - ImInboxSaveReqVO createReqVO = randomPojo(ImInboxSaveReqVO.class).setId(null); - - // 调用 - Long inboxId = inboxService.createInbox(createReqVO); - // 断言 - assertNotNull(inboxId); - // 校验记录的属性是否正确 - ImInboxDO inbox = imInboxMapper.selectById(inboxId); - assertPojoEquals(createReqVO, inbox, "id"); - } - - @Test - public void testUpdateInbox_success() { - // mock 数据 - ImInboxDO dbInbox = randomPojo(ImInboxDO.class); - imInboxMapper.insert(dbInbox);// @Sql: 先插入出一条存在的数据 - // 准备参数 - ImInboxSaveReqVO updateReqVO = randomPojo(ImInboxSaveReqVO.class, o -> { - o.setId(dbInbox.getId()); // 设置更新的 ID - }); - - // 调用 - inboxService.updateInbox(updateReqVO); - // 校验是否更新正确 - ImInboxDO inbox = imInboxMapper.selectById(updateReqVO.getId()); // 获取最新的 - assertPojoEquals(updateReqVO, inbox); - } - - @Test - public void testUpdateInbox_notExists() { - // 准备参数 - ImInboxSaveReqVO updateReqVO = randomPojo(ImInboxSaveReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> inboxService.updateInbox(updateReqVO), INBOX_NOT_EXISTS); - } - - @Test - public void testDeleteInbox_success() { - // mock 数据 - ImInboxDO dbInbox = randomPojo(ImInboxDO.class); - imInboxMapper.insert(dbInbox);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbInbox.getId(); - - // 调用 - inboxService.deleteInbox(id); - // 校验数据不存在了 - assertNull(imInboxMapper.selectById(id)); - } - - @Test - public void testDeleteInbox_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> inboxService.deleteInbox(id), INBOX_NOT_EXISTS); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetInboxPage() { - // mock 数据 - ImInboxDO dbInbox = randomPojo(ImInboxDO.class, o -> { // 等会查询到 - o.setUserId(null); - o.setMessageId(null); - o.setSequence(null); - o.setCreateTime(null); - }); - imInboxMapper.insert(dbInbox); - // 测试 userId 不匹配 - imInboxMapper.insert(cloneIgnoreId(dbInbox, o -> o.setUserId(null))); - // 测试 messageId 不匹配 - imInboxMapper.insert(cloneIgnoreId(dbInbox, o -> o.setMessageId(null))); - // 测试 sequence 不匹配 - imInboxMapper.insert(cloneIgnoreId(dbInbox, o -> o.setSequence(null))); - // 测试 createTime 不匹配 - imInboxMapper.insert(cloneIgnoreId(dbInbox, o -> o.setCreateTime(null))); - // 准备参数 - ImInboxPageReqVO reqVO = new ImInboxPageReqVO(); - reqVO.setUserId(null); - reqVO.setMessageId(null); - reqVO.setSequence(null); - reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); - - // 调用 - PageResult pageResult = inboxService.getInboxPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbInbox, pageResult.getList().get(0)); - } - -} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImplTest.java b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImplTest.java deleted file mode 100755 index cfd13e5..0000000 --- a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImplTest.java +++ /dev/null @@ -1,167 +0,0 @@ -package cn.iocoder.yudao.module.im.service.message; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import jakarta.annotation.Resource; - -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; - -import cn.iocoder.yudao.module.im.controller.admin.message.vo.*; -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; -import cn.iocoder.yudao.module.im.dal.mysql.message.ImMessageMapper; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import org.springframework.context.annotation.Import; - -import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; -import static org.junit.jupiter.api.Assertions.*; - -/** - * {@link ImMessageServiceImpl} 的单元测试类 - * - * @author 芋道源码 - */ -@Import(ImMessageServiceImpl.class) -public class ImMessageServiceImplTest extends BaseDbUnitTest { - - @Resource - private ImMessageServiceImpl messageService; - - @Resource - private ImMessageMapper imMessageMapper; - - @Test - public void testCreateMessage_success() { - // 准备参数 - ImMessageSaveReqVO createReqVO = randomPojo(ImMessageSaveReqVO.class).setId(null); - - // 调用 - Long messageId = messageService.createMessage(createReqVO); - // 断言 - assertNotNull(messageId); - // 校验记录的属性是否正确 - ImMessageDO message = imMessageMapper.selectById(messageId); - assertPojoEquals(createReqVO, message, "id"); - } - - @Test - public void testUpdateMessage_success() { - // mock 数据 - ImMessageDO dbMessage = randomPojo(ImMessageDO.class); - imMessageMapper.insert(dbMessage);// @Sql: 先插入出一条存在的数据 - // 准备参数 - ImMessageSaveReqVO updateReqVO = randomPojo(ImMessageSaveReqVO.class, o -> { - o.setId(dbMessage.getId()); // 设置更新的 ID - }); - - // 调用 - messageService.updateMessage(updateReqVO); - // 校验是否更新正确 - ImMessageDO message = imMessageMapper.selectById(updateReqVO.getId()); // 获取最新的 - assertPojoEquals(updateReqVO, message); - } - - @Test - public void testUpdateMessage_notExists() { - // 准备参数 - ImMessageSaveReqVO updateReqVO = randomPojo(ImMessageSaveReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> messageService.updateMessage(updateReqVO), MESSAGE_NOT_EXISTS); - } - - @Test - public void testDeleteMessage_success() { - // mock 数据 - ImMessageDO dbMessage = randomPojo(ImMessageDO.class); - imMessageMapper.insert(dbMessage);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbMessage.getId(); - - // 调用 - messageService.deleteMessage(id); - // 校验数据不存在了 - assertNull(imMessageMapper.selectById(id)); - } - - @Test - public void testDeleteMessage_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> messageService.deleteMessage(id), MESSAGE_NOT_EXISTS); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetMessagePage() { - // mock 数据 - ImMessageDO dbMessage = randomPojo(ImMessageDO.class, o -> { // 等会查询到 - o.setClientMessageId(null); - o.setSenderId(null); - o.setReceiverId(null); - o.setSenderNickname(null); - o.setSenderAvatar(null); - o.setConversationType(null); - o.setConversationNo(null); - o.setContentType(null); - o.setContent(null); - o.setSendTime(null); - o.setSendFrom(null); - o.setCreateTime(null); - }); - imMessageMapper.insert(dbMessage); - // 测试 clientMessageId 不匹配 - imMessageMapper.insert(cloneIgnoreId(dbMessage, o -> o.setClientMessageId(null))); - // 测试 senderId 不匹配 - imMessageMapper.insert(cloneIgnoreId(dbMessage, o -> o.setSenderId(null))); - // 测试 receiverId 不匹配 - imMessageMapper.insert(cloneIgnoreId(dbMessage, o -> o.setReceiverId(null))); - // 测试 senderNickname 不匹配 - imMessageMapper.insert(cloneIgnoreId(dbMessage, o -> o.setSenderNickname(null))); - // 测试 senderAvatar 不匹配 - imMessageMapper.insert(cloneIgnoreId(dbMessage, o -> o.setSenderAvatar(null))); - // 测试 conversationType 不匹配 - imMessageMapper.insert(cloneIgnoreId(dbMessage, o -> o.setConversationType(null))); - // 测试 conversationNo 不匹配 - imMessageMapper.insert(cloneIgnoreId(dbMessage, o -> o.setConversationNo(null))); - // 测试 contentType 不匹配 - imMessageMapper.insert(cloneIgnoreId(dbMessage, o -> o.setContentType(null))); - // 测试 content 不匹配 - imMessageMapper.insert(cloneIgnoreId(dbMessage, o -> o.setContent(null))); - // 测试 sendTime 不匹配 - imMessageMapper.insert(cloneIgnoreId(dbMessage, o -> o.setSendTime(null))); - // 测试 sendFrom 不匹配 - imMessageMapper.insert(cloneIgnoreId(dbMessage, o -> o.setSendFrom(null))); - // 测试 createTime 不匹配 - imMessageMapper.insert(cloneIgnoreId(dbMessage, o -> o.setCreateTime(null))); - // 准备参数 - ImMessagePageReqVO reqVO = new ImMessagePageReqVO(); - reqVO.setClientMessageId(null); - reqVO.setSenderId(null); - reqVO.setReceiverId(null); - reqVO.setSenderNickname(null); - reqVO.setSenderAvatar(null); - reqVO.setConversationType(null); - reqVO.setConversationNo(null); - reqVO.setContentType(null); - reqVO.setContent(null); - reqVO.setSendTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); - reqVO.setSendFrom(null); - reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); - - // 调用 - PageResult pageResult = messageService.getMessagePage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbMessage, pageResult.getList().get(0)); - } - -} \ No newline at end of file -- libgit2 0.21.4