Merge remote-tracking branch 'origin/ai-hub' into ai-hub

This commit is contained in:
chenchun
2025-10-16 09:35:56 +08:00
18 changed files with 208 additions and 141 deletions

View File

@@ -21,7 +21,7 @@ public class GoodsListOutput
/// 商品参考价格
/// </summary>
public decimal ReferencePrice { get; set; }
/// <summary>
/// 商品实际价格(折扣后的价格)
/// </summary>
@@ -31,7 +31,7 @@ public class GoodsListOutput
/// 折扣金额(仅尊享包)
/// </summary>
public decimal? DiscountAmount { get; set; }
/// <summary>
/// 商品类别
/// </summary>
@@ -43,9 +43,13 @@ public class GoodsListOutput
public string Remark { get; set; }
/// <summary>
/// 折扣说明(仅尊享包)
/// </summary>
public string? DiscountDescription { get; set; }
}
/// <summary>
/// 商品类型
/// </summary>
public GoodsTypeEnum GoodsType { get; set; }
}

View File

@@ -261,7 +261,8 @@ public class PayService : ApplicationService, IPayService
GoodsCategory = goodsType.GetGoodsCategory().ToString(),
Remark = goodsType.GetRemark(),
DiscountAmount = discountAmount,
DiscountDescription = discountDescription
DiscountDescription = discountDescription,
GoodsType = goodsType
};
goodsList.Add(goodsItem);

View File

@@ -10,11 +10,11 @@ namespace Yi.Framework.AiHub.Domain.Shared.Enums;
public class PriceAttribute : Attribute
{
public decimal Price { get; }
public decimal ReferencePrice { get; }
public int ValidMonths { get; }
public PriceAttribute(double price, int validMonths, double referencePrice)
{
Price = (decimal)price;
@@ -93,39 +93,32 @@ public class TokenAmountAttribute : Attribute
public enum GoodsTypeEnum
{
// VIP服务
[Price(29.9, 1,29.9)]
[DisplayName("YiXinVip 1 month", "1个月", "灵活选择")]
[GoodsCategory(GoodsCategoryType.Vip)]
[Price(29.9, 1, 29.9)] [DisplayName("YiXinVip 1 month", "1个月", "灵活选择")] [GoodsCategory(GoodsCategoryType.Vip)]
YiXinVip1 = 1,
[Price(83.7, 3,27.9)]
[DisplayName("YiXinVip 3 month", "3个月", "短期体验")]
[GoodsCategory(GoodsCategoryType.Vip)]
[Price(83.7, 3, 27.9)] [DisplayName("YiXinVip 3 month", "3个月", "短期体验")] [GoodsCategory(GoodsCategoryType.Vip)]
YiXinVip3 = 3,
[Price(155.4, 6,25.9)]
[DisplayName("YiXinVip 6 month", "6个月", "年度热销")]
[GoodsCategory(GoodsCategoryType.Vip)]
[Price(155.4, 6, 25.9)] [DisplayName("YiXinVip 6 month", "6个月", "年度热销")] [GoodsCategory(GoodsCategoryType.Vip)]
YiXinVip6 = 6,
[Price(183.2, 8,22.9)]
[Price(183.2, 8, 22.9)]
[DisplayName("YiXinVip 8 month", "8个月推荐", "限时活动,超高性价比")]
[GoodsCategory(GoodsCategoryType.Vip)]
YiXinVip8 = 8,
// 尊享包服务 - 需要VIP资格才能购买
[Price(188.9, 0,1750)]
[Price(188.9, 0, 1750)]
[DisplayName("YiXinPremiumPackage 5000W Tokens", "5000万Tokens", "简单尝试")]
[GoodsCategory(GoodsCategoryType.PremiumPackage)]
[TokenAmount(5000)]
[TokenAmount(50000000)]
PremiumPackage5000W = 101,
[Price(248.9, 0,3500)]
[Price(248.9, 0, 3500)]
[DisplayName("YiXinPremiumPackage 10000W Tokens", "1亿Tokens推荐", "极致性价比")]
[GoodsCategory(GoodsCategoryType.PremiumPackage)]
[TokenAmount(10000)]
[TokenAmount(100000000)]
PremiumPackage10000W = 102,
}
public static class GoodsTypeEnumExtensions
@@ -304,6 +297,6 @@ public static class GoodsTypeEnumExtensions
var discountedPrice = originalPrice - discount;
// 确保价格不为负数至少为0.01元
return Math.Max(discountedPrice, 0.01m);
return Math.Round(discountedPrice, 2);
}
}
}

View File

