IM/backend/IM_API/Services/GroupService.cs
nanxun 77db20dc38 前端:
1、完善创建群聊逻辑
后端:
1、完善群聊相关接口
2026-02-11 22:44:28 +08:00

252 lines
9.8 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;
private readonly IUserService _userService;
public GroupService(ImContext context, IMapper mapper, ILogger<GroupService> logger,
IPublishEndpoint publishEndpoint, IUserService userService)
{
_context = context;
_mapper = mapper;
_logger = logger;
_endPoint = publishEndpoint;
_userService = userService;
}
private async Task<List<int>> validFriendshipAsync (int userId, List<int> ids)
{
DateTime dateTime = DateTime.UtcNow;
//验证被邀请用户是否为好友
return await _context.Friends
.Where(f => f.UserId == userId && ids.Contains(f.FriendId))
.Select(f => f.FriendId)
.ToListAsync();
}
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();
if (userIds.Count > 0)
{
//邀请好友
await InviteUsersAsync(userId, group.Id ,userIds);
}
await transaction.CommitAsync();
await _endPoint.Publish(new GroupJoinEvent
{
EventId = Guid.NewGuid(),
AggregateId = userId.ToString(),
GroupId = group.Id,
OccurredAt = dateTime,
OperatorId = userId,
UserId = userId,
IsCreated = true
});
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);
//过滤非好友
var groupInviteIds = await validFriendshipAsync(userId, userIds);
var inviteList = groupInviteIds.Select(id => new GroupInvite
{
Created = DateTime.UtcNow,
GroupId = group.Id,
InviteUser = userId,
InvitedUser = id,
StateEnum = GroupInviteState.Pending
}).ToList();
_context.GroupInvites.AddRange(inviteList);
await _context.SaveChangesAsync();
await _endPoint.Publish(new GroupInviteEvent
{
GroupId = groupId,
AggregateId = userId.ToString(),
OccurredAt = DateTime.UtcNow,
EventId = Guid.NewGuid(),
Ids = userIds,
OperatorId = userId,
UserId = userId
});
}
public async Task MakeGroupMemberAsync(int userId, int groupId ,GroupMemberRole? role)
{
var isExist = await _context.GroupMembers.AnyAsync(x => x.GroupId == groupId && x.UserId == userId);
if (isExist) return;
var groupMember = new GroupMember
{
UserId = userId,
Created = DateTime.UtcNow,
RoleEnum = role ?? GroupMemberRole.Normal,
GroupId = groupId
};
_context.GroupMembers.Add(groupMember);
await _context.SaveChangesAsync();
}
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;
}
public async Task UpdateGroupConversationAsync(GroupUpdateConversationDto dto)
{
var group = await _context.Groups.FirstOrDefaultAsync(x => x.Id == dto.GroupId);
if (group is null) return;
group.LastMessage = dto.LastMessage;
group.MaxSequenceId = dto.MaxSequenceId;
group.LastSenderName = dto.LastSenderName;
group.LastUpdateTime = dto.LastUpdateTime;
_context.Groups.Update(group);
await _context.SaveChangesAsync();
}
public async Task HandleGroupInviteAsync(int userid, HandleGroupInviteDto dto)
{
var user = _userService.GetUserInfoAsync(userid);
var inviteInfo = await _context.GroupInvites.FirstOrDefaultAsync(x => x.Id == dto.InviteId)
?? throw new BaseException(CodeDefine.INVALID_ACTION);
if (inviteInfo.InvitedUser != userid) throw new BaseException(CodeDefine.AUTH_FAILED);
inviteInfo.StateEnum = dto.Action;
_context.GroupInvites.Update(inviteInfo);
await _context.SaveChangesAsync();
await _endPoint.Publish(new GroupInviteActionUpdateEvent
{
Action = dto.Action,
AggregateId = userid.ToString(),
OccurredAt = DateTime.UtcNow,
EventId = Guid.NewGuid(),
GroupId = inviteInfo.GroupId,
InviteId = inviteInfo.Id,
InviteUserId = inviteInfo.InviteUser.Value,
OperatorId = userid,
UserId = userid
});
}
public async Task HandleGroupRequestAsync(int userid, HandleGroupRequestDto dto)
{
var user = _userService.GetUserInfoAsync(userid);
//判断请求存在
var requestInfo = await _context.GroupRequests.FirstOrDefaultAsync(x => x.Id == dto.RequestId)
?? throw new BaseException(CodeDefine.INVALID_ACTION);
//判断成员存在
var memberInfo = await _context.GroupMembers.FirstOrDefaultAsync(x => x.UserId == userid)
?? throw new BaseException(CodeDefine.NO_GROUP_PERMISSION);
//判断成员权限
if (memberInfo.RoleEnum != GroupMemberRole.Master && memberInfo.RoleEnum != GroupMemberRole.Administrator)
throw new BaseException(CodeDefine.NO_GROUP_PERMISSION);
requestInfo.StateEnum = dto.Action;
_context.GroupRequests.Update(requestInfo);
await _context.SaveChangesAsync();
await _endPoint.Publish(new GroupRequestUpdateEvent
{
Action = requestInfo.StateEnum,
AdminUserId = userid,
AggregateId = userid.ToString(),
OccurredAt = DateTime.UtcNow,
EventId = Guid.NewGuid(),
GroupId = requestInfo.GroupId,
OperatorId = userid,
UserId = requestInfo.UserId,
RequestId = requestInfo.Id
});
}
public async Task MakeGroupRequestAsync(int userId, int? adminUserId, int groupId)
{
var requestInfo = await _context.GroupRequests
.FirstOrDefaultAsync(x => x.UserId == userId && x.GroupId == groupId);
if (requestInfo != null) return;
var member = await _context.GroupMembers.FirstOrDefaultAsync(
x => x.UserId == adminUserId && x.GroupId == groupId);
var request = new GroupRequest
{
Created = DateTime.UtcNow,
Description = string.Empty,
GroupId = groupId,
UserId = userId,
StateEnum = GroupRequestState.Pending
};
if(member != null && (
member.RoleEnum == GroupMemberRole.Administrator || member.RoleEnum == GroupMemberRole.Master))
{
request.StateEnum = GroupRequestState.Passed;
}
_context.GroupRequests.Add(request);
await _context.SaveChangesAsync();
await _endPoint.Publish(new GroupRequestEvent
{
OccurredAt = DateTime.UtcNow,
Description = request.Description,
GroupId = request.GroupId,
Action = request.StateEnum,
UserId = userId,
AggregateId = userId.ToString(),
EventId = Guid.NewGuid(),
OperatorId = userId
});
return;
}
}
}