前端:
1、优化消息排序逻辑 2、新增加载历史消息 3、修复已知问题 后端: 1、优化消息排序逻辑 2、增加用户信息缓存机制 3、修改日期类型为DateTimeOffset改善时区信息丢失问题 3、修复了已知问题 数据库: 1、新增SequenceId字段用于消息排序 2、新增ClientMsgId字段用于客户端消息回执
This commit is contained in:
@@ -4,6 +4,7 @@ using IM_API.Exceptions;
|
||||
using IM_API.Interface.Services;
|
||||
using IM_API.Models;
|
||||
using IM_API.Tools;
|
||||
using IM_API.VOs.Conversation;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace IM_API.Services
|
||||
@@ -27,26 +28,26 @@ namespace IM_API.Services
|
||||
|
||||
#endregion
|
||||
#region 获取用户会话列表
|
||||
public async Task<List<ConversationDto>> GetConversationsAsync(int userId)
|
||||
public async Task<List<ConversationVo>> GetConversationsAsync(int userId)
|
||||
{
|
||||
// 1. 获取私聊会话
|
||||
var privateList = await (from c in _context.Conversations
|
||||
join f in _context.Friends on new { c.UserId, c.TargetId }
|
||||
equals new { UserId = f.UserId, TargetId = f.FriendId }
|
||||
where c.UserId == userId && c.ChatType == (int)ChatType.PRIVATE
|
||||
where c.UserId == userId && c.ChatType == ChatType.PRIVATE
|
||||
select new { c, f.Avatar, f.RemarkName })
|
||||
.ToListAsync();
|
||||
|
||||
// 2. 获取群聊会话
|
||||
var groupList = await (from c in _context.Conversations
|
||||
join g in _context.Groups on c.TargetId equals g.Id
|
||||
where c.UserId == userId && c.ChatType == (int)ChatType.GROUP
|
||||
where c.UserId == userId && c.ChatType == ChatType.GROUP
|
||||
select new { c, g.Avatar, g.Name })
|
||||
.ToListAsync();
|
||||
|
||||
var privateDtos = privateList.Select(x =>
|
||||
{
|
||||
var dto = _mapper.Map<ConversationDto>(x.c);
|
||||
var dto = _mapper.Map<ConversationVo>(x.c);
|
||||
dto.TargetAvatar = x.Avatar;
|
||||
dto.TargetName = x.RemarkName;
|
||||
return dto;
|
||||
@@ -54,7 +55,7 @@ namespace IM_API.Services
|
||||
|
||||
var groupDtos = groupList.Select(x =>
|
||||
{
|
||||
var dto = _mapper.Map<ConversationDto>(x.c);
|
||||
var dto = _mapper.Map<ConversationVo>(x.c);
|
||||
dto.TargetAvatar = x.Avatar;
|
||||
dto.TargetName = x.Name;
|
||||
return dto;
|
||||
@@ -89,25 +90,23 @@ namespace IM_API.Services
|
||||
#endregion
|
||||
|
||||
#region 获取单个会话信息
|
||||
public async Task<ConversationDto> GetConversationByIdAsync(int userId, int conversationId)
|
||||
public async Task<ConversationVo> GetConversationByIdAsync(int userId, int conversationId)
|
||||
{
|
||||
var conversation = await _context.Conversations
|
||||
.Include(x => x.LastReadMessage)
|
||||
.FirstOrDefaultAsync(
|
||||
x => x.UserId == userId && x.Id == conversationId
|
||||
);
|
||||
if (conversation is null) throw new BaseException(CodeDefine.CONVERSATION_NOT_FOUND);
|
||||
var dto = _mapper.Map<ConversationDto>(conversation);
|
||||
//dto.LastReadMessage = _mapper.Map<MessageBaseDto>(conversation);
|
||||
if(conversation.ChatType == (int)ChatType.PRIVATE)
|
||||
var dto = _mapper.Map<ConversationVo>(conversation);
|
||||
if(conversation.ChatType == ChatType.PRIVATE)
|
||||
{
|
||||
var friendInfo = await _context.Friends.FirstOrDefaultAsync(
|
||||
x => x.UserId == userId && x.FriendId == conversation.TargetId
|
||||
var friendInfo = await _context.Friends.Include(n => n.FriendNavigation).FirstOrDefaultAsync(
|
||||
x => x.UserId == conversation.UserId && x.FriendId == conversation.TargetId
|
||||
);
|
||||
if (friendInfo is null) throw new BaseException(CodeDefine.FRIEND_RELATION_NOT_FOUND);
|
||||
_mapper.Map(friendInfo,dto);
|
||||
}
|
||||
if(conversation.ChatType == (int)ChatType.GROUP)
|
||||
if(conversation.ChatType == ChatType.GROUP)
|
||||
{
|
||||
var groupInfo = await _context.Groups.FirstOrDefaultAsync(
|
||||
x => x.Id == conversation.TargetId
|
||||
@@ -125,12 +124,18 @@ namespace IM_API.Services
|
||||
if (conversation is null) throw new BaseException(CodeDefine.CONVERSATION_NOT_FOUND);
|
||||
var message = await _context.Messages
|
||||
.Where(x => x.StreamKey == conversation.StreamKey)
|
||||
.OrderByDescending(x => x.Id)
|
||||
.OrderByDescending(x => x.SequenceId)
|
||||
.FirstOrDefaultAsync();
|
||||
conversation.LastReadMessage = message;
|
||||
conversation.UnreadCount = 0;
|
||||
_context.Conversations.Update(conversation);
|
||||
await _context.SaveChangesAsync();
|
||||
if(message != null)
|
||||
{
|
||||
conversation.UnreadCount = 0;
|
||||
conversation.LastMessage = message.Content;
|
||||
conversation.LastReadSequenceId = message.SequenceId;
|
||||
conversation.LastMessageTime = message.Created;
|
||||
_context.Conversations.Update(conversation);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
@@ -143,10 +148,10 @@ namespace IM_API.Services
|
||||
StreamKeyBuilder.Private(userAId, userBId) : StreamKeyBuilder.Group(userBId);
|
||||
var conversation = new Conversation()
|
||||
{
|
||||
ChatType = (int)chatType,
|
||||
ChatType = chatType,
|
||||
LastMessage = "",
|
||||
LastMessageTime = DateTime.UtcNow,
|
||||
LastReadMessageId = -1,
|
||||
LastMessageTime = DateTime.Now,
|
||||
LastReadSequenceId = null,
|
||||
StreamKey = streamKey,
|
||||
TargetId = userBId,
|
||||
UnreadCount = 0,
|
||||
@@ -156,5 +161,19 @@ namespace IM_API.Services
|
||||
_context.Conversations.Add(conversation);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
public async Task UpdateConversationAfterSentAsync(UpdateConversationDto dto)
|
||||
{
|
||||
var cList = await _context.Conversations.Where(x => x.StreamKey == dto.StreamKey).ToListAsync();
|
||||
foreach(var c in cList)
|
||||
{
|
||||
bool isSender = dto.SenderId == c.UserId;
|
||||
c.LastMessage = dto.LastMessage;
|
||||
c.LastMessageTime = dto.DateTime;
|
||||
c.LastReadSequenceId = isSender ? dto.LastSequenceId : c.LastReadSequenceId;
|
||||
c.UnreadCount = isSender ? 0 : c.UnreadCount + 1;
|
||||
}
|
||||
_context.Conversations.UpdateRange(cList);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user