@@ -139,7 +139,7 @@ public class AiGateWayManager : DomainService
await _aiMessageManager.CreateUserMessageAsync(userId.Value, sessionId,
new MessageInputDto
{
Content = request.Messages?.LastOrDefault().Content ?? string.Empty,
Content = sessionId is null ? "不予存储" : request.Messages?.LastOrDefault().Content ?? string.Empty,
ModelId = request.Model,
TokenUsage = data.Usage,
});
@@ -147,7 +147,8 @@ public class AiGateWayManager : DomainService
await _aiMessageManager.CreateSystemMessageAsync(userId.Value, sessionId,
new MessageInputDto
{
Content = data.Choices?.FirstOrDefault()?.Delta.Content,
Content =
sessionId is null ? "不予存储" : data.Choices?.FirstOrDefault()?.Delta.Content ?? string.Empty,
ModelId = request.Model,
TokenUsage = data.Usage
});
@@ -271,7 +272,7 @@ public class AiGateWayManager : DomainService
await _aiMessageManager.CreateUserMessageAsync(userId, sessionId,
new MessageInputDto
{
Content = request.Messages?.LastOrDefault()?.Content ?? string.Empty,
Content = sessionId is null ? "不予存储" : request.Messages?.LastOrDefault()?.Content ?? string.Empty,
ModelId = request.Model,
TokenUsage = tokenUsage,
});
@@ -279,7 +280,7 @@ public class AiGateWayManager : DomainService
await _aiMessageManager.CreateSystemMessageAsync(userId, sessionId,
new MessageInputDto
{
Content = backupSystemContent.ToString(),
Content = sessionId is null ? "不予存储" : backupSystemContent.ToString(),
ModelId = request.Model,
TokenUsage = tokenUsage
});
@@ -333,7 +334,7 @@ public class AiGateWayManager : DomainService
await _aiMessageManager.CreateUserMessageAsync(userId, sessionId,
new MessageInputDto
{
Content = request.Prompt,
Content = sessionId is null ? "不予存储" : request.Prompt,
ModelId = model,
TokenUsage = response.Usage,
});
@@ -341,13 +342,13 @@ public class AiGateWayManager : DomainService
await _aiMessageManager.CreateSystemMessageAsync(userId, sessionId,
new MessageInputDto
{
Content = response.Results?.FirstOrDefault()?.Url,
Content = sessionId is null ? "不予存储" : response.Results?.FirstOrDefault()?.Url,
ModelId = model,
TokenUsage = response.Usage
});
await _usageStatisticsManager.SetUsageAsync(userId, model, response.Usage);
// 扣减尊享token包用量
if (userId is not null && PremiumPackageConst.ModeIds.Contains(request.Model))
{
@@ -528,7 +529,7 @@ public class AiGateWayManager : DomainService
await _aiMessageManager.CreateUserMessageAsync(userId.Value, sessionId,
new MessageInputDto
{
Content = request.Messages?.FirstOrDefault()?.Content ?? string.Empty,
Content = sessionId is null ? "不予存储" : request.Messages?.FirstOrDefault()?.Content ?? string.Empty,
ModelId = request.Model,
TokenUsage = data.TokenUsage,
});
@@ -536,7 +537,7 @@ public class AiGateWayManager : DomainService
await _aiMessageManager.CreateSystemMessageAsync(userId.Value, sessionId,
new MessageInputDto
{
Content = data.content?.FirstOrDefault()?.text,
Content = sessionId is null ? "不予存储" : data.content?.FirstOrDefault()?.text,
ModelId = request.Model,
TokenUsage = data.TokenUsage
});
@@ -601,35 +602,12 @@ public class AiGateWayManager : DomainService
_logger.LogError(e, $"Ai对话异常");
var errorContent = $"对话Ai异常异常信息\n当前Ai模型{request.Model}\n异常信息{e.Message}\n异常堆栈:{e}";
throw new UserFriendlyException(errorContent);
// var model = new AnthropicStreamDto
// {
// Message = new AnthropicChatCompletionDto
// {
// content =
// [
// new AnthropicChatCompletionDtoContent
// {
// text = errorContent,
// }
// ],
// },
// Error = new AnthropicStreamErrorDto
// {
// Type = null,
// Message = errorContent
// }
// };
// var message = JsonConvert.SerializeObject(model, new JsonSerializerSettings
// {
// ContractResolver = new CamelCasePropertyNamesContractResolver()
// });
// await response.WriteAsJsonAsync(message, ThorJsonSerializer.DefaultOptions);
}
await _aiMessageManager.CreateUserMessageAsync(userId, sessionId,
new MessageInputDto
{
Content = request.Messages?.LastOrDefault()?.Content ?? string.Empty,
Content = sessionId is null ? "不予存储" : request.Messages?.LastOrDefault()?.Content ?? string.Empty,
ModelId = request.Model,
TokenUsage = tokenUsage,
});
@@ -637,7 +615,7 @@ public class AiGateWayManager : DomainService
await _aiMessageManager.CreateSystemMessageAsync(userId, sessionId,
new MessageInputDto
{
Content = backupSystemContent.ToString(),
Content = sessionId is null ? "不予存储" : backupSystemContent.ToString(),
ModelId = request.Model,
TokenUsage = tokenUsage
});
@@ -648,9 +626,9 @@ public class AiGateWayManager : DomainService
if (userId.HasValue && tokenUsage is not null)
{
var totalTokens = tokenUsage.TotalTokens ?? 0;
if (totalTokens > 0)
if (tokenUsage.TotalTokens > 0)
{
await PremiumPackageManager.TryConsumeTokensAsync(userId.Value, totalTokens);
await PremiumPackageManager.TryConsumeTokensAsync(userId.Value, totalTokens);
}
}
}