From acf7a47be60ce76368a79f110e1adc54bc0584cc Mon Sep 17 00:00:00 2001 From: Hawking Date: Fri, 5 May 2023 17:20:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AD=90=E5=8D=95=E5=88=86=E8=B4=A6=E6=97=B6?= =?UTF-8?q?=E6=8A=B5=E6=89=A3=E8=B6=85=E6=97=B6=E7=BD=9A=E9=87=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/OrderDetailServiceImpl.java | 136 +++++++++++++----- .../payment/mapper/OrderFineRecordMapper.java | 14 +- .../financial/OrderFineRecordMapper.xml | 18 ++- 3 files changed, 131 insertions(+), 37 deletions(-) diff --git a/ghy-order/src/main/java/com/ghy/order/service/impl/OrderDetailServiceImpl.java b/ghy-order/src/main/java/com/ghy/order/service/impl/OrderDetailServiceImpl.java index 6115a3ac..e86485c9 100644 --- a/ghy-order/src/main/java/com/ghy/order/service/impl/OrderDetailServiceImpl.java +++ b/ghy-order/src/main/java/com/ghy/order/service/impl/OrderDetailServiceImpl.java @@ -23,6 +23,8 @@ import com.ghy.order.service.OrderMasterService; import com.ghy.payment.domain.FinancialChangeRecord; import com.ghy.payment.domain.FinancialDetail; import com.ghy.payment.domain.FinancialMaster; +import com.ghy.payment.domain.OrderTimeoutRecord; +import com.ghy.payment.mapper.OrderFineRecordMapper; import com.ghy.payment.service.AdapayService; import com.ghy.payment.service.FinancialChangeRecordService; import com.ghy.payment.service.FinancialDetailService; @@ -79,6 +81,8 @@ public class OrderDetailServiceImpl implements OrderDetailService { private FinancialChangeRecordService financialChangeRecordService; @Resource private OrderGoodsService orderGoodsService; + @Resource + private OrderFineRecordMapper orderFineRecordMapper; // Adapay 手续费率 默认0.008 @Value("${adapay.fee_rate:0.008}") @@ -457,11 +461,45 @@ public class OrderDetailServiceImpl implements OrderDetailService { if (paid || payedAdd) { ArrayList divMembers = new ArrayList<>(); addPrice = fcRecord.getChangeMoney(); - // 待提现金额里加入改价单金额 - dtx = dtx.add(fcRecord.getChangeMoney()); - // 这里先自己承担手续费 后面再用平台抽成来补偿 - DivMember divMember = new DivMember(memberId, AdapayUtils.bigDecimalToString(fcRecord.getChangeMoney()), true); - divMembers.add(divMember); + BigDecimal fineMoney = BigDecimal.ZERO; + // 查询师傅的超时扣款记录 + List fineRecords = orderFineRecordMapper.selectUnFine(orderDetail.getWorkerId()); + ArrayList fineIds = new ArrayList<>(); + for (OrderTimeoutRecord fineRecord : fineRecords) { + // 抵扣超时罚金 这里的罚金是按创建时间升序排列的 优先抵扣最早的罚金 + if (fineMoney.add(fineRecord.getPayMoney()).compareTo(fcRecord.getChangeMoney()) > 0) { + // 加价单金额不足以抵扣罚金 + logger.info("子订单[{}]的加价单[{}]不足以抵扣罚金{}元", orderDetailId, fcRecord.getId(), fineRecord.getPayMoney()); + break; + } else { + // 抵扣罚金 + logger.info("子订单[{}]的加价单[{}]抵扣罚金{}元", orderDetailId, fcRecord.getId(), fineRecord.getPayMoney()); + fineMoney = fineMoney.add(fineRecord.getPayMoney()); + // 被抵扣的罚金记录ID先存下来,分账成功后修改状态 + fineIds.add(fineRecord.getId()); + } + } + + // 是否有罚金 + boolean haveFine = BigDecimal.ZERO.compareTo(fineMoney) < 0; + if (haveFine) { // 有罚金 + // 扣除罚金后的加价金额 + BigDecimal workerAddMoney = fcRecord.getChangeMoney().subtract(fineMoney); + // 待提现金额里加入加价金额 + dtx = dtx.add(workerAddMoney); + // 这里由平台承担手续费 + DivMember divMember = new DivMember(memberId, AdapayUtils.bigDecimalToString(workerAddMoney), false); + DivMember planDivMember = new DivMember("0", AdapayUtils.bigDecimalToString(fineMoney), true); + divMembers.add(divMember); + divMembers.add(planDivMember); + } else { // 没有罚金 + // 待提现金额里加入加价金额 + dtx = dtx.add(fcRecord.getChangeMoney()); + // 这里先自己承担手续费 后面再用平台抽成来补偿 + DivMember divMember = new DivMember(memberId, AdapayUtils.bigDecimalToString(fcRecord.getChangeMoney()), true); + divMembers.add(divMember); + } + //调用分账 logger.info("子订单[code={}]的[改价单]发起分账", odCode); JSONObject response = adapayService.paymentConfirm(financialDetail.getDeptId(), fcRecord.getRemark(), @@ -469,21 +507,25 @@ public class OrderDetailServiceImpl implements OrderDetailService { AdapayUtils.bigDecimalToString(fcRecord.getChangeMoney()), divMembers, null, null); if (AdapayStatusEnum.succeeded.code.equals(response.getString("status"))) { // 分账成功 logger.info("子订单[code={}]的[改价单]分账成功", odCode); - // 这是被扣掉的手续费 按理说这里肯定大于0 - String fee_amt = response.getString("fee_amt"); - feeAmt = new BigDecimal(fee_amt); - if (feeAmt.compareTo(platformFeeFD.getPayMoney()) < 0 && !"0.00".equals(fee_amt)) { - // 当 0.00<改价单的手续费<=平台抽成金额 时 - // 用平台抽成来补偿改价单的手续费 修改平台抽成子财务单金额 - fdUpdate.setPayMoney(fdUpdate.getPayMoney().subtract(feeAmt)); - int i = financialDetailService.updateFinancialDetail(fdUpdate); - compensate = i > 0; - } else { - logger.warn("主订单[code={}]的平台抽成金额不足以承担子订单[code={}]的[改价单]的手续费", - orderDetail.getOrderMasterCode(), odCode); - // 平台抽成不足以承担改价单手续费了 那没办法了只能自己承担 - // 待提现金额里减去改价单手续费 - dtx = dtx.subtract(feeAmt); + // 分账成功 把罚金状态改为已扣除 + fineIds.forEach(fineRecordId -> orderFineRecordMapper.updateFineStatus(fineRecordId, 1)); + if (!haveFine) { // 没有罚金的情况才需要补偿手续费 有罚金的话直接在罚金里承担手续费 + // 这是被扣掉的手续费 按理说这里应该大于0 + String fee_amt = response.getString("fee_amt"); + feeAmt = new BigDecimal(fee_amt); + if (feeAmt.compareTo(platformFeeFD.getPayMoney()) < 0 && !"0.00".equals(fee_amt)) { + // 当 0.00<改价单的手续费<=平台抽成金额 时 + // 用平台抽成来补偿改价单的手续费 修改平台抽成子财务单金额 + fdUpdate.setPayMoney(fdUpdate.getPayMoney().subtract(feeAmt)); + int i = financialDetailService.updateFinancialDetail(fdUpdate); + compensate = i > 0; + } else { + logger.warn("主订单[code={}]的平台抽成金额不足以承担子订单[code={}]的[改价单]的手续费", + orderDetail.getOrderMasterCode(), odCode); + // 平台抽成不足以承担改价单手续费了 那没办法了只能自己承担 + // 待提现金额里减去改价单手续费 + dtx = dtx.subtract(feeAmt); + } } } else { // 分账失败 if (AdapayErrorCode.CONFIRM_AMT_OVER_LIMIT.equals(response.getString("error_code"))) { @@ -522,27 +564,57 @@ public class OrderDetailServiceImpl implements OrderDetailService { payMoney = fdPayMoney; } if (BigDecimal.ZERO.compareTo(payMoney) > -1) { - logger.info("子财务单[code={}] 应支付金额={} 不需要分账", financialDetail.getCode(), payMoney); + logger.info("子财务单[{}] 应支付金额={} 不需要分账", financialDetail.getId(), payMoney); } else { + // 查询师傅的超时扣款记录 + List fineRecords = orderFineRecordMapper.selectUnFine(orderDetail.getWorkerId()); + // 超时罚金 + BigDecimal fineMoney = BigDecimal.ZERO; + ArrayList fineIds = new ArrayList<>(); + for (OrderTimeoutRecord fineRecord : fineRecords) { + // 抵扣超时罚金 这里的罚金是按创建时间升序排列的 优先抵扣最早的罚金 + if (fineMoney.add(fineRecord.getPayMoney()).compareTo(fdPayMoney) > 0) { + // 加价单金额不足以抵扣罚金 + logger.info("子订单[{}]的派单金额[{}元]不足以抵扣罚金{}元", orderDetailId, fdPayMoney, fineRecord.getPayMoney()); + break; + } else { + // 抵扣罚金 + logger.info("子订单[{}]的加价单[{}]抵扣罚金{}元", orderDetailId, fdPayMoney, fineRecord.getPayMoney()); + fineMoney = fineMoney.add(fineRecord.getPayMoney()); + // 被抵扣的罚金记录ID先存下来,分账成功后修改状态 + fineIds.add(fineRecord.getId()); + } + } + // 总分账金额 + BigDecimal fee = BigDecimal.ZERO; // 接单师傅的分账信息 - String payMoneyS = AdapayUtils.bigDecimalToString(payMoney); + String payMoneyS = AdapayUtils.bigDecimalToString(payMoney.subtract(fineMoney)); DivMember divMember = new DivMember(memberId, payMoneyS, false); divMembers.add(divMember); - - // 计算本次分账的手续费 保留两位小数(向上取整) - BigDecimal fee = payMoney.multiply(new BigDecimal(feeRate)).setScale(2, RoundingMode.UP); - // 平台的分账信息 用来承担手续费 - DivMember feeDivMember = new DivMember("0", fee.toString(), true); - divMembers.add(feeDivMember); - + // 是否有罚金 + boolean haveFine = BigDecimal.ZERO.compareTo(fineMoney) < 0; + if (haveFine) { // 有罚金 从罚金里扣除手续费 + // 平台的分账信息 用来承担罚金 + DivMember fineDivMember = new DivMember("0", AdapayUtils.bigDecimalToString(fineMoney), true); + divMembers.add(fineDivMember); + } else { // 没有罚金 需要扣除手续费 + // 计算本次分账的手续费 保留两位小数(向上取整) + fee = payMoney.multiply(new BigDecimal(feeRate)).setScale(2, RoundingMode.UP); + // 平台的分账信息 用来承担手续费 + DivMember feeDivMember = new DivMember("0", fee.toString(), true); + divMembers.add(feeDivMember); + } logger.info("子订单[code={}]发起分账", odCode); - JSONObject response = adapayService.paymentConfirm(financialDetail.getDeptId(), payment.getId(), payment.getOrderNo() + "_" + System.currentTimeMillis(), - fee.add(payMoney).toString(), divMembers, null, null); + JSONObject response = adapayService.paymentConfirm(financialDetail.getDeptId(), payment.getId(), + payment.getOrderNo() + "_" + System.currentTimeMillis(), + AdapayUtils.bigDecimalToString(fee.add(payMoney)), divMembers, null, null); boolean status = AdapayStatusEnum.succeeded.code.equals(response.getString("status")); // 如果确认支付失败 这里抛出异常 回滚订单状态 Assert.isTrue(status, response.toString()); + // 分账成功 把罚金状态改为已扣除 + fineIds.forEach(fineRecordId -> orderFineRecordMapper.updateFineStatus(fineRecordId, 1)); // 待提现金额里加入子财务单金额 - dtx = dtx.add(fdPayMoney); + dtx = dtx.add(fdPayMoney.subtract(fineMoney)); // 修改平台抽成子财务单金额 减去手续费 fdUpdate.setPayMoney(fdUpdate.getPayMoney().subtract(fee)); diff --git a/ghy-payment/src/main/java/com/ghy/payment/mapper/OrderFineRecordMapper.java b/ghy-payment/src/main/java/com/ghy/payment/mapper/OrderFineRecordMapper.java index 3cb9bc3b..5465e464 100644 --- a/ghy-payment/src/main/java/com/ghy/payment/mapper/OrderFineRecordMapper.java +++ b/ghy-payment/src/main/java/com/ghy/payment/mapper/OrderFineRecordMapper.java @@ -10,11 +10,21 @@ import java.util.List; */ public interface OrderFineRecordMapper { - OrderTimeoutRecord selectByDetailIdAndStatus(@Param("orderDetailId")Long orderDetailId, @Param("orderStatus")Integer orderStatus); + OrderTimeoutRecord selectByDetailIdAndStatus(@Param("orderDetailId") Long orderDetailId, @Param("orderStatus") Integer orderStatus); List selectList(OrderTimeoutRecord orderTimeoutRecord); int insert(OrderTimeoutRecord orderTimeoutRecord); - int update(OrderTimeoutRecord orderTimeoutRecord); +// int update(OrderTimeoutRecord orderTimeoutRecord); + + int updateFineStatus(@Param("id") Long id, @Param("fineStatus") int fineStatus); + + /** + * 查询某师傅的未扣款的罚金 + * + * @param workerId 师傅id + */ + List selectUnFine(@Param("workerId") Long workerId); + } diff --git a/ghy-payment/src/main/resources/mapper/financial/OrderFineRecordMapper.xml b/ghy-payment/src/main/resources/mapper/financial/OrderFineRecordMapper.xml index cf2940c2..acf89bd4 100644 --- a/ghy-payment/src/main/resources/mapper/financial/OrderFineRecordMapper.xml +++ b/ghy-payment/src/main/resources/mapper/financial/OrderFineRecordMapper.xml @@ -46,12 +46,24 @@ + + - INSERT INTO order_timeout_record (order_detail_id, worker_id, fine_status, order_status, pay_money) - VALUES (#{orderDetailId}, #{workerId}, #{fineStatus}, #{orderStatus}, #{payMoney}) + INSERT INTO order_timeout_record (order_detail_id, worker_id, order_status, pay_money) + VALUES (#{orderDetailId}, #{workerId}, #{orderStatus}, #{payMoney}) - + + + + + + UPDATE order_timeout_record SET fine_status = #{fineStatus} WHERE id = #{id}