Commit 72549020 by Future

会话列表优化

parent 0ea164f0
package io.geekidea.springbootplus.test;
import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.mapper.ImConversationMapper;
import com.wecloud.im.vo.ConversationVo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
/**
* imConversation 单元测试
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class ImConversationTest {
@Autowired
private ImConversationMapper imConversationMapper;
@Test
public void listConversation() {
List<ConversationVo> myImConversationList = imConversationMapper.getMyImConversationListAndMsgCount(1394579719625773056L,"", null);
List<ImConversation> myImConversationList1 = imConversationMapper.getMyImConversationList(1394579719625773056L);
}
}
......@@ -12,6 +12,7 @@ import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.entity.ImInbox;
import com.wecloud.im.entity.ImMessage;
import com.wecloud.im.entity.ImMessageOnlineSend;
import com.wecloud.im.executor.SendMsgThreadPool;
import com.wecloud.im.friend.entity.ImFriend;
import com.wecloud.im.friend.service.ImFriendService;
import com.wecloud.im.mq.MqSender;
......@@ -94,13 +95,11 @@ public class NormalChatAction {
@ActionMapping("/normal/send")
@ApiOperation("普通消息发送")
public void sendMsg(ActionRequest request, ChatContentVo data, String reqId) {
log.info("-1");
ImConversationQueryVo conversation = ehcacheService.getEhCacheConversation(data.getToConversation());
if (conversation == null) {
log.warn("会reqId: {} ,会话id: {}db中不存在", reqId, data.getToConversation());
return;
}
log.info("0");
// 查询发送者client
ImClient imClientSender = ehcacheService.getEhCacheClient(request.getSenderClientId());
if (imClientSender == null) {
......@@ -110,7 +109,6 @@ public class NormalChatAction {
// 查询imApplication
ImApplication imApplication = imApplicationService.getCacheById(imClientSender.getFkAppid());
log.info("1");
// 给所有人(在线+离线)遍历发送
// 先查询该会话所有成员
......@@ -128,7 +126,6 @@ public class NormalChatAction {
}
Map<Long, ImConversationMembers> memberMap = membersList.stream().collect(Collectors.toMap(ImConversationMembers::getFkClientId, member -> member));
log.info("2");
// 判断为单聊
if (ChatTypeEnum.SINGLE.getCode().equals(conversation.getChatType())) {
// 判断是否被拉黑逻辑
......@@ -157,7 +154,6 @@ public class NormalChatAction {
}
ImMessageOnlineSend imMessageOnlineSend = assembleImMessageOnlineSend(data, imClientSender, imApplication.getId());
log.info("3");
// 入库 保存收件箱
batchSaveInbox(imApplication, imClientSender, conversation, imMessageOnlineSend.getMsgId(), membersList);
// 入库成功后 判断是否是临时会话 如果是,双方会话display状态是否是1(显示),如果不是,需要修改为是
......@@ -181,8 +177,9 @@ public class NormalChatAction {
// 不给自己发
continue;
}
log.info("6");
this.sendMsgToMember(imApplication, member, imMessageOnlineSend, data.getPush(), isPush);
SendMsgThreadPool.SEND_MSG_THREAD_POOL_EXECUTOR.execute(() -> {
this.sendMsgToMember(imApplication, member, imMessageOnlineSend, data.getPush(), isPush);
});
}
// 响应发送方消息id等信息
......@@ -192,7 +189,6 @@ public class NormalChatAction {
private void sendMsgToMember(ImApplication imApplication, ImConversationMembers member, ImMessageOnlineSend imMessageOnlineSend, PushVO push, Boolean isPush) {
// 在线用户直接发消息
log.info("11");
Boolean sendSuccess = sendMsgForOnline(member.getFkClientId(), imMessageOnlineSend);
if (isPush && !sendSuccess && !member.getDoNotDisturb()) {
// 异步推送系统通知消息 5分钟内推一次消息
......@@ -218,7 +214,6 @@ public class NormalChatAction {
responseModel.setMsg(result.getMessage());
responseModel.setData(imMessageOnlineSend);
responseModel.setReqId(null);
log.info("21");
return channelSender.sendMsg(responseModel, receiverClientId);
}
......
......@@ -48,7 +48,7 @@ public interface ImConversationMapper extends BaseMapper<ImConversation> {
* @param currentClientId
* @return
*/
List<ConversationVo> getMyImConversationListAndMsgCount(@Param("currentClientId") Long currentClientId, @Param("clientId") String clientId, @Param("conversationId") Long conversationId);
List<ConversationVo> getMyImConversationListAndMsgCount(@Param("currentClientId") Long currentClientId, @Param("conversationId") Long conversationId);
/**
* 查询用户加入的所有会话
......
......@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImInbox;
import com.wecloud.im.param.ImInboxPageParam;
import com.wecloud.im.param.ImInboxQueryVo;
import com.wecloud.im.vo.ConversationCountVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
......@@ -46,8 +47,16 @@ public interface ImInboxMapper extends BaseMapper<ImInbox> {
/**
* 统计未读消息数量
*
* @param fkClientId
* @return
*/
List<ConversationCountVo> countMyNotRead(@Param("fkClientId") Long fkClientId);
/**
* 统计被@数量
* @param fkClientId
* @param clientId
* @return
*/
Integer countMyNotReadCount(@Param("clientId") Long clientId);
List<ConversationCountVo> countBeAt(@Param("fkClientId") Long fkClientId, @Param("clientId") String clientId);
}
package com.wecloud.im.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.entity.ImInbox;
import com.wecloud.im.param.ImMsgReceivedStatusUpdate;
import com.wecloud.im.param.MsgReadStatusUpdateParam;
import com.wecloud.im.param.UpdateMsgReadStatusByConversationParam;
import com.wecloud.im.vo.ConversationCountVo;
import io.geekidea.springbootplus.framework.common.service.BaseService;
import java.util.List;
/**
* 消息收件箱表 服务类
*
......@@ -26,10 +30,18 @@ public interface ImInboxService extends BaseService<ImInbox> {
/**
* 统计未读消息数量
*
* @param clientId
* @param fkClientId
* @return
*/
List<ConversationCountVo> countNotRead(Long fkClientId);
/**
* 统计被@数量
*
* @param imClient
* @return
*/
Integer countMyNotReadCount(Long clientId);
List<ConversationCountVo> countBeAt(ImClient imClient);
/**
* 消息修改为已读状态
......
......@@ -60,8 +60,10 @@ import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.service.ImClientService;
import com.wecloud.im.service.ImConversationMembersService;
import com.wecloud.im.service.ImConversationService;
import com.wecloud.im.service.ImInboxService;
import com.wecloud.im.service.ImMessageService;
import com.wecloud.im.vo.ChatRoomMemberVo;
import com.wecloud.im.vo.ConversationCountVo;
import com.wecloud.im.vo.ConversationMemberVo;
import com.wecloud.im.vo.ConversationVo;
import com.wecloud.im.vo.ImConversationCreateVo;
......@@ -154,6 +156,9 @@ public class ImConversationServiceImpl extends BaseServiceImpl<ImConversationMap
@Autowired
private RedisUtils redisUtils;
@Autowired
private ImInboxService inboxService;
@Resource
private EhcacheService ehcacheService;
......@@ -825,7 +830,7 @@ public class ImConversationServiceImpl extends BaseServiceImpl<ImConversationMap
// 获取当前client
ImClient currentClient = contextService.getImClientIfNotNullOrThrow();
// 查询用户加入的所有会话 与每个会话的未读条数 成员
List<ConversationVo> myImConversationListAndMsgCount = imConversationMapper.getMyImConversationListAndMsgCount(currentClient.getId(), currentClient.getClientId(), null);
List<ConversationVo> myImConversationListAndMsgCount = imConversationMapper.getMyImConversationListAndMsgCount(currentClient.getId(), null);
if (myImConversationListAndMsgCount.isEmpty()) {
return Collections.emptyList();
}
......@@ -838,30 +843,53 @@ public class ImConversationServiceImpl extends BaseServiceImpl<ImConversationMap
myImConversationListAndMsgCount = new ArrayList<>(topList);
myImConversationListAndMsgCount.addAll(normalList);
// 返回的
List<ConversationVo> myImConversationListAndMsgCountNew = new ArrayList<>();
// 最后返回的
List<ConversationVo> conversationListToReturn = new ArrayList<>();
List<ConversationCountVo> conversationCountVos = inboxService.countNotRead(currentClient.getId());
Map<Long, Integer> notReadMap = Maps.newHashMap();
if (CollectionUtils.isNotEmpty(conversationCountVos)) {
for (ConversationCountVo conversationCountVo : conversationCountVos) {
notReadMap.put(conversationCountVo.getConversationId(), conversationCountVo.getCount());
}
}
List<ConversationCountVo> beAtCountVos = inboxService.countBeAt(currentClient);
Map<Long, Integer> beAtCountMap = Maps.newHashMap();
if (CollectionUtils.isNotEmpty(beAtCountVos)) {
for (ConversationCountVo beAtCountVo : beAtCountVos) {
beAtCountMap.put(beAtCountVo.getConversationId(), beAtCountVo.getCount());
}
}
// 转换json格式
for (ConversationVo myconversationlistvo : myImConversationListAndMsgCount) {
// HashMap attributess = JsonUtils.json2Map(myconversationlistvo.getAttribute());
myconversationlistvo.setAttributes(myconversationlistvo.getAttribute());
if (ChatTypeEnum.SINGLE.getCode().equals(myconversationlistvo.getChatType())) {
String[] members = myconversationlistvo.getMembers().split(",");
for (ConversationVo conversationVo : myImConversationListAndMsgCount) {
conversationVo.setAttributes(conversationVo.getAttribute());
if (ChatTypeEnum.SINGLE.getCode().equals(conversationVo.getChatType())) {
String[] members = conversationVo.getMembers().split(",");
if (members.length == 1) {
// 单聊会话members只有一个人,过滤不返回(im-client未查询到数据)
continue;
}
}
// 查询会话的最后一条消息
OfflineMsgDto lastMsg = imMessageService.getLastMsgByConversationId(myconversationlistvo.getId(), currentClient.getId());
myconversationlistvo.setLastMsg(lastMsg);
if (myconversationlistvo.getBeAtCount() > 0) {
myconversationlistvo.setIsBeAt(Boolean.TRUE);
Integer notReadCount = notReadMap.get(conversationVo.getId());
if (notReadCount != null) {
conversationVo.setMsgNotReadCount(notReadCount);
} else {
conversationVo.setMsgNotReadCount(0);
}
Integer beAtCount = beAtCountMap.get(conversationVo.getId());
if (beAtCount != null && beAtCount > 0) {
conversationVo.setIsBeAt(Boolean.TRUE);
} else {
conversationVo.setIsBeAt(Boolean.FALSE);
}
myImConversationListAndMsgCountNew.add(myconversationlistvo);
// todo 优化为批量 查询会话的最后一条消息
OfflineMsgDto lastMsg = imMessageService.getLastMsgByConversationId(conversationVo.getId(), currentClient.getId());
conversationVo.setLastMsg(lastMsg);
conversationListToReturn.add(conversationVo);
}
log.info("{} 查询加入的会话列表结果条数 {}", currentClient.getClientId(), myImConversationListAndMsgCountNew.size());
return myImConversationListAndMsgCountNew;
log.info("{} 查询加入的会话列表结果条数 {}", currentClient.getClientId(), conversationListToReturn.size());
return conversationListToReturn;
} catch (Exception e) {
log.info("查询所有会话异常 ", e);
throw new BusinessException("查询错误,稍后重试");
......@@ -884,7 +912,7 @@ public class ImConversationServiceImpl extends BaseServiceImpl<ImConversationMap
}
}
// 查询用户加入的所有会话 与每个会话的未读条数 成员
List<ConversationVo> conversationList = imConversationMapper.getMyImConversationListAndMsgCount(client.getId(), client.getClientId(), param.getId());
List<ConversationVo> conversationList = imConversationMapper.getMyImConversationListAndMsgCount(client.getId(), param.getId());
if (CollectionUtils.isEmpty(conversationList)) {
return null;
}
......
......@@ -9,12 +9,15 @@ import com.wecloud.im.param.MsgReadStatusUpdateParam;
import com.wecloud.im.param.UpdateMsgReadStatusByConversationParam;
import com.wecloud.im.service.ImClientService;
import com.wecloud.im.service.ImInboxService;
import com.wecloud.im.vo.ConversationCountVo;
import io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 消息收件箱表 服务实现类
*
......@@ -40,12 +43,17 @@ public class ImInboxServiceImpl extends BaseServiceImpl<ImInboxMapper, ImInbox>
/**
* 统计未读消息数量
*
* @param clientId
* @param fkClientId
* @return
*/
@Override
public Integer countMyNotReadCount(Long clientId) {
return imInboxMapper.countMyNotReadCount(clientId);
public List<ConversationCountVo> countNotRead(Long fkClientId) {
return imInboxMapper.countMyNotRead(fkClientId);
}
@Override
public List<ConversationCountVo> countBeAt(ImClient imClient) {
return imInboxMapper.countBeAt(imClient.getId(), imClient.getClientId());
}
@Override
......
package com.wecloud.im.service.impl;
import com.wecloud.im.entity.ImClientBlacklist;
import com.wecloud.im.param.ImConversationQueryVo;
import com.wecloud.im.post.MessageBuilder;
import io.geekidea.springbootplus.framework.common.api.ApiCode;
......@@ -295,29 +296,11 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes
log.info("membersList为空,toConversationId:" + messageById.getFkConversationId());
throw new BusinessException("该会话成员列表为空");
}
// 删除inbox数据
imInboxService.remove(new QueryWrapper<ImInbox>().lambda()
.eq(ImInbox::getFkMsgId, imMsgRecall.getMsgId()));
// 遍历发送
for (ImConversationMembers conversationMembers : membersList) {
// // 保存收件箱
// long imInboxId = SnowflakeUtil.getId();
// ImInbox imInbox = new ImInbox();
// imInbox.setId(imInboxId);
// imInbox.setCreateTime(new Date());
// imInbox.setFkAppid(imApplication.getId());
// imInbox.setReceiver(conversationMembers.getFkClientId());
// imInbox.setFkMsgId(messageId);
// imInbox.setReadMsgStatus(0);
// imInbox.setReceiverMsgStatus(0);
// imInbox.setFkConversationId(toConversationId);
// imInboxService.save(imInbox);
// 查询接收方
ImClient imClientReceiver = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, imApplication.getId())
.eq(ImClient::getId, conversationMembers.getFkClientId()));
if (imClientReceiver == null) {
continue;
}
for (ImConversationMembers member : membersList) {
// 封装响应的实体
ImMessageOnlineSend imMessageOnlineSend = new ImMessageOnlineSend();
BeanUtils.copyProperties(messageById, imMessageOnlineSend);
......@@ -328,7 +311,7 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes
Map<String, Object> contentMap = Maps.newHashMap();
contentMap.put("msgOwner", msgOwner.getClientId());
imMessageOnlineSend.setContent(contentMap);
imMessageOnlineSend.setConversationId(conversationMembers.getFkConversationId());
imMessageOnlineSend.setConversationId(member.getFkConversationId());
imMessageOnlineSend.setWithdraw(Boolean.TRUE);
imMessageOnlineSend.setEvent(Boolean.TRUE);
......@@ -340,10 +323,10 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes
responseModel.setMsg(result.getMessage());
responseModel.setData(imMessageOnlineSend);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, imClientReceiver.getId());
channelSender.sendMsg(responseModel, member.getFkClientId());
// 异步推送系统通知消息
PushDTO pushDTO = mqSender.buildPushDto(imMsgRecall.getPush(), imClientReceiver.getId(), imClientReceiver.getClientId(), imApplication);
PushDTO pushDTO = mqSender.buildPushDto(imMsgRecall.getPush(), member.getFkClientId(), member.getClientId(), imApplication);
if (pushDTO != null) {
mqSender.orderSend(MqConstant.Topic.IM_ORDER_MSG_TOPIC, MqConstant.Tag.IM_ORDER_MSG_TAG, pushDTO);
}
......@@ -403,28 +386,11 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes
log.info("membersList为空,toConversationId:" + message.getFkConversationId());
throw new BusinessException("该会话成员列表为空");
}
// 删除inbox数据
imInboxService.remove(new QueryWrapper<ImInbox>().lambda()
.eq(ImInbox::getFkMsgId, message.getId()));
// 遍历发送
for (ImConversationMembers conversationMembers : membersList) {
// // 保存收件箱
// long imInboxId = SnowflakeUtil.getId();
// ImInbox imInbox = new ImInbox();
// imInbox.setId(imInboxId);
// imInbox.setCreateTime(new Date());
// imInbox.setFkAppid(imApplication.getId());
// imInbox.setReceiver(conversationMembers.getFkClientId());
// imInbox.setFkMsgId(messageId);
// imInbox.setReadMsgStatus(0);
// imInbox.setReceiverMsgStatus(0);
// imInbox.setFkConversationId(toConversationId);
// imInboxService.save(imInbox);
// 查询接收方
ImClient imClientReceiver = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, imApplication.getId())
.eq(ImClient::getId, conversationMembers.getFkClientId()));
if (imClientReceiver == null) {
continue;
}
for (ImConversationMembers member : membersList) {
// 封装响应的实体
ImMessageOnlineSend imMessageOnlineSend = new ImMessageOnlineSend();
BeanUtils.copyProperties(message, imMessageOnlineSend);
......@@ -435,7 +401,7 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes
Map<String, Object> contentMap = Maps.newHashMap();
contentMap.put("msgOwner", msgOwner.getClientId());
imMessageOnlineSend.setContent(contentMap);
imMessageOnlineSend.setConversationId(conversationMembers.getFkConversationId());
imMessageOnlineSend.setConversationId(member.getFkConversationId());
imMessageOnlineSend.setEvent(Boolean.TRUE);
// 向接收方推送
......@@ -446,7 +412,7 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes
responseModel.setMsg(result.getMessage());
responseModel.setData(imMessageOnlineSend);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, imClientReceiver.getId());
channelSender.sendMsg(responseModel, member.getFkClientId());
}
return Boolean.TRUE;
} else {
......
package com.wecloud.im.vo;
import lombok.Data;
import java.io.Serializable;
/**
* @Author Future
* @Date 2022/10/11 19:32
* @Description 统计VO
*/
@Data
public class ConversationCountVo implements Serializable {
private static final long serialVersionUID = 5417994988121322697L;
/**
* 会话id
*/
private Long conversationId;
/**
* 未读消息数量
*/
private Integer count;
}
......@@ -49,7 +49,7 @@ public class ConversationVo implements Serializable {
private Boolean systemFlag;
@ApiModelProperty("未读消息条数")
private Long msgNotReadCount;
private Integer msgNotReadCount;
@ApiModelProperty("成员")
private String members;
......
......@@ -41,24 +41,11 @@
im_client.client_id AS creator,
imConversationMembers.is_top as top,
imConversationMembers.is_do_not_disturb as do_not_disturb,
(SELECT COUNT(im_inbox.id)
FROM im_inbox
INNER JOIN im_message ON im_inbox.fk_msg_id = im_message.id
WHERE im_inbox.fk_conversation_id = imConversation.id
AND im_inbox.receiver = #{currentClientId}
AND im_inbox.read_msg_status = 0
AND im_message.withdraw = 0) AS msg_not_read_count,
(SELECT COUNT(*)
FROM im_inbox INNER JOIN im_message ON im_inbox.fk_msg_id = im_message.id
WHERE im_inbox.fk_conversation_id = imConversation.id
AND im_inbox.receiver = #{currentClientId}
AND im_inbox.read_msg_status = 0
AND (FIND_IN_SET(#{clientId},im_message.`at`) > 0 or FIND_IN_SET('-1',im_message.`at`) > 0)) AS beAtCount,
(
SELECT GROUP_CONCAT(im_client.client_id)
FROM im_conversation_members AS im_conversation_members
INNER JOIN im_client AS im_client ON im_client.id = im_conversation_members.fk_client_id
WHERE im_conversation_members.fk_conversation_id = imConversation.id
WHERE im_conversation_members.fk_conversation_id = imConversation.id and imConversation.chat_type=1
) AS members
FROM im_conversation_members AS imConversationMembers
INNER JOIN im_conversation AS imConversation
......
......@@ -46,11 +46,22 @@
from im_Inbox
</select>
<select id="countMyNotReadCount" resultType="java.lang.Integer">
SELECT COUNT(*)
<select id="countMyNotRead" resultType="com.wecloud.im.vo.ConversationCountVo">
SELECT fk_conversation_id conversationId, COUNT(*) as count
FROM im_inbox
WHERE receiver = #{clientId}
WHERE receiver = #{fkClientId}
AND receiver_msg_status = 0
</select>
<select id="countBeAt" resultType="com.wecloud.im.vo.ConversationCountVo">
SELECT im_inbox.fk_conversation_id conversationId, COUNT(*) as count
FROM im_inbox INNER JOIN im_message ON im_inbox.fk_msg_id = im_message.id
WHERE receiver = #{fkClientId}
AND receiver_msg_status = 0
AND (
FIND_IN_SET( #{clientId}, im_message.`at` ) > 0
OR FIND_IN_SET( '-1', im_message.`at` ) > 0
)
</select>
</mapper>
......@@ -37,7 +37,7 @@ public class MessageScheduled {
@Scheduled(cron = "0 0 3 * * ?")
public void inboxDelete() {
log.info("离线消息处理定时器处理开始...");
// 30天之前数据, 直接删除
// 15天之前数据, 直接删除
Date allDeleteTime = DateUtils.addDays(new Date(), -15);
imInboxService.remove(new QueryWrapper<ImInbox>().lambda()
.lt(ImInbox::getCreateTime, allDeleteTime));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment