From 9c058e9545c7f247c322e677ec4c3044eff35350 Mon Sep 17 00:00:00 2001 From: ccnetcore Date: Sun, 4 Jan 2026 00:08:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E5=B0=8A=E4=BA=AB=E6=A0=87=E8=AF=86=E5=B9=B6=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E6=89=A3=E5=87=8F=E5=B0=8A=E4=BA=AB=E7=94=A8=E9=87=8F=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增模型是否为尊享的标识字段 IsPremium,并在网关层透传到模型描述。 使用模型描述中的 IsPremium 统一判断是否扣减尊享 token,用以替代多处重复的数据库查询。 同时整理了相关代码与注释,使尊享用量扣减逻辑更加集中和清晰。 --- .../Dtos/AiModelDescribe.cs | 5 ++ .../Managers/AiGateWayManager.cs | 70 ++++++++----------- 2 files changed, 33 insertions(+), 42 deletions(-) diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Dtos/AiModelDescribe.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Dtos/AiModelDescribe.cs index 1de8547b..1b00d8e0 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Dtos/AiModelDescribe.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Dtos/AiModelDescribe.cs @@ -61,4 +61,9 @@ public class AiModelDescribe /// 模型倍率 /// public decimal Multiplier { get; set; } + + /// + /// 是否为尊享模型 + /// + public bool IsPremium { get; set; } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs index 72fdd515..9cbbedc6 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs @@ -85,19 +85,22 @@ public class AiGateWayManager : DomainService Description = model.Description, AppExtraUrl = app.ExtraUrl, ModelExtraInfo = model.ExtraInfo, - Multiplier = model.Multiplier + Multiplier = model.Multiplier, + IsPremium = model.IsPremium }) .FirstAsync(); if (aiModelDescribe is null) { throw new UserFriendlyException($"【{modelId}】模型当前版本【{modelApiType}】格式不支持"); } + // ✅ 统一处理 yi- 后缀(网关层模型规范化) if (!string.IsNullOrEmpty(aiModelDescribe.ModelId) && aiModelDescribe.ModelId.StartsWith("yi-", StringComparison.OrdinalIgnoreCase)) { aiModelDescribe.ModelId = aiModelDescribe.ModelId[3..]; } + return aiModelDescribe; } @@ -126,14 +129,14 @@ public class AiGateWayManager : DomainService var modelDescribe = await GetModelAsync(ModelApiTypeEnum.OpenAi, request.Model); var chatService = LazyServiceProvider.GetRequiredKeyedService(modelDescribe.HandlerName); - + var sourceModelId = request.Model; if (!string.IsNullOrEmpty(request.Model) && request.Model.StartsWith("yi-", StringComparison.OrdinalIgnoreCase)) { request.Model = request.Model[3..]; - } - + } + var data = await chatService.CompleteChatAsync(modelDescribe, request, cancellationToken); data.SupplementalMultiplier(modelDescribe.Multiplier); if (userId is not null) @@ -157,13 +160,7 @@ public class AiGateWayManager : DomainService await _usageStatisticsManager.SetUsageAsync(userId.Value, sourceModelId, data.Usage, tokenId); - // 扣减尊享token包用量 - var isPremium = await _aiModelRepository._DbQueryable - .Where(x => x.ModelId == request.Model) - .Select(x => x.IsPremium) - .FirstAsync(); - - if (isPremium) + if (modelDescribe.IsPremium) { var totalTokens = data.Usage?.TotalTokens ?? 0; if (totalTokens > 0) @@ -212,8 +209,8 @@ public class AiGateWayManager : DomainService request.Model.StartsWith("yi-", StringComparison.OrdinalIgnoreCase)) { request.Model = request.Model[3..]; - } - + } + var completeChatResponse = chatService.CompleteChatStreamAsync(modelDescribe, request, cancellationToken); var tokenUsage = new ThorUsageResponse(); @@ -322,12 +319,7 @@ public class AiGateWayManager : DomainService // 扣减尊享token包用量 if (userId is not null) { - var isPremium = await _aiModelRepository._DbQueryable - .Where(x => x.ModelId == request.Model) - .Select(x => x.IsPremium) - .FirstAsync(); - - if (isPremium) + if (modelDescribe.IsPremium) { var totalTokens = tokenUsage.TotalTokens ?? 0; if (totalTokens > 0) @@ -390,21 +382,13 @@ public class AiGateWayManager : DomainService await _usageStatisticsManager.SetUsageAsync(userId, model, response.Usage, tokenId); - // 扣减尊享token包用量 + // 直接扣减尊享token包用量 if (userId is not null) { - var isPremium = await _aiModelRepository._DbQueryable - .Where(x => x.ModelId == request.Model) - .Select(x => x.IsPremium) - .FirstAsync(); - - if (isPremium) + var totalTokens = response.Usage.TotalTokens ?? 0; + if (totalTokens > 0) { - var totalTokens = response.Usage.TotalTokens ?? 0; - if (totalTokens > 0) - { - await PremiumPackageManager.TryConsumeTokensAsync(userId.Value, totalTokens); - } + await PremiumPackageManager.TryConsumeTokensAsync(userId.Value, totalTokens); } } } @@ -558,11 +542,11 @@ public class AiGateWayManager : DomainService { request.Model = request.Model[3..]; } - + var chatService = LazyServiceProvider.GetRequiredKeyedService(modelDescribe.HandlerName); var data = await chatService.ChatCompletionsAsync(modelDescribe, request, cancellationToken); - + data.SupplementalMultiplier(modelDescribe.Multiplier); if (userId is not null) @@ -585,7 +569,7 @@ public class AiGateWayManager : DomainService await _usageStatisticsManager.SetUsageAsync(userId.Value, sourceModelId, data.TokenUsage, tokenId); - // 扣减尊享token包用量 + // 直接扣减尊享token包用量 var totalTokens = data.TokenUsage.TotalTokens ?? 0; if (totalTokens > 0) { @@ -632,7 +616,7 @@ public class AiGateWayManager : DomainService { request.Model = request.Model[3..]; } - + var completeChatResponse = chatService.StreamChatCompletionsAsync(modelDescribe, request, cancellationToken); ThorUsageResponse? tokenUsage = null; StringBuilder backupSystemContent = new StringBuilder(); @@ -677,7 +661,7 @@ public class AiGateWayManager : DomainService await _usageStatisticsManager.SetUsageAsync(userId, sourceModelId, tokenUsage, tokenId); - // 扣减尊享token包用量 + // 直接扣减尊享token包用量 if (userId.HasValue && tokenUsage is not null) { var totalTokens = tokenUsage.TotalTokens ?? 0; @@ -719,7 +703,7 @@ public class AiGateWayManager : DomainService { request.Model = request.Model[3..]; } - + var data = await chatService.ResponsesAsync(modelDescribe, request, cancellationToken); data.SupplementalMultiplier(modelDescribe.Multiplier); @@ -750,7 +734,7 @@ public class AiGateWayManager : DomainService await _usageStatisticsManager.SetUsageAsync(userId.Value, sourceModelId, tokenUsage, tokenId); - // 扣减尊享token包用量 + // 直接扣减尊享token包用量 var totalTokens = tokenUsage.TotalTokens ?? 0; if (totalTokens > 0) { @@ -795,6 +779,7 @@ public class AiGateWayManager : DomainService { request.Model = request.Model[3..]; } + var completeChatResponse = chatService.ResponsesStreamAsync(modelDescribe, request, cancellationToken); ThorUsageResponse? tokenUsage = null; try @@ -848,7 +833,7 @@ public class AiGateWayManager : DomainService await _usageStatisticsManager.SetUsageAsync(userId, sourceModelId, tokenUsage, tokenId); - // 扣减尊享token包用量 + // 直接扣减尊享token包用量 if (userId.HasValue && tokenUsage is not null) { var totalTokens = tokenUsage.TotalTokens ?? 0; @@ -908,7 +893,7 @@ public class AiGateWayManager : DomainService await _usageStatisticsManager.SetUsageAsync(userId.Value, modelId, tokenUsage, tokenId); - // 扣减尊享token包用量 + // 直接扣减尊享token包用量 var totalTokens = tokenUsage.TotalTokens ?? 0; if (totalTokens > 0) { @@ -992,7 +977,7 @@ public class AiGateWayManager : DomainService await _usageStatisticsManager.SetUsageAsync(userId, modelId, tokenUsage, tokenId); - // 扣减尊享token包用量 + // 直接扣减尊享token包用量 if (userId.HasValue && tokenUsage is not null) { var totalTokens = tokenUsage.TotalTokens ?? 0; @@ -1004,6 +989,7 @@ public class AiGateWayManager : DomainService } private const string ImageStoreHost = "https://ccnetcore.com/prod-api"; + /// /// Gemini 生成(Image)-非流式-缓存处理 /// 返回图片绝对路径 @@ -1060,7 +1046,7 @@ public class AiGateWayManager : DomainService await _usageStatisticsManager.SetUsageAsync(userId, modelId, tokenUsage, tokenId); - // 扣减尊享token包用量 + // 直接扣减尊享token包用量 var totalTokens = tokenUsage.TotalTokens ?? 0; if (totalTokens > 0) {