Commit 04123e5987b9f873301e48c1a9e649a3fb445b2e
1 parent
354fe6fc
新增:获取会话列表,获取消息列表
Showing
7 changed files
with
158 additions
and
127 deletions
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java
| 1 | 1 | package cn.iocoder.yudao.module.im.controller.admin.conversation; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | -import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 5 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | |
| 8 | -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | |
| 9 | -import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationPageReqVO; | |
| 10 | 5 | import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationRespVO; |
| 11 | 6 | import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationSaveReqVO; |
| 12 | 7 | import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; |
| 13 | 8 | import cn.iocoder.yudao.module.im.service.conversation.ImConversationService; |
| 14 | 9 | import io.swagger.v3.oas.annotations.Operation; |
| 15 | -import io.swagger.v3.oas.annotations.Parameter; | |
| 16 | 10 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 17 | 11 | import jakarta.annotation.Resource; |
| 18 | -import jakarta.servlet.http.HttpServletResponse; | |
| 19 | 12 | import jakarta.validation.Valid; |
| 20 | 13 | import org.springframework.security.access.prepost.PreAuthorize; |
| 21 | 14 | import org.springframework.validation.annotation.Validated; |
| 22 | 15 | import org.springframework.web.bind.annotation.*; |
| 23 | 16 | |
| 24 | -import java.io.IOException; | |
| 25 | 17 | import java.util.List; |
| 26 | 18 | |
| 27 | 19 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 28 | -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; | |
| 29 | 20 | |
| 30 | 21 | @Tag(name = "管理后台 - 会话") |
| 31 | 22 | @RestController |
| ... | ... | @@ -36,58 +27,30 @@ public class ImConversationController { |
| 36 | 27 | @Resource |
| 37 | 28 | private ImConversationService imConversationService; |
| 38 | 29 | |
| 39 | - @PostMapping("/create") | |
| 40 | - @Operation(summary = "创建会话") | |
| 41 | - @PreAuthorize("@ss.hasPermission('im:conversation:create')") | |
| 42 | - public CommonResult<Long> createConversation(@Valid @RequestBody ImConversationSaveReqVO createReqVO) { | |
| 43 | - return success(imConversationService.createConversation(createReqVO)); | |
| 30 | + @GetMapping("/get-conversation") | |
| 31 | + @Operation(summary = "获得用户的会话列表") | |
| 32 | + @PreAuthorize("hasAuthority('im:conversation:query')") | |
| 33 | + public CommonResult<List<ImConversationRespVO>> getConversationList() { | |
| 34 | + List<ImConversationDO> conversationList = imConversationService.getConversationList(); | |
| 35 | + return success(BeanUtils.toBean(conversationList, ImConversationRespVO.class)); | |
| 44 | 36 | } |
| 45 | 37 | |
| 46 | - @PutMapping("/update") | |
| 47 | - @Operation(summary = "更新会话") | |
| 48 | - @PreAuthorize("@ss.hasPermission('im:conversation:update')") | |
| 49 | - public CommonResult<Boolean> updateConversation(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) { | |
| 50 | - imConversationService.updateConversation(updateReqVO); | |
| 51 | - return success(true); | |
| 52 | - } | |
| 53 | 38 | |
| 54 | - @DeleteMapping("/delete") | |
| 55 | - @Operation(summary = "删除会话") | |
| 56 | - @Parameter(name = "id", description = "编号", required = true) | |
| 57 | - @PreAuthorize("@ss.hasPermission('im:conversation:delete')") | |
| 58 | - public CommonResult<Boolean> deleteConversation(@RequestParam("id") Long id) { | |
| 59 | - imConversationService.deleteConversation(id); | |
| 39 | + @PostMapping("/update-top") | |
| 40 | + @Operation(summary = "置顶会话") | |
| 41 | + @PreAuthorize("hasAuthority('im:conversation:update')") | |
| 42 | + public CommonResult<Boolean> updateTop(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) { | |
| 43 | + imConversationService.updateTop(updateReqVO); | |
| 60 | 44 | return success(true); |
| 61 | 45 | } |
| 62 | 46 | |
| 63 | - @GetMapping("/get") | |
| 64 | - @Operation(summary = "获得会话") | |
| 65 | - @Parameter(name = "id", description = "编号", required = true, example = "1024") | |
| 66 | - @PreAuthorize("@ss.hasPermission('im:conversation:query')") | |
| 67 | - public CommonResult<ImConversationRespVO> getConversation(@RequestParam("id") Long id) { | |
| 68 | - ImConversationDO conversation = imConversationService.getConversation(id); | |
| 69 | - return success(BeanUtils.toBean(conversation, ImConversationRespVO.class)); | |
| 70 | - } | |
| 71 | - | |
| 72 | - @GetMapping("/page") | |
| 73 | - @Operation(summary = "获得会话分页") | |
| 74 | - @PreAuthorize("@ss.hasPermission('im:conversation:query')") | |
| 75 | - public CommonResult<PageResult<ImConversationRespVO>> getConversationPage(@Valid ImConversationPageReqVO pageReqVO) { | |
| 76 | - PageResult<ImConversationDO> pageResult = imConversationService.getConversationPage(pageReqVO); | |
| 77 | - return success(BeanUtils.toBean(pageResult, ImConversationRespVO.class)); | |
| 78 | - } | |
| 79 | 47 | |
| 80 | - @GetMapping("/export-excel") | |
| 81 | - @Operation(summary = "导出会话 Excel") | |
| 82 | - @PreAuthorize("@ss.hasPermission('im:conversation:export')") | |
| 83 | - @OperateLog(type = EXPORT) | |
| 84 | - public void exportConversationExcel(@Valid ImConversationPageReqVO pageReqVO, | |
| 85 | - HttpServletResponse response) throws IOException { | |
| 86 | - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); | |
| 87 | - List<ImConversationDO> list = imConversationService.getConversationPage(pageReqVO).getList(); | |
| 88 | - // 导出 Excel | |
| 89 | - ExcelUtils.write(response, "会话.xls", "数据", ImConversationRespVO.class, | |
| 90 | - BeanUtils.toBean(list, ImConversationRespVO.class)); | |
| 48 | + @PostMapping("/update-last-read-time") | |
| 49 | + @Operation(summary = "更新最后已读时间") | |
| 50 | + @PreAuthorize("hasAuthority('im:conversation:update')") | |
| 51 | + public CommonResult<Boolean> updateLastReadTime(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) { | |
| 52 | + imConversationService.updateLastReadTime(updateReqVO); | |
| 53 | + return success(true); | |
| 91 | 54 | } |
| 92 | 55 | |
| 93 | 56 | } |
| 94 | 57 | \ No newline at end of file | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImMessageController.java
| 1 | 1 | package cn.iocoder.yudao.module.im.controller.admin.message; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | -import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 5 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | |
| 8 | -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | |
| 9 | 6 | import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessagePageReqVO; |
| 10 | 7 | import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageRespVO; |
| 11 | -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSaveReqVO; | |
| 12 | 8 | import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; |
| 13 | 9 | import cn.iocoder.yudao.module.im.service.message.ImMessageService; |
| 14 | 10 | import io.swagger.v3.oas.annotations.Operation; |
| 15 | 11 | import io.swagger.v3.oas.annotations.Parameter; |
| 16 | 12 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 17 | 13 | import jakarta.annotation.Resource; |
| 18 | -import jakarta.servlet.http.HttpServletResponse; | |
| 19 | 14 | import jakarta.validation.Valid; |
| 20 | 15 | import org.springframework.security.access.prepost.PreAuthorize; |
| 21 | 16 | import org.springframework.validation.annotation.Validated; |
| 22 | -import org.springframework.web.bind.annotation.*; | |
| 17 | +import org.springframework.web.bind.annotation.GetMapping; | |
| 18 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 19 | +import org.springframework.web.bind.annotation.RequestParam; | |
| 20 | +import org.springframework.web.bind.annotation.RestController; | |
| 23 | 21 | |
| 24 | -import java.io.IOException; | |
| 25 | 22 | import java.util.List; |
| 26 | 23 | |
| 27 | 24 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 28 | -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; | |
| 25 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | |
| 29 | 26 | |
| 30 | 27 | @Tag(name = "管理后台 - 消息") |
| 31 | 28 | @RestController |
| ... | ... | @@ -36,58 +33,36 @@ public class ImMessageController { |
| 36 | 33 | @Resource |
| 37 | 34 | private ImMessageService imMessageService; |
| 38 | 35 | |
| 39 | - @PostMapping("/create") | |
| 40 | - @Operation(summary = "创建消息") | |
| 41 | - @PreAuthorize("@ss.hasPermission('im:message:create')") | |
| 42 | - public CommonResult<Long> createMessage(@Valid @RequestBody ImMessageSaveReqVO createReqVO) { | |
| 43 | - return success(imMessageService.createMessage(createReqVO)); | |
| 36 | + @GetMapping("/get-message-by-sequence") | |
| 37 | + @Operation(summary = "拉取消息-增量拉取大于 seq 的消息") | |
| 38 | + @Parameter(name = "sequence", description = "序号", required = true, example = "1") | |
| 39 | + @Parameter(name = "size", description = "条数", required = true, example = "10") | |
| 40 | + @PreAuthorize("@ss.hasPermission('im:message:query')") | |
| 41 | + public CommonResult<List<ImMessageRespVO>> loadMessage( | |
| 42 | + @RequestParam("sequence") Long sequence, | |
| 43 | + @RequestParam("size") Integer size) { | |
| 44 | + List<ImMessageDO> message = imMessageService.loadMessage(getLoginUserId(), sequence, size); | |
| 45 | + return success(BeanUtils.toBean(message, ImMessageRespVO.class)); | |
| 44 | 46 | } |
| 45 | 47 | |
| 46 | - @PutMapping("/update") | |
| 47 | - @Operation(summary = "更新消息") | |
| 48 | - @PreAuthorize("@ss.hasPermission('im:message:update')") | |
| 49 | - public CommonResult<Boolean> updateMessage(@Valid @RequestBody ImMessageSaveReqVO updateReqVO) { | |
| 50 | - imMessageService.updateMessage(updateReqVO); | |
| 51 | - return success(true); | |
| 52 | - } | |
| 53 | 48 | |
| 54 | - @DeleteMapping("/delete") | |
| 55 | - @Operation(summary = "删除消息") | |
| 56 | - @Parameter(name = "id", description = "编号", required = true) | |
| 57 | - @PreAuthorize("@ss.hasPermission('im:message:delete')") | |
| 58 | - public CommonResult<Boolean> deleteMessage(@RequestParam("id") Long id) { | |
| 59 | - imMessageService.deleteMessage(id); | |
| 60 | - return success(true); | |
| 61 | - } | |
| 62 | - | |
| 63 | - @GetMapping("/get") | |
| 64 | - @Operation(summary = "获得消息") | |
| 65 | - @Parameter(name = "id", description = "编号", required = true, example = "1024") | |
| 49 | + @GetMapping("/get-all-message") | |
| 50 | + @Operation(summary = "拉取全部消息") | |
| 51 | + @Parameter(name = "size", description = "条数", required = true, example = "10") | |
| 66 | 52 | @PreAuthorize("@ss.hasPermission('im:message:query')") |
| 67 | - public CommonResult<ImMessageRespVO> getMessage(@RequestParam("id") Long id) { | |
| 68 | - ImMessageDO message = imMessageService.getMessage(id); | |
| 53 | + public CommonResult<List<ImMessageRespVO>> loadAllMessage(@RequestParam("size") Integer size) { | |
| 54 | + List<ImMessageDO> message = imMessageService.loadAllMessage(getLoginUserId(), size); | |
| 69 | 55 | return success(BeanUtils.toBean(message, ImMessageRespVO.class)); |
| 70 | 56 | } |
| 71 | 57 | |
| 58 | + | |
| 72 | 59 | @GetMapping("/page") |
| 73 | - @Operation(summary = "获得消息分页") | |
| 60 | + @Operation(summary = "查询聊天记录-分页") | |
| 74 | 61 | @PreAuthorize("@ss.hasPermission('im:message:query')") |
| 75 | 62 | public CommonResult<PageResult<ImMessageRespVO>> getMessagePage(@Valid ImMessagePageReqVO pageReqVO) { |
| 76 | - PageResult<ImMessageDO> pageResult = imMessageService.getMessagePage(pageReqVO); | |
| 77 | - return success(BeanUtils.toBean(pageResult, ImMessageRespVO.class)); | |
| 63 | + PageResult<ImMessageDO> messagePage = imMessageService.getMessagePage(pageReqVO); | |
| 64 | + return success(BeanUtils.toBean(messagePage, ImMessageRespVO.class)); | |
| 78 | 65 | } |
| 79 | 66 | |
| 80 | - @GetMapping("/export-excel") | |
| 81 | - @Operation(summary = "导出消息 Excel") | |
| 82 | - @PreAuthorize("@ss.hasPermission('im:message:export')") | |
| 83 | - @OperateLog(type = EXPORT) | |
| 84 | - public void exportMessageExcel(@Valid ImMessagePageReqVO pageReqVO, | |
| 85 | - HttpServletResponse response) throws IOException { | |
| 86 | - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); | |
| 87 | - List<ImMessageDO> list = imMessageService.getMessagePage(pageReqVO).getList(); | |
| 88 | - // 导出 Excel | |
| 89 | - ExcelUtils.write(response, "消息.xls", "数据", ImMessageRespVO.class, | |
| 90 | - BeanUtils.toBean(list, ImMessageRespVO.class)); | |
| 91 | - } | |
| 92 | 67 | |
| 93 | 68 | } |
| 94 | 69 | \ No newline at end of file | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImMessageMapper.java
| ... | ... | @@ -4,9 +4,13 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | 6 | import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessagePageReqVO; |
| 7 | +import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO; | |
| 7 | 8 | import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; |
| 9 | +import com.github.yulichang.wrapper.MPJLambdaWrapper; | |
| 8 | 10 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 11 | |
| 12 | +import java.util.List; | |
| 13 | + | |
| 10 | 14 | /** |
| 11 | 15 | * 消息 Mapper |
| 12 | 16 | * |
| ... | ... | @@ -32,4 +36,24 @@ public interface ImMessageMapper extends BaseMapperX<ImMessageDO> { |
| 32 | 36 | .orderByDesc(ImMessageDO::getId)); |
| 33 | 37 | } |
| 34 | 38 | |
| 39 | + default List<ImMessageDO> getGreaterThanSequenceMessage(Long userId, Long sequence, Integer size) { | |
| 40 | + //查询 inbox 表中,大于 sequence 的消息,关联 message 表,按照 inbox 表 sequence 升序 | |
| 41 | + return selectJoinList(ImMessageDO.class, new MPJLambdaWrapper<ImMessageDO>() | |
| 42 | + .selectAll(ImMessageDO.class) | |
| 43 | + .innerJoin(ImInboxDO.class, ImInboxDO::getMessageId, ImMessageDO::getId) | |
| 44 | + .eq(ImInboxDO::getUserId, userId) | |
| 45 | + .gt(ImInboxDO::getSequence, sequence) | |
| 46 | + .orderByAsc(ImInboxDO::getSequence) | |
| 47 | + .last("limit 0," + size)); | |
| 48 | + } | |
| 49 | + | |
| 50 | + default List<ImMessageDO> getAllMessage(Long userId, Integer size) { | |
| 51 | + //查询 inbox 表中,100条消息,关联 message 表,按照 inbox 表 sequence 降序 | |
| 52 | + return selectJoinList(ImMessageDO.class, new MPJLambdaWrapper<ImMessageDO>() | |
| 53 | + .selectAll(ImMessageDO.class) | |
| 54 | + .innerJoin(ImInboxDO.class, ImInboxDO::getMessageId, ImMessageDO::getId) | |
| 55 | + .eq(ImInboxDO::getUserId, userId) | |
| 56 | + .orderByDesc(ImInboxDO::getSequence) | |
| 57 | + .last("limit 0," + size)); | |
| 58 | + } | |
| 35 | 59 | } |
| 36 | 60 | \ No newline at end of file | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationService.java
| ... | ... | @@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversatio |
| 6 | 6 | import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; |
| 7 | 7 | import jakarta.validation.Valid; |
| 8 | 8 | |
| 9 | +import java.util.List; | |
| 10 | + | |
| 9 | 11 | /** |
| 10 | 12 | * 会话 Service 接口 |
| 11 | 13 | * |
| ... | ... | @@ -53,10 +55,23 @@ public interface ImConversationService { |
| 53 | 55 | |
| 54 | 56 | |
| 55 | 57 | /** |
| 56 | - * 保存私聊会话 | |
| 58 | + * 获得用户的会话列表 | |
| 59 | + * | |
| 60 | + * @return 会话列表 | |
| 61 | + */ | |
| 62 | + List<ImConversationDO> getConversationList(); | |
| 63 | + | |
| 64 | + /** | |
| 65 | + * 置顶会话 | |
| 57 | 66 | * |
| 58 | - * @param fromUserId 发送者 | |
| 59 | - * @param receiverId 接收者 | |
| 67 | + * @param updateReqVO 更新信息 | |
| 68 | + */ | |
| 69 | + void updateTop(ImConversationSaveReqVO updateReqVO); | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * 更新最后已读时间 | |
| 73 | + * | |
| 74 | + * @param updateReqVO 更新信息 | |
| 60 | 75 | */ |
| 61 | - void savePrivateConversation(Long fromUserId, Long receiverId); | |
| 76 | + void updateLastReadTime(ImConversationSaveReqVO updateReqVO); | |
| 62 | 77 | } |
| 63 | 78 | \ No newline at end of file | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.im.service.conversation; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.date.DateUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | 6 | import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationPageReqVO; |
| 6 | 7 | import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationSaveReqVO; |
| 7 | 8 | import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; |
| 8 | 9 | import cn.iocoder.yudao.module.im.dal.mysql.conversation.ImConversationMapper; |
| 9 | -import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; | |
| 10 | 10 | import jakarta.annotation.Resource; |
| 11 | 11 | import org.springframework.stereotype.Service; |
| 12 | 12 | import org.springframework.validation.annotation.Validated; |
| 13 | 13 | |
| 14 | +import java.util.Date; | |
| 15 | +import java.util.List; | |
| 16 | + | |
| 14 | 17 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 15 | 18 | import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.CONVERSATION_NOT_EXISTS; |
| 16 | 19 | |
| ... | ... | @@ -69,25 +72,36 @@ public class ImConversationServiceImpl implements ImConversationService { |
| 69 | 72 | } |
| 70 | 73 | |
| 71 | 74 | @Override |
| 72 | - public void savePrivateConversation(Long fromUserId, Long receiverId) { | |
| 73 | - // 创建并保存会话 | |
| 74 | - createAndSaveConversation(fromUserId, receiverId); | |
| 75 | - createAndSaveConversation(receiverId, fromUserId); | |
| 75 | + public List<ImConversationDO> getConversationList() { | |
| 76 | + return imConversationMapper.selectList(); | |
| 77 | + } | |
| 78 | + | |
| 79 | + @Override | |
| 80 | + public void updateTop(ImConversationSaveReqVO updateReqVO) { | |
| 81 | + createOrUpdateConversation(updateReqVO); | |
| 82 | + } | |
| 83 | + | |
| 84 | + @Override | |
| 85 | + public void updateLastReadTime(ImConversationSaveReqVO updateReqVO) { | |
| 86 | + createOrUpdateConversation(updateReqVO); | |
| 76 | 87 | } |
| 77 | 88 | |
| 78 | - private void createAndSaveConversation(Long userId, Long targetId) { | |
| 79 | - // 创建会话 | |
| 80 | - ImConversationDO conversation = new ImConversationDO(); | |
| 81 | - conversation.setUserId(userId); | |
| 82 | - conversation.setConversationType(ImConversationTypeEnum.PRIVATE.getType()); | |
| 83 | - conversation.setTargetId(targetId); | |
| 84 | - conversation.setNo("s_" + userId + "_" + targetId); | |
| 85 | - conversation.setPinned(false); | |
| 86 | - | |
| 87 | - // 根据 no 查询是否存在,不存在则新增 | |
| 88 | - ImConversationDO imConversationDO = imConversationMapper.selectByNo(conversation.getNo()); | |
| 89 | - if (imConversationDO == null) { | |
| 90 | - imConversationMapper.insert(conversation); | |
| 89 | + private void createOrUpdateConversation(ImConversationSaveReqVO updateReqVO) { | |
| 90 | + // 操作会话(已读、置顶)时,才会延迟创建,要先判断是否存在,根据 no 查询是否存在,不存在则新增 | |
| 91 | + ImConversationDO conversation = imConversationMapper.selectByNo(updateReqVO.getNo()); | |
| 92 | + if (conversation == null) { | |
| 93 | + ImConversationDO conversationDO = new ImConversationDO(); | |
| 94 | + conversationDO.setNo(updateReqVO.getNo()); | |
| 95 | + conversationDO.setUserId(updateReqVO.getUserId()); | |
| 96 | + conversationDO.setTargetId(updateReqVO.getTargetId()); | |
| 97 | + conversationDO.setConversationType(updateReqVO.getConversationType()); | |
| 98 | + conversationDO.setPinned(updateReqVO.getPinned()); | |
| 99 | + conversationDO.setLastReadTime(DateUtil.toLocalDateTime(new Date())); | |
| 100 | + imConversationMapper.insert(conversationDO); | |
| 101 | + } else { | |
| 102 | + // 更新 | |
| 103 | + ImConversationDO updateObj = BeanUtils.toBean(updateReqVO, ImConversationDO.class); | |
| 104 | + imConversationMapper.updateById(updateObj); | |
| 91 | 105 | } |
| 92 | 106 | } |
| 93 | 107 | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageService.java
| ... | ... | @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; |
| 7 | 7 | import cn.iocoder.yudao.module.im.websocket.message.ImSendMessage; |
| 8 | 8 | import jakarta.validation.Valid; |
| 9 | 9 | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 10 | 12 | /** |
| 11 | 13 | * 消息 Service 接口 |
| 12 | 14 | * |
| ... | ... | @@ -72,9 +74,29 @@ public interface ImMessageService { |
| 72 | 74 | |
| 73 | 75 | /** |
| 74 | 76 | * 保存群聊消息 |
| 75 | - * @param message 消息 | |
| 77 | + * | |
| 78 | + * @param message 消息 | |
| 76 | 79 | * @param fromUserId 发送者用户ID |
| 77 | 80 | * @return id |
| 78 | 81 | */ |
| 79 | 82 | ImMessageDO saveGroupMessage(ImSendMessage message, Long fromUserId); |
| 83 | + | |
| 84 | + /** | |
| 85 | + * 拉取消息-大于 seq 的消息 | |
| 86 | + * | |
| 87 | + * @param userId 用户id | |
| 88 | + * @param sequence 序列号 | |
| 89 | + * @param size 数量 | |
| 90 | + * @return 消息列表 | |
| 91 | + */ | |
| 92 | + List<ImMessageDO> loadMessage(Long userId, Long sequence, Integer size); | |
| 93 | + | |
| 94 | + /** | |
| 95 | + * 拉取全部消息 | |
| 96 | + * | |
| 97 | + * @param userId 登录用户编号 | |
| 98 | + * @param size 数量 | |
| 99 | + * @return 消息列表 | |
| 100 | + */ | |
| 101 | + List<ImMessageDO> loadAllMessage(Long userId, Integer size); | |
| 80 | 102 | } |
| 81 | 103 | \ No newline at end of file | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImpl.java
| ... | ... | @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessagePageReqVO |
| 6 | 6 | import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSaveReqVO; |
| 7 | 7 | import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; |
| 8 | 8 | import cn.iocoder.yudao.module.im.dal.mysql.message.ImMessageMapper; |
| 9 | +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; | |
| 9 | 10 | import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; |
| 10 | 11 | import cn.iocoder.yudao.module.im.websocket.message.ImSendMessage; |
| 11 | 12 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| ... | ... | @@ -15,6 +16,8 @@ import org.dromara.hutool.core.date.TimeUtil; |
| 15 | 16 | import org.springframework.stereotype.Service; |
| 16 | 17 | import org.springframework.validation.annotation.Validated; |
| 17 | 18 | |
| 19 | +import java.util.List; | |
| 20 | + | |
| 18 | 21 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 19 | 22 | import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.MESSAGE_NOT_EXISTS; |
| 20 | 23 | |
| ... | ... | @@ -91,7 +94,12 @@ public class ImMessageServiceImpl implements ImMessageService { |
| 91 | 94 | imMessageDO.setSenderAvatar(user.getAvatar()); |
| 92 | 95 | imMessageDO.setConversationType(message.getConversationType()); |
| 93 | 96 | imMessageDO.setContentType(message.getContentType()); |
| 94 | - imMessageDO.setConversationNo(fromUserId + "_" + message.getReceiverId()); | |
| 97 | + //单聊:s_{userId}_{targetId} 群聊:群聊:g_{groupId} | |
| 98 | + if (message.getConversationType().equals(ImConversationTypeEnum.PRIVATE.getType())) { | |
| 99 | + imMessageDO.setConversationNo("s_" + fromUserId + "_" + message.getReceiverId()); | |
| 100 | + } else if (message.getConversationType().equals(ImConversationTypeEnum.GROUP.getType())) { | |
| 101 | + imMessageDO.setConversationNo("g_" + message.getReceiverId()); | |
| 102 | + } | |
| 95 | 103 | imMessageDO.setContent(message.getContent()); |
| 96 | 104 | //消息来源 100-用户发送;200-系统发送(一般是通知);不能为空 |
| 97 | 105 | imMessageDO.setSendFrom(100); |
| ... | ... | @@ -117,4 +125,14 @@ public class ImMessageServiceImpl implements ImMessageService { |
| 117 | 125 | return saveImMessageDO(message, fromUserId); |
| 118 | 126 | } |
| 119 | 127 | |
| 128 | + @Override | |
| 129 | + public List<ImMessageDO> loadMessage(Long userId, Long sequence, Integer size) { | |
| 130 | + return imMessageMapper.getGreaterThanSequenceMessage(userId, sequence, size); | |
| 131 | + } | |
| 132 | + | |
| 133 | + @Override | |
| 134 | + public List<ImMessageDO> loadAllMessage(Long userId, Integer size) { | |
| 135 | + return imMessageMapper.getAllMessage(userId, size); | |
| 136 | + } | |
| 137 | + | |
| 120 | 138 | } |
| 121 | 139 | \ No newline at end of file | ... | ... |