From 20156803daa7480d5da30d32282c2b96fbd76924 Mon Sep 17 00:00:00 2001 From: zpc Date: Wed, 11 Feb 2026 00:58:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=88=86=E9=94=80?= =?UTF-8?q?=E5=A5=96=E5=8A=B1=E5=8A=9F=E8=83=BD=20-=20=E4=B8=8B=E7=BA=A7?= =?UTF-8?q?=E7=94=A8=E6=88=B7RMB=E6=94=AF=E4=BB=98=E5=90=8E=E7=BB=99?= =?UTF-8?q?=E4=B8=8A=E7=BA=A7=E5=8F=91=E6=94=BE=E5=93=88=E5=B0=BC=E5=88=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/PaymentNotifyService.cs | 140 +++++++++++++++++- 1 file changed, 137 insertions(+), 3 deletions(-) diff --git a/server/HoneyBox/src/HoneyBox.Core/Services/PaymentNotifyService.cs b/server/HoneyBox/src/HoneyBox.Core/Services/PaymentNotifyService.cs index 34df3037..bfe45a30 100644 --- a/server/HoneyBox/src/HoneyBox.Core/Services/PaymentNotifyService.cs +++ b/server/HoneyBox/src/HoneyBox.Core/Services/PaymentNotifyService.cs @@ -494,10 +494,21 @@ public class PaymentNotifyService : IPaymentNotifyService return false; } - // 处理成功后,调用微信发货接口 - if (processResult && !string.IsNullOrEmpty(notifyData.OpenId)) + // 处理成功后的后续操作 + if (processResult) { - await UploadWechatShippingInfoAsync(notifyData.OpenId, orderNo); + // 分销奖励(仅对抽盒子订单生效,不包括充值、运费等) + if (attach.StartsWith("order_") || attach.StartsWith("infinite_") || + LotteryOrderTypes.Contains(attach) || InfiniteOrderTypes.Contains(attach)) + { + await ProcessDistributionRewardAsync(orderNo, user.Id); + } + + // 调用微信发货接口 + if (!string.IsNullOrEmpty(notifyData.OpenId)) + { + await UploadWechatShippingInfoAsync(notifyData.OpenId, orderNo); + } } return processResult; @@ -1501,5 +1512,128 @@ public class PaymentNotifyService : IPaymentNotifyService } } + /// + /// 处理分销奖励 + /// 下级用户用RMB支付后,根据配置的分销比例给上级用户发放哈尼券奖励 + /// + /// 订单号 + /// 下级用户ID + private async Task ProcessDistributionRewardAsync(string orderNo, int userId) + { + try + { + // 1. 获取订单信息 + var order = await _dbContext.Orders + .Where(o => o.OrderNum == orderNo) + .Select(o => new { o.Price, o.UserId }) + .FirstOrDefaultAsync(); + + if (order == null || order.Price <= 0) + { + return; + } + + // 2. 获取分销比例配置 + var fxBili = await GetDistributionRatioAsync(); + if (fxBili <= 0) + { + return; + } + + // 3. 计算奖励金额 + // fx_bili 是百分比,如 3 表示 3% + var ratio = fxBili / 100m; + var rewardRmb = Math.Round(order.Price * ratio, 2); + if (rewardRmb <= 0) + { + return; + } + + // 4. 获取上级用户ID + var pid = await _dbContext.Users + .Where(u => u.Id == userId) + .Select(u => u.Pid) + .FirstOrDefaultAsync(); + + if (pid <= 0) + { + return; + } + + // 5. 发放哈尼券奖励(1 RMB = 100 哈尼券) + var rewardIntegral = rewardRmb * 100; + var result = await _paymentService.AddIntegralAsync( + pid, + rewardIntegral, + " ·", // PHP 代码中的内容就是 " ·" + orderNo, + 5, // type=5 表示推荐奖励 + userId // share_uid 记录下级用户ID + ); + + if (result) + { + _logger.LogInformation( + "分销奖励发放成功: OrderNo={OrderNo}, 下级UserId={UserId}, 上级Pid={Pid}, 支付金额={Price}, 奖励比例={Ratio}%, 奖励哈尼券={Reward}", + orderNo, userId, pid, order.Price, fxBili, rewardIntegral); + } + else + { + _logger.LogWarning( + "分销奖励发放失败: OrderNo={OrderNo}, 下级UserId={UserId}, 上级Pid={Pid}", + orderNo, userId, pid); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "处理分销奖励异常: OrderNo={OrderNo}, UserId={UserId}", orderNo, userId); + // 分销奖励失败不影响主流程 + } + } + + /// + /// 获取分销比例配置 + /// + /// 分销比例(百分比),如 3 表示 3% + private async Task GetDistributionRatioAsync() + { + try + { + var config = await _dbContext.Configs + .Where(c => c.ConfigKey == "base") + .Select(c => c.ConfigValue) + .FirstOrDefaultAsync(); + + if (string.IsNullOrEmpty(config)) + { + return 0; + } + + var jsonDoc = JsonSerializer.Deserialize(config); + if (jsonDoc.TryGetProperty("fx_bili", out var fxBiliElement)) + { + // fx_bili 可能是字符串或数字 + if (fxBiliElement.ValueKind == JsonValueKind.Number) + { + return fxBiliElement.GetDecimal(); + } + else if (fxBiliElement.ValueKind == JsonValueKind.String) + { + var fxBiliStr = fxBiliElement.GetString(); + if (decimal.TryParse(fxBiliStr, out var fxBili)) + { + return fxBili; + } + } + } + } + catch (Exception ex) + { + _logger.LogWarning(ex, "获取分销比例配置失败"); + } + + return 0; + } + #endregion }