Files
Yi.Admin/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/TokenManager.cs

135 lines
4.4 KiB
C#
Raw Normal View History

2025-11-27 19:01:16 +08:00
using SqlSugar;
using Volo.Abp.Domain.Services;
using Yi.Framework.AiHub.Domain.Entities;
2025-07-03 22:31:39 +08:00
using Yi.Framework.AiHub.Domain.Entities.OpenApi;
2025-11-27 19:01:16 +08:00
using Yi.Framework.AiHub.Domain.Shared.Consts;
2025-07-03 22:31:39 +08:00
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.AiHub.Domain.Managers;
2025-11-27 19:01:16 +08:00
/// <summary>
/// Token验证结果
/// </summary>
public class TokenValidationResult
{
/// <summary>
/// 用户Id
/// </summary>
public Guid UserId { get; set; }
/// <summary>
/// Token Id
/// </summary>
public Guid TokenId { get; set; }
}
2025-07-03 22:31:39 +08:00
public class TokenManager : DomainService
{
private readonly ISqlSugarRepository<TokenAggregateRoot> _tokenRepository;
2025-11-27 19:01:16 +08:00
private readonly ISqlSugarRepository<UsageStatisticsAggregateRoot> _usageStatisticsRepository;
2025-07-03 22:31:39 +08:00
2025-11-27 19:01:16 +08:00
public TokenManager(
ISqlSugarRepository<TokenAggregateRoot> tokenRepository,
ISqlSugarRepository<UsageStatisticsAggregateRoot> usageStatisticsRepository)
2025-07-03 22:31:39 +08:00
{
_tokenRepository = tokenRepository;
2025-11-27 19:01:16 +08:00
_usageStatisticsRepository = usageStatisticsRepository;
2025-07-03 22:31:39 +08:00
}
2025-11-27 19:01:16 +08:00
/// <summary>
/// 验证Token并返回用户Id和TokenId
/// </summary>
/// <param name="token">Token密钥</param>
/// <param name="modelId">模型Id用于判断是否是尊享模型需要检查额度</param>
/// <returns>Token验证结果</returns>
public async Task<TokenValidationResult> ValidateTokenAsync(string? token, string? modelId = null)
2025-07-03 22:31:39 +08:00
{
2025-11-27 19:01:16 +08:00
if (token is null)
2025-07-03 22:31:39 +08:00
{
2025-11-27 19:01:16 +08:00
throw new UserFriendlyException("当前请求未包含token", "401");
2025-07-03 22:31:39 +08:00
}
2025-11-27 19:01:16 +08:00
if (!token.StartsWith("yi-"))
2025-07-03 22:31:39 +08:00
{
2025-11-27 19:01:16 +08:00
throw new UserFriendlyException("当前请求token非法", "401");
2025-07-03 22:31:39 +08:00
}
2025-11-27 19:01:16 +08:00
var entity = await _tokenRepository._DbQueryable
.Where(x => x.Token == token)
.FirstAsync();
if (entity is null)
2025-07-03 22:31:39 +08:00
{
2025-11-27 19:01:16 +08:00
throw new UserFriendlyException("当前请求token无效", "401");
2025-07-03 22:31:39 +08:00
}
2025-11-27 19:01:16 +08:00
// 检查Token是否被禁用
if (entity.IsDisabled)
2025-07-03 22:31:39 +08:00
{
2025-11-27 19:01:16 +08:00
throw new UserFriendlyException("当前Token已被禁用请启用后再使用", "403");
2025-07-03 22:31:39 +08:00
}
2025-11-27 19:01:16 +08:00
// 检查Token是否过期
if (entity.ExpireTime.HasValue && entity.ExpireTime.Value < DateTime.Now)
2025-07-03 22:31:39 +08:00
{
2025-11-27 19:01:16 +08:00
throw new UserFriendlyException("当前Token已过期请更新过期时间或创建新的Token", "403");
2025-07-03 22:31:39 +08:00
}
2025-11-27 19:01:16 +08:00
// 如果是尊享模型且Token设置了额度限制检查是否超限
if (!string.IsNullOrEmpty(modelId) &&
PremiumPackageConst.ModeIds.Contains(modelId) &&
entity.PremiumQuotaLimit.HasValue)
2025-07-03 22:31:39 +08:00
{
2025-11-27 19:01:16 +08:00
var usedQuota = await GetTokenPremiumUsedQuotaAsync(entity.UserId, entity.Id);
if (usedQuota >= entity.PremiumQuotaLimit.Value)
2025-07-03 22:31:39 +08:00
{
2025-11-27 19:01:16 +08:00
throw new UserFriendlyException($"当前Token的尊享包额度已用完已使用{usedQuota},限制:{entity.PremiumQuotaLimit.Value}请调整额度限制或使用其他Token", "403");
2025-07-03 22:31:39 +08:00
}
}
2025-11-27 19:01:16 +08:00
return new TokenValidationResult
{
UserId = entity.UserId,
TokenId = entity.Id
};
}
/// <summary>
/// 获取Token的尊享包已使用额度
/// </summary>
private async Task<long> GetTokenPremiumUsedQuotaAsync(Guid userId, Guid tokenId)
{
var premiumModelIds = PremiumPackageConst.ModeIds;
var usedQuota = await _usageStatisticsRepository._DbQueryable
.Where(x => x.UserId == userId && x.TokenId == tokenId && premiumModelIds.Contains(x.ModelId))
.SumAsync(x => x.TotalTokenCount);
return usedQuota;
}
/// <summary>
/// 获取用户的Token兼容旧接口返回第一个可用的Token
/// </summary>
[Obsolete("请使用 ValidateTokenAsync 方法")]
public async Task<string?> GetAsync(Guid userId)
{
var entity = await _tokenRepository._DbQueryable
.Where(x => x.UserId == userId && !x.IsDisabled)
.OrderBy(x => x.CreationTime)
.FirstAsync();
return entity?.Token;
}
/// <summary>
/// 获取用户Id兼容旧接口
/// </summary>
[Obsolete("请使用 ValidateTokenAsync 方法")]
public async Task<Guid> GetUserIdAsync(string? token)
{
var result = await ValidateTokenAsync(token);
return result.UserId;
2025-07-03 22:31:39 +08:00
}
2025-11-27 19:01:16 +08:00
}