using FreeSql;
using LiveForum.Code.JwtInfrastructure;
using LiveForum.IService.Others;
using LiveForum.Model;
using LiveForum.Model.Dto.Others;
namespace LiveForum.Service.Others
{
///
/// 防沉迷校验服务实现
///
public class AntiAddictionService : IAntiAddictionService
{
private readonly IBaseRepository _rulesRepository;
private readonly IBaseRepository _userRepository;
private readonly JwtUserInfoModel _userInfoModel;
///
/// 构造函数
///
public AntiAddictionService(
IBaseRepository rulesRepository,
IBaseRepository userRepository,
JwtUserInfoModel userInfoModel)
{
_rulesRepository = rulesRepository;
_userRepository = userRepository;
_userInfoModel = userInfoModel;
}
///
/// 检查当前时间是否处于指定操作类型的防沉迷时段内(仅对未成年用户生效)
///
public async Task IsRestrictedAsync(string actionType)
{
// 只对未成年用户生效
var userId = (long)_userInfoModel.UserId;
var user = await _userRepository.Select.Where(x => x.Id == userId).FirstAsync();
if (user == null || !user.IsMinor)
return false;
var rules = await _rulesRepository.Select.ToListAsync();
var now = DateTime.Now.TimeOfDay;
foreach (var rule in rules)
{
// 检查该规则是否限制了指定操作
bool restrictsAction = actionType switch
{
"Post" => rule.RestrictPost,
"Reply" => rule.RestrictReply,
"Flower" => rule.RestrictFlower,
_ => false
};
if (!restrictsAction) continue;
// 判断当前时间是否在时段内
if (IsTimeInPeriod(now, rule.StartTime, rule.EndTime))
return true;
}
return false;
}
///
/// 判断时间是否在时段内(支持跨午夜)
///
public static bool IsTimeInPeriod(TimeSpan current, TimeSpan start, TimeSpan end)
{
if (start < end)
{
// 普通时段:如 09:00 ~ 12:00
return current >= start && current < end;
}
else if (start > end)
{
// 跨午夜时段:如 23:00 ~ 01:00
return current >= start || current < end;
}
else
{
// start == end:视为无效时段,不限制
return false;
}
}
///
/// 获取所有防沉迷规则
///
public async Task> GetAllRulesAsync()
{
var rules = await _rulesRepository.Select.ToListAsync();
return rules.Select(r => new AntiAddictionRuleDto
{
Id = r.Id,
StartTime = r.StartTime.ToString(@"hh\:mm"),
EndTime = r.EndTime.ToString(@"hh\:mm"),
RestrictPost = r.RestrictPost,
RestrictReply = r.RestrictReply,
RestrictFlower = r.RestrictFlower
}).ToList();
}
}
}