using AutoMapper; using IM_API.Domain.Events; using IM_API.Dtos; using IM_API.Exceptions; using IM_API.Interface.Services; using IM_API.Models; using IM_API.Tools; using MassTransit; using Microsoft.EntityFrameworkCore; namespace IM_API.Services { public class FriendService : IFriendSerivce { private readonly ImContext _context; private readonly ILogger _logger; private readonly IMapper _mapper; private readonly IPublishEndpoint _endpoint; public FriendService(ImContext context, ILogger logger, IMapper mapper, IPublishEndpoint endpoint) { _context = context; _logger = logger; _mapper = mapper; _endpoint = endpoint; } #region 拉黑好友 public async Task BlockeFriendAsync(int friendId) { var friend = await _context.Friends.FirstOrDefaultAsync(x => x.Id == friendId); if (friend == null) throw new BaseException(CodeDefine.FRIEND_RELATION_NOT_FOUND); friend.StatusEnum = FriendStatus.Blocked; await _context.SaveChangesAsync(); return true; } #endregion #region 通过用户id拉黑好友 public async Task BlockFriendByUserIdAsync(int userId, int toUserId) { var friend = await _context.Friends.FirstOrDefaultAsync(x => x.UserId == userId && x.FriendId == toUserId); if (friend == null) throw new BaseException(CodeDefine.FRIEND_RELATION_NOT_FOUND); friend.StatusEnum = FriendStatus.Blocked; await _context.SaveChangesAsync(); return true; } #endregion #region 删除好友关系 public async Task DeleteFriendAsync(int friendId) { var friend = await _context.Friends.FirstOrDefaultAsync(x => x.Id == friendId); if (friend is null) throw new BaseException(CodeDefine.FRIEND_RELATION_NOT_FOUND); _context.Friends.Remove(friend); await _context.SaveChangesAsync(); return true; } #endregion #region 通过用户id删除好友关系 public async Task DeleteFriendByUserIdAsync(int userId, int toUserId) { var friend = await _context.Friends.FirstOrDefaultAsync(x => x.UserId == userId && x.FriendId == toUserId); if (friend is null) throw new BaseException(CodeDefine.FRIEND_RELATION_NOT_FOUND); _context.Friends.Remove(friend); await _context.SaveChangesAsync(); return true; } #endregion #region 获取好友列表 public async Task> GetFriendListAsync(int userId, int page, int limit, bool desc) { var query = _context.Friends.Include(u => u.FriendNavigation).Where(x => x.UserId == userId && x.Status == (sbyte)FriendStatus.Added); if (desc) { query = query.OrderByDescending(x => x.UserId); } var friendList = await query.Skip(((page - 1) * limit)).Take(limit).ToListAsync(); return _mapper.Map>(friendList); } #endregion #region 获取好友请求列表 public async Task> GetFriendRequestListAsync(int userId, int page, int limit, bool desc) { var query = _context.FriendRequests .Include(x => x.ResponseUserNavigation) .Include(x => x.RequestUserNavigation) .Where( x => (x.ResponseUser == userId) || x.RequestUser == userId ) .Select(s => new FriendRequestResDto { Id = s.Id, RequestUser = s.RequestUser, ResponseUser = s.ResponseUser, Avatar = s.RequestUser == userId ? s.ResponseUserNavigation.Avatar : s.RequestUserNavigation.Avatar, Created = s.Created, NickName = s.RequestUser == userId ? s.ResponseUserNavigation.NickName : s.RequestUserNavigation.NickName, Description = s.Description, State = (FriendRequestState)s.State }) ; query = query.OrderByDescending(x => x.Id); var friendRequestList = await query.Skip(((page - 1) * limit)).Take(limit).ToListAsync(); return friendRequestList; } #endregion #region 处理好友请求 public async Task HandleFriendRequestAsync(HandleFriendRequestDto requestDto) { //查询好友请求记录 var friendRequest = await _context.FriendRequests .Include(e => e.ResponseUserNavigation) .FirstOrDefaultAsync(x => x.Id == requestDto.RequestId); if (friendRequest is null) throw new BaseException(CodeDefine.FRIEND_REQUEST_NOT_FOUND); //查询好友关系 var friend = await _context.Friends.FirstOrDefaultAsync( x => x.UserId == friendRequest.RequestUser && x.FriendId == friendRequest.ResponseUser ); if (friend is null) throw new BaseException(CodeDefine.FRIEND_RELATION_NOT_FOUND); if (friend.StatusEnum != FriendStatus.Pending) throw new BaseException(CodeDefine.FRIEND_REQUEST_EXISTS); //处理好友请求操作 switch (requestDto.Action) { //拒绝后标记 case HandleFriendRequestAction.Reject: friend.StatusEnum = FriendStatus.Declined; friendRequest.StateEnum = FriendRequestState.Declined; break; //同意后标记 case HandleFriendRequestAction.Accept: friendRequest.StateEnum = FriendRequestState.Passed; await _endpoint.Publish(new FriendAddEvent() { AggregateId = friendRequest.Id.ToString(), OccurredAt = DateTime.UtcNow, Created = DateTime.UtcNow, EventId = Guid.NewGuid(), OperatorId = friendRequest.ResponseUser, RequestInfo = _mapper.Map(friendRequest), requestUserRemarkname = requestDto.RemarkName, }); break; //无效操作 default: throw new BaseException(CodeDefine.INVALID_ACTION); } await _context.SaveChangesAsync(); return true; } #endregion #region 发起好友请求 public async Task SendFriendRequestAsync(FriendRequestDto dto) { //查询用户是否存在 bool isExist = await _context.Users.AnyAsync(x => x.Id == dto.ToUserId); if (!isExist) throw new BaseException(CodeDefine.USER_NOT_FOUND); bool isExistUser2 = await _context.Users.AnyAsync(x => x.Id == dto.FromUserId); if(!isExistUser2) throw new BaseException(CodeDefine.USER_NOT_FOUND); // 检查是否已有好友关系或待处理请求 bool alreadyExists = await _context.FriendRequests.AnyAsync(x => x.RequestUser == dto.FromUserId && x.ResponseUser == dto.ToUserId && x.State == (sbyte)FriendRequestState.Pending ); if (alreadyExists) throw new BaseException(CodeDefine.FRIEND_REQUEST_EXISTS); var friendShip = await _context.Friends.FirstOrDefaultAsync(x => x.UserId == dto.FromUserId && x.FriendId == dto.ToUserId); //检查是否被对方拉黑 bool isBlocked = friendShip != null && friendShip.StatusEnum == FriendStatus.Blocked; if (isBlocked) throw new BaseException(CodeDefine.FRIEND_REQUEST_REJECTED); if (friendShip != null) throw new BaseException(CodeDefine.ALREADY_FRIENDS); //生成实体 var friendRequst = _mapper.Map(dto); _context.FriendRequests.Add(friendRequst); await _context.SaveChangesAsync(); await _endpoint.Publish(new RequestFriendEvent() { AggregateId = friendRequst.Id.ToString(), OccurredAt = friendRequst.Created, Description = friendRequst.Description, EventId = Guid.NewGuid(), FromUserId = friendRequst.RequestUser, ToUserId = friendRequst.ResponseUser, OperatorId = friendRequst.RequestUser }); return true; } #endregion #region 创建好友关系 public async Task MakeFriendshipAsync(int userAId, int userBId, string? remarkName) { bool userAexist = await _context.Friends.AnyAsync(x => x.UserId == userAId && x.FriendId == userBId); if (!userAexist) { User? userbInfo = await _context.Users.FirstOrDefaultAsync(x => x.Id == userBId); if (userbInfo is null) throw new BaseException(CodeDefine.USER_NOT_FOUND); Friend friendA = new Friend() { Avatar = userbInfo.Avatar, Created = DateTime.UtcNow, FriendId = userbInfo.Id, RemarkName = remarkName ?? userbInfo.NickName, StatusEnum = FriendStatus.Added, UserId = userAId }; _context.Friends.Add(friendA); await _context.SaveChangesAsync(); } } #endregion } }