feat: 商品枚举与支付服务优化,支持中文名称、参考价格及类别筛选
This commit is contained in:
@@ -0,0 +1,16 @@
|
|||||||
|
using Yi.Framework.AiHub.Domain.Shared.Enums;
|
||||||
|
|
||||||
|
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.Pay;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取商品列表输入DTO
|
||||||
|
/// </summary>
|
||||||
|
public class GetGoodsListInput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 商品类别(可选)
|
||||||
|
/// 如果不传,则返回所有商品
|
||||||
|
/// 如果传了,则只返回指定类别的商品(VIP服务或尊享包)
|
||||||
|
/// </summary>
|
||||||
|
public GoodsCategoryType? GoodsCategoryType { get; set; }
|
||||||
|
}
|
||||||
@@ -17,25 +17,32 @@ public class GoodsListOutput
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal OriginalPrice { get; set; }
|
public decimal OriginalPrice { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 商品参考价格
|
||||||
|
/// </summary>
|
||||||
|
public decimal ReferencePrice { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 商品实际价格(折扣后的价格)
|
/// 商品实际价格(折扣后的价格)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal GoodsPrice { get; set; }
|
public decimal GoodsPrice { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 商品类型
|
/// 折扣金额(仅尊享包)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GoodsTypeEnum GoodsType { get; set; }
|
public decimal? DiscountAmount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 商品类别
|
||||||
|
/// </summary>
|
||||||
|
public string GoodsCategory { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 商品备注
|
/// 商品备注
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Remark { get; set; }
|
public string Remark { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 折扣金额(仅尊享包)
|
|
||||||
/// </summary>
|
|
||||||
public decimal? DiscountAmount { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 折扣说明(仅尊享包)
|
/// 折扣说明(仅尊享包)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public interface IPayService : IApplicationService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取商品列表
|
/// 获取商品列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="input">获取商品列表输入</param>
|
||||||
/// <returns>商品列表</returns>
|
/// <returns>商品列表</returns>
|
||||||
Task<List<GoodsListOutput>> GetGoodsListAsync();
|
Task<List<GoodsListOutput>> GetGoodsListAsync([FromQuery] GetGoodsListInput input);
|
||||||
}
|
}
|
||||||
@@ -189,9 +189,10 @@ public class PayService : ApplicationService, IPayService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取商品列表
|
/// 获取商品列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="input">获取商品列表输入</param>
|
||||||
/// <returns>商品列表</returns>
|
/// <returns>商品列表</returns>
|
||||||
[HttpGet("pay/GoodsList")]
|
[HttpGet("pay/GoodsList")]
|
||||||
public async Task<List<GoodsListOutput>> GetGoodsListAsync()
|
public async Task<List<GoodsListOutput>> GetGoodsListAsync([FromQuery] GetGoodsListInput input)
|
||||||
{
|
{
|
||||||
var goodsList = new List<GoodsListOutput>();
|
var goodsList = new List<GoodsListOutput>();
|
||||||
|
|
||||||
@@ -205,34 +206,46 @@ public class PayService : ApplicationService, IPayService
|
|||||||
// 遍历所有商品枚举
|
// 遍历所有商品枚举
|
||||||
foreach (GoodsTypeEnum goodsType in Enum.GetValues(typeof(GoodsTypeEnum)))
|
foreach (GoodsTypeEnum goodsType in Enum.GetValues(typeof(GoodsTypeEnum)))
|
||||||
{
|
{
|
||||||
|
// 如果指定了商品类别,则过滤
|
||||||
|
if (input.GoodsCategoryType.HasValue)
|
||||||
|
{
|
||||||
|
var goodsCategory = goodsType.GetGoodsCategory();
|
||||||
|
if (goodsCategory != input.GoodsCategoryType.Value)
|
||||||
|
{
|
||||||
|
continue; // 跳过不匹配的商品
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var originalPrice = goodsType.GetTotalAmount();
|
var originalPrice = goodsType.GetTotalAmount();
|
||||||
decimal actualPrice = originalPrice;
|
decimal actualPrice = originalPrice;
|
||||||
decimal? discountAmount = null;
|
decimal? discountAmount = null;
|
||||||
string? discountDescription = null;
|
string? discountDescription = null;
|
||||||
|
|
||||||
// 如果是尊享包商品,计算折扣
|
// 如果是尊享包商品,计算折扣
|
||||||
if (goodsType.IsPremiumPackage() && CurrentUser.IsAuthenticated)
|
if (goodsType.IsPremiumPackage())
|
||||||
{
|
{
|
||||||
discountAmount = goodsType.CalculateDiscount(totalRechargeAmount);
|
discountDescription = "累计充值每10元可减2.5元,最多减50元";
|
||||||
actualPrice = goodsType.GetDiscountedPrice(totalRechargeAmount);
|
if ( CurrentUser.IsAuthenticated)
|
||||||
|
{
|
||||||
|
discountAmount = goodsType.CalculateDiscount(totalRechargeAmount);
|
||||||
|
actualPrice = goodsType.GetDiscountedPrice(totalRechargeAmount);
|
||||||
|
|
||||||
if (discountAmount > 0)
|
if (discountAmount > 0)
|
||||||
{
|
{
|
||||||
discountDescription = $"已优惠 ¥{discountAmount:F2}(累计充值每10元减2.5元,最多减50元)";
|
discountDescription = $"根据累积充值已优惠 ¥{discountAmount:F2}";
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
discountDescription = "累计充值每10元可减2.5元,最多减50元";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var goodsItem = new GoodsListOutput
|
var goodsItem = new GoodsListOutput
|
||||||
{
|
{
|
||||||
GoodsName = goodsType.GetDisplayName(),
|
GoodsName = goodsType.GetChineseName(),
|
||||||
OriginalPrice = originalPrice,
|
OriginalPrice = originalPrice,
|
||||||
|
ReferencePrice = goodsType.GetReferencePrice(),
|
||||||
GoodsPrice = actualPrice,
|
GoodsPrice = actualPrice,
|
||||||
GoodsType = goodsType,
|
GoodsCategory = goodsType.GetGoodsCategory().ToString(),
|
||||||
Remark = GetGoodsRemark(goodsType),
|
Remark = goodsType.GetRemark(),
|
||||||
DiscountAmount = discountAmount,
|
DiscountAmount = discountAmount,
|
||||||
DiscountDescription = discountDescription
|
DiscountDescription = discountDescription
|
||||||
};
|
};
|
||||||
@@ -242,28 +255,7 @@ public class PayService : ApplicationService, IPayService
|
|||||||
|
|
||||||
return goodsList;
|
return goodsList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取商品备注信息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="goodsType">商品类型</param>
|
|
||||||
/// <returns>商品备注</returns>
|
|
||||||
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 "未知商品类型";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取交易状态描述
|
/// 获取交易状态描述
|
||||||
|
|||||||
@@ -10,12 +10,16 @@ namespace Yi.Framework.AiHub.Domain.Shared.Enums;
|
|||||||
public class PriceAttribute : Attribute
|
public class PriceAttribute : Attribute
|
||||||
{
|
{
|
||||||
public decimal Price { get; }
|
public decimal Price { get; }
|
||||||
|
|
||||||
|
public decimal ReferencePrice { get; }
|
||||||
|
|
||||||
public int ValidMonths { get; }
|
public int ValidMonths { get; }
|
||||||
|
|
||||||
public PriceAttribute(double price, int validMonths)
|
public PriceAttribute(double price, int validMonths, double referencePrice)
|
||||||
{
|
{
|
||||||
Price = (decimal)price;
|
Price = (decimal)price;
|
||||||
ValidMonths = validMonths;
|
ValidMonths = validMonths;
|
||||||
|
ReferencePrice = (decimal)referencePrice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,10 +30,14 @@ public class PriceAttribute : Attribute
|
|||||||
public class DisplayNameAttribute : Attribute
|
public class DisplayNameAttribute : Attribute
|
||||||
{
|
{
|
||||||
public string DisplayName { get; }
|
public string DisplayName { get; }
|
||||||
|
public string ChineseName { get; }
|
||||||
|
public string Remark { get; }
|
||||||
|
|
||||||
public DisplayNameAttribute(string displayName)
|
public DisplayNameAttribute(string displayName, string chineseName = "", string remark = "")
|
||||||
{
|
{
|
||||||
DisplayName = displayName;
|
DisplayName = displayName;
|
||||||
|
ChineseName = chineseName;
|
||||||
|
Remark = remark;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +64,7 @@ public enum GoodsCategoryType
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// VIP服务
|
/// VIP服务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
VipService = 1,
|
Vip = 1,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 尊享包服务
|
/// 尊享包服务
|
||||||
@@ -85,35 +93,35 @@ public class TokenAmountAttribute : Attribute
|
|||||||
public enum GoodsTypeEnum
|
public enum GoodsTypeEnum
|
||||||
{
|
{
|
||||||
// VIP服务
|
// VIP服务
|
||||||
[Price(29.9, 1)]
|
[Price(29.9, 1,29.9)]
|
||||||
[DisplayName("YiXinVip 1 month")]
|
[DisplayName("YiXinVip 1 month", "1个月", "灵活选择")]
|
||||||
[GoodsCategory(GoodsCategoryType.VipService)]
|
[GoodsCategory(GoodsCategoryType.Vip)]
|
||||||
YiXinVip1 = 1,
|
YiXinVip1 = 1,
|
||||||
|
|
||||||
[Price(83.7, 3)]
|
[Price(83.7, 3,27.9)]
|
||||||
[DisplayName("YiXinVip 3 month")]
|
[DisplayName("YiXinVip 3 month", "3个月", "短期体验")]
|
||||||
[GoodsCategory(GoodsCategoryType.VipService)]
|
[GoodsCategory(GoodsCategoryType.Vip)]
|
||||||
YiXinVip3 = 3,
|
YiXinVip3 = 3,
|
||||||
|
|
||||||
[Price(155.4, 6)]
|
[Price(155.4, 6,25.9)]
|
||||||
[DisplayName("YiXinVip 6 month")]
|
[DisplayName("YiXinVip 6 month", "6个月", "年度热销")]
|
||||||
[GoodsCategory(GoodsCategoryType.VipService)]
|
[GoodsCategory(GoodsCategoryType.Vip)]
|
||||||
YiXinVip6 = 6,
|
YiXinVip6 = 6,
|
||||||
|
|
||||||
[Price(183.2, 8)]
|
[Price(183.2, 8,22.9)]
|
||||||
[DisplayName("YiXinVip 8 month")]
|
[DisplayName("YiXinVip 8 month", "8个月(推荐)", "限时活动,超高性价比")]
|
||||||
[GoodsCategory(GoodsCategoryType.VipService)]
|
[GoodsCategory(GoodsCategoryType.Vip)]
|
||||||
YiXinVip8 = 8,
|
YiXinVip8 = 8,
|
||||||
|
|
||||||
// 尊享包服务 - 需要VIP资格才能购买
|
// 尊享包服务 - 需要VIP资格才能购买
|
||||||
[Price(188.9, 0)]
|
[Price(188.9, 0,1750)]
|
||||||
[DisplayName("Premium Package 5000W Tokens")]
|
[DisplayName("YiXinPremiumPackage 5000W Tokens", "5000万Tokens", "简单尝试")]
|
||||||
[GoodsCategory(GoodsCategoryType.PremiumPackage)]
|
[GoodsCategory(GoodsCategoryType.PremiumPackage)]
|
||||||
[TokenAmount(5000)]
|
[TokenAmount(5000)]
|
||||||
PremiumPackage5000W = 101,
|
PremiumPackage5000W = 101,
|
||||||
|
|
||||||
[Price(248.9, 0)]
|
[Price(248.9, 0,3500)]
|
||||||
[DisplayName("Premium Package 10000W Tokens")]
|
[DisplayName("YiXinPremiumPackage 10000W Tokens", "1亿Tokens(推荐)", "极致性价比")]
|
||||||
[GoodsCategory(GoodsCategoryType.PremiumPackage)]
|
[GoodsCategory(GoodsCategoryType.PremiumPackage)]
|
||||||
[TokenAmount(10000)]
|
[TokenAmount(10000)]
|
||||||
PremiumPackage10000W = 102,
|
PremiumPackage10000W = 102,
|
||||||
@@ -181,6 +189,18 @@ public static class GoodsTypeEnumExtensions
|
|||||||
return validMonths > 0 ? totalPrice / validMonths : 0m;
|
return validMonths > 0 ? totalPrice / validMonths : 0m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取商品参考价格
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="goodsType">商品类型</param>
|
||||||
|
/// <returns>参考价格</returns>
|
||||||
|
public static decimal GetReferencePrice(this GoodsTypeEnum goodsType)
|
||||||
|
{
|
||||||
|
var fieldInfo = goodsType.GetType().GetField(goodsType.ToString());
|
||||||
|
var priceAttribute = fieldInfo?.GetCustomAttribute<PriceAttribute>();
|
||||||
|
return priceAttribute?.ReferencePrice ?? 0m;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取商品类别
|
/// 获取商品类别
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -190,7 +210,7 @@ public static class GoodsTypeEnumExtensions
|
|||||||
{
|
{
|
||||||
var fieldInfo = goodsType.GetType().GetField(goodsType.ToString());
|
var fieldInfo = goodsType.GetType().GetField(goodsType.ToString());
|
||||||
var categoryAttribute = fieldInfo?.GetCustomAttribute<GoodsCategoryAttribute>();
|
var categoryAttribute = fieldInfo?.GetCustomAttribute<GoodsCategoryAttribute>();
|
||||||
return categoryAttribute?.Category ?? GoodsCategoryType.VipService;
|
return categoryAttribute?.Category ?? GoodsCategoryType.Vip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -210,7 +230,7 @@ public static class GoodsTypeEnumExtensions
|
|||||||
/// <returns>是否为VIP服务</returns>
|
/// <returns>是否为VIP服务</returns>
|
||||||
public static bool IsVipService(this GoodsTypeEnum goodsType)
|
public static bool IsVipService(this GoodsTypeEnum goodsType)
|
||||||
{
|
{
|
||||||
return goodsType.GetGoodsCategory() == GoodsCategoryType.VipService;
|
return goodsType.GetGoodsCategory() == GoodsCategoryType.Vip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -225,6 +245,30 @@ public static class GoodsTypeEnumExtensions
|
|||||||
return tokenAttribute?.TokenAmount ?? 0;
|
return tokenAttribute?.TokenAmount ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取商品中文名称
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="goodsType">商品类型</param>
|
||||||
|
/// <returns>中文名称</returns>
|
||||||
|
public static string GetChineseName(this GoodsTypeEnum goodsType)
|
||||||
|
{
|
||||||
|
var fieldInfo = goodsType.GetType().GetField(goodsType.ToString());
|
||||||
|
var displayNameAttribute = fieldInfo?.GetCustomAttribute<DisplayNameAttribute>();
|
||||||
|
return displayNameAttribute?.ChineseName ?? goodsType.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取商品备注
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="goodsType">商品类型</param>
|
||||||
|
/// <returns>备注信息</returns>
|
||||||
|
public static string GetRemark(this GoodsTypeEnum goodsType)
|
||||||
|
{
|
||||||
|
var fieldInfo = goodsType.GetType().GetField(goodsType.ToString());
|
||||||
|
var displayNameAttribute = fieldInfo?.GetCustomAttribute<DisplayNameAttribute>();
|
||||||
|
return displayNameAttribute?.Remark ?? string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 计算折扣金额(仅用于尊享包)
|
/// 计算折扣金额(仅用于尊享包)
|
||||||
/// 规则:每累加充值10元,减少2.5元,最多减少50元
|
/// 规则:每累加充值10元,减少2.5元,最多减少50元
|
||||||
|
|||||||
Reference in New Issue
Block a user