diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/AiUserRoleMenuDto.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/AiUserRoleMenuDto.cs
index d3297f59..fa054cca 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/AiUserRoleMenuDto.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/AiUserRoleMenuDto.cs
@@ -8,4 +8,29 @@ public class AiUserRoleMenuDto:UserRoleMenuDto
/// 是否绑定服务号
///
public bool IsBindFuwuhao { get; set; }
+
+ ///
+ /// 是否为VIP用户
+ ///
+ public bool IsVip { get; set; }
+
+ ///
+ /// VIP到期时间
+ ///
+ public DateTime? VipExpireTime { get; set; }
+
+ ///
+ /// 尊享包总Token数
+ ///
+ public long PremiumTotalTokens { get; set; }
+
+ ///
+ /// 尊享包已使用Token数
+ ///
+ public long PremiumUsedTokens { get; set; }
+
+ ///
+ /// 尊享包剩余Token数
+ ///
+ public long PremiumRemainingTokens { get; set; }
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Pay/GoodsListOutput.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Pay/GoodsListOutput.cs
new file mode 100644
index 00000000..f6696356
--- /dev/null
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Pay/GoodsListOutput.cs
@@ -0,0 +1,44 @@
+using Yi.Framework.AiHub.Domain.Shared.Enums;
+
+namespace Yi.Framework.AiHub.Application.Contracts.Dtos.Pay;
+
+///
+/// 商品列表输出DTO
+///
+public class GoodsListOutput
+{
+ ///
+ /// 商品名称
+ ///
+ public string GoodsName { get; set; }
+
+ ///
+ /// 商品原价
+ ///
+ public decimal OriginalPrice { get; set; }
+
+ ///
+ /// 商品实际价格(折扣后的价格)
+ ///
+ public decimal GoodsPrice { get; set; }
+
+ ///
+ /// 商品类型
+ ///
+ public GoodsTypeEnum GoodsType { get; set; }
+
+ ///
+ /// 商品备注
+ ///
+ public string Remark { get; set; }
+
+ ///
+ /// 折扣金额(仅尊享包)
+ ///
+ public decimal? DiscountAmount { get; set; }
+
+ ///
+ /// 折扣说明(仅尊享包)
+ ///
+ public string? DiscountDescription { get; set; }
+}
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/IServices/IPayService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/IServices/IPayService.cs
index 1f303501..55edcacf 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/IServices/IPayService.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/IServices/IPayService.cs
@@ -30,4 +30,10 @@ public interface IPayService : IApplicationService
/// 查询订单状态输入
/// 订单状态信息
Task QueryOrderStatusAsync([FromQuery] QueryOrderStatusInput input);
+
+ ///
+ /// 获取商品列表
+ ///
+ /// 商品列表
+ Task> GetGoodsListAsync();
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/AiAccountService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/AiAccountService.cs
index e5290f0d..c1a15efc 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/AiAccountService.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/AiAccountService.cs
@@ -8,6 +8,8 @@ using Yi.Framework.AiHub.Domain.Entities;
using Yi.Framework.Rbac.Application.Contracts.IServices;
using Yi.Framework.Rbac.Domain.Shared.Dtos;
using Yi.Framework.SqlSugarCore.Abstractions;
+using Yi.Framework.AiHub.Domain.Extensions;
+using Yi.Framework.AiHub.Domain.Shared.Consts;
namespace Yi.Framework.AiHub.Application.Services;
@@ -15,11 +17,19 @@ public class AiAccountService : ApplicationService
{
private IAccountService _accountService;
private ISqlSugarRepository _userRepository;
+ private ISqlSugarRepository _rechargeRepository;
+ private ISqlSugarRepository _premiumPackageRepository;
- public AiAccountService(IAccountService accountService, ISqlSugarRepository userRepository)
+ public AiAccountService(
+ IAccountService accountService,
+ ISqlSugarRepository userRepository,
+ ISqlSugarRepository rechargeRepository,
+ ISqlSugarRepository premiumPackageRepository)
{
_accountService = accountService;
_userRepository = userRepository;
+ _rechargeRepository = rechargeRepository;
+ _premiumPackageRepository = premiumPackageRepository;
}
///
@@ -33,7 +43,54 @@ public class AiAccountService : ApplicationService
var userId = CurrentUser.GetId();
var userAccount = await _accountService.GetAsync(null, null, userId: CurrentUser.GetId());
var output = userAccount.Adapt();
+
+ // 是否绑定服务号
output.IsBindFuwuhao = await _userRepository.IsAnyAsync(x => userId == x.UserId);
+
+ // 是否为VIP用户
+ output.IsVip = CurrentUser.IsAiVip();
+
+ // 获取VIP到期时间
+ if (output.IsVip)
+ {
+ var recharges = await _rechargeRepository._DbQueryable
+ .Where(x => x.UserId == userId)
+ .ToListAsync();
+
+ if (recharges.Any())
+ {
+ // 如果有任何一个充值记录的过期时间为null,说明是永久VIP
+ if (recharges.Any(x => !x.ExpireDateTime.HasValue))
+ {
+ output.VipExpireTime = null; // 永久VIP
+ }
+ else
+ {
+ // 取最大的过期时间
+ output.VipExpireTime = recharges
+ .Where(x => x.ExpireDateTime.HasValue)
+ .Max(x => x.ExpireDateTime);
+ }
+ }
+ }
+
+ // 获取尊享包Token信息
+ var premiumPackages = await _premiumPackageRepository._DbQueryable
+ .Where(x => x.UserId == userId && x.IsActive)
+ .ToListAsync();
+
+ if (premiumPackages.Any())
+ {
+ // 过滤掉已过期的包
+ var validPackages = premiumPackages
+ .Where(p => p.IsAvailable())
+ .ToList();
+
+ output.PremiumTotalTokens = validPackages.Sum(x => x.TotalTokens);
+ output.PremiumUsedTokens = validPackages.Sum(x => x.UsedTokens);
+ output.PremiumRemainingTokens = validPackages.Sum(x => x.RemainingTokens);
+ }
+
return output;
}
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/OpenApiService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/OpenApiService.cs
index 7c004ac6..8fba666b 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/OpenApiService.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/OpenApiService.cs
@@ -2,14 +2,18 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Volo.Abp.Application.Services;
+using Volo.Abp.Users;
+using Yi.Framework.AiHub.Domain.Entities;
using Yi.Framework.AiHub.Domain.Entities.Model;
using Yi.Framework.AiHub.Domain.Extensions;
using Yi.Framework.AiHub.Domain.Managers;
+using Yi.Framework.AiHub.Domain.Shared.Consts;
using Yi.Framework.AiHub.Domain.Shared.Dtos.Anthropic;
using Yi.Framework.AiHub.Domain.Shared.Dtos.OpenAi;
using Yi.Framework.AiHub.Domain.Shared.Dtos.OpenAi.Embeddings;
using Yi.Framework.AiHub.Domain.Shared.Dtos.OpenAi.Images;
using Yi.Framework.AiHub.Domain.Shared.Enums;
+using Yi.Framework.Rbac.Application.Contracts.IServices;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.AiHub.Application.Services;
@@ -22,10 +26,13 @@ public class OpenApiService : ApplicationService
private readonly AiGateWayManager _aiGateWayManager;
private readonly ISqlSugarRepository _aiModelRepository;
private readonly AiBlacklistManager _aiBlacklistManager;
+ private readonly IAccountService _accountService;
+ private readonly PremiumPackageManager _premiumPackageManager;
public OpenApiService(IHttpContextAccessor httpContextAccessor, ILogger logger,
TokenManager tokenManager, AiGateWayManager aiGateWayManager,
- ISqlSugarRepository aiModelRepository, AiBlacklistManager aiBlacklistManager)
+ ISqlSugarRepository aiModelRepository, AiBlacklistManager aiBlacklistManager,
+ IAccountService accountService, PremiumPackageManager premiumPackageManager)
{
_httpContextAccessor = httpContextAccessor;
_logger = logger;
@@ -33,6 +40,8 @@ public class OpenApiService : ApplicationService
_aiGateWayManager = aiGateWayManager;
_aiModelRepository = aiModelRepository;
_aiBlacklistManager = aiBlacklistManager;
+ _accountService = accountService;
+ _premiumPackageManager = premiumPackageManager;
}
///
@@ -120,7 +129,7 @@ public class OpenApiService : ApplicationService
///
- /// Anthropic对话
+ /// Anthropic对话(尊享服务专用)
///
///
///
@@ -132,6 +141,27 @@ public class OpenApiService : ApplicationService
var httpContext = this._httpContextAccessor.HttpContext;
var userId = await _tokenManager.GetUserIdAsync(GetTokenByHttpContext(httpContext));
await _aiBlacklistManager.VerifiyAiBlacklist(userId);
+
+ // 验证用户是否为VIP
+ var userInfo = await _accountService.GetAsync(null, null, userId);
+ if (userInfo == null)
+ {
+ throw new UserFriendlyException("用户信息不存在");
+ }
+
+ // 检查是否为VIP(使用RoleCodes判断)
+ if (!userInfo.RoleCodes.Contains(AiHubConst.VipRole) && userInfo.User.UserName != "cc")
+ {
+ throw new UserFriendlyException("该接口为尊享服务专用,需要VIP权限才能使用");
+ }
+
+ // 检查尊享token包用量
+ var availableTokens = await _premiumPackageManager.GetAvailableTokensAsync(userId);
+ if (availableTokens <= 0)
+ {
+ throw new UserFriendlyException("尊享token包用量不足,请先购买尊享token包");
+ }
+
//ai网关代理httpcontext
if (input.Stream)
{
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/PayService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/PayService.cs
index 14df22fb..872a1959 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/PayService.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/PayService.cs
@@ -14,6 +14,7 @@ using Yi.Framework.AiHub.Domain.Entities.Pay;
using Yi.Framework.SqlSugarCore.Abstractions;
using System.ComponentModel;
using System.Reflection;
+using Volo.Abp.Users;
using Yi.Framework.AiHub.Application.Contracts.Dtos.Recharge;
namespace Yi.Framework.AiHub.Application.Services;
@@ -185,6 +186,85 @@ public class PayService : ApplicationService, IPayService
};
}
+ ///
+ /// 获取商品列表
+ ///
+ /// 商品列表
+ [HttpGet("pay/GoodsList")]
+ public async Task> GetGoodsListAsync()
+ {
+ var goodsList = new List();
+
+ // 获取当前用户的累加充值金额(仅已登录用户)
+ decimal totalRechargeAmount = 0m;
+ if (CurrentUser.IsAuthenticated)
+ {
+ totalRechargeAmount = await _payManager.GetUserTotalRechargeAmountAsync(CurrentUser.GetId());
+ }
+
+ // 遍历所有商品枚举
+ foreach (GoodsTypeEnum goodsType in Enum.GetValues(typeof(GoodsTypeEnum)))
+ {
+ var originalPrice = goodsType.GetTotalAmount();
+ decimal actualPrice = originalPrice;
+ decimal? discountAmount = null;
+ string? discountDescription = null;
+
+ // 如果是尊享包商品,计算折扣
+ if (goodsType.IsPremiumPackage() && CurrentUser.IsAuthenticated)
+ {
+ discountAmount = goodsType.CalculateDiscount(totalRechargeAmount);
+ actualPrice = goodsType.GetDiscountedPrice(totalRechargeAmount);
+
+ if (discountAmount > 0)
+ {
+ discountDescription = $"已优惠 ¥{discountAmount:F2}(累计充值每10元减1元,最多减20元)";
+ }
+ else
+ {
+ discountDescription = "累计充值每10元可减1元,最多减20元";
+ }
+ }
+
+ var goodsItem = new GoodsListOutput
+ {
+ GoodsName = goodsType.GetDisplayName(),
+ OriginalPrice = originalPrice,
+ GoodsPrice = actualPrice,
+ GoodsType = goodsType,
+ Remark = GetGoodsRemark(goodsType),
+ DiscountAmount = discountAmount,
+ DiscountDescription = discountDescription
+ };
+
+ goodsList.Add(goodsItem);
+ }
+
+ return goodsList;
+ }
+
+ ///
+ /// 获取商品备注信息
+ ///
+ /// 商品类型
+ /// 商品备注
+ private string GetGoodsRemark(GoodsTypeEnum goodsType)
+ {
+ if (goodsType.IsPremiumPackage())
+ {
+ var tokenAmount = goodsType.GetTokenAmount();
+ return $"尊享包服务,提供 {tokenAmount:N0} Tokens(需要VIP资格)";
+ }
+ else if (goodsType.IsVipService())
+ {
+ var validMonths = goodsType.GetValidMonths();
+ var monthlyPrice = goodsType.GetMonthlyPrice();
+ return $"VIP服务,有效期 {validMonths} 个月,月均价 ¥{monthlyPrice:F2}";
+ }
+
+ return "未知商品类型";
+ }
+
///
/// 获取交易状态描述
///
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Enums/GoodsTypeEnum.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Enums/GoodsTypeEnum.cs
index fa17a001..0f1016ff 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Enums/GoodsTypeEnum.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Enums/GoodsTypeEnum.cs
@@ -106,53 +106,18 @@ public enum GoodsTypeEnum
YiXinVip8 = 8,
// 尊享包服务 - 需要VIP资格才能购买
- [Price(49.9, 0)]
- [DisplayName("Premium Package 5M Tokens")]
+ [Price(188.9, 0)]
+ [DisplayName("Premium Package 5000W Tokens")]
[GoodsCategory(GoodsCategoryType.PremiumPackage)]
- [TokenAmount(5_000_000)]
- PremiumPackage5M = 101,
+ [TokenAmount(5000)]
+ PremiumPackage5000W = 101,
- [Price(99.9, 0)]
- [DisplayName("Premium Package 10M Tokens")]
+ [Price(248.9, 0)]
+ [DisplayName("Premium Package 10000W Tokens")]
[GoodsCategory(GoodsCategoryType.PremiumPackage)]
- [TokenAmount(10_000_000)]
- PremiumPackage10M = 102,
-
- [Price(199.9, 0)]
- [DisplayName("Premium Package 25M Tokens")]
- [GoodsCategory(GoodsCategoryType.PremiumPackage)]
- [TokenAmount(25_000_000)]
- PremiumPackage25M = 103,
-
- [Price(399.9, 0)]
- [DisplayName("Premium Package 50M Tokens")]
- [GoodsCategory(GoodsCategoryType.PremiumPackage)]
- [TokenAmount(50_000_000)]
- PremiumPackage50M = 104
-
- // [Price(197.1, 9)]
- // [DisplayName("YiXinVip 9 month")]
- // YiXinVip9 = 9
-
- // [Price(0.01, 1)]
- // [DisplayName("YiXinVip Test")]
- // YiXinVipTest = 0,
- //
- // [Price(0.01, 1)]
- // [DisplayName("YiXinVip 1 month")]
- // YiXinVip1 = 1,
- //
- // [Price(0.01, 3)]
- // [DisplayName("YiXinVip 3 month")]
- // YiXinVip3 = 3,
- //
- // [Price(0.01, 6)]
- // [DisplayName("YiXinVip 6 month")]
- // YiXinVip6 = 6,
- //
- // [Price(0.01, 10)]
- // [DisplayName("YiXinVip 10 month")]
- // YiXinVip10 = 10
+ [TokenAmount(10000)]
+ PremiumPackage10000W = 102,
+
}
public static class GoodsTypeEnumExtensions
@@ -259,4 +224,42 @@ public static class GoodsTypeEnumExtensions
var tokenAttribute = fieldInfo?.GetCustomAttribute();
return tokenAttribute?.TokenAmount ?? 0;
}
+
+ ///
+ /// 计算折扣金额(仅用于尊享包)
+ /// 规则:每累加充值10元,减少1元,最多减少20元
+ ///
+ /// 商品类型
+ /// 用户累加充值金额
+ /// 折扣金额
+ public static decimal CalculateDiscount(this GoodsTypeEnum goodsType, decimal totalRechargeAmount)
+ {
+ // 只有尊享包才有折扣
+ if (!goodsType.IsPremiumPackage())
+ {
+ return 0m;
+ }
+
+ // 每10元减1元
+ var discountAmount = Math.Floor(totalRechargeAmount / 10m);
+
+ // 最多减少20元
+ return Math.Min(discountAmount, 20m);
+ }
+
+ ///
+ /// 获取折扣后的价格(仅用于尊享包)
+ ///
+ /// 商品类型
+ /// 用户累加充值金额
+ /// 折扣后的价格
+ public static decimal GetDiscountedPrice(this GoodsTypeEnum goodsType, decimal totalRechargeAmount)
+ {
+ var originalPrice = goodsType.GetTotalAmount();
+ var discount = goodsType.CalculateDiscount(totalRechargeAmount);
+ var discountedPrice = originalPrice - discount;
+
+ // 确保价格不为负数,至少为0.01元
+ return Math.Max(discountedPrice, 0.01m);
+ }
}
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 d0e2ca9b..22c31057 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
@@ -31,6 +31,7 @@ public class AiGateWayManager : DomainService
private readonly AiMessageManager _aiMessageManager;
private readonly UsageStatisticsManager _usageStatisticsManager;
private readonly ISpecialCompatible _specialCompatible;
+ private PremiumPackageManager? _premiumPackageManager;
public AiGateWayManager(ISqlSugarRepository aiAppRepository, ILogger logger,
AiMessageManager aiMessageManager, UsageStatisticsManager usageStatisticsManager,
@@ -43,6 +44,9 @@ public class AiGateWayManager : DomainService
_specialCompatible = specialCompatible;
}
+ private PremiumPackageManager PremiumPackageManager =>
+ _premiumPackageManager ??= LazyServiceProvider.LazyGetRequiredService();
+
///
/// 获取模型
///
@@ -510,6 +514,17 @@ public class AiGateWayManager : DomainService
});
await _usageStatisticsManager.SetUsageAsync(userId.Value, request.Model, data.TokenUsage);
+
+ // 扣减尊享token包用量
+ var totalTokens = (data.TokenUsage?.InputTokens ?? 0) + (data.TokenUsage?.OutputTokens ?? 0);
+ if (totalTokens > 0)
+ {
+ var consumeSuccess = await PremiumPackageManager.ConsumeTokensAsync(userId.Value, totalTokens);
+ if (!consumeSuccess)
+ {
+ _logger.LogWarning($"用户 {userId.Value} 尊享token包扣减失败,消耗token数: {totalTokens}");
+ }
+ }
}
await response.WriteAsJsonAsync(data, cancellationToken);
@@ -603,6 +618,20 @@ public class AiGateWayManager : DomainService
});
await _usageStatisticsManager.SetUsageAsync(userId, request.Model, tokenUsage);
+
+ // 扣减尊享token包用量
+ if (userId.HasValue && tokenUsage is not null)
+ {
+ 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}");
+ }
+ }
+ }
}
#region Anthropic格式Http响应
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/PayManager.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/PayManager.cs
index 288ee54c..220c218a 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/PayManager.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/PayManager.cs
@@ -1,6 +1,7 @@
using System.Text.Json;
using Volo.Abp.Domain.Services;
using Volo.Abp.Users;
+using Yi.Framework.AiHub.Domain.Entities;
using Yi.Framework.AiHub.Domain.Entities.Pay;
using Yi.Framework.AiHub.Domain.Shared.Enums;
using Yi.Framework.SqlSugarCore.Abstractions;
@@ -16,14 +17,18 @@ public class PayManager : DomainService
private readonly ISqlSugarRepository _payNoticeRepository;
private readonly ICurrentUser _currentUser;
private readonly ISqlSugarRepository _payOrderRepository;
+ private readonly ISqlSugarRepository _rechargeRepository;
public PayManager(
ISqlSugarRepository payNoticeRepository,
- ICurrentUser currentUser, ISqlSugarRepository payOrderRepository)
+ ICurrentUser currentUser,
+ ISqlSugarRepository payOrderRepository,
+ ISqlSugarRepository rechargeRepository)
{
_payNoticeRepository = payNoticeRepository;
_currentUser = currentUser;
_payOrderRepository = payOrderRepository;
+ _rechargeRepository = rechargeRepository;
}
///
@@ -39,6 +44,8 @@ public class PayManager : DomainService
throw new UserFriendlyException("用户未登录");
}
+ var userId = _currentUser.GetId();
+
// 如果是尊享包商品,需要验证用户是否为VIP
if (goodsType.IsPremiumPackage())
{
@@ -53,13 +60,27 @@ public class PayManager : DomainService
// 获取商品信息
var goodsName = goodsType.GetDisplayName();
- var totalAmount = goodsType.GetTotalAmount();
+
+ // 计算订单金额(尊享包使用折扣价格,VIP服务使用原价)
+ decimal totalAmount;
+ if (goodsType.IsPremiumPackage())
+ {
+ // 获取用户累加充值金额
+ var totalRechargeAmount = await GetUserTotalRechargeAmountAsync(userId);
+ // 使用折扣后的价格
+ totalAmount = goodsType.GetDiscountedPrice(totalRechargeAmount);
+ }
+ else
+ {
+ // VIP服务使用原价
+ totalAmount = goodsType.GetTotalAmount();
+ }
// 创建订单实体
var payOrder = new PayOrderAggregateRoot
{
OutTradeNo = outTradeNo,
- UserId = _currentUser.GetId(),
+ UserId = userId,
UserName = _currentUser.UserName ?? string.Empty,
TotalAmount = totalAmount,
GoodsName = goodsName,
@@ -145,4 +166,19 @@ public class PayManager : DomainService
}
return TradeStatusEnum.WAIT_TRADE;
}
+
+ ///
+ /// 获取用户累加充值金额
+ ///
+ /// 用户ID
+ /// 累加充值金额
+ public async Task GetUserTotalRechargeAmountAsync(Guid userId)
+ {
+ var totalAmount = await _rechargeRepository
+ ._DbQueryable
+ .Where(x => x.UserId == userId )
+ .SumAsync(x => x.RechargeAmount);
+
+ return totalAmount;
+ }
}