diff --git a/server/HoneyBox/src/HoneyBox.Core/Services/OrderService.cs b/server/HoneyBox/src/HoneyBox.Core/Services/OrderService.cs index 506736cd..1f497c49 100644 --- a/server/HoneyBox/src/HoneyBox.Core/Services/OrderService.cs +++ b/server/HoneyBox/src/HoneyBox.Core/Services/OrderService.cs @@ -3,6 +3,7 @@ using HoneyBox.Model.Data; using HoneyBox.Model.Entities; using HoneyBox.Model.Models; using HoneyBox.Model.Models.Goods; +using HoneyBox.Model.Models.Lottery; using HoneyBox.Model.Models.Order; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; @@ -16,6 +17,7 @@ public class OrderService : IOrderService { private readonly HoneyBoxDbContext _dbContext; private readonly ILogger _logger; + private readonly ILotteryEngine _lotteryEngine; // 抽奖赏品ID范围 [10, 33] private static readonly int[] ShangPrizeIdRange = { 10, 33 }; @@ -26,10 +28,11 @@ public class OrderService : IOrderService // 无限赏商品类型 private static readonly int[] InfiniteGoodsTypes = { 2, 8, 9, 10, 16, 17 }; - public OrderService(HoneyBoxDbContext dbContext, ILogger logger) + public OrderService(HoneyBoxDbContext dbContext, ILogger logger, ILotteryEngine lotteryEngine) { _dbContext = dbContext; _logger = logger; + _lotteryEngine = lotteryEngine; } #region 订单金额计算 @@ -1066,6 +1069,9 @@ public class OrderService : IOrderService await _dbContext.SaveChangesAsync(); + // 执行普通抽奖逻辑(一番赏等) + await ExecuteLotteryAsync(userId, order.Id, request.GoodsId, goods.Type, num, request.PrizeNum, orderNum); + response = new OrderBuyResponseDto { Status = 0, // 已支付完成 @@ -1085,6 +1091,45 @@ public class OrderService : IOrderService } } + /// + /// 执行普通抽奖逻辑(一番赏、擂台赏、转转赏等) + /// + private async Task ExecuteLotteryAsync(int userId, int orderId, int goodsId, int orderType, int num, int prizeNum, string orderNum) + { + try + { + var drawRequest = new LotteryDrawRequest + { + UserId = userId, + GoodsId = goodsId, + Num = num, + OrderId = orderId, + OrderNum = orderNum, + OrderType = orderType, + Source = 1 // 抽奖获得 + }; + + // 执行多次抽奖 + var results = await _lotteryEngine.DrawMultipleAsync(drawRequest, prizeNum); + + var successCount = results.Count(r => r.Success); + _logger.LogInformation("普通抽奖完成: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}, Num={Num}, PrizeNum={PrizeNum}, SuccessCount={SuccessCount}", + userId, orderId, goodsId, num, prizeNum, successCount); + + if (successCount == 0) + { + _logger.LogWarning("普通抽奖全部失败: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}", + userId, orderId, goodsId); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "执行普通抽奖失败: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}", + userId, orderId, goodsId); + // 抽奖失败不影响订单创建,但需要记录日志以便后续处理 + } + } + /// /// 生成订单号 /// @@ -1443,6 +1488,9 @@ public class OrderService : IOrderService await _dbContext.SaveChangesAsync(); + // 执行无限赏抽奖逻辑 + await ExecuteInfiniteLotteryAsync(userId, order.Id, request.GoodsId, goods.Type, prizeNum, orderNum); + response = new OrderBuyResponseDto { Status = 0, // 已支付完成 @@ -1462,6 +1510,45 @@ public class OrderService : IOrderService } } + /// + /// 执行无限赏抽奖逻辑 + /// + private async Task ExecuteInfiniteLotteryAsync(int userId, int orderId, int goodsId, int orderType, int prizeNum, string orderNum) + { + try + { + var drawRequest = new LotteryDrawRequest + { + UserId = userId, + GoodsId = goodsId, + Num = 0, // 无限赏固定为0 + OrderId = orderId, + OrderNum = orderNum, + OrderType = orderType, + Source = 1 // 抽奖获得 + }; + + // 执行多次抽奖 + var results = await _lotteryEngine.DrawInfiniteMultipleAsync(drawRequest, prizeNum); + + var successCount = results.Count(r => r.Success); + _logger.LogInformation("无限赏抽奖完成: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}, PrizeNum={PrizeNum}, SuccessCount={SuccessCount}", + userId, orderId, goodsId, prizeNum, successCount); + + if (successCount == 0) + { + _logger.LogWarning("无限赏抽奖全部失败: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}", + userId, orderId, goodsId); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "执行无限赏抽奖失败: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}", + userId, orderId, goodsId); + // 抽奖失败不影响订单创建,但需要记录日志以便后续处理 + } + } + /// /// 生成无限赏订单号 /// diff --git a/server/HoneyBox/src/HoneyBox.Core/Services/PaymentNotifyService.cs b/server/HoneyBox/src/HoneyBox.Core/Services/PaymentNotifyService.cs index 639f7528..73d42037 100644 --- a/server/HoneyBox/src/HoneyBox.Core/Services/PaymentNotifyService.cs +++ b/server/HoneyBox/src/HoneyBox.Core/Services/PaymentNotifyService.cs @@ -1,6 +1,7 @@ using HoneyBox.Core.Interfaces; using HoneyBox.Model.Data; using HoneyBox.Model.Entities; +using HoneyBox.Model.Models.Lottery; using HoneyBox.Model.Models.Payment; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; @@ -15,6 +16,7 @@ public class PaymentNotifyService : IPaymentNotifyService private readonly HoneyBoxDbContext _dbContext; private readonly IWechatPayService _wechatPayService; private readonly IPaymentService _paymentService; + private readonly ILotteryEngine _lotteryEngine; private readonly ILogger _logger; /// @@ -42,11 +44,13 @@ public class PaymentNotifyService : IPaymentNotifyService HoneyBoxDbContext dbContext, IWechatPayService wechatPayService, IPaymentService paymentService, + ILotteryEngine lotteryEngine, ILogger logger) { _dbContext = dbContext; _wechatPayService = wechatPayService; _paymentService = paymentService; + _lotteryEngine = lotteryEngine; _logger = logger; } @@ -390,10 +394,8 @@ public class PaymentNotifyService : IPaymentNotifyService _logger.LogInformation("一番赏订单支付处理成功: OrderId={OrderId}, UserId={UserId}, GoodsId={GoodsId}, Num={Num}, OrderType={OrderType}", orderId, userId, goodsId, num, order.OrderType); - // 6. 触发抽奖逻辑 - // 注意:抽奖逻辑(ordinary_prize_notice等)需要在后续任务中实现 - // 这里只完成支付回调的基础处理:订单状态更新、资产扣减、优惠券更新 - // 抽奖逻辑涉及复杂的奖品分配算法,将在专门的抽奖服务中实现 + // 6. 执行普通抽奖逻辑 + await ExecuteLotteryAsync(userId, orderId, goodsId, order.OrderType, num, order.PrizeNum, order.OrderNum); return true; } @@ -409,6 +411,45 @@ public class PaymentNotifyService : IPaymentNotifyService } } + /// + /// 执行普通抽奖逻辑(一番赏、擂台赏、转转赏等) + /// + private async Task ExecuteLotteryAsync(int userId, int orderId, int goodsId, int orderType, int num, int prizeNum, string orderNum) + { + try + { + var drawRequest = new LotteryDrawRequest + { + UserId = userId, + GoodsId = goodsId, + Num = num, + OrderId = orderId, + OrderNum = orderNum, + OrderType = orderType, + Source = 1 // 抽奖获得 + }; + + // 执行多次抽奖 + var results = await _lotteryEngine.DrawMultipleAsync(drawRequest, prizeNum); + + var successCount = results.Count(r => r.Success); + _logger.LogInformation("普通抽奖完成: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}, Num={Num}, PrizeNum={PrizeNum}, SuccessCount={SuccessCount}", + userId, orderId, goodsId, num, prizeNum, successCount); + + if (successCount == 0) + { + _logger.LogWarning("普通抽奖全部失败: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}", + userId, orderId, goodsId); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "执行普通抽奖失败: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}", + userId, orderId, goodsId); + // 抽奖失败不影响支付回调处理,但需要记录日志以便后续处理 + } + } + /// public async Task ProcessInfiniteOrderAsync(int orderId, int userId, int goodsId) { @@ -501,14 +542,8 @@ public class PaymentNotifyService : IPaymentNotifyService _logger.LogInformation("无限赏订单支付处理成功: OrderId={OrderId}, UserId={UserId}, GoodsId={GoodsId}, OrderType={OrderType}, PrizeNum={PrizeNum}", orderId, userId, goodsId, order.OrderType, order.PrizeNum); - // 6. 触发无限赏抽奖逻辑 - // 注意:无限赏抽奖逻辑(infinite_drawprize等)需要在后续任务中实现 - // 这里只完成支付回调的基础处理:订单状态更新、资产扣减、优惠券更新 - // 无限赏抽奖涉及复杂的概率计算和奖品分配算法,将在专门的抽奖服务中实现 - // PHP中根据order_type调用不同的抽奖方法: - // - order_type=10: infinite_shangchengshang (商城赏) - // - order_type=17: infinite_drawprize_tesu (特殊无限赏) - // - 其他: infinite_drawprize (普通无限赏) + // 6. 执行无限赏抽奖逻辑 + await ExecuteInfiniteLotteryAsync(userId, orderId, goodsId, order.OrderType, order.PrizeNum, order.OrderNum); return true; } @@ -524,6 +559,45 @@ public class PaymentNotifyService : IPaymentNotifyService } } + /// + /// 执行无限赏抽奖逻辑 + /// + private async Task ExecuteInfiniteLotteryAsync(int userId, int orderId, int goodsId, int orderType, int prizeNum, string orderNum) + { + try + { + var drawRequest = new LotteryDrawRequest + { + UserId = userId, + GoodsId = goodsId, + Num = 0, // 无限赏固定为0 + OrderId = orderId, + OrderNum = orderNum, + OrderType = orderType, + Source = 1 // 抽奖获得 + }; + + // 执行多次抽奖 + var results = await _lotteryEngine.DrawInfiniteMultipleAsync(drawRequest, prizeNum); + + var successCount = results.Count(r => r.Success); + _logger.LogInformation("无限赏抽奖完成: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}, PrizeNum={PrizeNum}, SuccessCount={SuccessCount}", + userId, orderId, goodsId, prizeNum, successCount); + + if (successCount == 0) + { + _logger.LogWarning("无限赏抽奖全部失败: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}", + userId, orderId, goodsId); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "执行无限赏抽奖失败: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}", + userId, orderId, goodsId); + // 抽奖失败不影响支付回调处理,但需要记录日志以便后续处理 + } + } + /// public async Task ProcessRechargeOrderAsync(string orderNo) { diff --git a/server/HoneyBox/src/HoneyBox.Infrastructure/Modules/ServiceModule.cs b/server/HoneyBox/src/HoneyBox.Infrastructure/Modules/ServiceModule.cs index 42b356e2..72fd7b38 100644 --- a/server/HoneyBox/src/HoneyBox.Infrastructure/Modules/ServiceModule.cs +++ b/server/HoneyBox/src/HoneyBox.Infrastructure/Modules/ServiceModule.cs @@ -208,7 +208,8 @@ public class ServiceModule : Module { var dbContext = c.Resolve(); var logger = c.Resolve>(); - return new OrderService(dbContext, logger); + var lotteryEngine = c.Resolve(); + return new OrderService(dbContext, logger, lotteryEngine); }).As().InstancePerLifetimeScope(); // 注册仓库服务 @@ -252,8 +253,9 @@ public class ServiceModule : Module var dbContext = c.Resolve(); var wechatPayService = c.Resolve(); var paymentService = c.Resolve(); + var lotteryEngine = c.Resolve(); var logger = c.Resolve>(); - return new PaymentNotifyService(dbContext, wechatPayService, paymentService, logger); + return new PaymentNotifyService(dbContext, wechatPayService, paymentService, lotteryEngine, logger); }).As().InstancePerLifetimeScope(); // 注册充值服务