diff --git a/ghy-admin/src/main/java/com/ghy/web/timer/AdapaySyncTimer.java b/ghy-admin/src/main/java/com/ghy/web/timer/AdapaySyncTimer.java index 91b20e1c..0c693b58 100644 --- a/ghy-admin/src/main/java/com/ghy/web/timer/AdapaySyncTimer.java +++ b/ghy-admin/src/main/java/com/ghy/web/timer/AdapaySyncTimer.java @@ -5,6 +5,8 @@ import com.alibaba.fastjson.JSONObject; import com.ghy.common.adapay.model.AdapayStatusEnum; import com.ghy.common.enums.AdapayOrderType; import com.ghy.common.utils.AdapayUtils; +import com.ghy.customer.domain.CustomerBank; +import com.ghy.customer.service.CustomerBankService; import com.ghy.order.service.OrderDetailService; import com.ghy.payment.domain.DrawCashRecord; import com.ghy.payment.mapper.DrawCashRecordMapper; @@ -39,6 +41,8 @@ public class AdapaySyncTimer { @Resource private WorkerBankService workerBankService; @Resource + private CustomerBankService customerBankService; + @Resource private OrderDetailService orderDetailService; @Resource private DrawCashRecordMapper drawCashRecordMapper; @@ -75,6 +79,33 @@ public class AdapaySyncTimer { log.error(e.getMessage(), e); } } + + List customerBanks = customerBankService.getCustomerBankList(new CustomerBank()); + for (CustomerBank customer : customerBanks) { + Long deptId = customer.getDeptId(); + String memberId = customer.getAdapayMemberId(); + String settleAccountId = customer.getSettleAccountId(); + if (deptId == null || StringUtils.isBlank(memberId) || StringUtils.isBlank(settleAccountId)) { + continue; + } + try { + JSONObject accountBalance = adapayService.queryAccountBalance(deptId, memberId, settleAccountId, "01"); + if (AdapayStatusEnum.succeeded.code.equals(accountBalance.getString("status"))) { + // 可提现金额 + String avlBalance = accountBalance.getString("avl_balance"); + if (BigDecimal.ZERO.compareTo(new BigDecimal(avlBalance)) > -1) { + continue; + } + // 提现 + log.info("Customer[{},{}]开始提现: avlBalance={}", customer.getCustomerId(), customer.getName(), avlBalance); + String orderNo = AdapayUtils.createOrderNo(AdapayOrderType.DRAW_CASH); + JSONObject drawCash = adapayService.drawCash(deptId, orderNo, "T1", avlBalance, memberId, "提现", null); + log.info("Customer[{},{}]提现结果: {}", customer.getCustomerId(), customer.getName(), drawCash.toJSONString()); + } + } catch (BaseAdaPayException e) { + log.error(e.getMessage(), e); + } + } } @Scheduled(fixedRate = 5 * 60 * 1000L) diff --git a/ghy-custom/src/main/resources/mapper/customer/CustomerBankMapper.xml b/ghy-custom/src/main/resources/mapper/customer/CustomerBankMapper.xml index cd7c28a0..f7bd490d 100644 --- a/ghy-custom/src/main/resources/mapper/customer/CustomerBankMapper.xml +++ b/ghy-custom/src/main/resources/mapper/customer/CustomerBankMapper.xml @@ -22,20 +22,8 @@ - SELECT customer_bank_id, - settle_account_id, - customer_id, - name, - cert_id, - bank_name, - bank_num, - phone, - dept_id, - adapay_member_id, - settle_account, - create_by, - create_time, - remark + SELECT customer_bank_id, settle_account_id, customer_id, name, cert_id, bank_name, bank_num, phone, dept_id, + adapay_member_id, settle_account, create_by, create_time, update_by, update_time, remark FROM customer_bank diff --git a/ghy-order/src/main/java/com/ghy/order/domain/OrderMaster.java b/ghy-order/src/main/java/com/ghy/order/domain/OrderMaster.java index 6c313280..10131a82 100644 --- a/ghy-order/src/main/java/com/ghy/order/domain/OrderMaster.java +++ b/ghy-order/src/main/java/com/ghy/order/domain/OrderMaster.java @@ -113,4 +113,14 @@ public class OrderMaster extends BaseEntity { private Boolean shelveStatus; private List exceptOrderMasterIds; + + /** + * 是否超时 1=是 0=否 + */ + private Integer timeout; + + /** + * 超时扣款次数 + */ + private Integer timeoutFineTimes; } diff --git a/ghy-order/src/main/java/com/ghy/order/mapper/OrderMasterMapper.java b/ghy-order/src/main/java/com/ghy/order/mapper/OrderMasterMapper.java index d29329d1..d8994451 100644 --- a/ghy-order/src/main/java/com/ghy/order/mapper/OrderMasterMapper.java +++ b/ghy-order/src/main/java/com/ghy/order/mapper/OrderMasterMapper.java @@ -89,4 +89,22 @@ public interface OrderMasterMapper { List selectByIds(@Param("orderMasterId") Collection orderMasterIds); int updatePayStatus(@Param("orderMasterId") Long orderMasterId, @Param("payStatus") Integer payStatus); + + /** + * 更新主订单超时状态 + * + * @param id 主订单ID + * @param timeout 是否超时 + * @param timeoutFineTimes 超时罚款次数 + * @return 1 + */ + int updateTimeout(@Param("id") Long id, @Param("timeout") int timeout, @Param("timeoutFineTimes") Integer timeoutFineTimes); + + /** + * 移除主订单的师傅ID + * + * @param id 主订单ID + * @return 1 + */ + int removeWorker(Long id); } diff --git a/ghy-order/src/main/java/com/ghy/order/service/OrderMasterService.java b/ghy-order/src/main/java/com/ghy/order/service/OrderMasterService.java index 6cdc826d..7e12b7b1 100644 --- a/ghy-order/src/main/java/com/ghy/order/service/OrderMasterService.java +++ b/ghy-order/src/main/java/com/ghy/order/service/OrderMasterService.java @@ -135,4 +135,31 @@ public interface OrderMasterService { * @return true/false */ boolean isAllAssign(Long orderMasterId); + + /** + * 更新主订单超时状态 + * + * @param id 主订单ID + * @param timeout 是否超时 + * @return 1 + */ + int updateTimeout(Long id, int timeout); + + /** + * 更新子订单超时状态 + * + * @param id 子订单ID + * @param timeout 是否超时 + * @param timeoutFineTimes 超时罚款次数 + * @return 1 + */ + int updateTimeout(Long id, int timeout, int timeoutFineTimes); + + /** + * 移除主订单的师傅ID + * + * @param id 主订单ID + * @return 1 + */ + int removeWorker(Long id); } 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..112d039b 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}") @@ -404,6 +408,7 @@ public class OrderDetailServiceImpl implements OrderDetailService { if (orderDetail == null) { throw new BaseException("找不到对应的子订单"); } + OrderMaster orderMaster = orderMasterService.selectById(orderDetail.getOrderMasterId()); String odCode = orderDetail.getCode(); Assert.isTrue(!orderDetail.getOrderStatus().equals(OrderStatus.FINISH.code()), "订单已经是完成状态"); FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderDetail.getOrderMasterId()); @@ -457,11 +462,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(), orderMaster.getDeptId()); + 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 +508,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 +565,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(), orderMaster.getDeptId()); + // 超时罚金 + 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-order/src/main/java/com/ghy/order/service/impl/OrderMasterServiceImpl.java b/ghy-order/src/main/java/com/ghy/order/service/impl/OrderMasterServiceImpl.java index ae387b07..099074a8 100644 --- a/ghy-order/src/main/java/com/ghy/order/service/impl/OrderMasterServiceImpl.java +++ b/ghy-order/src/main/java/com/ghy/order/service/impl/OrderMasterServiceImpl.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; @@ -69,6 +71,8 @@ public class OrderMasterServiceImpl implements OrderMasterService { private FinancialDetailService financialDetailService; @Resource private FinancialChangeRecordService financialChangeRecordService; + @Resource + private OrderFineRecordMapper orderFineRecordMapper; private static final AtomicLong INDEX = new AtomicLong(1L); @@ -170,7 +174,7 @@ public class OrderMasterServiceImpl implements OrderMasterService { Assert.notNull(payment, String.format("主订单[id=%d]找不到支付记录", orderMasterId)); // 修改主订单状态 - updateStatus(orderMasterId, OrderStatus.FINISH_CHECK.code()); + updateStatus(orderMasterId, OrderStatus.FINISH.code()); if (BigDecimal.ZERO.compareTo(financialMaster.getPayMoney()) > -1) { logger.info("订单[code={}]支付金额<=0,不需要分账", orderMaster.getCode()); @@ -230,7 +234,29 @@ public class OrderMasterServiceImpl implements OrderMasterService { } } - memberMap.put(AdapayUtils.getWorkerMemberId(orderMaster.getWorkerId(), orderMaster.getDeptId()), bigWorkerAmt); + // 超时罚金 + BigDecimal fineMoney = BigDecimal.ZERO; + // 查询师傅的超时扣款记录 + List fineRecords = orderFineRecordMapper.selectUnFine(orderMaster.getWorkerId(), orderMaster.getDeptId()); + ArrayList fineIds = new ArrayList<>(); + for (OrderTimeoutRecord fineRecord : fineRecords) { + // 抵扣超时罚金 这里的罚金是按创建时间升序排列的 优先抵扣最早的罚金 + if (fineMoney.add(fineRecord.getPayMoney()).compareTo(bigWorkerAmt) > 0) { + // 加价单金额不足以抵扣罚金 + logger.info("主订单[{}]的服务金额[{}]不足以抵扣罚金{}元", orderMasterId, bigWorkerAmt, fineRecord.getPayMoney()); + break; + } else { + // 抵扣罚金 + logger.info("主订单[{}]的服务金额抵扣罚金{}元", orderMasterId, fineRecord.getPayMoney()); + fineMoney = fineMoney.add(fineRecord.getPayMoney()); + // 被抵扣的罚金记录ID先存下来,分账成功后修改状态 + fineIds.add(fineRecord.getId()); + } + } + + // 罚金分给平台账户 + memberMap.merge("0", fineMoney, BigDecimal::add); + memberMap.put(AdapayUtils.getWorkerMemberId(orderMaster.getWorkerId(), orderMaster.getDeptId()), bigWorkerAmt.subtract(fineMoney)); confirmAmt = confirmAmt.add(bigWorkerAmt); // 分账账户 @@ -264,6 +290,8 @@ public class OrderMasterServiceImpl implements OrderMasterService { throw new BaseAdaPayException(response.getString("code"), response.getString("message")); } } + // 分账成功 把罚金状态改为已扣除 + fineIds.forEach(fineRecordId -> orderFineRecordMapper.updateFineStatus(fineRecordId, 1)); // 走到这里确认支付和分账都成功了 异步进入自动提现流程 logger.info("订单[code={}]开始自动提现", orderMaster.getCode()); @@ -367,7 +395,9 @@ public class OrderMasterServiceImpl implements OrderMasterService { @Override public List selectByStatus(List status) { - Assert.isTrue(!CollectionUtils.isEmpty(status), "订单状态为空"); + if (CollectionUtils.isEmpty(status)) { + return Collections.emptyList(); + } return orderMasterMapper.selectByStatus(status); } @@ -473,4 +503,19 @@ public class OrderMasterServiceImpl implements OrderMasterService { }).sum(); return masterCount == detailCount; } + + @Override + public int updateTimeout(Long id, int timeout) { + return orderMasterMapper.updateTimeout(id, timeout, null); + } + + @Override + public int updateTimeout(Long id, int timeout, int timeoutFineTimes) { + return orderMasterMapper.updateTimeout(id, timeout, timeoutFineTimes); + } + + @Override + public int removeWorker(Long id) { + return orderMasterMapper.removeWorker(id); + } } diff --git a/ghy-order/src/main/resources/mapper/order/OrderMasterMapper.xml b/ghy-order/src/main/resources/mapper/order/OrderMasterMapper.xml index 03d30e1b..43b6fe85 100644 --- a/ghy-order/src/main/resources/mapper/order/OrderMasterMapper.xml +++ b/ghy-order/src/main/resources/mapper/order/OrderMasterMapper.xml @@ -9,7 +9,7 @@ - + @@ -25,8 +25,10 @@ - - + + + + @@ -46,9 +48,12 @@ expect_time_end, create_by, create_time, + update_time, remark, all_self_assigned, - goods_id + goods_id, + timeout_, + timeout_fine_times FROM order_master @@ -68,9 +73,12 @@ om.expect_time_end, om.create_by, om.create_time, + om.update_time, om.remark, om.all_self_assigned, - om.goods_id + om.goods_id, + om.timeout_, + om.timeout_fine_times FROM order_master om LEFT JOIN customer_address ca ON ca.customer_address_id = om.address_id LEFT JOIN goods g ON g.goods_id = om.goods_id @@ -350,4 +358,17 @@ + + UPDATE order_master + SET timeout_ = #{timeout} + ,timeout_fine_times = #{timeoutFineTimes} + WHERE id = #{id} + + + + UPDATE order_master + SET worker_id = NULL + WHERE id = #{id} + + diff --git a/ghy-payment/src/main/java/com/ghy/payment/domain/OrderTimeoutRecord.java b/ghy-payment/src/main/java/com/ghy/payment/domain/OrderTimeoutRecord.java index 6d7cef46..138c002c 100644 --- a/ghy-payment/src/main/java/com/ghy/payment/domain/OrderTimeoutRecord.java +++ b/ghy-payment/src/main/java/com/ghy/payment/domain/OrderTimeoutRecord.java @@ -21,6 +21,7 @@ public class OrderTimeoutRecord { */ private Long orderDetailId; private Long workerId; + private Long deptId; private List orderDetailIds; @@ -48,9 +49,10 @@ public class OrderTimeoutRecord { public OrderTimeoutRecord() { } - public OrderTimeoutRecord(Long orderDetailId, Long workerId, Integer orderStatus) { + public OrderTimeoutRecord(Long orderDetailId, Long workerId, Long deptId, Integer orderStatus) { this.orderDetailId = orderDetailId; this.workerId = workerId; + this.deptId = deptId; this.orderStatus = orderStatus; } } 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..18a83f8f 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,22 @@ import java.util.List; */ public interface OrderFineRecordMapper { - OrderTimeoutRecord selectByDetailIdAndStatus(@Param("orderDetailId")Long orderDetailId, @Param("orderStatus")Integer orderStatus); + List 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 + * @param deptId 公司id + */ + List selectUnFine(@Param("workerId") Long workerId, @Param("deptId") Long deptId); + } diff --git a/ghy-payment/src/main/java/com/ghy/payment/service/impl/OrderFineRecordServiceImpl.java b/ghy-payment/src/main/java/com/ghy/payment/service/impl/OrderFineRecordServiceImpl.java index 5fd5c722..becef1cb 100644 --- a/ghy-payment/src/main/java/com/ghy/payment/service/impl/OrderFineRecordServiceImpl.java +++ b/ghy-payment/src/main/java/com/ghy/payment/service/impl/OrderFineRecordServiceImpl.java @@ -3,6 +3,7 @@ package com.ghy.payment.service.impl; import com.ghy.payment.domain.OrderTimeoutRecord; import com.ghy.payment.mapper.OrderFineRecordMapper; import com.ghy.payment.service.OrderFineRecordService; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -21,7 +22,12 @@ public class OrderFineRecordServiceImpl implements OrderFineRecordService { @Override public OrderTimeoutRecord selectByDetailIdAndStatus(Long orderDetailId, Integer orderStatus) { - return orderFineRecordMapper.selectByDetailIdAndStatus(orderDetailId, orderStatus); + OrderTimeoutRecord orderTimeoutRecord = null; + List orderTimeoutRecords = orderFineRecordMapper.selectByDetailIdAndStatus(orderDetailId, orderStatus); + if (CollectionUtils.isNotEmpty(orderTimeoutRecords)) { + orderTimeoutRecord = orderTimeoutRecords.get(0); + } + return orderTimeoutRecord; } @Override diff --git a/ghy-payment/src/main/resources/mapper/financial/OrderFineRecordMapper.xml b/ghy-payment/src/main/resources/mapper/financial/OrderFineRecordMapper.xml index 29eb3362..8b71fa33 100644 --- a/ghy-payment/src/main/resources/mapper/financial/OrderFineRecordMapper.xml +++ b/ghy-payment/src/main/resources/mapper/financial/OrderFineRecordMapper.xml @@ -7,19 +7,22 @@ - + + + + - SELECT id, order_detail_id, fine_status, order_status, create_time + SELECT id, order_detail_id, worker_id, dept_id, fine_status, order_status, pay_money, create_time FROM order_timeout_record - - INSERT INTO order_timeout_record (order_detail_id, fine_status, order_status) - VALUES (#{orderDetailId}, #{fineStatus}, #{orderStatus}) + + + + INSERT INTO order_timeout_record (order_detail_id, worker_id, dept_id, order_status, pay_money) + VALUES (#{orderDetailId}, #{workerId}, #{deptId}, #{orderStatus}, #{payMoney}) - + + + + + + UPDATE order_timeout_record SET fine_status = #{fineStatus} WHERE id = #{id} 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 24877beb..56b93942 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 @@ -6,9 +6,11 @@ import com.ghy.order.domain.OrderMaster; import com.ghy.order.service.OrderDetailService; import com.ghy.order.service.OrderMasterService; 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.FinancialDetailService; +import com.ghy.payment.service.FinancialMasterService; import com.ghy.quartz.service.OrderService; import com.ghy.system.domain.SysDeptConfig; import com.ghy.system.service.ISysDeptConfigService; @@ -31,13 +33,18 @@ import java.util.stream.Collectors; @Service public class OrderServiceImpl implements OrderService { + private static final Integer ZERO = 0; private static final Integer ONE = 1; + private static final Integer TWO = 2; /** * 需要超时扣款的订单状态 + * + * @see OrderStatus */ @Value("${order.timeout.status:-4,-3,-2,1,2,3}") private List timeoutOrderStatus; + private static final List orderMasterTimeoutStatus = Arrays.asList(0, 1); @Resource private ThreadPoolTaskExecutor executor; @@ -50,6 +57,8 @@ public class OrderServiceImpl implements OrderService { @Resource private FinancialDetailService financialDetailService; @Resource + private FinancialMasterService financialMasterService; + @Resource private ISysDeptConfigService sysDeptConfigService; @Override @@ -59,14 +68,93 @@ public class OrderServiceImpl implements OrderService { if (nowT.getHour() < 8 || nowT.getHour() > 18) { return; } - // 查询符合超时的单 + // 查询待接单状态的主单 + List orderMasters = orderMasterService.selectByStatus(orderMasterTimeoutStatus); + log.info("扫描到{}条未完成的主订单", orderMasters.size()); + for (OrderMaster orderMaster : orderMasters) { + executor.execute(() -> checkTimeout(orderMaster)); + } + + // 查询符合超时的子单 List orders = orderDetailService.selectByStatus(timeoutOrderStatus); - log.info("扫描到{}条未完成的订单", orders.size()); + log.info("扫描到{}条未完成的子订单", orders.size()); for (OrderDetail order : orders) { executor.execute(() -> checkTimeout(order)); } } + @Transactional(rollbackFor = Exception.class) + void checkTimeout(OrderMaster order) { + Date now = new Date(); + // 待接单状态的超时逻辑 + if (ZERO.equals(order.getOrderStatus())) { + Date createTime = order.getCreateTime(); + Date overTime30min = getOverTime(createTime, 30 * 60 * 1000); + Date overTime1h = getOverTime(createTime, 60 * 60 * 1000); + // 是否已经超时 + boolean timeout = ONE.equals(order.getTimeout()); + if (!timeout) { + if (overTime30min.before(now) && overTime1h.after(now)) { + // 30min未接单为超时 + log.info("主订单[{}]超时30分钟", order.getId()); + orderMasterService.updateTimeout(order.getId(), 1); + timeout = true; + } + } + if (timeout) { + if (overTime1h.before(now) && order.getWorkerId() != null) { + log.info("主订单[{}]超时60分钟", order.getId()); + // 已超时 60min后取消超时状态 清空workerId + orderMasterService.updateTimeout(order.getId(), 0); + orderMasterService.removeWorker(order.getId()); + } + } + return; + } + + // 未派单状态的超时逻辑 + if (ONE.equals(order.getOrderStatus())) { + Date updateTime = order.getUpdateTime(); + Date overTime30min = getOverTime(updateTime, 30 * 60 * 1000); + Date overTime4h = getOverTime(updateTime, 4 * 60 * 60 * 1000); + Date overTime6h = getOverTime(updateTime, 6 * 60 * 60 * 1000); + // 是否已经超时 + boolean timeout = ONE.equals(order.getTimeout()); + Integer fineTimes = order.getTimeoutFineTimes(); + if (!timeout) { + if (overTime30min.before(now)) { + // 30min未接单为超时 + log.info("主订单[{}]超时30分钟", order.getId()); + orderMasterService.updateTimeout(order.getId(), 1); + timeout = true; + } + } + + if (timeout) { + if (overTime4h.before(now) && ZERO.equals(fineTimes)) { + log.info("主订单[{}]超时4小时", order.getId()); + orderMasterService.updateTimeout(order.getId(), 1, 1); + // insert 罚金记录 + OrderTimeoutRecord record = new OrderTimeoutRecord(order.getId(), order.getWorkerId(), order.getDeptId(), order.getOrderStatus()); + record.setPayMoney(getFineMoney(order)); + record.setFineStatus(0); + orderFineRecordMapper.insert(record); + fineTimes = ONE; + } + + if (overTime6h.before(now) && ONE.equals(fineTimes)) { + log.info("主订单[{}]超时6小时", order.getId()); + orderMasterService.updateTimeout(order.getId(), 1, 2); + // insert 罚金记录 + OrderTimeoutRecord record = new OrderTimeoutRecord(order.getId(), order.getWorkerId(), order.getDeptId(), order.getOrderStatus()); + record.setPayMoney(getFineMoney(order)); + record.setFineStatus(0); + orderFineRecordMapper.insert(record); + } + } + } + } + /** * 判断是否超时 * @@ -86,7 +174,7 @@ public class OrderServiceImpl implements OrderService { Date overTime = getOverTime(order.getExpectTimeStart(), 4 * 60 * 60 * 1000); if (overTime.before(now)) { log.info("订单[{}]服务中状态超时4小时 扣款", order.getId()); - OrderTimeoutRecord record = new OrderTimeoutRecord(order.getId(), order.getWorkerId(), order.getOrderStatus()); + OrderTimeoutRecord record = new OrderTimeoutRecord(order.getId(), order.getWorkerId(), order.getDeptId(), order.getOrderStatus()); record.setPayMoney(getFineMoney(order)); record.setFineStatus(0); orderFineRecordMapper.insert(record); @@ -115,7 +203,7 @@ public class OrderServiceImpl implements OrderService { Date overTime = getOverTime(order.getUpdateTime(), 4 * 60 * 60 * 1000); if (overTime.before(now)) { log.info("订单[{}]超时4h 扣款", order.getId()); - OrderTimeoutRecord record = new OrderTimeoutRecord(order.getId(), order.getWorkerId(), order.getOrderStatus()); + OrderTimeoutRecord record = new OrderTimeoutRecord(order.getId(), order.getWorkerId(), order.getDeptId(), order.getOrderStatus()); record.setPayMoney(getFineMoney(order)); record.setFineStatus(0); orderFineRecordMapper.insert(record); @@ -128,7 +216,7 @@ public class OrderServiceImpl implements OrderService { Date overTime = getOverTime(orderTime, 6 * 60 * 60 * 1000); if (overTime.before(now)) { log.info("订单[{}]超时6h 再次扣款", order.getId()); - OrderTimeoutRecord record = new OrderTimeoutRecord(order.getId(), order.getWorkerId(), order.getOrderStatus()); + OrderTimeoutRecord record = new OrderTimeoutRecord(order.getId(), order.getWorkerId(), order.getDeptId(), order.getOrderStatus()); record.setPayMoney(getFineMoney(order)); record.setFineStatus(0); orderFineRecordMapper.insert(record); @@ -141,8 +229,9 @@ public class OrderServiceImpl implements OrderService { * 计算订单罚金(固定罚金+比例罚金) */ private BigDecimal getFineMoney(OrderDetail order) { + OrderMaster orderMaster = orderMasterService.selectById(order.getOrderMasterId()); FinancialDetail orderFinancial = financialDetailService.selectByOrderDetailId(order.getId()); - SysDeptConfig deptConfig = sysDeptConfigService.selectByDeptId(order.getDeptId()); + SysDeptConfig deptConfig = sysDeptConfigService.selectByDeptId(orderMaster.getDeptId()); BigDecimal fineMoney = deptConfig.getGoingOutTime(); // 如果扣款额为null或<0 if (fineMoney == null || BigDecimal.ZERO.compareTo(fineMoney) > -1) { @@ -157,6 +246,26 @@ public class OrderServiceImpl implements OrderService { return fineMoney.add(rateMoney); } + /** + * 计算订单罚金(固定罚金+比例罚金) + */ + private BigDecimal getFineMoney(OrderMaster orderMaster) { + FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMaster.getId()); + SysDeptConfig deptConfig = sysDeptConfigService.selectByDeptId(orderMaster.getDeptId()); + BigDecimal fineMoney = deptConfig.getGoingOutTime(); + // 如果扣款额为null或<0 + if (fineMoney == null || BigDecimal.ZERO.compareTo(fineMoney) > -1) { + fineMoney = BigDecimal.ZERO; + } + BigDecimal timeoutRate = deptConfig.getGoingOutTimeRate(); + // 如果扣款比例 为null 或 <0 或 >1.00 + if (timeoutRate == null || BigDecimal.ZERO.compareTo(timeoutRate) > 0 || BigDecimal.ONE.compareTo(timeoutRate) < 0) { + return fineMoney; + } + BigDecimal rateMoney = financialMaster.getPayMoney().multiply(timeoutRate); + return fineMoney.add(rateMoney); + } + /** * 计算超时时间 * diff --git a/ghy-system/src/main/java/com/ghy/system/service/impl/SysDeptConfigServiceImpl.java b/ghy-system/src/main/java/com/ghy/system/service/impl/SysDeptConfigServiceImpl.java index c531687c..d82b87aa 100644 --- a/ghy-system/src/main/java/com/ghy/system/service/impl/SysDeptConfigServiceImpl.java +++ b/ghy-system/src/main/java/com/ghy/system/service/impl/SysDeptConfigServiceImpl.java @@ -7,6 +7,7 @@ import com.ghy.system.mapper.SysDeptConfigMapper; import com.ghy.system.mapper.SysDeptMapper; import com.ghy.system.service.ISysDeptConfigService; import org.springframework.stereotype.Service; +import org.springframework.util.Assert; import javax.annotation.Resource; import java.util.List; @@ -26,6 +27,7 @@ public class SysDeptConfigServiceImpl implements ISysDeptConfigService { @Override public SysDeptConfig selectByDeptId(Long deptId) { + Assert.notNull(deptId, "deptId is null!!!"); return sysDeptConfigMapper.selectByDeptId(deptId); } diff --git a/ghy-system/src/main/resources/mapper/system/SysDeptConfigMapper.xml b/ghy-system/src/main/resources/mapper/system/SysDeptConfigMapper.xml index bb696012..1660eebe 100644 --- a/ghy-system/src/main/resources/mapper/system/SysDeptConfigMapper.xml +++ b/ghy-system/src/main/resources/mapper/system/SysDeptConfigMapper.xml @@ -54,12 +54,7 @@