| | |
| | | o.merchant_id, m.merchant_name, m.merchant_rights_config, |
| | | o.product_id, o.product_name_snapshot, p.rights_config, |
| | | o.order_type, o.order_amount, o.base_pay_amount, o.coupon_amount, |
| | | o.subsidy_amount, o.pay_amount, o.order_status, o.verify_status, o.withdrawal_status, o.created_at, |
| | | o.subsidy_amount, o.pay_amount, o.order_status, o.verify_status, o.created_at, |
| | | vr.verify_time, vr.status as verify_record_status |
| | | from benefit_order o |
| | | left join talent_user tu on tu.id = o.talent_id |
| | |
| | | """, orderId, principal.merchantId(), principal.storeId()); |
| | | if (orders.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND, "订单不存在"); |
| | | Map<String, Object> order = orders.get(0); |
| | | // 撤销核销与核销、退款、提现锁定共用同一把订单行锁;锁内读到的核销记录才是稳定的。 |
| | | orderFundBoundary.lock(orderId).requireRevocable(); |
| | | // 撤销核销与核销、退款共用同一把订单行锁;锁内读到的核销记录才是稳定的。 |
| | | orderFundBoundary.lock(orderId); |
| | | if (!"GROUP_BUY".equals(String.valueOf(order.get("orderType")))) { |
| | | throw new BusinessException(ErrorCode.CONFLICT, "当前业务类型不支持撤销核销"); |
| | | } |
| | |
| | | return result; |
| | | } |
| | | |
| | | private String revokeReason(String orderType, boolean withdrawalLocked) { |
| | | if (withdrawalLocked) return "订单已进入提现记录"; |
| | | private String revokeReason(String orderType) { |
| | | return "GROUP_BUY".equals(orderType) ? "已过可撤销时间" : "当前业务类型不支持撤销核销"; |
| | | } |
| | | |
| | |
| | | result.put("couponAmount", couponAmount); |
| | | // 免费入住没有 benefit_order 金额,补贴来自核销记录中的后台配置,不能按原价减实付覆盖为 0。 |
| | | result.put("subsidyAmount", "FREE_STAY".equals(orderType) ? configuredSubsidyAmount : totalDiscount); |
| | | // 已进入提现记录的订单不能再撤销核销,商户端不值得展示一个必然失败的按钮。 |
| | | Long withdrawalStatus = number(order.get("withdrawalStatus")); |
| | | boolean withdrawalLocked = withdrawalStatus != null && withdrawalStatus == 1; |
| | | boolean canRevoke = "GROUP_BUY".equals(orderType) && verifyTime != null && Duration.between(verifyTime, LocalDateTime.now()).toHours() < REVOCATION_HOURS && verifyStatus != null && verifyStatus == 1 && !withdrawalLocked; |
| | | boolean canRevoke = "GROUP_BUY".equals(orderType) && verifyTime != null && Duration.between(verifyTime, LocalDateTime.now()).toHours() < REVOCATION_HOURS && verifyStatus != null && verifyStatus == 1; |
| | | result.put("canRevoke", canRevoke); |
| | | result.put("revokeDeadline", verifyTime == null ? null : verifyTime.plusHours(REVOCATION_HOURS).toString()); |
| | | result.put("revokeReason", canRevoke ? "" : revokeReason(orderType, withdrawalLocked)); |
| | | result.put("revokeReason", canRevoke ? "" : revokeReason(orderType)); |
| | | return result; |
| | | } |
| | | |