310 lines
11 KiB
C#
310 lines
11 KiB
C#
using FreeSql;
|
|
|
|
using LiveForum.Code.Base;
|
|
using LiveForum.Code.JwtInfrastructure;
|
|
using LiveForum.IService.Users;
|
|
using LiveForum.Model;
|
|
using LiveForum.Model.Dto.UserFollow;
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace LiveForum.Service.Users
|
|
{
|
|
public class UserFollowService : IUserFollowService
|
|
{
|
|
private readonly JwtUserInfoModel _userInfoModel;
|
|
private readonly IBaseRepository<T_Follows> _followsRepository;
|
|
private readonly IBaseRepository<T_Users> _usersRepository;
|
|
|
|
/// <summary>
|
|
/// 构造函数
|
|
/// </summary>
|
|
/// <param name="userInfoModel">JWT用户信息模型</param>
|
|
/// <param name="followsRepository">关注仓储</param>
|
|
/// <param name="usersRepository">用户仓储</param>
|
|
public UserFollowService(
|
|
JwtUserInfoModel userInfoModel,
|
|
IBaseRepository<T_Follows> followsRepository,
|
|
IBaseRepository<T_Users> usersRepository)
|
|
{
|
|
_userInfoModel = userInfoModel;
|
|
_followsRepository = followsRepository;
|
|
_usersRepository = usersRepository;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 关注/取消关注用户
|
|
/// </summary>
|
|
/// <param name="request">请求参数</param>
|
|
/// <returns></returns>
|
|
public async Task<BaseResponse<FollowUserRespDto>> FollowUser(FollowUserReq request)
|
|
{
|
|
var currentUserId = (long)_userInfoModel.UserId;
|
|
|
|
// 1. 不能关注自己
|
|
if (request.UserId == currentUserId)
|
|
{
|
|
return new BaseResponse<FollowUserRespDto>(ResponseCode.Error, "不能关注自己");
|
|
}
|
|
|
|
// 2. 检查目标用户是否存在
|
|
var targetUser = await _usersRepository.Select
|
|
.Where(x => x.Id == request.UserId)
|
|
.FirstAsync();
|
|
|
|
if (targetUser == null)
|
|
{
|
|
return new BaseResponse<FollowUserRespDto>(ResponseCode.Error, "用户不存在");
|
|
}
|
|
|
|
// 3. 查找是否已关注
|
|
var existingFollow = await _followsRepository.Select
|
|
.Where(x => x.FollowerId == currentUserId && x.FollowedUserId == request.UserId)
|
|
.FirstAsync();
|
|
|
|
bool isFollowed = false;
|
|
var followerCount = await _followsRepository.Select
|
|
.Where(x => x.FollowedUserId == request.UserId)
|
|
.CountAsync();
|
|
|
|
if (request.Action == 1) // 关注
|
|
{
|
|
if (existingFollow != null)
|
|
{
|
|
return new BaseResponse<FollowUserRespDto>(ResponseCode.Error, "已关注该用户");
|
|
}
|
|
|
|
// 创建关注关系
|
|
var follow = new T_Follows
|
|
{
|
|
FollowerId = currentUserId,
|
|
FollowedUserId = request.UserId,
|
|
CreatedAt = DateTime.Now
|
|
};
|
|
|
|
await _followsRepository.InsertAsync(follow);
|
|
isFollowed = true;
|
|
followerCount++;
|
|
}
|
|
else if (request.Action == 2) // 取消关注
|
|
{
|
|
if (existingFollow == null)
|
|
{
|
|
return new BaseResponse<FollowUserRespDto>(ResponseCode.Error, "未关注该用户");
|
|
}
|
|
|
|
// 删除关注关系
|
|
await _followsRepository.DeleteAsync(existingFollow);
|
|
isFollowed = false;
|
|
followerCount = Math.Max(0, followerCount - 1);
|
|
}
|
|
else
|
|
{
|
|
return new BaseResponse<FollowUserRespDto>(ResponseCode.Error, "无效的操作类型");
|
|
}
|
|
|
|
// 4. 构建返回数据
|
|
var result = new FollowUserRespDto
|
|
{
|
|
UserId = request.UserId,
|
|
IsFollowed = isFollowed,
|
|
FollowerCount = (int)followerCount
|
|
};
|
|
|
|
return new BaseResponse<FollowUserRespDto>(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取关注列表
|
|
/// </summary>
|
|
/// <param name="request">请求参数</param>
|
|
/// <returns></returns>
|
|
public async Task<BaseResponse<GetUserFollowingRespDto>> GetUserFollowing(GetUserFollowingReq request)
|
|
{
|
|
var currentUserId = (long)_userInfoModel.UserId;
|
|
|
|
// 构建查询条件 - 获取该用户关注的人
|
|
var query = _followsRepository.Select
|
|
.Where(x => x.FollowerId == request.UserId)
|
|
.OrderByDescending(x => x.CreatedAt);
|
|
|
|
// 获取总数
|
|
var total = await query.CountAsync();
|
|
|
|
// 分页
|
|
var follows = await query
|
|
.Skip((request.PageIndex - 1) * request.PageSize)
|
|
.Take(request.PageSize)
|
|
.ToListAsync();
|
|
|
|
if (!follows.Any())
|
|
{
|
|
return new BaseResponse<GetUserFollowingRespDto>(new GetUserFollowingRespDto
|
|
{
|
|
PageIndex = request.PageIndex,
|
|
PageSize = request.PageSize,
|
|
Total = (int)total,
|
|
TotalPages = (int)Math.Ceiling((double)total / request.PageSize),
|
|
Items = new List<FollowingUserDto>()
|
|
});
|
|
}
|
|
|
|
// 获取被关注的用户ID列表
|
|
var followedUserIds = follows.Select(x => x.FollowedUserId).ToList();
|
|
|
|
// 获取用户信息
|
|
var users = await _usersRepository.Select
|
|
.Where(x => followedUserIds.Contains(x.Id))
|
|
.ToListAsync();
|
|
|
|
// 构建用户ID字典
|
|
var userDict = users.ToDictionary(x => x.Id, x => x);
|
|
|
|
// 检查当前用户是否已关注这些用户(互相关注状态)
|
|
var currentUserFollowedIds = new HashSet<long>();
|
|
if (request.UserId != currentUserId)
|
|
{
|
|
var myFollows = await _followsRepository.Select
|
|
.Where(x => x.FollowerId == currentUserId && followedUserIds.Contains(x.FollowedUserId))
|
|
.ToListAsync();
|
|
|
|
foreach (var follow in myFollows)
|
|
{
|
|
currentUserFollowedIds.Add(follow.FollowedUserId);
|
|
}
|
|
}
|
|
|
|
// 构建返回数据
|
|
var items = follows.Select(follow =>
|
|
{
|
|
var user = userDict.ContainsKey(follow.FollowedUserId) ? userDict[follow.FollowedUserId] : null;
|
|
|
|
if (user == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return new FollowingUserDto
|
|
{
|
|
UserId = user.Id,
|
|
UserName = user.NickName,
|
|
NickName = user.NickName,
|
|
Avatar = user.Avatar ?? "",
|
|
IsVip = user.IsVip,
|
|
IsCertified = user.IsCertified,
|
|
Signature = user.Signature ?? "",
|
|
FollowedAt = follow.CreatedAt,
|
|
IsFollowed = request.UserId == currentUserId || currentUserFollowedIds.Contains(follow.FollowedUserId)
|
|
};
|
|
}).Where(x => x != null).ToList();
|
|
|
|
return new BaseResponse<GetUserFollowingRespDto>(new GetUserFollowingRespDto
|
|
{
|
|
PageIndex = request.PageIndex,
|
|
PageSize = request.PageSize,
|
|
Total = (int)total,
|
|
TotalPages = (int)Math.Ceiling((double)total / request.PageSize),
|
|
Items = items
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取粉丝列表
|
|
/// </summary>
|
|
/// <param name="request">请求参数</param>
|
|
/// <returns></returns>
|
|
public async Task<BaseResponse<GetUserFollowersRespDto>> GetUserFollowers(GetUserFollowersReq request)
|
|
{
|
|
var currentUserId = (long)_userInfoModel.UserId;
|
|
|
|
// 构建查询条件 - 获取关注该用户的人
|
|
var query = _followsRepository.Select
|
|
.Where(x => x.FollowedUserId == request.UserId)
|
|
.OrderByDescending(x => x.CreatedAt);
|
|
|
|
// 获取总数
|
|
var total = await query.CountAsync();
|
|
|
|
// 分页
|
|
var follows = await query
|
|
.Skip((request.PageIndex - 1) * request.PageSize)
|
|
.Take(request.PageSize)
|
|
.ToListAsync();
|
|
|
|
if (!follows.Any())
|
|
{
|
|
return new BaseResponse<GetUserFollowersRespDto>(new GetUserFollowersRespDto
|
|
{
|
|
PageIndex = request.PageIndex,
|
|
PageSize = request.PageSize,
|
|
Total = (int)total,
|
|
TotalPages = (int)Math.Ceiling((double)total / request.PageSize),
|
|
Items = new List<FollowerUserDto>()
|
|
});
|
|
}
|
|
|
|
// 获取粉丝用户ID列表
|
|
var followerUserIds = follows.Select(x => x.FollowerId).ToList();
|
|
|
|
// 获取用户信息
|
|
var users = await _usersRepository.Select
|
|
.Where(x => followerUserIds.Contains(x.Id))
|
|
.ToListAsync();
|
|
|
|
// 构建用户ID字典
|
|
var userDict = users.ToDictionary(x => x.Id, x => x);
|
|
|
|
// 检查当前用户是否已关注这些粉丝(互相关注状态)
|
|
var currentUserFollowedIds = new HashSet<long>();
|
|
if (request.UserId != currentUserId)
|
|
{
|
|
var myFollows = await _followsRepository.Select
|
|
.Where(x => x.FollowerId == currentUserId && followerUserIds.Contains(x.FollowedUserId))
|
|
.ToListAsync();
|
|
|
|
foreach (var follow in myFollows)
|
|
{
|
|
currentUserFollowedIds.Add(follow.FollowedUserId);
|
|
}
|
|
}
|
|
|
|
// 构建返回数据
|
|
var items = follows.Select(follow =>
|
|
{
|
|
var user = userDict.ContainsKey(follow.FollowerId) ? userDict[follow.FollowerId] : null;
|
|
|
|
if (user == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return new FollowerUserDto
|
|
{
|
|
UserId = user.Id,
|
|
UserName = user.NickName,
|
|
NickName = user.NickName,
|
|
Avatar = user.Avatar ?? "",
|
|
IsVip = user.IsVip,
|
|
IsCertified = user.IsCertified,
|
|
Signature = user.Signature ?? "",
|
|
FollowedAt = follow.CreatedAt,
|
|
IsFollowed = currentUserFollowedIds.Contains(follow.FollowerId)
|
|
};
|
|
}).Where(x => x != null).ToList();
|
|
|
|
return new BaseResponse<GetUserFollowersRespDto>(new GetUserFollowersRespDto
|
|
{
|
|
PageIndex = request.PageIndex,
|
|
PageSize = request.PageSize,
|
|
Total = (int)total,
|
|
TotalPages = (int)Math.Ceiling((double)total / request.PageSize),
|
|
Items = items
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|