From 2c3b5d6b5454dd16fd9425b1b8821fbfb2241bfd Mon Sep 17 00:00:00 2001 From: HH Date: Tue, 13 Dec 2022 23:51:14 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AD=90=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E5=AE=8C=E6=88=90=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/OrderDetailServiceImpl.java | 244 ++++++++++-------- .../ghy/payment/domain/FinancialDetail.java | 3 +- .../ghy/payment/service/AdapayService.java | 35 +++ .../service/FinancialDetailService.java | 13 +- .../impl/FinancialDetailServiceImpl.java | 8 + .../financial/FinancialDetailMapper.xml | 3 + 6 files changed, 201 insertions(+), 105 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 dae236d4..ca161207 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 @@ -13,7 +13,6 @@ import com.ghy.common.enums.PayStatus; import com.ghy.common.exception.base.BaseException; import com.ghy.common.utils.AdapayUtils; import com.ghy.common.utils.ObjectUtils; -import com.ghy.common.utils.StringUtils; import com.ghy.order.domain.OrderDetail; import com.ghy.order.domain.OrderGoods; import com.ghy.order.domain.OrderMaster; @@ -32,6 +31,7 @@ import com.ghy.payment.service.FinancialMasterService; import com.huifu.adapay.core.exception.BaseAdaPayException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -84,6 +84,10 @@ public class OrderDetailServiceImpl implements OrderDetailService { @Resource private OrderGoodsService orderGoodsService; + // Adapay 手续费率 默认0.008 + @Value("${adapay.fee_rate:0.008}") + private String feeRate; + @Override public int insertOrderDetail(OrderDetail orderDetail) { return orderDetailMapper.insertOrderDetail(orderDetail); @@ -113,7 +117,7 @@ public class OrderDetailServiceImpl implements OrderDetailService { Integer masterServerGoodsNum = masterGoodsMap.get(orderGoods.getGoodsStandardId()).getServerGoodsNum(); masterGoodsMap.get(orderGoods.getGoodsStandardId()).setServerGoodsNum(masterServerGoodsNum += orderGoods.getServerGoodsNum()); }); - } else if (OrderStatus.FINISH_CHECK.code() == originOrderDetail.getOrderStatus() && orderDetail.getOrderStatus() < OrderStatus.FINISH_CHECK.code()){ + } else if (OrderStatus.FINISH_CHECK.code() == originOrderDetail.getOrderStatus() && orderDetail.getOrderStatus() < OrderStatus.FINISH_CHECK.code()) { List orderGoodsList = orderGoodsService.selectByOrderDetailId(orderDetail.getId()); orderGoodsList.stream().forEach(orderGoods -> { orderGoods.setServerGoodsNum(0); @@ -124,7 +128,7 @@ public class OrderDetailServiceImpl implements OrderDetailService { }); } // 更新主单关联商品 - masterOrderGoodsList.stream().forEach(masterOrderGoods ->{ + masterOrderGoodsList.stream().forEach(masterOrderGoods -> { orderGoodsService.updateOrderGoods(masterOrderGoods); }); @@ -321,7 +325,7 @@ public class OrderDetailServiceImpl implements OrderDetailService { * 子订单确认完成 * 1.修改子订单状态为 OrderStatus.FINISH.code * 2.将子订单对应的子财务单确认分账 - * 3.异步提现至银行卡 + * 3.提现至银行卡 * * @param orderDetailId 子订单ID */ @@ -331,127 +335,163 @@ public class OrderDetailServiceImpl implements OrderDetailService { public synchronized void finish(Long orderDetailId) throws BaseAdaPayException { // 校验订单 OrderDetail orderDetail = selectById(orderDetailId); - if(orderDetail == null){ + if (orderDetail == null) { throw new BaseException("找不到对应的子订单"); } + String odCode = orderDetail.getCode(); Assert.isTrue(!orderDetail.getOrderStatus().equals(OrderStatus.FINISH.code()), "订单已经是完成状态"); FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderDetail.getOrderMasterId()); - if(financialMaster == null){ + if (financialMaster == null) { throw new BaseException("找不到主财务单"); } PaymentDTO payment = financialMasterService.selectPaymentById(financialMaster.getPaymentId()); - if(payment == null){ + if (payment == null) { throw new BaseException("找不到支付记录"); } - List financialDetail = financialDetailService.selectListByOrderDetailId(orderDetailId); - if(financialDetail == null){ + List financialDetails = financialDetailService.selectListByOrderDetailId(orderDetailId); + if (CollectionUtils.isEmpty(financialDetails)) { throw new BaseException("找不到子财务单"); } - if(financialDetail.get(0).getPayStatus() != 1){ + // 子订单对应的子财务单只有一条 直接取出 + FinancialDetail financialDetail = financialDetails.get(0); + if (financialDetail.getPayStatus() != 1) { throw new BaseException("订单不是“已支付”状态"); } + Long financialMasterId = financialDetail.getFinancialMasterId(); + // 找到 type=平台抽成 的子财务单 用来承担手续费 + List details = financialDetailService.selectByFinancialMasterIdAndType(financialMasterId, 3); + FinancialDetail platformFD = details.get(0); + FinancialDetail update = new FinancialDetail(); + update.setId(platformFD.getId()); + + logger.debug("子订单[code={}]的完单流程开始", odCode); + // 更新订单状态 orderDetailMapper.updateStatus(orderDetailId, OrderStatus.FINISH.code()); - // 找到所有的加价记录 + + // 加价单手续费补偿成功与否 + boolean compensate = false; + // 加价单手续费 + BigDecimal feeAmt = null; + // 待提现金额 + BigDecimal dtx = BigDecimal.ZERO; + // 子单收款人的memberId + String memberId = AdapayUtils.getWorkerMemberId(financialDetail.getPayeeId(), financialDetail.getDeptId()); + + // --------------------- 改价单分账部分 start --------------------- + // 查询子订单的加价记录 List financialChangeRecords = financialChangeRecordService.selectByDetailIds(String.valueOf(orderDetailId)); - if(!CollectionUtils.isEmpty(financialChangeRecords)){ + if (financialChangeRecords.size() == 0) { + logger.debug("子订单[code={}]没有改价单", odCode); + } else if (financialChangeRecords.size() == 1) { ArrayList divMembers = new ArrayList<>(); - financialChangeRecords.forEach(financialChangeRecord -> { - // 递增解决分账 - financialDetail.forEach(detail->{ - BigDecimal money; - // 剩余金额足够本次分账 - if(financialChangeRecord.getLeftMoney().compareTo(detail.getPayMoney()) > 0){ - money = detail.getPayMoney(); - detail.setPayMoney(BigDecimal.ZERO); - }else { - // 剩余金额不够分账 - money = financialChangeRecord.getLeftMoney(); - detail.setPayMoney(detail.getPayMoney().subtract(money)); - } - String memberId = AdapayUtils.getWorkerMemberId(detail.getPayeeId(), detail.getDeptId()); - DivMember divMember = new DivMember(memberId, AdapayUtils.bigDecimalToString(money), false); - divMembers.add(divMember); - }); - //调用分账 - logger.info("子订单[code={}]分账信息: {}", orderDetail.getCode(), JSON.toJSONString(divMembers)); - JSONObject response; - try { - response = adapayService.paymentConfirm(financialDetail.get(0).getDeptId(), financialChangeRecord.getRemark(), payment.getOrderNo() + "_" + System.currentTimeMillis(), - String.valueOf(financialChangeRecord.getLeftMoney()), divMembers, null, null); - logger.info("子订单[code={}]分账结果: {}", orderDetail.getCode(), response.toJSONString()); - } catch (BaseAdaPayException e) { - throw new RuntimeException(e); - } - }); + // 改价记录只会有一条 直接取出 + FinancialChangeRecord fcRecord = financialChangeRecords.get(0); + // 待提现金额里加入改价单金额 + dtx = dtx.add(fcRecord.getChangeMoney()); + // 这里先自己承担手续费 后面再用平台抽成来补偿 + DivMember divMember = new DivMember(memberId, AdapayUtils.bigDecimalToString(fcRecord.getChangeMoney()), true); + divMembers.add(divMember); + //调用分账 + logger.info("子订单[code={}]的[改价单]的分账信息: {}", odCode, JSON.toJSONString(divMembers)); + JSONObject response; + response = adapayService.paymentConfirm(financialDetail.getDeptId(), fcRecord.getRemark(), + payment.getOrderNo() + "_" + System.currentTimeMillis(), + String.valueOf(fcRecord.getLeftMoney()), divMembers, null, null); + logger.info("子订单[code={}]的[改价单]的分账结果: {}", odCode, response.toJSONString()); + boolean status = AdapayStatusEnum.succeeded.code.equals(response.getString("status")); + // 如果确认支付失败 这里抛出异常 回滚订单状态 + Assert.isTrue(status, response.getString("error_msg")); + // 这是被扣掉的手续费 + String fee_amt = response.getString("fee_amt"); + feeAmt = new BigDecimal(fee_amt); + if (feeAmt.compareTo(platformFD.getPayMoney()) < 0 && !"0.00".equals(fee_amt)) { + // 用平台抽成来补偿改价单的手续费 修改平台抽成子财务单金额 + update.setPayMoney(platformFD.getPayMoney().subtract(feeAmt)); + int i = financialDetailService.updateFinancialDetail(update); + compensate = i > 0; + } else { + logger.warn("主订单[code={}]的平台抽成金额不足以承担子订单[code={}]的[改价单]的手续费", + orderDetail.getOrderMasterCode(), odCode); + // 平台抽成不足以承担改价单手续费了 那没办法了只能自己承担 + // 待提现金额里减去改价单手续费 + dtx = dtx.subtract(feeAmt); + } + } else { + logger.error("financialChangeRecords.size = " + financialChangeRecords.size()); } + // --------------------- 改价单分账部分 end --------------------- + + // --------------------- 子财务单分账部分 start --------------------- // 分账账户信息 - Map divMemberMap = new HashMap<>(); + ArrayList divMembers = new ArrayList<>(); - BigDecimal feeAmount = BigDecimal.ZERO; - for (FinancialDetail detail : financialDetail) { - if (BigDecimal.ZERO.compareTo(detail.getPayMoney()) > -1) { - logger.info("子财务单[code={}]支付金额<=0,不需要分账", detail.getCode()); - // 支付金额<=0的话 不需要走下面的流程了 - continue; - } - // 重复的数据一次提现 - String memberId = AdapayUtils.getWorkerMemberId(detail.getPayeeId(), detail.getDeptId()); - DivMember divMember; - if(divMemberMap.containsKey(memberId)){ - divMember = divMemberMap.get(memberId); - divMember.setAmount(AdapayUtils.bigDecimalToString(new BigDecimal(divMember.getAmount()).add(detail.getPayMoney()))); - }else { - divMember = new DivMember(memberId, AdapayUtils.bigDecimalToString(detail.getPayMoney()), false); - divMemberMap.put(memberId, divMember); - } - feeAmount = feeAmount.add(detail.getPayMoney()); + // 子单的金额 + BigDecimal fdPayMoney = financialDetail.getPayMoney(); + // 实际要分账的金额(子单的金额 + 平台补偿改价单手续费) + BigDecimal payMoney; + if (compensate) { + // 平台补偿改价单手续费 + payMoney = fdPayMoney.add(feeAmt); + } else { + // 平台不补偿改价单手续费 + payMoney = fdPayMoney; } - for (Map.Entry entry : divMemberMap.entrySet()) { - divMembers.add(entry.getValue()); + if (BigDecimal.ZERO.compareTo(payMoney) > -1) { + logger.info("子财务单[code={}] 应支付金额={} 不需要分账", financialDetail.getCode(), payMoney); + } else { + // 接单师傅的分账信息 + String payMoneyS = AdapayUtils.bigDecimalToString(payMoney); + 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); + + logger.info("子订单[code={}]分账信息: {}", odCode, JSON.toJSONString(divMembers)); + JSONObject response = adapayService.paymentConfirm(financialDetail.getDeptId(), payment.getId(), payment.getOrderNo() + "_" + System.currentTimeMillis(), + fee.add(payMoney).toString(), divMembers, null, null); + logger.info("子订单[code={}]分账结果: {}", odCode, response.toJSONString()); + boolean status = AdapayStatusEnum.succeeded.code.equals(response.getString("status")); + // 如果确认支付失败 这里抛出异常 回滚订单状态 + Assert.isTrue(status, response.getString("error_msg")); + // 待提现金额里加入子财务单金额 + dtx = dtx.add(payMoney); + // 修改平台抽成子财务单金额 + update.setPayMoney(platformFD.getPayMoney().subtract(fee)); + financialDetailService.updateFinancialDetail(update); } - BigDecimal fee = BigDecimal.ZERO; - if(feeAmount.multiply(BigDecimal.valueOf(0.004)).compareTo(BigDecimal.valueOf(0.01)) < 1){ - fee = fee.add(BigDecimal.valueOf(0.01)); - }else { - fee = feeAmount.multiply(BigDecimal.valueOf(0.004)); + // --------------------- 子财务单分账部分 end --------------------- + + // --------------------- 自动提现流程 start --------------------- + // 走到这里确认分账成功了 进入自动提现流程 + logger.info("子订单[code={}]开始自动提现", odCode); + if (BigDecimal.ZERO.compareTo(dtx) > -1) { + logger.info("子订单[code={}] 待提现金额={} 无需提现", odCode, dtx); } - DivMember feeDivMember = new DivMember("0", AdapayUtils.bigDecimalToString(fee), true); - divMembers.add(feeDivMember); - - BigDecimal totalMoney = feeAmount.add(fee.setScale(2, RoundingMode.CEILING)); - // 扣除交易费用 - String sureMoney = AdapayUtils.bigDecimalToString(totalMoney); - - logger.info("子订单[code={}]分账信息: {}", orderDetail.getCode(), JSON.toJSONString(divMembers)); - JSONObject response = adapayService.paymentConfirm(financialDetail.get(0).getDeptId(), payment.getId(), payment.getOrderNo() + "_" + System.currentTimeMillis(), - sureMoney, divMembers, null, null); - logger.info("子订单[code={}]分账结果: {}", orderDetail.getCode(), response.toJSONString()); - - boolean status = AdapayStatusEnum.pending.code.equals(response.getString("status")) || - AdapayStatusEnum.succeeded.code.equals(response.getString("status")); - // 如果确认支付失败 这里抛出异常 回滚订单状态 - Assert.isTrue(status, response.getString("error_msg")); - // 走到这里确认分账成功了 异步进入自动提现流程 - logger.info("子订单[code={}]开始自动提现", orderDetail.getCode()); - divMembers.forEach(member -> { - try { - String orderNo = AdapayUtils.createOrderNo(AdapayOrderType.DRAW_CASH); - JSONObject drawCashResponse = adapayService.drawCash(financialDetail.get(0).getDeptId(), orderNo, "T1", - member.getAmount(), member.getMemberId(), "订单结算", null); - - boolean drawCashStatus = AdapayStatusEnum.pending.code.equals(drawCashResponse.getString("status")) || - AdapayStatusEnum.succeeded.code.equals(drawCashResponse.getString("status")); - - if (!drawCashStatus) { - //如果提现失败 把信息记录到error日志里 - logger.error("自动发起提现失败: deptId={}, memberId={}, amount={}, 失败原因:{}", financialDetail.get(0).getDeptId(), - member.getMemberId(), member.getAmount(), drawCashResponse.getString("error_msg")); - } - } catch (BaseAdaPayException e) { - logger.error("自动发起提现失败: orderDetailId={}, memberId={}, cashAmt={}", orderDetailId, member.getMemberId(), member.getAmount(), e); + try { + String orderNo = AdapayUtils.createOrderNo(AdapayOrderType.DRAW_CASH); + // 待提现金额 + String cashAmt = AdapayUtils.bigDecimalToString(dtx); + JSONObject drawCashResponse = adapayService.drawCash(financialDetail.getDeptId(), orderNo, "T1", + cashAmt, memberId, "订单结算", null); + boolean drawCashStatus = AdapayStatusEnum.pending.code.equals(drawCashResponse.getString("status")) || + AdapayStatusEnum.succeeded.code.equals(drawCashResponse.getString("status")); + if (drawCashStatus) { + // 提现成功 + logger.info("子订单[code={}]自动提现成功", odCode); + } else { + // 提现失败 把信息记录到error日志里 + logger.error("自动发起提现失败: 子订单code={}, deptId={}, memberId={}, amount={}, 失败信息: {}", odCode, + financialDetail.getDeptId(), memberId, cashAmt, drawCashResponse.toJSONString()); } - }); + } catch (Exception e) { + logger.error("自动发起提现失败: 子订单code={}, deptId={}, memberId={}", odCode, financialDetail.getDeptId(), memberId, e); + } + // --------------------- 自动提现流程 end --------------------- } @Override @@ -463,7 +503,7 @@ public class OrderDetailServiceImpl implements OrderDetailService { @Transactional(rollbackFor = Exception.class) public int changePrice(Long orderDetailId, BigDecimal changeMoney, Integer type, String remark) throws Exception { OrderDetail orderDetail = orderDetailMapper.selectById(orderDetailId); - if(orderDetail==null){ + if (orderDetail == null) { throw new BaseException("子单不存在!"); } FinancialChangeRecord param = new FinancialChangeRecord(); diff --git a/ghy-payment/src/main/java/com/ghy/payment/domain/FinancialDetail.java b/ghy-payment/src/main/java/com/ghy/payment/domain/FinancialDetail.java index eae78ee4..6ee17140 100644 --- a/ghy-payment/src/main/java/com/ghy/payment/domain/FinancialDetail.java +++ b/ghy-payment/src/main/java/com/ghy/payment/domain/FinancialDetail.java @@ -56,7 +56,8 @@ public class FinancialDetail extends BaseEntity { * 收款人ID * 当财务子单类型是师傅转派时 收款人ID是师傅或徒弟的workerId * 当财务子单类型是多级分销时 收款人ID是分销者的customerId - * 当财务子单类型是4或5时 无需填写收款人ID + * 当财务子单类型是4时 无需填写收款人ID + * 当财务子单类型是3,5时 金额属于平台 无需填写收款人ID */ @Excel(name = "收款人ID", cellType = Excel.ColumnType.NUMERIC) private Long payeeId; diff --git a/ghy-payment/src/main/java/com/ghy/payment/service/AdapayService.java b/ghy-payment/src/main/java/com/ghy/payment/service/AdapayService.java index ec62d299..d8129bf7 100644 --- a/ghy-payment/src/main/java/com/ghy/payment/service/AdapayService.java +++ b/ghy-payment/src/main/java/com/ghy/payment/service/AdapayService.java @@ -70,6 +70,25 @@ public class AdapayService { * @param feeMode String(1) 手续费收取模式:O-商户手续费账户扣取手续费,I-交易金额中扣取手续费;值为空时,默认值为I;若为O时,分账对象列表中不支持传入手续费承担方 * @param description String(128) 附加说明 * @return 成功时同步返回一个包含 支付确认对象的JSON https://docs.adapay.tech/api/trade.html#id54 + * 成功示例:{ + * "order_no": "TEST18888888888_001", + * "created_time": "1670932918", + * "confirm_amt": "10.00", + * "confirmed_amt": "0.00", + * "reserved_amt": "0.00", + * "div_members": [{ + * "member_id": "W7D888", + * "amount": "10.00", + * "fee_flag": "Y" + * }], + * "refunded_amt": "0.00", + * "prod_mode": "true", + * "id": "0021120221213200158990448709336858888888", + * "app_id": "app_01af32e7-6173-414f-88e5-79cae64d5e24", + * "fee_amt": "0.08", + * "object": "payment_confirm", + * "status": "succeeded" + * } */ public JSONObject paymentConfirm(@NotNull Long deptId, @NotNull String paymentId, @NotNull String orderNo, @NotNull String confirmAmt, List divMembers, @@ -278,6 +297,22 @@ public class AdapayService { * @param deviceInfo 前端设备信息 https://docs.adapay.tech/api/appendix.html#deviceinfo * @param divMembers 分账对象信息列表 https://docs.adapay.tech/api/appendix.html#divmembers * @return 同步返回一个 支付对象,详见 https://docs.adapay.tech/api/trade.html#id2 + * 成功示例: { + * "order_no": "TEST18888888888_001", + * "created_time": "1670932358", + * "party_order_id": "02212212137155817188888", + * "pay_amt": "10.00", + * "expend": { + * "qrcode_url": "https://qr.alipay.com/bax022139la4gqagxbti8888" + * }, + * "prod_mode": "true", + * "pay_channel": "alipay_qr", + * "query_url": "https://api.adapay.tech/v1/expire/payments/1/cff1102a8a0d5d4be1d444acb7726fdd", + * "id": "002112022121319523810448706986096888888", + * "app_id": "app_01af32e7-6173-414f-88e5-79cae64d5e24", + * "object": "payment", + * "status": "succeeded" + * } */ public JSONObject pay(@NotNull Long deptId, @NotNull String payChannel, @NotNull PayParam payParam, Expend expend, DeviceInfo deviceInfo, diff --git a/ghy-payment/src/main/java/com/ghy/payment/service/FinancialDetailService.java b/ghy-payment/src/main/java/com/ghy/payment/service/FinancialDetailService.java index 1343d020..0378de87 100644 --- a/ghy-payment/src/main/java/com/ghy/payment/service/FinancialDetailService.java +++ b/ghy-payment/src/main/java/com/ghy/payment/service/FinancialDetailService.java @@ -14,9 +14,9 @@ import java.util.Map; public interface FinancialDetailService { /** - * @param countTime 是否查询准确时间 + * @param countTime 是否查询准确时间 * @param financialDetailTypes 子财务单类型 - * @param payeeId 收款人id + * @param payeeId 收款人id * @return 月份集合 */ List count(String countTime, List financialDetailTypes, Integer payeeId); @@ -67,6 +67,7 @@ public interface FinancialDetailService { int deleteFinancialDetailByIds(String ids); int deleteFinancialDetailByOrderDetailId(Long orderDetailId); + /** * 校验财务细单编码是否重复 * @@ -102,4 +103,12 @@ public interface FinancialDetailService { * @param financialDetail 子财务单 */ void updateByFinancialMasterId(FinancialDetail financialDetail); + + /** + * 查询主财务单下指定类型的子财务单 + * + * @param financialMasterId 主财务单id + * @param type 子财务单类型 FinancialDetail.financialDetailType + */ + List selectByFinancialMasterIdAndType(Long financialMasterId, int type); } diff --git a/ghy-payment/src/main/java/com/ghy/payment/service/impl/FinancialDetailServiceImpl.java b/ghy-payment/src/main/java/com/ghy/payment/service/impl/FinancialDetailServiceImpl.java index bf954f56..e6d851bd 100644 --- a/ghy-payment/src/main/java/com/ghy/payment/service/impl/FinancialDetailServiceImpl.java +++ b/ghy-payment/src/main/java/com/ghy/payment/service/impl/FinancialDetailServiceImpl.java @@ -142,6 +142,14 @@ public class FinancialDetailServiceImpl implements FinancialDetailService { financialDetailMapper.updateByFinancialMasterId(financialDetail); } + @Override + public List selectByFinancialMasterIdAndType(Long financialMasterId, int type) { + FinancialDetail financialDetail = new FinancialDetail(); + financialDetail.setFinancialMasterId(financialMasterId); + financialDetail.setFinancialDetailType(type); + return financialDetailMapper.selectFinancialDetailList(financialDetail); + } + @Override public Map byOrderIdInMap(List orderIdList) { Map longFinancialDetailHashMap = new HashMap<>(); diff --git a/ghy-payment/src/main/resources/mapper/financial/FinancialDetailMapper.xml b/ghy-payment/src/main/resources/mapper/financial/FinancialDetailMapper.xml index 2ae8a5f7..cd3772f4 100644 --- a/ghy-payment/src/main/resources/mapper/financial/FinancialDetailMapper.xml +++ b/ghy-payment/src/main/resources/mapper/financial/FinancialDetailMapper.xml @@ -75,6 +75,9 @@ and payee_id = #{payeeId} + + and financial_detail_type = #{financialDetailType} + and financial_detail_type in From 14da970999cb7ebfe4f100d148d652113a20de8c Mon Sep 17 00:00:00 2001 From: "kuang.yife" Date: Wed, 14 Dec 2022 00:39:51 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E5=A4=87=E6=A1=88=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ghy-admin/src/main/resources/templates/login.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ghy-admin/src/main/resources/templates/login.html b/ghy-admin/src/main/resources/templates/login.html index 22812da5..1eb93397 100644 --- a/ghy-admin/src/main/resources/templates/login.html +++ b/ghy-admin/src/main/resources/templates/login.html @@ -3,7 +3,7 @@ - 登录叮咚工链系统 + 追风者 @@ -66,6 +66,7 @@ From c5242eeb658b8e8cb47ac3af84bbfa33a998987d Mon Sep 17 00:00:00 2001 From: HH Date: Wed, 14 Dec 2022 00:40:40 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AD=90=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E5=AE=8C=E6=88=90=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/ghy/order/service/impl/OrderDetailServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ca161207..e23bec45 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 @@ -397,7 +397,7 @@ public class OrderDetailServiceImpl implements OrderDetailService { JSONObject response; response = adapayService.paymentConfirm(financialDetail.getDeptId(), fcRecord.getRemark(), payment.getOrderNo() + "_" + System.currentTimeMillis(), - String.valueOf(fcRecord.getLeftMoney()), divMembers, null, null); + AdapayUtils.bigDecimalToString(fcRecord.getChangeMoney()), divMembers, null, null); logger.info("子订单[code={}]的[改价单]的分账结果: {}", odCode, response.toJSONString()); boolean status = AdapayStatusEnum.succeeded.code.equals(response.getString("status")); // 如果确认支付失败 这里抛出异常 回滚订单状态 From 5e5ad630f6ae5ab372647dedec437746dbc3baf5 Mon Sep 17 00:00:00 2001 From: HH Date: Wed, 14 Dec 2022 01:35:09 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AD=90=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E5=AE=8C=E6=88=90=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ghy/common/adapay/AdapayErrorCode.java | 6 +++ .../service/impl/OrderDetailServiceImpl.java | 51 +++++++++++-------- 2 files changed, 37 insertions(+), 20 deletions(-) create mode 100644 ghy-common/src/main/java/com/ghy/common/adapay/AdapayErrorCode.java diff --git a/ghy-common/src/main/java/com/ghy/common/adapay/AdapayErrorCode.java b/ghy-common/src/main/java/com/ghy/common/adapay/AdapayErrorCode.java new file mode 100644 index 00000000..b16e0f8b --- /dev/null +++ b/ghy-common/src/main/java/com/ghy/common/adapay/AdapayErrorCode.java @@ -0,0 +1,6 @@ +package com.ghy.common.adapay; + +public interface AdapayErrorCode { + + String CONFIRM_AMT_OVER_LIMIT = "confirm_amt_over_limit"; +} 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 e23bec45..e07c18e9 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 @@ -2,6 +2,7 @@ package com.ghy.order.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.ghy.common.adapay.AdapayErrorCode; import com.ghy.common.adapay.model.AdapayStatusEnum; import com.ghy.common.adapay.model.DivMember; import com.ghy.common.adapay.model.PaymentDTO; @@ -394,28 +395,38 @@ public class OrderDetailServiceImpl implements OrderDetailService { divMembers.add(divMember); //调用分账 logger.info("子订单[code={}]的[改价单]的分账信息: {}", odCode, JSON.toJSONString(divMembers)); - JSONObject response; - response = adapayService.paymentConfirm(financialDetail.getDeptId(), fcRecord.getRemark(), + JSONObject response = adapayService.paymentConfirm(financialDetail.getDeptId(), fcRecord.getRemark(), payment.getOrderNo() + "_" + System.currentTimeMillis(), AdapayUtils.bigDecimalToString(fcRecord.getChangeMoney()), divMembers, null, null); - logger.info("子订单[code={}]的[改价单]的分账结果: {}", odCode, response.toJSONString()); - boolean status = AdapayStatusEnum.succeeded.code.equals(response.getString("status")); - // 如果确认支付失败 这里抛出异常 回滚订单状态 - Assert.isTrue(status, response.getString("error_msg")); - // 这是被扣掉的手续费 - String fee_amt = response.getString("fee_amt"); - feeAmt = new BigDecimal(fee_amt); - if (feeAmt.compareTo(platformFD.getPayMoney()) < 0 && !"0.00".equals(fee_amt)) { - // 用平台抽成来补偿改价单的手续费 修改平台抽成子财务单金额 - update.setPayMoney(platformFD.getPayMoney().subtract(feeAmt)); - int i = financialDetailService.updateFinancialDetail(update); - compensate = i > 0; - } else { - logger.warn("主订单[code={}]的平台抽成金额不足以承担子订单[code={}]的[改价单]的手续费", - orderDetail.getOrderMasterCode(), odCode); - // 平台抽成不足以承担改价单手续费了 那没办法了只能自己承担 - // 待提现金额里减去改价单手续费 - dtx = dtx.subtract(feeAmt); + if (AdapayStatusEnum.succeeded.code.equals(response.getString("status"))) { // 分账成功 + logger.info("子订单[code={}]的[改价单]分账成功", odCode); + // 这是被扣掉的手续费 + String fee_amt = response.getString("fee_amt"); + feeAmt = new BigDecimal(fee_amt); + if (feeAmt.compareTo(platformFD.getPayMoney()) < 0 && !"0.00".equals(fee_amt)) { + // 用平台抽成来补偿改价单的手续费 修改平台抽成子财务单金额 + update.setPayMoney(platformFD.getPayMoney().subtract(feeAmt)); + int i = financialDetailService.updateFinancialDetail(update); + 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"))) { + // 当前确认金额 > 支付金额 - 已支付确认金额 - 已支付撤销金额 + // 这里有两种可能 1.可能是之前算错了手续费的旧订单 + // 2.可能是之前执行过完单流程 改价单分账成功了 但是子财务单分账失败了 + // 所以直接跳过 + logger.info("子订单[code={}] 跳过[改价单]分账", odCode); + } else { + logger.error("子订单[code={}]的[改价单 paymentId={}]分账失败: {}", odCode, fcRecord.getRemark(), response.toJSONString()); + // 其它错误抛异常 + throw new IllegalArgumentException(response.getString("error_msg")); + } } } else { logger.error("financialChangeRecords.size = " + financialChangeRecords.size()); From 5606c8fdbc3431b7a3a475b570c8e2ff571ee296 Mon Sep 17 00:00:00 2001 From: HH Date: Wed, 14 Dec 2022 02:12:28 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AD=90=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E5=AE=8C=E6=88=90=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/OrderDetailServiceImpl.java | 33 ++++++++++++------- .../quartz/service/impl/OrderServiceImpl.java | 5 ++- 2 files changed, 24 insertions(+), 14 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 e07c18e9..c9806d07 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 @@ -45,10 +45,7 @@ import java.math.RoundingMode; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; @@ -369,6 +366,19 @@ public class OrderDetailServiceImpl implements OrderDetailService { // 更新订单状态 orderDetailMapper.updateStatus(orderDetailId, OrderStatus.FINISH.code()); + List orderDetails = orderDetailMapper.selectByOrderMasterId(orderDetail.getOrderMasterId()); + Set statusSet = orderDetails.stream().map(OrderDetail::getOrderStatus).collect(Collectors.toSet()); + boolean allFinish = true; + for (Integer integer : statusSet) { + if (integer < 5) { + allFinish = false; + break; + } + } + // 如果已经不存在"已完成"和"已取消"以外的子订单 就把主订单也改为完成 + if (allFinish) { + orderMasterMapper.updateStatus(orderDetail.getOrderMasterId(), OrderStatus.FINISH.code()); + } // 加价单手续费补偿成功与否 boolean compensate = false; @@ -376,18 +386,19 @@ public class OrderDetailServiceImpl implements OrderDetailService { BigDecimal feeAmt = null; // 待提现金额 BigDecimal dtx = BigDecimal.ZERO; + // 加价金额 + BigDecimal addPrice; // 子单收款人的memberId String memberId = AdapayUtils.getWorkerMemberId(financialDetail.getPayeeId(), financialDetail.getDeptId()); // --------------------- 改价单分账部分 start --------------------- // 查询子订单的加价记录 List financialChangeRecords = financialChangeRecordService.selectByDetailIds(String.valueOf(orderDetailId)); - if (financialChangeRecords.size() == 0) { - logger.debug("子订单[code={}]没有改价单", odCode); - } else if (financialChangeRecords.size() == 1) { + if (!CollectionUtils.isEmpty(financialChangeRecords)) { ArrayList divMembers = new ArrayList<>(); // 改价记录只会有一条 直接取出 FinancialChangeRecord fcRecord = financialChangeRecords.get(0); + addPrice = fcRecord.getChangeMoney(); // 待提现金额里加入改价单金额 dtx = dtx.add(fcRecord.getChangeMoney()); // 这里先自己承担手续费 后面再用平台抽成来补偿 @@ -429,7 +440,7 @@ public class OrderDetailServiceImpl implements OrderDetailService { } } } else { - logger.error("financialChangeRecords.size = " + financialChangeRecords.size()); + addPrice = BigDecimal.ZERO; } // --------------------- 改价单分账部分 end --------------------- @@ -437,9 +448,9 @@ public class OrderDetailServiceImpl implements OrderDetailService { // 分账账户信息 ArrayList divMembers = new ArrayList<>(); - // 子单的金额 - BigDecimal fdPayMoney = financialDetail.getPayMoney(); - // 实际要分账的金额(子单的金额 + 平台补偿改价单手续费) + // 子单的实际金额 + BigDecimal fdPayMoney = financialDetail.getPayMoney().subtract(addPrice); + // 实际要分账的金额(子单的实际金额 + 平台补偿改价单手续费) BigDecimal payMoney; if (compensate) { // 平台补偿改价单手续费 diff --git a/ghy-quartz/src/main/java/com/ghy/quartz/service/impl/OrderServiceImpl.java b/ghy-quartz/src/main/java/com/ghy/quartz/service/impl/OrderServiceImpl.java index 18532fe8..badd6c85 100644 --- a/ghy-quartz/src/main/java/com/ghy/quartz/service/impl/OrderServiceImpl.java +++ b/ghy-quartz/src/main/java/com/ghy/quartz/service/impl/OrderServiceImpl.java @@ -3,7 +3,6 @@ package com.ghy.quartz.service.impl; import com.ghy.common.enums.FinancialDetailType; import com.ghy.common.enums.OrderStatus; import com.ghy.order.domain.OrderDetail; -import com.ghy.order.domain.OrderMaster; import com.ghy.order.service.OrderDetailService; import com.ghy.order.service.OrderMasterService; import com.ghy.payment.domain.FinancialDetail; @@ -11,7 +10,6 @@ import com.ghy.payment.domain.OrderTimeoutRecord; import com.ghy.payment.mapper.OrderFineRecordMapper; import com.ghy.payment.service.FinancialDetailService; import com.ghy.quartz.service.OrderService; -import com.huifu.adapay.core.exception.BaseAdaPayException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -137,7 +135,8 @@ public class OrderServiceImpl implements OrderService { // 查询出"待确认"状态的子订单 List orderDetails = orderDetailService.selectByStatus(Collections.singletonList(OrderStatus.FINISH_CHECK.code())); long now = System.currentTimeMillis(); - long day14ago = now - (60 * 60 * 1000L); +// long day14ago = now - (60 * 60 * 1000L); + long day14ago = now - 10000L; for (OrderDetail orderDetail : orderDetails) { // 查询符合自动确认的订单 if (day14ago > orderDetail.getUpdateTime().getTime()) { From adecf6be3b0af8d3bf1071f7c3c04e45a298a4b8 Mon Sep 17 00:00:00 2001 From: HH Date: Wed, 14 Dec 2022 19:48:04 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AD=90=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E5=AE=8C=E6=88=90=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/OrderDetailServiceImpl.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 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 c9806d07..6ebfc8f1 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 @@ -366,19 +366,6 @@ public class OrderDetailServiceImpl implements OrderDetailService { // 更新订单状态 orderDetailMapper.updateStatus(orderDetailId, OrderStatus.FINISH.code()); - List orderDetails = orderDetailMapper.selectByOrderMasterId(orderDetail.getOrderMasterId()); - Set statusSet = orderDetails.stream().map(OrderDetail::getOrderStatus).collect(Collectors.toSet()); - boolean allFinish = true; - for (Integer integer : statusSet) { - if (integer < 5) { - allFinish = false; - break; - } - } - // 如果已经不存在"已完成"和"已取消"以外的子订单 就把主订单也改为完成 - if (allFinish) { - orderMasterMapper.updateStatus(orderDetail.getOrderMasterId(), OrderStatus.FINISH.code()); - } // 加价单手续费补偿成功与否 boolean compensate = false; @@ -514,6 +501,25 @@ public class OrderDetailServiceImpl implements OrderDetailService { logger.error("自动发起提现失败: 子订单code={}, deptId={}, memberId={}", odCode, financialDetail.getDeptId(), memberId, e); } // --------------------- 自动提现流程 end --------------------- + + // --------------------- 触发主订单完单流程 start --------------------- + try { + List orderDetails = orderDetailMapper.selectByOrderMasterId(orderDetail.getOrderMasterId()); + Set statusSet = orderDetails.stream().map(OrderDetail::getOrderStatus).collect(Collectors.toSet()); + boolean allFinish = true; + for (Integer integer : statusSet) { + if (integer < 5) { + allFinish = false; + break; + } + } + // 如果已经不存在"已完成"和"已取消"以外的子订单 就把主订单也改为完成 + if (allFinish) { + orderMasterService.finish(orderDetail.getOrderMasterId()); + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + } } @Override