IM/backend/IM_API/Services/GroupService.cs
nanxun 58bc8b4b5a 前端:
1、优化消息排序逻辑
2、新增加载历史消息
3、修复已知问题
后端:
1、优化消息排序逻辑
2、增加用户信息缓存机制
3、修改日期类型为DateTimeOffset改善时区信息丢失问题
3、修复了已知问题
数据库:
1、新增SequenceId字段用于消息排序
2、新增ClientMsgId字段用于客户端消息回执
2026-02-07 22:37:56 +08:00

130 lines
4.5 KiB
C#

using AutoMapper;
using AutoMapper.QueryableExtensions;
using IM_API.Domain.Events;
using IM_API.Dtos.Group;
using IM_API.Exceptions;
using IM_API.Interface.Services;
using IM_API.Models;
using IM_API.Tools;
using MassTransit;
using Microsoft.EntityFrameworkCore;
using System;
namespace IM_API.Services
{
public class GroupService : IGroupService
{
private readonly ImContext _context;
private readonly IMapper _mapper;
private readonly ILogger<GroupService> _logger;
private readonly IPublishEndpoint _endPoint;
public GroupService(ImContext context, IMapper mapper, ILogger<GroupService> logger, IPublishEndpoint publishEndpoint)
{
_context = context;
_mapper = mapper;
_logger = logger;
_endPoint = publishEndpoint;
}
private async Task<List<GroupInvite>> GetGroupInvites(int userId, int groupId, List<int> ids)
{
DateTime dateTime = DateTime.Now;
//验证被邀请用户是否为好友
var validFriendIds = await _context.Friends
.Where(f => f.UserId == userId && ids.Contains(f.FriendId))
.Select(f => f.FriendId)
.ToListAsync();
//创建群成员对象
return validFriendIds.Select(fid => new GroupInvite
{
Created = dateTime,
GroupId = groupId,
InvitedUser = fid,
StateEnum = GroupInviteState.Pending,
InviteUser = userId
}).ToList();
}
public async Task<GroupInfoDto> CreateGroupAsync(int userId, GroupCreateDto groupCreateDto)
{
List<int> userIds = groupCreateDto.UserIDs ?? [];
using var transaction = await _context.Database.BeginTransactionAsync();
try
{
//先创建群
DateTime dateTime = DateTime.Now;
Group group = _mapper.Map<Group>(groupCreateDto);
group.GroupMaster = userId;
_context.Groups.Add(group);
await _context.SaveChangesAsync();
var groupInvites = new List<GroupInvite>();
if (userIds.Count > 0)
{
groupInvites = await GetGroupInvites(userId,group.Id, userIds);
_context.GroupInvites.AddRange(groupInvites);
}
var groupMember = new GroupMember
{
UserId = userId,
Created = dateTime,
RoleEnum = GroupMemberRole.Master,
GroupId = group.Id
};
_context.GroupMembers.Add(groupMember);
await _context.SaveChangesAsync();
await transaction.CommitAsync();
await _endPoint.Publish(new GroupInviteEvent
{
AggregateId = userId.ToString(),
GroupId = group.Id,
EventId = Guid.NewGuid(),
OccurredAt = dateTime,
Ids = groupInvites.Select(x => x.Id).ToList(),
OperatorId = userId,
UserId = userId
});
return _mapper.Map<GroupInfoDto>(group);
}
catch
{
await transaction.RollbackAsync();
throw;
}
}
public Task DeleteGroupAsync(int userId, int groupId)
{
throw new NotImplementedException();
}
public async Task InviteUsersAsync(int userId, int groupId, List<int> userIds)
{
var group = await _context.Groups.FirstOrDefaultAsync(
x => x.Id == groupId) ?? throw new BaseException(CodeDefine.GROUP_NOT_FOUND);
}
public Task JoinGroupAsync(int userId, int groupId)
{
throw new NotImplementedException();
}
public async Task<List<GroupInfoDto>> GetGroupListAsync(int userId, int page, int limit, bool desc)
{
var query = _context.GroupMembers
.Where(x => x.UserId == userId)
.Select(s => s.Group);
if (desc)
{
query = query.OrderByDescending(x => x.Id);
}
var list = await query
.Skip((page - 1) * limit)
.Take(limit)
.ProjectTo<GroupInfoDto>(_mapper.ConfigurationProvider)
.ToListAsync();
return list;
}
}
}