Commit 788c24dff4f57baf0743f03519f2f849e3a8c9e1

Authored by dylanmay
1 parent b540f8d4

会话和消息处理

yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java
... ... @@ -5,8 +5,14 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 5 import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdateLastReadTimeReqVO;
6 6 import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationRespVO;
7 7 import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdatePinnedReqVO;
  8 +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListByNoReqVO;
8 9 import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO;
  10 +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
  11 +import cn.iocoder.yudao.module.im.enums.message.ImMessageContentTypeEnum;
9 12 import cn.iocoder.yudao.module.im.service.conversation.ImConversationService;
  13 +import cn.iocoder.yudao.module.im.service.message.ImMessageService;
  14 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  15 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
10 16 import io.swagger.v3.oas.annotations.Operation;
11 17 import io.swagger.v3.oas.annotations.tags.Tag;
12 18 import jakarta.annotation.Resource;
... ... @@ -15,6 +21,7 @@ import org.springframework.validation.annotation.Validated;
15 21 import org.springframework.web.bind.annotation.*;
16 22  
17 23 import java.util.List;
  24 +import java.util.Objects;
18 25  
19 26 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
20 27 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
... ... @@ -28,11 +35,50 @@ public class ImConversationController {
28 35 @Resource
29 36 private ImConversationService imConversationService;
30 37  
  38 + @Resource
  39 + private ImMessageService imMessageService;
  40 +
  41 + @Resource
  42 + AdminUserApi adminUserApi;
  43 +
31 44 @GetMapping("/list")
32 45 @Operation(summary = "获得用户的会话列表")
33 46 public CommonResult<List<ImConversationRespVO>> getConversationList() {
34   - List<ImConversationDO> conversationList = imConversationService.getConversationList();
35   - return success(BeanUtils.toBean(conversationList, ImConversationRespVO.class));
  47 + List<ImConversationDO> conversationList = imConversationService.getConversationList(getLoginUserId());
  48 + List<ImConversationRespVO> imConversationRespVOList = BeanUtils.toBean(conversationList, ImConversationRespVO.class);
  49 + imConversationRespVOList.forEach(item -> {
  50 + // 处理个人图像和昵称
  51 + Long receiverId = item.getTargetId();
  52 + AdminUserRespDTO receiverUser = adminUserApi.getUser(receiverId);
  53 + if (receiverUser != null) {
  54 + item.setAvatar(receiverUser.getAvatar());
  55 + item.setNickname(receiverUser.getNickname());
  56 + }
  57 +
  58 + // 处理未读消息条数【TODO:】
  59 +
  60 +
  61 + // 处理最后一条消息描述
  62 + ImMessageListByNoReqVO imMessageListByNoReqVO = new ImMessageListByNoReqVO();
  63 + imMessageListByNoReqVO.setConversationNo(item.getNo());
  64 + List<ImMessageDO> listMessage = imMessageService.getMessageListByConversationNo(imMessageListByNoReqVO);
  65 +
  66 + if (!listMessage.isEmpty()) {
  67 + ImMessageDO lastMessage = listMessage.get(listMessage.size() - 1);
  68 + if (lastMessage != null) {
  69 + if (Objects.equals(lastMessage.getContentType(), ImMessageContentTypeEnum.TEXT.getType())) {
  70 + item.setLastMessageDescription(lastMessage.getContent());
  71 + } else if (Objects.equals(lastMessage.getContentType(), ImMessageContentTypeEnum.PICTURE.getType())) {
  72 + item.setLastMessageDescription("[图片]");
  73 + } else {
  74 + item.setLastMessageDescription("[未知类型]");
  75 + }
  76 + }
  77 + }
  78 +
  79 +
  80 + });
  81 + return success(imConversationRespVOList);
36 82 }
37 83  
38 84 @PostMapping("/update-pinned")
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationRespVO.java
... ... @@ -35,4 +35,16 @@ public class ImConversationRespVO {
35 35 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
36 36 private LocalDateTime createTime;
37 37  
  38 + @Schema(description = "会话接受者头像", requiredMode = Schema.RequiredMode.REQUIRED)
  39 + private String avatar;
  40 +
  41 + @Schema(description = "会话接受者昵称", requiredMode = Schema.RequiredMode.REQUIRED)
  42 + private String nickname;
  43 +
  44 + @Schema(description = "最后一条消息的描述", requiredMode = Schema.RequiredMode.REQUIRED)
  45 + private String lastMessageDescription;
  46 +
  47 + @Schema(description = "未读消息条数", requiredMode = Schema.RequiredMode.REQUIRED)
  48 + private String unreadMessagesCount;
  49 +
38 50 }
39 51 \ 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
... ... @@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.im.controller.admin.message;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5   -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListReqVO;
6   -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageRespVO;
7   -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendReqVO;
8   -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendRespVO;
  5 +import cn.iocoder.yudao.module.im.controller.admin.message.vo.*;
9 6 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
10 7 import cn.iocoder.yudao.module.im.service.message.ImMessageService;
11 8 import io.swagger.v3.oas.annotations.Operation;
... ... @@ -50,7 +47,14 @@ public class ImMessageController {
50 47 @GetMapping("/list")
51 48 @Operation(summary = "消息列表-根据接收人和发送时间进行分页查询")
52 49 public CommonResult<List<ImMessageRespVO>> getMessageList(@Valid ImMessageListReqVO listReqVO) {
53   - List<ImMessageDO> messagePage = imMessageService.getMessageList(getLoginUserId(), listReqVO);
  50 + List<ImMessageDO> messagePage = imMessageService.getMessageList(listReqVO);
  51 + return success(BeanUtils.toBean(messagePage, ImMessageRespVO.class));
  52 + }
  53 +
  54 + @GetMapping("/listByNo")
  55 + @Operation(summary = "消息列表-根据接收人和发送时间进行分页查询")
  56 + public CommonResult<List<ImMessageRespVO>> getMessageListByNo(@Valid ImMessageListByNoReqVO listReqVO) {
  57 + List<ImMessageDO> messagePage = imMessageService.getMessageListByConversationNo(listReqVO);
54 58 return success(BeanUtils.toBean(messagePage, ImMessageRespVO.class));
55 59 }
56 60  
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageListByNoReqVO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.im.controller.admin.message.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import lombok.Data;
  8 +import lombok.ToString;
  9 +import org.springframework.format.annotation.DateTimeFormat;
  10 +
  11 +import java.time.LocalDateTime;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
  14 +
  15 +@Schema(description = "管理后台 - 消息列表 Request VO")
  16 +@Data
  17 +@ToString(callSuper = true)
  18 +public class ImMessageListByNoReqVO {
  19 +
  20 + @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27 12:00:00")
  21 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
  22 + private LocalDateTime sendTime;
  23 +
  24 + @Schema(description = "会话编号编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494")
  25 + @NotNull(message = "会话编号不能为空")
  26 + private String conversationNo ;
  27 +
  28 +}
0 29 \ No newline at end of file
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageListReqVO.java
... ... @@ -21,6 +21,10 @@ public class ImMessageListReqVO {
21 21 @NotNull(message = "接收人编号不能为空")
22 22 private Long receiverId;
23 23  
  24 + @Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494")
  25 + @NotNull(message = "发送人编号不能为空")
  26 + private Long senderId;
  27 +
24 28 @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
25 29 @InEnum(value = ImConversationTypeEnum.class,message = "会话类型必须是 {value}")
26 30 @NotNull(message = "会话类型不能为空")
... ... @@ -30,4 +34,8 @@ public class ImMessageListReqVO {
30 34 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
31 35 private LocalDateTime sendTime;
32 36  
  37 + @Schema(description = "会话编号编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494")
  38 + @NotNull(message = "会话编号不能为空")
  39 + private String conversationNo ;
  40 +
33 41 }
34 42 \ No newline at end of file
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageSendReqVO.java
... ... @@ -24,6 +24,10 @@ public class ImMessageSendReqVO {
24 24 @NotNull(message = "会话类型不能为空")
25 25 private Integer conversationType;
26 26  
  27 + @Schema(description = "会话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  28 + @NotNull(message = "会话编号不能为空")
  29 + private String conversationNo;
  30 +
27 31 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
28 32 @InEnum(ImMessageContentTypeEnum.class)
29 33 @NotNull(message = "消息类型不能为空")
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationService.java
... ... @@ -18,7 +18,7 @@ public interface ImConversationService {
18 18 *
19 19 * @return 会话列表
20 20 */
21   - List<ImConversationDO> getConversationList();
  21 + List<ImConversationDO> getConversationList(Long loginUserId);
22 22  
23 23 /**
24 24 * 置顶会话
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImpl.java
... ... @@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversatio
5 5 import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO;
6 6 import cn.iocoder.yudao.module.im.dal.mysql.conversation.ImConversationMapper;
7 7 import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
  8 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  9 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
8 10 import jakarta.annotation.Resource;
9 11 import org.springframework.stereotype.Service;
10 12 import org.springframework.validation.annotation.Validated;
... ... @@ -24,8 +26,20 @@ public class ImConversationServiceImpl implements ImConversationService {
24 26 private ImConversationMapper imConversationMapper;
25 27  
26 28 @Override
27   - public List<ImConversationDO> getConversationList() {
28   - return imConversationMapper.selectList();
  29 + public List<ImConversationDO> getConversationList(Long loginUserId) {
  30 + // 根据loginUserId判断targetId, 自己不能做targetId
  31 + // 如何loginUserId和targetId相同,则需要调换userId和targetId
  32 + List<ImConversationDO> conversationList = imConversationMapper.selectList();
  33 + // 遍历判断loginUserId和targetId相同,相同则将userId设置为targetId, targetId设置为userId
  34 + conversationList.forEach(item -> {
  35 + if (item.getTargetId().equals(loginUserId)) {
  36 + Long targetId = item.getTargetId();
  37 + Long userId = item.getUserId();
  38 + item.setTargetId(userId);
  39 + item.setUserId(targetId);
  40 + }
  41 + });
  42 + return conversationList;
29 43 }
30 44  
31 45 @Override
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageService.java
1 1 package cn.iocoder.yudao.module.im.service.message;
2 2  
  3 +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListByNoReqVO;
3 4 import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListReqVO;
4 5 import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendReqVO;
5 6 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
... ... @@ -16,11 +17,19 @@ public interface ImMessageService {
16 17 /**
17 18 * 获得历史消息
18 19 *
19   - * @param loginUserId 登录用户编号
20 20 * @param listReqVO 分页查询
21 21 * @return 消息分页
22 22 */
23   - List<ImMessageDO> getMessageList(Long loginUserId, ImMessageListReqVO listReqVO);
  23 + List<ImMessageDO> getMessageList(ImMessageListReqVO listReqVO);
  24 +
  25 +
  26 + /**
  27 + * 获得历史消息
  28 + *
  29 + * @param listReqVO 分页查询
  30 + * @return 消息分页
  31 + */
  32 + List<ImMessageDO> getMessageListByConversationNo(ImMessageListByNoReqVO listReqVO);
24 33  
25 34 /**
26 35 * 拉取消息-大于 seq 的消息
... ...
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImpl.java
... ... @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.im.service.message;
2 2  
3 3 import cn.hutool.core.bean.BeanUtil;
4 4 import cn.hutool.core.collection.CollUtil;
  5 +import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListByNoReqVO;
5 6 import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListReqVO;
6 7 import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendReqVO;
7 8 import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO;
... ... @@ -46,9 +47,9 @@ public class ImMessageServiceImpl implements ImMessageService {
46 47 private ImGroupMemberService imGroupMemberService;
47 48  
48 49 @Override
49   - public List<ImMessageDO> getMessageList(Long loginUserId, ImMessageListReqVO listReqVO) {
  50 + public List<ImMessageDO> getMessageList(ImMessageListReqVO listReqVO) {
50 51 // 1. 获得会话编号
51   - String no = ImConversationTypeEnum.generateConversationNo(loginUserId, listReqVO.getReceiverId(), listReqVO.getConversationType());
  52 + String no = ImConversationTypeEnum.generateConversationNo(listReqVO.getSenderId(), listReqVO.getReceiverId(), listReqVO.getConversationType());
52 53 // 2. 查询历史消息
53 54 ImMessageDO message = new ImMessageDO()
54 55 .setSendTime(listReqVO.getSendTime())
... ... @@ -57,6 +58,17 @@ public class ImMessageServiceImpl implements ImMessageService {
57 58 }
58 59  
59 60 @Override
  61 + public List<ImMessageDO> getMessageListByConversationNo(ImMessageListByNoReqVO listReqVO) {
  62 +
  63 + // 1. 查询历史消息
  64 + ImMessageDO message = new ImMessageDO()
  65 + .setSendTime(listReqVO.getSendTime())
  66 + .setConversationNo(listReqVO.getConversationNo());
  67 + return imMessageMapper.selectMessageList(message);
  68 + }
  69 +
  70 +
  71 + @Override
60 72 public List<ImMessageDO> pullMessageList(Long userId, Long sequence, Integer size) {
61 73 List<Long> messageIds = imInboxService.selectMessageIdsByUserIdAndSequence(userId, sequence, size);
62 74 if (CollUtil.isEmpty(messageIds)) {
... ... @@ -84,7 +96,7 @@ public class ImMessageServiceImpl implements ImMessageService {
84 96 ImMessageDO imMessageDO = BeanUtil.copyProperties(message, ImMessageDO.class)
85 97 .setSenderNickname(fromUser.getNickname()).setSenderAvatar(fromUser.getAvatar())
86 98 .setSenderId(fromUserId)
87   - .setConversationNo(ImConversationTypeEnum.generateConversationNo(fromUserId, message.getReceiverId(), message.getConversationType()))
  99 + .setConversationNo(message.getConversationNo())
88 100 .setSendFrom(ImMessageSourceEnum.USER_SEND.getSource())
89 101 .setMessageStatus(ImMessageStatusEnum.SENDING.getStatus())
90 102 .setSendTime(LocalDateTime.now());
... ...