From f495f9c8054e78df95498b42f1eb7cba47b5434b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 20 Apr 2026 14:04:30 +0800 Subject: [PATCH] ✨ feat(im): 添加私聊私聊历史消息查询功能 --- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImPrivateMessageController.java | 14 +++++++++++--- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapper.java | 46 +++++++++++++++++++++++++++++++++++----------- yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageService.java | 10 ++++++++++ yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImpl.java | 6 ++++++ yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapperTest.java | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImplTest.java | 34 ++++++++++++++++++++++------------ yudao-module-im/yudao-module-im-biz/src/test/resources/application-unit-test.yaml | 37 +++++++++++++++++++++++++++++++++++++ yudao-module-im/yudao-module-im-biz/src/test/resources/sql/clean.sql | 1 + yudao-module-im/yudao-module-im-biz/src/test/resources/sql/create_tables.sql | 17 +++++++++++++++++ 9 files changed, 338 insertions(+), 26 deletions(-) create mode 100644 yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapperTest.java create mode 100644 yudao-module-im/yudao-module-im-biz/src/test/resources/application-unit-test.yaml create mode 100644 yudao-module-im/yudao-module-im-biz/src/test/resources/sql/clean.sql create mode 100644 yudao-module-im/yudao-module-im-biz/src/test/resources/sql/create_tables.sql diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImPrivateMessageController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImPrivateMessageController.java index 2392d54..9937e8f 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImPrivateMessageController.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImPrivateMessageController.java @@ -2,6 +2,7 @@ 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.privates.ImPrivateMessageListReqVO; import cn.iocoder.yudao.module.im.controller.admin.message.vo.privates.ImPrivateMessageRespVO; import cn.iocoder.yudao.module.im.controller.admin.message.vo.privates.ImPrivateMessageSendReqVO; import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO; @@ -60,9 +61,16 @@ public class ImPrivateMessageController { @DeleteMapping("/recall") @Operation(summary = "撤回私聊消息") @Parameter(name = "id", description = "消息编号", required = true, example = "1") - public CommonResult recallPrivateMessage(@RequestParam("id") Long id) { - privateMessageService.recallPrivateMessage(getLoginUserId(), id); - return success(true); + public CommonResult recallPrivateMessage(@RequestParam("id") Long id) { + ImPrivateMessageDO message = privateMessageService.recallPrivateMessage(getLoginUserId(), id); + return success(BeanUtils.toBean(message, ImPrivateMessageRespVO.class)); + } + + @GetMapping("/list") + @Operation(summary = "查询私聊历史消息") + public CommonResult> getPrivateMessageList(@Valid ImPrivateMessageListReqVO reqVO) { + List messages = privateMessageService.getPrivateMessageList(getLoginUserId(), reqVO); + return success(BeanUtils.toBean(messages, ImPrivateMessageRespVO.class)); } } diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapper.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapper.java index 4628d83..956da09 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapper.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapper.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO; +import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; import org.apache.ibatis.annotations.Mapper; import java.util.List; @@ -27,29 +28,52 @@ public interface ImPrivateMessageMapper extends BaseMapperX default List selectListByMinId(Long userId, Long minId, Integer size) { QueryWrapperX wrapper = new QueryWrapperX<>(); wrapper.and(w -> w.eq("sender_id", userId) - .or().eq("receiver_id", userId)) + .or() + .eq("receiver_id", userId)) .gt("id", minId) .orderByAsc("id"); wrapper.limitN(size); return selectList(wrapper); } + /** + * 查询私聊历史消息(游标拉取) + * + * @param userId 当前用户编号 + * @param receiverId 对方用户编号 + * @param maxId 起始消息 id(不含),为空则从最新开始 + * @param limit 拉取数量 + * @return 消息列表(按 id 倒序) + */ + default List selectHistoryList(Long userId, Long receiverId, Long maxId, Integer limit) { + QueryWrapperX wrapper = new QueryWrapperX<>(); + wrapper.and(w -> w.eq("sender_id", userId).eq("receiver_id", receiverId) + .or() + .eq("sender_id", receiverId).eq("receiver_id", userId)) + .ne("status", ImMessageStatusEnum.RECALL.getStatus()) + .lt(maxId != null, "id", maxId) + .orderByDesc("id"); + wrapper.limitN(limit); + return selectList(wrapper); + } + default ImPrivateMessageDO selectBySenderIdAndClientMessageId(Long senderId, String clientMessageId) { return selectOne(new LambdaQueryWrapperX() .eq(ImPrivateMessageDO::getSenderId, senderId) .eq(ImPrivateMessageDO::getClientMessageId, clientMessageId)); } - /** - * 批量更新私聊消息已读状态 - * 将发送方 = friendId、接收方 = userId 且状态为 UNREAD 的消息更新为 READ - */ - default int updateStatusToRead(Long userId, Long friendId) { - return update(new ImPrivateMessageDO().setStatus(1), // READ - new LambdaQueryWrapperX() - .eq(ImPrivateMessageDO::getSenderId, friendId) - .eq(ImPrivateMessageDO::getReceiverId, userId) - .eq(ImPrivateMessageDO::getStatus, 0)); // UNREAD + default List selectListBySenderIdAndReceiverIdAndStatus(Long senderId, Long receiverId, Integer status) { + return selectList(new LambdaQueryWrapperX() + .eq(ImPrivateMessageDO::getSenderId, senderId) + .eq(ImPrivateMessageDO::getReceiverId, receiverId) + .eq(ImPrivateMessageDO::getStatus, status)); + } + + default void updateByIdsAndStatus(List ids, Integer whereStatus, ImPrivateMessageDO updateObj) { + update(updateObj, new LambdaQueryWrapperX() + .in(ImPrivateMessageDO::getId, ids) + .eq(ImPrivateMessageDO::getStatus, whereStatus)); } } diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageService.java index 5e3ece9..d8d2d3e 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageService.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageService.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.im.service.message; +import cn.iocoder.yudao.module.im.controller.admin.message.vo.privates.ImPrivateMessageListReqVO; import cn.iocoder.yudao.module.im.controller.admin.message.vo.privates.ImPrivateMessageSendReqVO; import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO; @@ -48,4 +49,13 @@ public interface ImPrivateMessageService { */ ImPrivateMessageDO recallPrivateMessage(Long userId, Long messageId); + /** + * 查询私聊历史消息(游标拉取) + * + * @param userId 当前用户编号 + * @param reqVO 拉取请求 + * @return 消息列表(按 id 倒序) + */ + List getPrivateMessageList(Long userId, ImPrivateMessageListReqVO reqVO); + } diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImpl.java index de9c2b6..78b9623 100644 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImpl.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImpl.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 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.message.vo.privates.ImPrivateMessageListReqVO; import cn.iocoder.yudao.module.im.controller.admin.message.vo.privates.ImPrivateMessageSendReqVO; import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO; import cn.iocoder.yudao.module.im.dal.dataobject.message.content.RecallMessage; @@ -189,4 +190,9 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { return SpringUtil.getBean(getClass()); } + @Override + public List getPrivateMessageList(Long userId, ImPrivateMessageListReqVO reqVO) { + return privateMessageMapper.selectHistoryList(userId, reqVO.getReceiverId(), reqVO.getMaxId(), reqVO.getLimit()); + } + } diff --git a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapperTest.java b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapperTest.java new file mode 100644 index 0000000..ce1bbac --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapperTest.java @@ -0,0 +1,199 @@ +package cn.iocoder.yudao.module.im.dal.mysql.message; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO; +import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; +import jakarta.annotation.Resource; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import java.time.LocalDateTime; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * IM 私聊消息 Mapper 单元测试 + * + * @author 芋道源码 + */ +@Import(ImPrivateMessageMapper.class) +public class ImPrivateMessageMapperTest extends BaseDbUnitTest { + + @Resource + private ImPrivateMessageMapper mapper; + + // ========== selectListByMinId ========== + + @Test + public void testSelectListByMinId() { + // 准备:用户 1 发给用户 2 + ImPrivateMessageDO msg1 = buildMessage(1L, 2L, ImMessageStatusEnum.UNREAD); + mapper.insert(msg1); + // 用户 2 发给用户 1 + ImPrivateMessageDO msg2 = buildMessage(2L, 1L, ImMessageStatusEnum.UNREAD); + mapper.insert(msg2); + // 用户 3 发给用户 4(不相关) + ImPrivateMessageDO msg3 = buildMessage(3L, 4L, ImMessageStatusEnum.UNREAD); + mapper.insert(msg3); + + // 调用:用户 1 从 id=0 拉取 + List result = mapper.selectListByMinId(1L, 0L, 100); + + // 断言:只包含与用户 1 相关的 2 条 + assertEquals(2, result.size()); + assertTrue(result.stream().allMatch(m -> + m.getSenderId().equals(1L) || m.getReceiverId().equals(1L))); + } + + @Test + public void testSelectListByMinId_withMinId() { + // 准备 + ImPrivateMessageDO msg1 = buildMessage(1L, 2L, ImMessageStatusEnum.UNREAD); + mapper.insert(msg1); + ImPrivateMessageDO msg2 = buildMessage(2L, 1L, ImMessageStatusEnum.UNREAD); + mapper.insert(msg2); + + // 调用:从 msg1.id 之后拉取 + List result = mapper.selectListByMinId(1L, msg1.getId(), 100); + + // 断言:只有 msg2 + assertEquals(1, result.size()); + assertEquals(msg2.getId(), result.get(0).getId()); + } + + @Test + public void testSelectListByMinId_limitSize() { + // 准备:插入 3 条 + mapper.insert(buildMessage(1L, 2L, ImMessageStatusEnum.UNREAD)); + mapper.insert(buildMessage(2L, 1L, ImMessageStatusEnum.UNREAD)); + mapper.insert(buildMessage(1L, 2L, ImMessageStatusEnum.UNREAD)); + + // 调用:limit 2 + List result = mapper.selectListByMinId(1L, 0L, 2); + + // 断言 + assertEquals(2, result.size()); + } + + // ========== selectHistoryList ========== + + @Test + public void testSelectHistoryList_basic() { + // 准备:用户 1 <-> 用户 2 的消息 + ImPrivateMessageDO msg1 = buildMessage(1L, 2L, ImMessageStatusEnum.UNREAD); + mapper.insert(msg1); + ImPrivateMessageDO msg2 = buildMessage(2L, 1L, ImMessageStatusEnum.UNREAD); + mapper.insert(msg2); + // 用户 1 <-> 用户 3 的消息(不相关) + ImPrivateMessageDO msg3 = buildMessage(1L, 3L, ImMessageStatusEnum.UNREAD); + mapper.insert(msg3); + + // 调用 + List result = mapper.selectHistoryList(1L, 2L, null, 100); + + // 断言:只有与用户 2 对话的 2 条,按 id 倒序 + assertEquals(2, result.size()); + assertTrue(result.get(0).getId() > result.get(1).getId()); + } + + @Test + public void testSelectHistoryList_excludeRecall() { + // 准备 + ImPrivateMessageDO msg1 = buildMessage(1L, 2L, ImMessageStatusEnum.UNREAD); + mapper.insert(msg1); + ImPrivateMessageDO msg2 = buildMessage(1L, 2L, ImMessageStatusEnum.RECALL); + mapper.insert(msg2); + + // 调用 + List result = mapper.selectHistoryList(1L, 2L, null, 100); + + // 断言:撤回的不返回 + assertEquals(1, result.size()); + assertEquals(msg1.getId(), result.get(0).getId()); + } + + @Test + public void testSelectHistoryList_withMaxId() { + // 准备 + ImPrivateMessageDO msg1 = buildMessage(1L, 2L, ImMessageStatusEnum.UNREAD); + mapper.insert(msg1); + ImPrivateMessageDO msg2 = buildMessage(1L, 2L, ImMessageStatusEnum.UNREAD); + mapper.insert(msg2); + ImPrivateMessageDO msg3 = buildMessage(1L, 2L, ImMessageStatusEnum.UNREAD); + mapper.insert(msg3); + + // 调用:从 msg3 往前拉 + List result = mapper.selectHistoryList(1L, 2L, msg3.getId(), 100); + + // 断言:只有 msg1 和 msg2 + assertEquals(2, result.size()); + assertTrue(result.stream().allMatch(m -> m.getId() < msg3.getId())); + } + + @Test + public void testSelectHistoryList_limit() { + // 准备 + mapper.insert(buildMessage(1L, 2L, ImMessageStatusEnum.UNREAD)); + mapper.insert(buildMessage(2L, 1L, ImMessageStatusEnum.UNREAD)); + mapper.insert(buildMessage(1L, 2L, ImMessageStatusEnum.UNREAD)); + + // 调用:limit 2 + List result = mapper.selectHistoryList(1L, 2L, null, 2); + + // 断言 + assertEquals(2, result.size()); + } + + @Test + public void testSelectHistoryList_bidirectional() { + // 准备:验证双向查询 + ImPrivateMessageDO msg1 = buildMessage(2L, 1L, ImMessageStatusEnum.UNREAD); // 对方发的 + mapper.insert(msg1); + + // 调用:以用户 1 的视角查 + List result = mapper.selectHistoryList(1L, 2L, null, 100); + + // 断言:能查到对方发来的消息 + assertEquals(1, result.size()); + assertEquals(2L, result.get(0).getSenderId()); + } + + // ========== selectBySenderIdAndClientMessageId ========== + + @Test + public void testSelectBySenderIdAndClientMessageId() { + // 准备 + ImPrivateMessageDO msg = buildMessage(1L, 2L, ImMessageStatusEnum.UNREAD); + msg.setClientMessageId("uuid-001"); + mapper.insert(msg); + + // 调用 + ImPrivateMessageDO result = mapper.selectBySenderIdAndClientMessageId(1L, "uuid-001"); + + // 断言 + assertNotNull(result); + assertEquals(msg.getId(), result.getId()); + } + + @Test + public void testSelectBySenderIdAndClientMessageId_notFound() { + ImPrivateMessageDO result = mapper.selectBySenderIdAndClientMessageId(1L, "not-exist"); + assertNull(result); + } + + // ========== 工具方法 ========== + + private ImPrivateMessageDO buildMessage(Long senderId, Long receiverId, ImMessageStatusEnum status) { + return ImPrivateMessageDO.builder() + .clientMessageId("uuid-" + System.nanoTime()) + .senderId(senderId) + .receiverId(receiverId) + .type(0) + .content("{\"content\":\"test\"}") + .status(status.getStatus()) + .sendTime(LocalDateTime.now()) + .build(); + } + +} diff --git a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImplTest.java b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImplTest.java index 4de2112..3d41ad2 100644 --- a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImplTest.java +++ b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImplTest.java @@ -177,20 +177,30 @@ public class ImPrivateMessageServiceImplTest { @Test public void testRecallMessage_success() { - // 准备 - ImPrivateMessageDO message = ImPrivateMessageDO.builder() - .id(10L).senderId(1L).receiverId(2L) - .status(ImMessageStatusEnum.UNREAD.getStatus()).build(); - when(imPrivateMessageMapper.selectById(10L)).thenReturn(message); - when(imPrivateMessageMapper.updateById(any(ImPrivateMessageDO.class))).thenReturn(1); + try (MockedStatic springUtilMockedStatic = mockStatic(SpringUtil.class)) { + springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImPrivateMessageServiceImpl.class))) + .thenReturn(privateMessageService); - // 调用 - privateMessageService.recallPrivateMessage(1L, 10L); + // 准备 + ImPrivateMessageDO message = ImPrivateMessageDO.builder() + .id(10L).senderId(1L).receiverId(2L) + .status(ImMessageStatusEnum.UNREAD.getStatus()) + .sendTime(LocalDateTime.now()).build(); // 刚发送,5 分钟内 + when(imPrivateMessageMapper.selectById(10L)).thenReturn(message); + when(imPrivateMessageMapper.updateById(any(ImPrivateMessageDO.class))).thenReturn(1); + when(imPrivateMessageMapper.insert(any(ImPrivateMessageDO.class))).thenReturn(1); - // 断言 - verify(imPrivateMessageMapper).updateById(any(ImPrivateMessageDO.class)); - // 验证推送了 RECALL 事件(给接收方和发送方) - verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), anyString(), any()); + // 调用 + ImPrivateMessageDO result = privateMessageService.recallPrivateMessage(1L, 10L); + + // 断言:返回 TIP_TEXT 消息 + assertNotNull(result); + // 验证:更新原消息状态 + 插入 tipMessage + verify(imPrivateMessageMapper).updateById(any(ImPrivateMessageDO.class)); + verify(imPrivateMessageMapper).insert(any(ImPrivateMessageDO.class)); + // 验证推送了消息(给接收方和发送方) + verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), anyString(), any()); + } } @Test diff --git a/yudao-module-im/yudao-module-im-biz/src/test/resources/application-unit-test.yaml b/yudao-module-im/yudao-module-im-biz/src/test/resources/application-unit-test.yaml new file mode 100644 index 0000000..4772788 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/test/resources/application-unit-test.yaml @@ -0,0 +1,37 @@ +spring: + main: + lazy-initialization: true + banner-mode: off + +--- #################### 数据库相关配置 #################### + +spring: + datasource: + name: ruoyi-vue-pro + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; + driver-class-name: org.h2.Driver + username: sa + password: + druid: + async-init: true + initial-size: 1 + sql: + init: + schema-locations: classpath:/sql/create_tables.sql + encoding: UTF-8 + + data: + redis: + host: 127.0.0.1 + port: 16379 + database: 0 + +mybatis-plus: + lazy-initialization: true + type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject + +--- #################### 芋道相关配置 #################### + +yudao: + info: + base-package: cn.iocoder.yudao diff --git a/yudao-module-im/yudao-module-im-biz/src/test/resources/sql/clean.sql b/yudao-module-im/yudao-module-im-biz/src/test/resources/sql/clean.sql new file mode 100644 index 0000000..cc76de2 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/test/resources/sql/clean.sql @@ -0,0 +1 @@ +DELETE FROM "im_private_message"; diff --git a/yudao-module-im/yudao-module-im-biz/src/test/resources/sql/create_tables.sql b/yudao-module-im/yudao-module-im-biz/src/test/resources/sql/create_tables.sql new file mode 100644 index 0000000..30e95e7 --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/test/resources/sql/create_tables.sql @@ -0,0 +1,17 @@ +CREATE TABLE IF NOT EXISTS "im_private_message" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '编号', + "client_message_id" varchar(64) DEFAULT NULL COMMENT '客户端消息编号', + "sender_id" bigint NOT NULL COMMENT '发送人编号', + "receiver_id" bigint NOT NULL COMMENT '接收人编号', + "type" tinyint NOT NULL COMMENT '消息类型', + "content" varchar(4096) DEFAULT NULL COMMENT '消息内容', + "status" tinyint NOT NULL COMMENT '消息状态', + "send_time" timestamp NOT NULL COMMENT '发送时间', + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT 0, + PRIMARY KEY ("id") +) COMMENT 'IM 私聊消息表'; -- libgit2 0.21.4