140 lines
4.8 KiB
C#
140 lines
4.8 KiB
C#
using FreeSql;
|
||
|
||
using LiveForum.IService.Posts;
|
||
using LiveForum.Model;
|
||
|
||
using System;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace LiveForum.Service.Posts
|
||
{
|
||
/// <summary>
|
||
/// 发帖/回复时间间隔校验服务实现
|
||
/// </summary>
|
||
public class PostReplyIntervalService : IPostReplyIntervalService
|
||
{
|
||
private readonly IBaseRepository<T_PostReplyIntervals> _intervalsRepository;
|
||
private readonly IBaseRepository<T_Users> _usersRepository;
|
||
private readonly IBaseRepository<T_Posts> _postsRepository;
|
||
private readonly IBaseRepository<T_Comments> _commentsRepository;
|
||
|
||
/// <summary>
|
||
/// 默认间隔值(未配置时使用),0 表示不限制
|
||
/// </summary>
|
||
private const int DEFAULT_INTERVAL = 0;
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
public PostReplyIntervalService(
|
||
IBaseRepository<T_PostReplyIntervals> intervalsRepository,
|
||
IBaseRepository<T_Users> usersRepository,
|
||
IBaseRepository<T_Posts> postsRepository,
|
||
IBaseRepository<T_Comments> commentsRepository)
|
||
{
|
||
_intervalsRepository = intervalsRepository;
|
||
_usersRepository = usersRepository;
|
||
_postsRepository = postsRepository;
|
||
_commentsRepository = commentsRepository;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户的发帖间隔配置(秒)
|
||
/// </summary>
|
||
public async Task<int> GetPostIntervalAsync(long userId)
|
||
{
|
||
var user = await _usersRepository.Select
|
||
.Where(x => x.Id == userId)
|
||
.FirstAsync();
|
||
|
||
if (user?.CertifiedType == null || user.CertifiedType <= 0)
|
||
return DEFAULT_INTERVAL;
|
||
|
||
var config = await _intervalsRepository.Select
|
||
.Where(x => x.CertificationTypeId == user.CertifiedType.Value)
|
||
.FirstAsync();
|
||
|
||
return config?.PostInterval ?? DEFAULT_INTERVAL;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户的回复间隔配置(秒)
|
||
/// </summary>
|
||
public async Task<int> GetReplyIntervalAsync(long userId)
|
||
{
|
||
var user = await _usersRepository.Select
|
||
.Where(x => x.Id == userId)
|
||
.FirstAsync();
|
||
|
||
if (user?.CertifiedType == null || user.CertifiedType <= 0)
|
||
return DEFAULT_INTERVAL;
|
||
|
||
var config = await _intervalsRepository.Select
|
||
.Where(x => x.CertificationTypeId == user.CertifiedType.Value)
|
||
.FirstAsync();
|
||
|
||
return config?.ReplyInterval ?? DEFAULT_INTERVAL;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户最近一次成功发帖时间
|
||
/// </summary>
|
||
public async Task<DateTime?> GetLastPostTimeAsync(long userId)
|
||
{
|
||
var lastPost = await _postsRepository.Select
|
||
.Where(x => x.UserId == userId && !x.IsDeleted)
|
||
.OrderByDescending(x => x.CreatedAt)
|
||
.FirstAsync();
|
||
|
||
return lastPost?.CreatedAt;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户最近一次成功回复时间
|
||
/// </summary>
|
||
public async Task<DateTime?> GetLastCommentTimeAsync(long userId)
|
||
{
|
||
var lastComment = await _commentsRepository.Select
|
||
.Where(x => x.UserId == userId && !x.IsDeleted)
|
||
.OrderByDescending(x => x.CreatedAt)
|
||
.FirstAsync();
|
||
|
||
return lastComment?.CreatedAt;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 校验发帖间隔,返回 null 表示通过,否则返回剩余秒数
|
||
/// </summary>
|
||
public async Task<int?> CheckPostIntervalAsync(long userId)
|
||
{
|
||
var interval = await GetPostIntervalAsync(userId);
|
||
if (interval <= 0) return null; // 不限制
|
||
|
||
var lastTime = await GetLastPostTimeAsync(userId);
|
||
if (lastTime == null) return null; // 从未发帖
|
||
|
||
var elapsed = (DateTime.Now - lastTime.Value).TotalSeconds;
|
||
if (elapsed >= interval) return null; // 已满足间隔
|
||
|
||
return (int)Math.Ceiling(interval - elapsed); // 返回剩余秒数
|
||
}
|
||
|
||
/// <summary>
|
||
/// 校验回复间隔,返回 null 表示通过,否则返回剩余秒数
|
||
/// </summary>
|
||
public async Task<int?> CheckReplyIntervalAsync(long userId)
|
||
{
|
||
var interval = await GetReplyIntervalAsync(userId);
|
||
if (interval <= 0) return null; // 不限制
|
||
|
||
var lastTime = await GetLastCommentTimeAsync(userId);
|
||
if (lastTime == null) return null; // 从未回复
|
||
|
||
var elapsed = (DateTime.Now - lastTime.Value).TotalSeconds;
|
||
if (elapsed >= interval) return null; // 已满足间隔
|
||
|
||
return (int)Math.Ceiling(interval - elapsed); // 返回剩余秒数
|
||
}
|
||
}
|
||
}
|