157 lines
5.9 KiB
C#
157 lines
5.9 KiB
C#
using AutoMapper;
|
|
using GroupService.Domain.IReposities;
|
|
using GroupService.Domain.ValueObjects;
|
|
using GroupService.WebApi.Application.Dtos;
|
|
using GroupService.WebApi.Application.IntegrationServices;
|
|
using IM.Commons;
|
|
|
|
namespace GroupService.WebApi.Application.GroupInvitation
|
|
{
|
|
public class GroupInvitationService
|
|
{
|
|
private readonly IGroupInvitationReposity reposity;
|
|
private readonly IGroupMemberReposity memberReposity;
|
|
private readonly IIdentityIntegrationService idService;
|
|
private readonly IGroupReposity groupReposity;
|
|
private readonly IMapper mapper;
|
|
|
|
public GroupInvitationService(IGroupInvitationReposity reposity, IGroupMemberReposity memberReposity, IIdentityIntegrationService idService, IGroupReposity groupReposity, IMapper mapper)
|
|
{
|
|
this.reposity = reposity;
|
|
this.memberReposity = memberReposity;
|
|
this.idService = idService;
|
|
this.groupReposity = groupReposity;
|
|
this.mapper = mapper;
|
|
}
|
|
|
|
public async Task<Result<GroupInvitationResponse>> CreateAsync(Guid operatorId, Guid userId, Guid groupId)
|
|
{
|
|
var userRes = await idService.FindUserByIdAsync(userId);
|
|
if (!userRes.Succeeded)
|
|
{
|
|
return Result<GroupInvitationResponse>.Fail(userRes);
|
|
}
|
|
var operatorInfo = await idService.FindUserByIdAsync(operatorId);
|
|
|
|
var member = await memberReposity.FindOneByGroupIdAndUserIdAsync(groupId, operatorId);
|
|
if (member == null)
|
|
{
|
|
return Result.Fail<GroupInvitationResponse>(ResultCode.PERMISSION_DENIED);
|
|
}
|
|
|
|
// 检查是否已存在对该用户的未处理邀请,避免 Duplicate entry 报错
|
|
var existing = await reposity.FindByGroupIdAndUserIdAsync(groupId, userId);
|
|
if (existing != null)
|
|
{
|
|
return Result.Success(mapper.Map<GroupInvitationResponse>(existing));
|
|
}
|
|
|
|
var group = await groupReposity.FindByIdAsync(groupId);
|
|
|
|
var userProfile = new UserProfile()
|
|
{
|
|
Avatar = userRes.Data.Avatar,
|
|
NickName = userRes.Data.NickName
|
|
};
|
|
|
|
var operatorProfile = new UserProfile()
|
|
{
|
|
Avatar = operatorInfo.Data.Avatar,
|
|
NickName = operatorInfo.Data.NickName
|
|
};
|
|
|
|
var groupProfile = new GroupProfile()
|
|
{
|
|
Avatar = group.Avatar,
|
|
GroupName = group.Name
|
|
};
|
|
|
|
var invitation = new Domain.Entities.GroupInvitation(groupId, groupProfile, userId, userProfile
|
|
, operatorId, operatorProfile);
|
|
reposity.Create(invitation);
|
|
|
|
return Result.Success(mapper.Map<GroupInvitationResponse>(invitation));
|
|
}
|
|
|
|
public async Task<Result<object>> CreateBatchAsync(Guid operatorId, List<Guid> userIds, Guid groupId)
|
|
{
|
|
var group = await groupReposity.FindByIdAsync(groupId);
|
|
if (group is null)
|
|
return Result.Fail(ResultCode.GROUP_NOT_FOUND);
|
|
|
|
// 校验操作者是否有权限(群成员/管理员/群主)
|
|
var operatorMember = await memberReposity.FindOneByGroupIdAndUserIdAsync(groupId, operatorId);
|
|
if (operatorMember == null)
|
|
return Result.Fail(ResultCode.PERMISSION_DENIED);
|
|
|
|
var operatorInfo = await idService.FindUserByIdAsync(operatorId);
|
|
var operatorProfile = new UserProfile()
|
|
{
|
|
Avatar = operatorInfo.Data?.Avatar,
|
|
NickName = operatorInfo.Data?.NickName ?? string.Empty
|
|
};
|
|
|
|
var groupProfile = new GroupProfile()
|
|
{
|
|
Avatar = group.Avatar,
|
|
GroupName = group.Name
|
|
};
|
|
|
|
// 批量创建邀请,跳过已存在未处理邀请的用户
|
|
foreach (var userId in userIds)
|
|
{
|
|
var existing = await reposity.FindByGroupIdAndUserIdAsync(groupId, userId);
|
|
if (existing != null)
|
|
continue;
|
|
|
|
var userRes = await idService.FindUserByIdAsync(userId);
|
|
if (!userRes.Succeeded)
|
|
continue;
|
|
|
|
var userProfile = new UserProfile()
|
|
{
|
|
Avatar = userRes.Data?.Avatar,
|
|
NickName = userRes.Data?.NickName ?? string.Empty
|
|
};
|
|
|
|
var invitation = new Domain.Entities.GroupInvitation(
|
|
groupId, groupProfile, userId, userProfile, operatorId, operatorProfile);
|
|
reposity.Create(invitation);
|
|
}
|
|
|
|
return Result.Success();
|
|
}
|
|
public async Task<Result<object>> HandleAsync(GroupInvitationHandleCommand command)
|
|
{
|
|
var invitation = await reposity.FindByIdAsync(command.InvitationId);
|
|
if (invitation is null || invitation.UserId != command.UserId)
|
|
{
|
|
return Result.Fail(ResultCode.GROUP_INVITE_EXPIRED);
|
|
}
|
|
|
|
if (command.Action == GroupInvitationAction.Accept)
|
|
{
|
|
invitation.Accept();
|
|
}
|
|
else if (command.Action == GroupInvitationAction.Reject)
|
|
{
|
|
invitation.Reject();
|
|
}
|
|
|
|
return Result.Success();
|
|
}
|
|
|
|
public async Task<Result<GroupInvitationResponse>> GetByIdAsync(Guid id, Guid userId)
|
|
{
|
|
var invitation = await reposity.FindByIdAsync(id);
|
|
|
|
if (invitation is null || (invitation.UserId != userId && invitation.OperatorId != userId))
|
|
{
|
|
return Result.Fail<GroupInvitationResponse>(ResultCode.GROUP_INVITE_EXPIRED);
|
|
}
|
|
|
|
return Result.Success(mapper.Map<GroupInvitationResponse>(invitation));
|
|
}
|
|
}
|
|
}
|