shinnosuke
2026-08-10 5eed7d5f33409b239782518e66f14507dfd11fc5
talent-card-server/src/main/java/com/talentcard/server/business/portal/PendingOrderPortalService.java
@@ -83,10 +83,12 @@
         """, request.couponId(), merchantId, basePayAmount, cardLevel, productId, request.talentId(), orderNo);
      if (coupons.isEmpty()) throw new BusinessException(ErrorCode.CONFLICT, "该优惠券当前不可用,请重新选择");
      long couponAmount = Math.min(MoneyUtils.yuanToCent((BigDecimal) coupons.get(0).get("couponAmount")), longNumber(order.get("basePayAmount")));
      long payAmount = Math.max(0, longNumber(order.get("basePayAmount")) - couponAmount);
      long subsidyAmount = Math.max(0, resolveOriginalAmount(order, couponAmount, payAmount) - payAmount);
      jdbcTemplate.update("""
         update benefit_order set coupon_id = ?, coupon_amount = ?, pay_amount = ?, price_version = price_version + 1
         update benefit_order set coupon_id = ?, coupon_amount = ?, pay_amount = ?, subsidy_amount = ?, price_version = price_version + 1
         where order_no = ? and talent_id = ? and order_status = 0 and price_version = ?
         """, request.couponId(), couponAmount, Math.max(0, longNumber(order.get("basePayAmount")) - couponAmount), orderNo, request.talentId(), request.priceVersion());
         """, request.couponId(), couponAmount, payAmount, subsidyAmount, orderNo, request.talentId(), request.priceVersion());
      return detail(orderNo, request.talentId());
   }
@@ -174,18 +176,7 @@
      }
      result.put("couponLabel", order.get("couponName") == null ? "无" : "减" + yuan(couponAmount).stripTrailingZeros().toPlainString() + "元");
      result.put("talentDiscountText", talentDiscountText(order));
      long originalAmount = longNumber(order.get("orderAmount"));
      if (originalAmount <= 0) {
         BigDecimal productOriginalPrice = decimal(order.get("productOriginalPrice"));
         originalAmount = productOriginalPrice.signum() > 0
               ? MoneyUtils.yuanToCent(productOriginalPrice)
               : longNumber(order.get("basePayAmount"));
      }
      if (originalAmount <= 0) {
         // Historical orders may have missed both price snapshots.  Their selected
         // coupon and payable amount still represent the amount before coupon use.
         originalAmount = Math.max(0, longNumber(order.get("payAmount")) + couponAmount);
      }
      long originalAmount = resolveOriginalAmount(order, couponAmount, longNumber(order.get("payAmount")));
      result.put("originalAmount", yuan(originalAmount));
      // “优惠金额”在待支付页仅表示优惠券抵扣,不应把人才折扣或补贴混入其中。
      result.put("discountAmount", yuan(couponAmount));
@@ -195,6 +186,18 @@
      return result;
   }
   private long resolveOriginalAmount(Map<String, Object> order, long couponAmount, long payAmount) {
      long originalAmount = longNumber(order.get("orderAmount"));
      if (originalAmount > 0) return originalAmount;
      BigDecimal productOriginalPrice = decimal(order.get("productOriginalPrice"));
      if (productOriginalPrice.signum() > 0) return MoneyUtils.yuanToCent(productOriginalPrice);
      long basePayAmount = longNumber(order.get("basePayAmount"));
      if (basePayAmount > 0) return basePayAmount;
      // Historical orders may have missed both price snapshots. Their selected
      // coupon and payable amount still represent the amount before coupon use.
      return Math.max(0, payAmount + couponAmount);
   }
   private List<Map<String, Object>> query(String sql, Object... args) { return jdbcTemplate.queryForList(sql, args).stream().map(DatabaseRows::normalize).toList(); }
   private BigDecimal decimal(Object value) {
      if (value == null) return BigDecimal.ZERO;