From 1a62270421d30b0bd3cdf1eb65b1dbb3a6ed3db4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=A2=93=E5=BD=AD?= Date: Mon, 18 May 2026 00:19:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E6=83=A0=E5=8A=B5=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E5=8F=98=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Event/Dtos/UserCompetitionDtos.cs | 5 + .../Event/UnifiedRegistrationService.cs | 146 ++++++++++++++++-- .../Event/UserEventRegistrationService.cs | 19 +-- YD_Event.Application/YD_Event.Application.xml | 5 + 4 files changed, 150 insertions(+), 25 deletions(-) diff --git a/YD_Event.Application/Event/Dtos/UserCompetitionDtos.cs b/YD_Event.Application/Event/Dtos/UserCompetitionDtos.cs index 0c11b80..e7001e5 100644 --- a/YD_Event.Application/Event/Dtos/UserCompetitionDtos.cs +++ b/YD_Event.Application/Event/Dtos/UserCompetitionDtos.cs @@ -651,6 +651,11 @@ public class ValidateCouponOutput /// public long? CouponId { get; set; } + /// + /// 用户优惠券ID + /// + public long? UserCouponId { get; set; } + /// /// 优惠券名称 /// diff --git a/YD_Event.Application/Event/UnifiedRegistrationService.cs b/YD_Event.Application/Event/UnifiedRegistrationService.cs index 113997c..789e116 100644 --- a/YD_Event.Application/Event/UnifiedRegistrationService.cs +++ b/YD_Event.Application/Event/UnifiedRegistrationService.cs @@ -1265,6 +1265,58 @@ public class UnifiedRegistrationService : ITransient }; } + // 如果订单使用了优惠券,标记为已使用 + if (!string.IsNullOrEmpty(registration.OrderNo)) + { + var order = await _orderRepository.GetFirstAsync(o => o.OrderNo == registration.OrderNo && !o.DeleteMark); + if (order != null && order.CouponId.HasValue) + { + var userCoupon = await _userCouponRepository.GetFirstAsync(uc => + uc.CouponId == order.CouponId.Value && + uc.UserId == registration.CreatedUserId && + uc.Status == 0 && + !uc.DeleteMark); + + if (userCoupon != null) + { + userCoupon.Status = 1; + userCoupon.UseTime = DateTime.Now; + userCoupon.OrderId = order.Id; + userCoupon.UpdatedTime = DateTime.Now; + userCoupon.UpdatedUserId = operatorUserId; + await _userCouponRepository.UpdateAsync(userCoupon); + + // 如果有兑换码,标记兑换码为已使用 + if (userCoupon.RedemptionCodeId.HasValue) + { + var redemptionCode = await _redemptionCodeRepository.GetFirstAsync(rc => + rc.Id == userCoupon.RedemptionCodeId.Value && + rc.Status == 0 && + !rc.DeleteMark); + + if (redemptionCode != null) + { + redemptionCode.Status = 1; + redemptionCode.UsedTime = DateTime.Now; + redemptionCode.UpdatedTime = DateTime.Now; + redemptionCode.UpdatedUserId = operatorUserId; + await _redemptionCodeRepository.UpdateAsync(redemptionCode); + } + } + + // 更新优惠券的已使用数量 + var coupon = await _couponRepository.GetFirstAsync(c => c.Id == order.CouponId.Value && !c.DeleteMark); + if (coupon != null) + { + coupon.UsedQuantity++; + coupon.UpdatedTime = DateTime.Now; + coupon.UpdatedUserId = operatorUserId; + await _couponRepository.UpdateAsync(coupon); + } + } + } + } + // 更新报名记录状态为待审核 - 正式创建报名记录 registration.PaymentProofUrl = input.PaymentProofUrl ?? registration.PaymentProofUrl; registration.PaymentStatus = 0; // 待审核 - 正式报名记录 @@ -2346,13 +2398,36 @@ public class UnifiedRegistrationService : ITransient userCoupon.Status = 1; userCoupon.UseTime = successTime ?? DateTime.Now; userCoupon.OrderId = order.Id; + userCoupon.UpdatedTime = DateTime.Now; + userCoupon.UpdatedUserId = operatorUserId; await _userCouponRepository.UpdateAsync(userCoupon); + // 如果有兑换码,标记兑换码为已使用 + if (userCoupon.RedemptionCodeId.HasValue) + { + var redemptionCode = await _redemptionCodeRepository.GetFirstAsync(rc => + rc.Id == userCoupon.RedemptionCodeId.Value && + rc.Status == 0 && + !rc.DeleteMark); + + if (redemptionCode != null) + { + redemptionCode.Status = 1; + redemptionCode.UsedTime = DateTime.Now; + redemptionCode.UpdatedTime = DateTime.Now; + redemptionCode.UpdatedUserId = operatorUserId; + await _redemptionCodeRepository.UpdateAsync(redemptionCode); + _logger.LogInformation($"兑换码已标记为已使用,兑换码ID={redemptionCode.Id}"); + } + } + // 更新优惠券的已使用数量 var coupon = await _couponRepository.GetByIdAsync(order.CouponId.Value); if (coupon != null) { coupon.UsedQuantity++; + coupon.UpdatedTime = DateTime.Now; + coupon.UpdatedUserId = operatorUserId; await _couponRepository.UpdateAsync(coupon); } @@ -2365,6 +2440,7 @@ public class UnifiedRegistrationService : ITransient /// /// 取消报名 /// + [UnitOfWork] public async Task CancelRegistrationAsync(long registrationId, long operatorUserId) { var reg = await _registrationRepository.GetFirstAsync(r => r.Id == registrationId && r.CreatedUserId == operatorUserId); @@ -2566,14 +2642,14 @@ public class UnifiedRegistrationService : ITransient // 如果用户没有该优惠券,检查是否可以直接领取(假设可以直接通过兑换码领取) if (userCoupon == null) { - // 创建用户优惠券记录 + // 创建用户优惠券记录,但不立即标记为已使用 userCoupon = new YD_Event.Core.Entities.UserCoupon { Id = _idGenerator.NewLong(), UserId = userId, CouponId = coupon.Id, ClaimTime = DateTime.Now, - Status = 0, + Status = 0, // 保持未使用状态 RedemptionCodeId = redemptionCode.Id, RedemptionCode = redemptionCode.Code, CreatedUserId = userId, @@ -2582,15 +2658,7 @@ public class UnifiedRegistrationService : ITransient }; await _userCouponRepository.InsertAsync(userCoupon); - // 更新兑换码状态和关联 - redemptionCode.Status = 1; - redemptionCode.UsedTime = DateTime.Now; - redemptionCode.UserCouponId = userCoupon.Id; - await _redemptionCodeRepository.UpdateAsync(redemptionCode); - - // 更新优惠券已领取数量 - coupon.ClaimedQuantity += 1; - await _couponRepository.UpdateAsync(coupon); + // 注意:不立即更新兑换码状态,也不增加已领取数量,等支付完成后再做 } // 计算优惠金额 @@ -2598,6 +2666,7 @@ public class UnifiedRegistrationService : ITransient result.IsValid = true; result.CouponId = coupon.Id; + result.UserCouponId = userCoupon.Id; result.CouponName = coupon.Name ?? "优惠券"; result.DiscountType = coupon.Type; result.DiscountValue = coupon.Value; @@ -4209,6 +4278,61 @@ public class UnifiedRegistrationService : ITransient await SoftDeleteItemsAsync(items.Select(i => i.Id).ToList(), operatorUserId, now, refundOrder.Id); } + _logger.LogInformation("开始执行优惠券和兑换码回滚:报名ID={RegistrationId}, 订单号={OrderNo}", + registrationId, registration.OrderNo); + + if (order.CouponId.HasValue) + { + var userCoupon = await _userCouponRepository.GetFirstAsync(uc => + uc.CouponId == order.CouponId.Value && + uc.OrderId == order.Id && + uc.Status == 1 && + !uc.DeleteMark); + + if (userCoupon != null) + { + // 回滚用户优惠券状态 + userCoupon.Status = 0; + userCoupon.UseTime = null; + userCoupon.OrderId = null; + userCoupon.UpdatedTime = now; + userCoupon.UpdatedUserId = operatorUserId; + await _userCouponRepository.UpdateAsync(userCoupon); + _logger.LogInformation("用户优惠券回滚成功:用户优惠券ID={UserCouponId}", userCoupon.Id); + + // 如果有兑换码,回滚兑换码 + if (userCoupon.RedemptionCodeId.HasValue) + { + var redemptionCode = await _redemptionCodeRepository.GetFirstAsync(rc => + rc.Id == userCoupon.RedemptionCodeId.Value && + rc.Status == 1 && + !rc.DeleteMark); + + if (redemptionCode != null) + { + redemptionCode.Status = 0; + redemptionCode.UsedTime = null; + redemptionCode.UpdatedTime = now; + redemptionCode.UpdatedUserId = operatorUserId; + await _redemptionCodeRepository.UpdateAsync(redemptionCode); + _logger.LogInformation("兑换码回滚成功:兑换码ID={RedemptionCodeId}", redemptionCode.Id); + } + } + + // 更新优惠券的已使用数量 + var coupon = await _couponRepository.GetFirstAsync(c => c.Id == order.CouponId.Value && !c.DeleteMark); + if (coupon != null) + { + coupon.UsedQuantity = Math.Max(0, coupon.UsedQuantity - 1); + coupon.UpdatedTime = now; + coupon.UpdatedUserId = operatorUserId; + await _couponRepository.UpdateAsync(coupon); + _logger.LogInformation("优惠券已使用数量更新成功:优惠券ID={CouponId}, 原使用数量={OldUsed}, 新使用数量={NewUsed}", + coupon.Id, coupon.UsedQuantity + 1, coupon.UsedQuantity); + } + } + } + _logger.LogInformation("报名失败退款处理成功,报名ID={RegistrationId}, 退款金额={Amount}, 退款单号={RefundNo}", registrationId, order.ActualAmount, refundOrderNo); diff --git a/YD_Event.Application/Event/UserEventRegistrationService.cs b/YD_Event.Application/Event/UserEventRegistrationService.cs index 5aff311..45b2192 100644 --- a/YD_Event.Application/Event/UserEventRegistrationService.cs +++ b/YD_Event.Application/Event/UserEventRegistrationService.cs @@ -966,20 +966,11 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient if (queryResult.Success && queryResult.TradeState == "SUCCESS") { - orderInfo.Order.OrderStatus = OrderStatus.Paid; - orderInfo.Order.PaymentTime = queryResult.SuccessTime?.DateTime; - if (queryResult.PayerAmount.HasValue) - { - orderInfo.Order.ActualAmount = queryResult.PayerAmount.Value / 100m; - } - await _orderRepository.UpdateAsync(orderInfo.Order); - - var registration = await _registrationRepository.GetByIdAsync(orderInfo.Order.RegistrationId); - if (registration != null && registration.PaymentStatus != 1) - { - registration.PaymentStatus = 1; - await _registrationRepository.UpdateAsync(registration); - } + await _unifiedRegistrationService.HandlePaymentSuccessAsync( + orderNo, + queryResult.TransactionId, + queryResult.SuccessTime?.DateTime, + orderInfo.Order.CreatedUserId); _logger.LogInformation("查询订单支付状态 - 订单已更新为已支付,订单号:{OrderNo}", orderNo); return 1; } diff --git a/YD_Event.Application/YD_Event.Application.xml b/YD_Event.Application/YD_Event.Application.xml index 14ba7af..f5f573e 100644 --- a/YD_Event.Application/YD_Event.Application.xml +++ b/YD_Event.Application/YD_Event.Application.xml @@ -7923,6 +7923,11 @@ 优惠券ID + + + 用户优惠券ID + + 优惠券名称