From da9b7a52dbc6fcd2173efef90528d8fccc322554 Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期五, 17 七月 2026 16:22:40 +0800
Subject: [PATCH] P1问题fix

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java |  184 ++++++++++++++++++++++++++-------------------
 1 files changed, 107 insertions(+), 77 deletions(-)

diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
index 0703407..e9311f9 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -662,6 +662,27 @@
 		return chargingOrder != null && "ICBC".equals(chargingOrder.getSourceName());
 	}
 
+	private BigDecimal resolveUpfrontCouponDiscount(Long appCouponId, Long userId, BigDecimal rechargeAmount) {
+		TAppCoupon appCoupon = appCouponClient.getAppCouponById(appCouponId).getData();
+		if (appCoupon == null || !userId.equals(appCoupon.getAppUserId())) {
+			throw new ServiceException("优惠券不存在或不属于当前用户");
+		}
+		if (!Integer.valueOf(1).equals(appCoupon.getStatus())) {
+			throw new ServiceException("优惠券已使用");
+		}
+		LocalDateTime now = LocalDateTime.now();
+		if ((appCoupon.getStartTime() != null && appCoupon.getStartTime().isAfter(now))
+				|| (appCoupon.getEndTime() != null && appCoupon.getEndTime().isBefore(now))) {
+			throw new ServiceException("优惠券不在有效期内");
+		}
+		try {
+			TCoupon coupon = JSON.parseObject(appCoupon.getCouponJson(), TCoupon.class);
+			return ChargingCouponSupport.calculateUpfrontDiscount(coupon, rechargeAmount);
+		} catch (IllegalArgumentException e) {
+			throw new ServiceException(e.getMessage());
+		}
+	}
+
     /**
      * 判断订单是否为白名单订单
      *
@@ -733,74 +754,36 @@
 		AppUserWhitelistMatchVO whitelist = appUserWhitelistClient.matchWhitelist(userId, tChargingGun.getSiteId()).getData();
 		boolean whitelistMatched = whitelist != null && Boolean.TRUE.equals(whitelist.getMatched());
 		if (whitelistMatched) {
-			payMethod = 3;
-			addChargingOrder.setPayMethod(3);
 			addChargingOrder.setAppUserCouponId(null);
 		}
+		boolean whitelistAllFree = whitelistMatched
+				&& Integer.valueOf(WHITELIST_BENEFIT_ALL_FREE).equals(whitelist.getBenefitType());
 		BigDecimal userBalance = money(appUser.getBalance());
 		BigDecimal balancePayAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
-		BigDecimal thirdPayAmount = rechargeAmount;
+		BigDecimal upfrontCouponDiscount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
 		if (payMethod == 2 && userBalance.compareTo(rechargeAmount) >= 0) {
 			payMethod = 1;
 			addChargingOrder.setPayMethod(1);
 		}
 		if (isBalancePayMode(payMethod)) {
 			addChargingOrder.setAppUserCouponId(null);
-			if (payMethod == 1 && userBalance.compareTo(rechargeAmount) < 0) {
+		} else if (!whitelistMatched && addChargingOrder.getAppUserCouponId() != null) {
+			upfrontCouponDiscount = resolveUpfrontCouponDiscount(
+					addChargingOrder.getAppUserCouponId(), userId, rechargeAmount);
+		}
+		BigDecimal payableAmount = whitelistAllFree
+				? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
+				: rechargeAmount.subtract(upfrontCouponDiscount).max(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
+		BigDecimal thirdPayAmount = payableAmount;
+		if (isBalancePayMode(payMethod)) {
+			if (payMethod == 1 && userBalance.compareTo(payableAmount) < 0) {
 				return AjaxResult.error("余额不足,请选择组合支付或第三方支付");
 			}
-			balancePayAmount = payMethod == 1 ? rechargeAmount : userBalance.min(rechargeAmount).setScale(2, RoundingMode.HALF_UP);
-			thirdPayAmount = rechargeAmount.subtract(balancePayAmount).setScale(2, RoundingMode.HALF_UP);
+			balancePayAmount = payMethod == 1 ? payableAmount : userBalance.min(payableAmount).setScale(2, RoundingMode.HALF_UP);
+			thirdPayAmount = payableAmount.subtract(balancePayAmount).setScale(2, RoundingMode.HALF_UP);
 		}
-		if (whitelistMatched) {
-			balancePayAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
-			thirdPayAmount = Integer.valueOf(WHITELIST_BENEFIT_ALL_FREE).equals(whitelist.getBenefitType())
-					? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
-					: rechargeAmount;
-		}
-		//查询待支付状态的订单,没有支付则删除订单
-		List<TChargingOrder> list = this.list(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, userId)
-				.eq(TChargingOrder::getRechargePaymentStatus, 1).eq(TChargingOrder::getDelFlag, 0));
-		for (TChargingOrder tChargingOrder : list) {
-			Integer rechargePaymentType = tChargingOrder.getRechargePaymentType();
-			if ("ICBC".equals(tChargingOrder.getSourceName())) {
-				IcbcPaymentResp data = icbcPaymentClient.query(tChargingOrder.getCode()).getData();
-				if (null != data && isIcbcRemovableStatus(data.getStatus(), tChargingOrder)) {
-					this.removeById(tChargingOrder.getId());
-				}
-			}
-			if (!"ICBC".equals(tChargingOrder.getSourceName()) && 1 == rechargePaymentType) {
-				NotifyV3PayDecodeRespBody data = wxPaymentClient.queryOrderInfo(tChargingOrder.getCode()).getData();
-				if (null != data) {
-					String trade_state = data.getTrade_state();
-					//支付失败,删除无效的订单
-					if (trade_state.equals("REFUND") || trade_state.equals("NOTPAY") || trade_state.equals("REVOKED") || trade_state.equals("PAYERROR")) {
-						this.removeById(tChargingOrder.getId());
-					}
-				}
-			}
-			if (!"ICBC".equals(tChargingOrder.getSourceName()) && 2 == rechargePaymentType) {
-				AliQueryOrder data = aliPaymentClient.query(tChargingOrder.getCode()).getData();
-				if (null != data) {
-					//支付失败,删除无效的订单
-					String tradeStatus = data.getTradeStatus();
-					if (null != tradeStatus && tradeStatus.equals("TRADE_CLOSED")) {
-						this.removeById(tChargingOrder.getId());
-					}
-				}
-			}
-			if (!"ICBC".equals(tChargingOrder.getSourceName()) && 3 == rechargePaymentType) {
-				AliQueryOrder data = h5AliPaymentClient.query(tChargingOrder.getCode()).getData();
-				if (null != data) {
-					//支付失败,删除无效的订单
-					String tradeStatus = data.getTradeStatus();
-					if (null != tradeStatus && tradeStatus.equals("TRADE_CLOSED")) {
-						this.removeById(tChargingOrder.getId());
-					}
-				}
-			}
-		}
-		
+		payMethod = ChargingPaymentSupport.resolvePayMethod(balancePayAmount, thirdPayAmount, payMethod);
+		addChargingOrder.setPayMethod(payMethod);
 		//检查当前枪是否是正在使用中
 		TChargingOrder one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getChargingGunId, addChargingOrder.getId())
 				.in(TChargingOrder::getStatus, Arrays.asList(3)).eq(TChargingOrder::getDelFlag, 0));
@@ -809,7 +792,8 @@
 		}
 		//查询当前充电枪是否有正在支付的订单
 		one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getChargingGunId, addChargingOrder.getId())
-				.eq(TChargingOrder::getAppUserCarId, userId).eq(TChargingOrder::getRechargePaymentStatus, 1).eq(TChargingOrder::getDelFlag, 0));
+				.eq(TChargingOrder::getAppUserId, userId).eq(TChargingOrder::getRechargePaymentStatus, 1)
+				.eq(TChargingOrder::getDelFlag, 0).last("limit 1"));
 		if (null != one) {
 			//查询三方支付数据,支付中直接结束三方订单
 			if ("ICBC".equals(one.getSourceName())) {
@@ -893,6 +877,7 @@
 		chargingOrder.setThirdRefundAmount(BigDecimal.ZERO);
 		chargingOrder.setRechargeAmount(rechargeAmount);
 		chargingOrder.setAppCouponId(addChargingOrder.getAppUserCouponId());
+		chargingOrder.setCouponDiscountAmount(upfrontCouponDiscount);
 		chargingOrder.setIsWhitelist(whitelistMatched ? 1 : 0);
 		chargingOrder.setWhitelistId(whitelistMatched ? whitelist.getWhitelistId() : null);
 		chargingOrder.setWhitelistBenefitType(whitelistMatched ? whitelist.getBenefitType() : null);
@@ -919,7 +904,8 @@
 		TAccountingStrategy accountingStrategy = accountingStrategyClient.getAccountingStrategyById(accountingStrategyId).getData();
 		
 		//会员折扣支持直营网点和加盟商站点
-		if (!whitelistMatched && !isBalancePayMode(payMethod) && null != appUser.getVipId()) {
+		if (!whitelistMatched && Integer.valueOf(1).equals(site.getMemberDiscountFlag())
+				&& !isBalancePayMode(payMethod) && null != appUser.getVipId()) {
 			GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
 			getAppUserVipDetail.setAppUserId(appUser.getId());
 			getAppUserVipDetail.setVipId(appUser.getVipId());
@@ -1146,6 +1132,43 @@
 	public IcbcPaymentResp queryIcbcAdminPayment(String orderCode) {
 		TChargingOrder order = loadIcbcAdminOrder(orderCode, false);
 		return requireFeignData(icbcPaymentClient.query(order.getCode()), "工行支付查询失败");
+	}
+
+	@Transactional
+	@Override
+	public AjaxResult confirmIcbcPayment(String orderCode) {
+		if (!StringUtils.hasLength(orderCode)) {
+			return AjaxResult.error("订单号不能为空");
+		}
+		Long userId = tokenService.getLoginUserApplet().getUserId();
+		TChargingOrder order = this.getOne(new LambdaQueryWrapper<TChargingOrder>()
+				.eq(TChargingOrder::getCode, orderCode)
+				.eq(TChargingOrder::getAppUserId, userId)
+				.eq(TChargingOrder::getDelFlag, 0)
+				.last("limit 1"));
+		if (order == null) {
+			return AjaxResult.error("支付订单不存在");
+		}
+		if (Integer.valueOf(2).equals(order.getRechargePaymentStatus())) {
+			return AjaxResult.success(Collections.singletonMap("confirmed", true));
+		}
+		if (!isIcbcOrder(order)) {
+			return AjaxResult.error("当前订单不是工行支付订单");
+		}
+
+		R<IcbcPaymentResp> queryResult = icbcPaymentClient.query(orderCode);
+		IcbcPaymentResp payment = queryResult == null ? null : queryResult.getData();
+		if (!IcbcAdminFundOperationSupport.isBankPaid(payment)
+				|| payment == null
+				|| !orderCode.equals(payment.getOrderId())
+				|| !StringUtils.hasLength(payment.getTradeNo())) {
+			return AjaxResult.success(Collections.singletonMap("confirmed", false));
+		}
+		AjaxResult callbackResult = chargingOrderCallback(1, orderCode, payment.getTradeNo(), "1");
+		if (!Integer.valueOf(200).equals(callbackResult.get("code"))) {
+			return callbackResult;
+		}
+		return AjaxResult.success(Collections.singletonMap("confirmed", true));
 	}
 
 	@Override
@@ -4104,14 +4127,18 @@
                 }
 
                 //计算优惠券
-                BigDecimal couponDiscount = BigDecimal.ZERO;
+                boolean couponAppliedUpfront = money(chargingOrder.getCouponDiscountAmount()).compareTo(BigDecimal.ZERO) > 0;
+                BigDecimal couponDiscount = couponAppliedUpfront
+                        ? money(chargingOrder.getCouponDiscountAmount()) : BigDecimal.ZERO;
                 if (!isWhitelistOrder(chargingOrder) && !isBalancePayMode(chargingOrder.getPayMethod()) && null != chargingOrder.getAppCouponId()) {
-                    //判断实际充电金额是否满足优惠券使用条件,如果不满足则不适用优惠券。
                     TAppCoupon appCoupon = appCouponClient.getAppCouponById(chargingOrder.getAppCouponId()).getData();
                     String couponJson = appCoupon.getCouponJson();
                     TCoupon tCoupon = JSON.parseObject(couponJson, TCoupon.class);
                     Integer preferentialMode = tCoupon.getPreferentialMode();
-                    if (1 == preferentialMode) {
+                    if (couponAppliedUpfront) {
+                        appCoupon.setStatus(2);
+                        appCouponClient.updateAppCoupon(appCoupon);
+                    } else if (1 == preferentialMode) {
                         //满减
                         if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) {
                             BigDecimal couponDiscountAmount = tCoupon.getDiscountAmount();
@@ -4130,7 +4157,7 @@
                             chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
                         }
                     }
-                    if (2 == preferentialMode) {
+                    if (!couponAppliedUpfront && 2 == preferentialMode) {
                         //抵扣
                         if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) {
                             //折扣金额
@@ -4166,13 +4193,13 @@
                 }
                 //优惠券优惠金额
                 couponDiscount = couponDiscount.setScale(4, RoundingMode.HALF_EVEN);
-                //退款金额+优惠券
-                refundAmount = refundAmount.add(couponDiscount);
-                //实际支付金额-优惠券
-                payAmount = payAmount.subtract(couponDiscount);
-                if (serviceCharge_total.compareTo(BigDecimal.ZERO) > 0) {
-                    serviceCharge_total = serviceCharge_total.subtract(couponDiscount);
+                //历史订单在结算时计算优惠;新订单已在预付时少收优惠金额,不能再次增加退款。
+                if (!couponAppliedUpfront) {
+                    refundAmount = refundAmount.add(couponDiscount);
                 }
+                //实际支付金额-优惠券
+                payAmount = payAmount.subtract(couponDiscount).max(BigDecimal.ZERO);
+                serviceCharge_total = serviceCharge_total.subtract(couponDiscount).max(BigDecimal.ZERO);
                 chargingOrder.setCouponDiscountAmount(couponDiscount.setScale(2, RoundingMode.HALF_EVEN));
                 chargingOrder.setWhitelistDiscountAmount(whitelistDiscount.setScale(2, RoundingMode.HALF_EVEN));
                 chargingOrder.setWhitelistElectricRefundAmount(electricDiscount.setScale(2, RoundingMode.HALF_EVEN));
@@ -6495,14 +6522,18 @@
                 }
 
                 //计算优惠券
-                BigDecimal couponDiscount = BigDecimal.ZERO;
+                boolean couponAppliedUpfront = money(chargingOrder.getCouponDiscountAmount()).compareTo(BigDecimal.ZERO) > 0;
+                BigDecimal couponDiscount = couponAppliedUpfront
+                        ? money(chargingOrder.getCouponDiscountAmount()) : BigDecimal.ZERO;
                 if (null != chargingOrder.getAppCouponId()) {
-                    //判断实际充电金额是否满足优惠券使用条件,如果不满足则不适用优惠券。
                     TAppCoupon appCoupon = appCouponClient.getAppCouponById(chargingOrder.getAppCouponId()).getData();
                     String couponJson = appCoupon.getCouponJson();
                     TCoupon tCoupon = JSON.parseObject(couponJson, TCoupon.class);
                     Integer preferentialMode = tCoupon.getPreferentialMode();
-                    if (1 == preferentialMode) {
+                    if (couponAppliedUpfront) {
+                        appCoupon.setStatus(2);
+                        appCouponClient.updateAppCoupon(appCoupon);
+                    } else if (1 == preferentialMode) {
                         //满减
                         if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) {
                             BigDecimal couponDiscountAmount = tCoupon.getDiscountAmount();
@@ -6521,7 +6552,7 @@
                             chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
                         }
                     }
-                    if (2 == preferentialMode) {
+                    if (!couponAppliedUpfront && 2 == preferentialMode) {
                         //抵扣
                         if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) {
                             //折扣金额
@@ -6546,13 +6577,12 @@
                 }
                 //优惠券优惠金额
                 couponDiscount = couponDiscount.setScale(4, RoundingMode.HALF_EVEN);
-                //退款金额+优惠券
-                refundAmount = refundAmount.add(couponDiscount);
-                //实际支付金额-优惠券
-                payAmount = payAmount.subtract(couponDiscount);
-                if (serviceCharge_total.compareTo(BigDecimal.ZERO) > 0) {
-                    serviceCharge_total = serviceCharge_total.subtract(couponDiscount);
+                if (!couponAppliedUpfront) {
+                    refundAmount = refundAmount.add(couponDiscount);
                 }
+                //实际支付金额-优惠券
+                payAmount = payAmount.subtract(couponDiscount).max(BigDecimal.ZERO);
+                serviceCharge_total = serviceCharge_total.subtract(couponDiscount).max(BigDecimal.ZERO);
                 chargingOrder.setCouponDiscountAmount(couponDiscount.setScale(2, RoundingMode.HALF_EVEN));
                 chargingOrder.setServiceCharge(serviceCharge_total.setScale(2, RoundingMode.HALF_EVEN));
                 chargingOrder.setPaymentAmount(payAmount.setScale(2, RoundingMode.HALF_EVEN));

--
Gitblit v1.7.1