107 lines
3.5 KiB
C#
107 lines
3.5 KiB
C#
using FreeSql;
|
||
|
||
using LiveForum.Code.JwtInfrastructure;
|
||
using LiveForum.IService.Others;
|
||
using LiveForum.Model;
|
||
using LiveForum.Model.Dto.Others;
|
||
|
||
namespace LiveForum.Service.Others
|
||
{
|
||
/// <summary>
|
||
/// 防沉迷校验服务实现
|
||
/// </summary>
|
||
public class AntiAddictionService : IAntiAddictionService
|
||
{
|
||
private readonly IBaseRepository<T_AntiAddictionRules> _rulesRepository;
|
||
private readonly IBaseRepository<T_Users> _userRepository;
|
||
private readonly JwtUserInfoModel _userInfoModel;
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
public AntiAddictionService(
|
||
IBaseRepository<T_AntiAddictionRules> rulesRepository,
|
||
IBaseRepository<T_Users> userRepository,
|
||
JwtUserInfoModel userInfoModel)
|
||
{
|
||
_rulesRepository = rulesRepository;
|
||
_userRepository = userRepository;
|
||
_userInfoModel = userInfoModel;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查当前时间是否处于指定操作类型的防沉迷时段内(仅对未成年用户生效)
|
||
/// </summary>
|
||
public async Task<bool> 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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 判断时间是否在时段内(支持跨午夜)
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取所有防沉迷规则
|
||
/// </summary>
|
||
public async Task<List<AntiAddictionRuleDto>> 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();
|
||
}
|
||
}
|
||
}
|