271 lines
10 KiB
C#
271 lines
10 KiB
C#
using AutoMapper;
|
|
using AutoMapper.QueryableExtensions;
|
|
using IM_API.Domain.Events;
|
|
using IM_API.Dtos.Group;
|
|
using IM_API.Dtos.User;
|
|
using IM_API.Exceptions;
|
|
using IM_API.Interface.Services;
|
|
using IM_API.Models;
|
|
using IM_API.Tools;
|
|
using IM_API.VOs.Group;
|
|
using MassTransit;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System;
|
|
using System.Linq;
|
|
|
|
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;
|
|
}
|
|
|
|
public async Task<List<GroupMemberVo>> GetGroupMembers(int userId, int groupId)
|
|
{
|
|
var members = await _context.GroupMembers
|
|
.Where(x => x.GroupId == groupId).ToListAsync();
|
|
if (members is null || members.Count() == 0)
|
|
return [];
|
|
|
|
var users = await _userService.GetUserInfoListAsync(members.Select(x => x.UserId).ToList());
|
|
return users.Zip(members, (u, m) =>
|
|
{
|
|
var user = _mapper.Map<GroupMemberVo>(u);
|
|
_mapper.Map(m, user);
|
|
return user;
|
|
}).ToList();
|
|
}
|
|
}
|
|
}
|