修复风控登录时间记录与历史账号判断

This commit is contained in:
meoacgx committed 2025-12-24 02:02:43 +08:00
1 parent e8e7224e5a
commit cd5a07543e
3 files changed
+71 -12

No files matched your search

@@ -17,9 +17,12 @@ public class AccountRiskService
/// </summary>
public RiskCheckResult CheckLoginDuration(Account account)
{
if (account.LastLoginAt == null)
var referenceAt = account.GetRiskReferenceAtUtc();
var loginHours = account.GetRiskReferenceHours();
if (referenceAt == null || loginHours == null)
{
// 无登录记录,视为高风险(刚导入的账号)
// 兜底:完全缺少可参考的时间,视为高风险
return new RiskCheckResult
{
IsRisky = true,
@@ -28,16 +31,30 @@ public class AccountRiskService
};
}
var loginHours = (DateTime.UtcNow - account.LastLoginAt.Value).TotalHours;
if (loginHours < RISK_THRESHOLD_HOURS)
// 兼容历史数据:LastLoginAt 为空时,使用导入时间(CreatedAt)作为估算,避免永久误报
var isEstimated = account.IsRiskReferenceEstimated();
if (isEstimated && loginHours >= RISK_THRESHOLD_HOURS)
{
var remainingHours = RISK_THRESHOLD_HOURS - loginHours;
return new RiskCheckResult
{
IsRisky = false,
Message = "账号登录时长已满足要求(按导入时间估算)",
DetailedMessage = $"当前已导入时长:{loginHours.Value:F1} 小时"
};
}
if (loginHours.Value < RISK_THRESHOLD_HOURS)
{
var remainingHours = RISK_THRESHOLD_HOURS - loginHours.Value;
return new RiskCheckResult
{
IsRisky = true,
Message = $"账号登录时长不足 24 小时(当前:{loginHours:F1} 小时)",
DetailedMessage = $"建议等待 {remainingHours:F1} 小时后再进行敏感操作,以降低被 Telegram 风控的风险"
Message = isEstimated
? $"账号未记录登录时间(按导入时间估算:{loginHours.Value:F1} 小时)"
: $"账号登录时长不足 24 小时(当前:{loginHours.Value:F1} 小时)",
DetailedMessage = isEstimated
? $"该账号尚未记录登录时间(可能是较早导入的账号),已按导入时间估算;建议等待 {remainingHours:F1} 小时后再进行敏感操作,以降低被 Telegram 风控的风险"
: $"建议等待 {remainingHours:F1} 小时后再进行敏感操作,以降低被 Telegram 风控的风险"
};
}
@@ -45,7 +62,7 @@ public class AccountRiskService
{
IsRisky = false,
Message = "账号登录时长已满足要求",
DetailedMessage = $"当前登录时长:{loginHours:F1} 小时"
DetailedMessage = $"当前登录时长:{loginHours.Value:F1} 小时"
};
}
@@ -145,8 +162,12 @@ public class BatchRiskCheckResult
var riskyPhones = string.Join("、", RiskyAccounts.Select(a =>
{
var hours = a.GetLoginHours();
return hours.HasValue ? $"{a.Phone}({hours.Value:F1}h)" : a.Phone;
var hours = a.GetRiskReferenceHours();
if (!hours.HasValue)
return a.Phone;
var tag = a.IsRiskReferenceEstimated() ? "导入" : "登录";
return $"{a.Phone}({tag}{hours.Value:F1}h)";
}));
return $"以下账号登录时长不足 24 小时:{riskyPhones}";
@@ -5,6 +5,42 @@ namespace TelegramPanel.Data.Entities;
/// </summary>
public static class AccountExtensions
{
/// <summary>
/// 获取风控检查用的参考时间(优先 LastLoginAt,其次 CreatedAt/LastSyncAt 作为估算兜底)
/// </summary>
public static DateTime? GetRiskReferenceAtUtc(this Account account)
{
if (account.LastLoginAt != null)
return account.LastLoginAt.Value;
// 兼容历史数据:早期导入的账号可能没有写入 LastLoginAt
if (account.CreatedAt != default)
return account.CreatedAt;
if (account.LastSyncAt != default)
return account.LastSyncAt;
return null;
}
/// <summary>
/// 风控参考时间是否为估算值(非真实登录时间)
/// </summary>
public static bool IsRiskReferenceEstimated(this Account account)
=> account.LastLoginAt == null && account.GetRiskReferenceAtUtc() != null;
/// <summary>
/// 获取风控检查用的参考小时数
/// </summary>
public static double? GetRiskReferenceHours(this Account account)
{
var at = account.GetRiskReferenceAtUtc();
if (at == null)
return null;
return (DateTime.UtcNow - at.Value).TotalHours;
}
/// <summary>
/// 获取登录小时数的格式化字符串
/// </summary>
@@ -354,6 +354,7 @@
existingAccount.ApiId = telegramApiId;
existingAccount.ApiHash = telegramApiHash;
existingAccount.LastSyncAt = DateTime.UtcNow;
existingAccount.LastLoginAt = DateTime.UtcNow;
await AccountManagement.UpdateAccountAsync(existingAccount);
Snackbar.Add("账号信息已更新", Severity.Success);
@@ -372,7 +373,8 @@
ApiHash = telegramApiHash,
IsActive = true,
CreatedAt = DateTime.UtcNow,
LastSyncAt = DateTime.UtcNow
LastSyncAt = DateTime.UtcNow,
LastLoginAt = DateTime.UtcNow
};
await AccountManagement.CreateAccountAsync(account);