IM/backend/IM_API/Services/ConversationService.cs
nanxun 77744015de 前端:
1、更新界面图标
2、修改消息缓存逻辑
3、新增清空未读消息数
后端:
1、修复不同时区导致的时间显示问题
2、新增清空未读消息数接口
2026-01-21 18:48:05 +08:00

138 lines
5.6 KiB
C#

using AutoMapper;
using IM_API.Dtos;
using IM_API.Exceptions;
using IM_API.Interface.Services;
using IM_API.Models;
using IM_API.Tools;
using Microsoft.EntityFrameworkCore;
namespace IM_API.Services
{
public class ConversationService : IConversationService
{
private readonly ImContext _context;
private readonly IMapper _mapper;
public ConversationService(ImContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}
#region
public async Task<bool> ClearConversationsAsync(int userId)
{
await _context.Conversations.Where(x => x.UserId == userId).ExecuteDeleteAsync();
return true;
}
#endregion
#region
public async Task<List<ConversationDto>> 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
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
select new { c, g.Avatar, g.Name })
.ToListAsync();
var privateDtos = privateList.Select(x =>
{
var dto = _mapper.Map<ConversationDto>(x.c);
dto.TargetAvatar = x.Avatar;
dto.TargetName = x.RemarkName;
return dto;
});
var groupDtos = groupList.Select(x =>
{
var dto = _mapper.Map<ConversationDto>(x.c);
dto.TargetAvatar = x.Avatar;
dto.TargetName = x.Name;
return dto;
});
// 4. 合并并排序
return privateDtos.Concat(groupDtos)
.OrderByDescending(x => x.DateTime)
.ToList();
}
#endregion
#region
public async Task<bool> DeleteConversationAsync(int conversationId)
{
var conversation = await _context.Conversations.FirstOrDefaultAsync(x => x.Id == conversationId);
if (conversation == null) throw new BaseException(CodeDefine.CONVERSATION_NOT_FOUND);
_context.Conversations.Remove(conversation);
await _context.SaveChangesAsync();
return true;
}
#endregion
#region
public async Task<List<string>> GetUserAllStreamKeyAsync(int userId)
{
return await _context.Conversations.Where(x => x.UserId == userId)
.Select(x => x.StreamKey)
.Distinct()
.ToListAsync();
}
#endregion
#region
public async Task<ConversationDto> 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 friendInfo = await _context.Friends.FirstOrDefaultAsync(
x => x.UserId == 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)
{
var groupInfo = await _context.Groups.FirstOrDefaultAsync(
x => x.Id == conversation.TargetId
);
if (groupInfo is null) throw new BaseException(CodeDefine.GROUP_NOT_FOUND);
_mapper.Map(groupInfo, dto);
}
return dto;
}
#endregion
public async Task<bool> ClearUnreadCountAsync(int userId, int conversationId)
{
var conversation = await _context.Conversations.FirstOrDefaultAsync(x => x.UserId == userId && x.Id == conversationId);
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)
.FirstOrDefaultAsync();
conversation.LastReadMessage = message;
conversation.UnreadCount = 0;
_context.Conversations.Update(conversation);
await _context.SaveChangesAsync();
return true;
}
}
}