refactor: 简化尊享包Token扣减逻辑,移除多包分配与校验流程

This commit is contained in:
ccnetcore
2025-10-14 22:34:05 +08:00
parent 533b87fc5b
commit 7a53e0c90c
3 changed files with 12 additions and 94 deletions

View File

@@ -76,23 +76,9 @@ public class PremiumPackageAggregateRoot : FullAuditedAggregateRoot<Guid>
/// <returns>是否消耗成功</returns>
public bool ConsumeTokens(long tokenCount)
{
if (RemainingTokens < tokenCount)
{
return false;
}
if (!IsActive)
{
return false;
}
if (ExpireDateTime.HasValue && ExpireDateTime.Value < DateTime.Now)
{
return false;
}
RemainingTokens -= tokenCount;
UsedTokens += tokenCount;
return true;
}

View File

@@ -292,7 +292,7 @@ public class AiGateWayManager : DomainService
var totalTokens = tokenUsage.TotalTokens ?? 0;
if (totalTokens > 0)
{
await PremiumPackageManager.ConsumeTokensAsync(userId.Value, totalTokens);
await PremiumPackageManager.TryConsumeTokensAsync(userId.Value, totalTokens);
}
}
}
@@ -354,7 +354,7 @@ public class AiGateWayManager : DomainService
var totalTokens = response.Usage.TotalTokens ?? 0;
if (totalTokens > 0)
{
await PremiumPackageManager.ConsumeTokensAsync(userId.Value, totalTokens);
await PremiumPackageManager.TryConsumeTokensAsync(userId.Value, totalTokens);
}
}
}
@@ -547,7 +547,7 @@ public class AiGateWayManager : DomainService
var totalTokens = data.TokenUsage.TotalTokens ?? 0;
if (totalTokens > 0)
{
await PremiumPackageManager.ConsumeTokensAsync(userId.Value, totalTokens);
await PremiumPackageManager.TryConsumeTokensAsync(userId.Value, totalTokens);
}
}
@@ -650,11 +650,7 @@ public class AiGateWayManager : DomainService
var totalTokens = tokenUsage.TotalTokens ?? 0;
if (totalTokens > 0)
{
var consumeSuccess = await PremiumPackageManager.ConsumeTokensAsync(userId.Value, totalTokens);
if (!consumeSuccess)
{
_logger.LogWarning($"用户 {userId.Value} 尊享token包扣减失败消耗token数: {totalTokens}");
}
await PremiumPackageManager.TryConsumeTokensAsync(userId.Value, totalTokens);
}
}
}

View File

@@ -69,12 +69,12 @@ public class PremiumPackageManager : DomainService
/// <param name="userId">用户ID</param>
/// <param name="tokenCount">需要消耗的Token数量</param>
/// <returns>是否消耗成功</returns>
public async Task<bool> ConsumeTokensAsync(Guid userId, long tokenCount)
public async Task<bool> TryConsumeTokensAsync(Guid userId, long tokenCount)
{
// 获取用户所有可用的尊享包按剩余token升序排列优先消耗快用完的
var availablePackages = await _premiumPackageRepository._DbQueryable
.Where(x => x.UserId == userId && x.IsActive)
.OrderBy(x => x.RemainingTokens)
.OrderBy(x => x.CreationTime)
.ToListAsync();
if (!availablePackages.Any())
@@ -94,34 +94,12 @@ public class PremiumPackageManager : DomainService
return false;
}
// 计算总可用Token
var totalAvailableTokens = validPackages.Sum(p => p.RemainingTokens);
if (totalAvailableTokens < tokenCount)
{
_logger.LogWarning(
$"用户 {userId} 尊享包Token不足需要: {tokenCount}, 可用: {totalAvailableTokens},将扣减到负数");
}
var firstPackage = validPackages.First();
// 直接扣除最早的token包需要消耗的token允许扣减到负数
firstPackage.ConsumeTokens(tokenCount);
await _premiumPackageRepository.UpdateAsync(firstPackage);
// 从可用的包中逐个扣除Token允许扣减到负数
var remainingToConsume = tokenCount;
foreach (var package in validPackages)
{
if (remainingToConsume <= 0)
break;
// 直接扣除剩余需要消耗的token允许扣减到负数
var toConsume = remainingToConsume;
if (package.ConsumeTokens(toConsume))
{
await _premiumPackageRepository.UpdateAsync(package);
remainingToConsume -= toConsume;
_logger.LogInformation(
$"用户 {userId} 从尊享包 {package.Id} 消耗 {toConsume} tokens, 剩余: {package.RemainingTokens}");
}
}
return remainingToConsume == 0;
return true;
}
/// <summary>
@@ -137,46 +115,4 @@ public class PremiumPackageManager : DomainService
.Where(p => !p.ExpireDateTime.HasValue || p.ExpireDateTime.Value >= DateTime.Now)
.SumAsync(p => p.RemainingTokens);
}
/// <summary>
/// 获取用户的所有尊享包
/// </summary>
/// <param name="userId">用户ID</param>
/// <returns>尊享包列表</returns>
public async Task<List<PremiumPackageAggregateRoot>> GetUserPremiumPackagesAsync(Guid userId)
{
return await _premiumPackageRepository._DbQueryable
.Where(x => x.UserId == userId)
.OrderByDescending(x => x.CreationTime)
.ToListAsync();
}
/// <summary>
/// 停用过期的尊享包
/// </summary>
/// <returns>停用的包数量</returns>
public async Task<int> DeactivateExpiredPackagesAsync()
{
_logger.LogInformation("开始执行尊享包过期自动停用任务");
var now = DateTime.Now;
var expiredPackages = await _premiumPackageRepository._DbQueryable
.Where(x => x.IsActive && x.ExpireDateTime.HasValue && x.ExpireDateTime.Value < now)
.ToListAsync();
if (!expiredPackages.Any())
{
_logger.LogInformation("没有找到过期的尊享包");
return 0;
}
foreach (var package in expiredPackages)
{
package.Deactivate();
await _premiumPackageRepository.UpdateAsync(package);
}
_logger.LogInformation($"成功停用 {expiredPackages.Count} 个过期的尊享包");
return expiredPackages.Count;
}
}