From 7bc56e0b683accba9bb5206a078984b32f9ecad3 Mon Sep 17 00:00:00 2001 From: HH Date: Thu, 4 Aug 2022 19:35:14 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E8=B6=85=E6=97=B6=E6=89=A3?= =?UTF-8?q?=E6=AC=BE=E3=80=81=E8=87=AA=E5=8A=A8=E7=A1=AE=E8=AE=A4=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E8=AE=A2=E5=8D=95=E5=B9=B6=E5=88=86=E8=B4=A6=E6=8F=90?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ghy/common/enums/FinancialDetailType.java | 3 +- .../ghy/order/mapper/OrderDetailMapper.java | 6 + .../ghy/order/mapper/OrderMasterMapper.java | 5 + .../ghy/order/service/OrderDetailService.java | 6 + .../ghy/order/service/OrderMasterService.java | 5 + .../service/impl/OrderDetailServiceImpl.java | 7 + .../service/impl/OrderMasterServiceImpl.java | 11 ++ .../mapper/order/OrderDetailMapper.xml | 8 ++ .../mapper/order/OrderMasterMapper.xml | 8 ++ .../ghy/payment/domain/FinancialDetail.java | 6 +- .../ghy/payment/domain/OrderFineRecord.java | 33 +++++ .../payment/mapper/OrderFineRecordMapper.java | 15 ++ .../financial/OrderFineRecordMapper.xml | 38 +++++ .../quartz/service/impl/OrderServiceImpl.java | 135 ++++++++++++++++-- 14 files changed, 270 insertions(+), 16 deletions(-) create mode 100644 ghy-payment/src/main/java/com/ghy/payment/domain/OrderFineRecord.java create mode 100644 ghy-payment/src/main/java/com/ghy/payment/mapper/OrderFineRecordMapper.java create mode 100644 ghy-payment/src/main/resources/mapper/financial/OrderFineRecordMapper.xml diff --git a/ghy-common/src/main/java/com/ghy/common/enums/FinancialDetailType.java b/ghy-common/src/main/java/com/ghy/common/enums/FinancialDetailType.java index 9bbb996a..40605ec0 100644 --- a/ghy-common/src/main/java/com/ghy/common/enums/FinancialDetailType.java +++ b/ghy-common/src/main/java/com/ghy/common/enums/FinancialDetailType.java @@ -11,7 +11,8 @@ public enum FinancialDetailType { WORKER_FEE(1, "大师傅/店铺提成金额"), PLATFORM_FEE(2, "平台提成金额"), PLACE_FEE(3, "分销金额,可能存在多级"), - RETURN_FEE(4, "退款金额"); + RETURN_FEE(4, "退款金额"), + FINE_FEE(5, "超时罚金"); private final Integer code; private final String desc; diff --git a/ghy-order/src/main/java/com/ghy/order/mapper/OrderDetailMapper.java b/ghy-order/src/main/java/com/ghy/order/mapper/OrderDetailMapper.java index ee2243f6..1d482c97 100644 --- a/ghy-order/src/main/java/com/ghy/order/mapper/OrderDetailMapper.java +++ b/ghy-order/src/main/java/com/ghy/order/mapper/OrderDetailMapper.java @@ -1,6 +1,7 @@ package com.ghy.order.mapper; import com.ghy.order.domain.OrderDetail; +import com.ghy.order.domain.OrderMaster; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -79,4 +80,9 @@ public interface OrderDetailMapper { * @param orderDetail 子订单 */ int updateByOrderMasterId(OrderDetail orderDetail); + + /** + * 查询指定状态的订单 + */ + List selectByStatus(List status); } 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 82867922..6f289668 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 @@ -72,4 +72,9 @@ public interface OrderMasterMapper { * @return 0失败 1成功 */ int updateStatus(@Param("orderMasterId") Long orderMasterId, @Param("orderStatus") int orderStatus); + + /** + * 查询指定状态的订单 + */ + List selectByStatus(List status); } diff --git a/ghy-order/src/main/java/com/ghy/order/service/OrderDetailService.java b/ghy-order/src/main/java/com/ghy/order/service/OrderDetailService.java index 72ab7a8e..a4506fa3 100644 --- a/ghy-order/src/main/java/com/ghy/order/service/OrderDetailService.java +++ b/ghy-order/src/main/java/com/ghy/order/service/OrderDetailService.java @@ -1,6 +1,7 @@ package com.ghy.order.service; import com.ghy.order.domain.OrderDetail; +import com.ghy.order.domain.OrderMaster; import java.util.List; import java.util.Map; @@ -92,4 +93,9 @@ public interface OrderDetailService { * @param orderDetail 子订单 */ void updateByOrderMasterId(OrderDetail orderDetail); + + /** + * 查询指定状态的订单 + */ + List selectByStatus(List status); } 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 3d435eaa..d0e8f363 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 @@ -99,4 +99,9 @@ public interface OrderMasterService { * @param agree 0=不同意 1=同意 */ void cancelAgree(Long orderMasterId, Integer agree); + + /** + * 查询指定状态的订单 + */ + List selectByStatus(List status); } 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 97561861..e6a3c416 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 @@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.math.BigDecimal; @@ -82,6 +83,7 @@ public class OrderDetailServiceImpl implements OrderDetailService { for (OrderDetail detail : orderDetailMapper.selectByOrderMasterId(detailInfo.getOrderMasterId())) { if (detail.getOrderStatus() < orderStatus) { flag = false; + break; } } if (flag) { @@ -262,4 +264,9 @@ public class OrderDetailServiceImpl implements OrderDetailService { orderDetailMapper.updateByOrderMasterId(orderDetail); } + @Override + public List selectByStatus(List status) { + Assert.isTrue(!CollectionUtils.isEmpty(status), "订单状态为空"); + return orderDetailMapper.selectByStatus(status); + } } 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 5fd773d8..43470ba2 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 @@ -30,6 +30,7 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.math.BigDecimal; @@ -193,6 +194,10 @@ public class OrderMasterServiceImpl implements OrderMasterService { case 4: // 退款 confirmAmt = confirmAmt.subtract(financialDetail.getPayMoney()); + case 5: + // 订单超时罚金 归平台所有 + memberMap.merge("0", financialDetail.getPayMoney(), BigDecimal::add); + break; default: break; } @@ -324,6 +329,12 @@ public class OrderMasterServiceImpl implements OrderMasterService { } } + @Override + public List selectByStatus(List status) { + Assert.isTrue(!CollectionUtils.isEmpty(status), "订单状态为空"); + return orderMasterMapper.selectByStatus(status); + } + /** * 主订单发起退款 * diff --git a/ghy-order/src/main/resources/mapper/order/OrderDetailMapper.xml b/ghy-order/src/main/resources/mapper/order/OrderDetailMapper.xml index 19c05327..ff8fec5e 100644 --- a/ghy-order/src/main/resources/mapper/order/OrderDetailMapper.xml +++ b/ghy-order/src/main/resources/mapper/order/OrderDetailMapper.xml @@ -223,4 +223,12 @@ + + diff --git a/ghy-order/src/main/resources/mapper/order/OrderMasterMapper.xml b/ghy-order/src/main/resources/mapper/order/OrderMasterMapper.xml index 5883ef11..19b173e8 100644 --- a/ghy-order/src/main/resources/mapper/order/OrderMasterMapper.xml +++ b/ghy-order/src/main/resources/mapper/order/OrderMasterMapper.xml @@ -256,4 +256,12 @@ WHERE `code` = #{orderMasterCode} + + 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 36089407..839a14c8 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 @@ -3,6 +3,7 @@ package com.ghy.payment.domain; import com.ghy.common.annotation.Excel; import com.ghy.common.core.domain.BaseEntity; import lombok.Data; +import lombok.EqualsAndHashCode; import java.math.BigDecimal; import java.util.Date; @@ -12,6 +13,7 @@ import java.util.Date; * 财务细单(可能是师傅分佣后的细单关联,也可能是分佣账单,平台提成账单等类型) */ @Data +@EqualsAndHashCode(callSuper = true) public class FinancialDetail extends BaseEntity { private static final long serialVersionUID = 1L; @@ -46,14 +48,14 @@ public class FinancialDetail extends BaseEntity { @Excel(name = "实付金额", cellType = Excel.ColumnType.STRING) private BigDecimal payMoney; - @Excel(name = "财务子单类型,1师傅转派/2多级分销/3平台抽成/4撤销支付或退款", cellType = Excel.ColumnType.NUMERIC) + @Excel(name = "财务子单类型,1师傅转派/2多级分销/3平台抽成/4撤销支付或退款/5超时罚金", cellType = Excel.ColumnType.NUMERIC) private Integer financialDetailType; /** * 收款人ID * 当财务子单类型是师傅转派时 收款人ID是师傅或徒弟的workerId * 当财务子单类型是多级分销时 收款人ID是分销者的customerId - * 当财务子单类型是平台抽成和退款时 无需填写收款人ID + * 当财务子单类型是4或5时 无需填写收款人ID */ @Excel(name = "收款人ID", cellType = Excel.ColumnType.NUMERIC) private Long payeeId; diff --git a/ghy-payment/src/main/java/com/ghy/payment/domain/OrderFineRecord.java b/ghy-payment/src/main/java/com/ghy/payment/domain/OrderFineRecord.java new file mode 100644 index 00000000..edf3da58 --- /dev/null +++ b/ghy-payment/src/main/java/com/ghy/payment/domain/OrderFineRecord.java @@ -0,0 +1,33 @@ +package com.ghy.payment.domain; + +import lombok.Data; + +import java.util.Date; + +/** + * 订单扣款记录 + * + * @author HH 2022/8/4 + */ +@Data +public class OrderFineRecord { + + private Long id; + + private Long orderDetailId; + + private Integer fineType; + + private Integer orderStatus; + + private Date createTime; + + public OrderFineRecord() { + } + + public OrderFineRecord(Long orderDetailId, Integer fineType, Integer orderStatus) { + this.orderDetailId = orderDetailId; + this.fineType = fineType; + 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 new file mode 100644 index 00000000..974b972a --- /dev/null +++ b/ghy-payment/src/main/java/com/ghy/payment/mapper/OrderFineRecordMapper.java @@ -0,0 +1,15 @@ +package com.ghy.payment.mapper; + +import com.ghy.payment.domain.OrderFineRecord; + +import java.util.List; + +/** + * 订单扣款记录 + */ +public interface OrderFineRecordMapper { + + List selectList(OrderFineRecord orderFineRecord); + + int insert(OrderFineRecord orderFineRecord); +} diff --git a/ghy-payment/src/main/resources/mapper/financial/OrderFineRecordMapper.xml b/ghy-payment/src/main/resources/mapper/financial/OrderFineRecordMapper.xml new file mode 100644 index 00000000..458255a7 --- /dev/null +++ b/ghy-payment/src/main/resources/mapper/financial/OrderFineRecordMapper.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + SELECT id, order_detail_id, fine_type, order_status, create_time + FROM order_fine_record + + + + + + INSERT INTO order_fine_record (order_detail_id, fine_type, order_status) + VALUES (#{orderDetailId}, #{fineType}, #{orderStatus}) + + \ No newline at end of file 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 dea627d6..0dd622c2 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 @@ -1,35 +1,144 @@ 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.service.FinancialMasterService; +import com.ghy.payment.domain.FinancialDetail; +import com.ghy.payment.domain.OrderFineRecord; +import com.ghy.payment.mapper.OrderFineRecordMapper; +import com.ghy.payment.service.FinancialDetailService; import com.ghy.quartz.service.OrderService; -import org.springframework.beans.factory.annotation.Autowired; +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; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.Calendar; +import java.util.Date; +import java.util.List; @Service public class OrderServiceImpl implements OrderService { - @Autowired - private OrderMasterService orderMasterService; + private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class); + /** + * 一小时的毫秒数 + */ + private static final long HOUR_TIME_MILLIS = 60 * 60 * 1000L; + /** + * 超时罚金2元 + */ + private static final BigDecimal TIMEOUT_MONEY = BigDecimal.valueOf(2); - @Autowired - private FinancialMasterService financialMasterService; + /** + * 需要超时扣款的订单状态 + */ + @Value("${order.timeout.status:-4,-3,-2,1,2,3}") + private List timeoutOrderStatus; + + @Resource + private ThreadPoolTaskExecutor executor; + @Resource + private OrderMasterService orderMasterService; + @Resource + private OrderDetailService orderDetailService; + @Resource + private OrderFineRecordMapper orderFineRecordMapper; + @Resource + private FinancialDetailService financialDetailService; @Override public void overTimeOrder(String orderStatus) { - // 查询符合超时的单 + LocalDateTime now = LocalDateTime.now(); + int nowDay = now.getDayOfMonth(); + int nowHour = now.getHour(); + if (nowHour > 17 || nowHour < 9) { + // 如果处于休息时间 定时任务不执行 + return; + } - // 更新对应单的状态 + // 查询符合超时的单 + List orders = orderDetailService.selectByStatus(timeoutOrderStatus); + for (OrderDetail order : orders) { + Date updateTime = order.getUpdateTime(); + Calendar instance = Calendar.getInstance(); + instance.setTime(updateTime); + if (instance.get(Calendar.DAY_OF_MONTH) == nowDay) { + // 如果订单更新的时间是今天 + if (System.currentTimeMillis() - updateTime.getTime() > HOUR_TIME_MILLIS * 4) { + // 并且距离上一次更新时间已经超过4h 则判定超时 + executor.execute(() -> orderTimeout(order)); + } + } else { + // 如果订单更新的时间不是今天 + if (System.currentTimeMillis() - updateTime.getTime() > HOUR_TIME_MILLIS * 19) { + // 并且距离上一次更新时间已经超过15h 则判定超时 + executor.execute(() -> orderTimeout(order)); + } + } + } + + } + + @Transactional(rollbackFor = Exception.class) + public void orderTimeout(OrderDetail order) { + // 查询扣款记录 如果已经扣过了 就不处理了 + OrderFineRecord orderFineRecord = new OrderFineRecord(order.getId(), 1, order.getOrderStatus()); + List records = orderFineRecordMapper.selectList(orderFineRecord); + if (!CollectionUtils.isEmpty(records)) { + return; + } + + // 保存一条扣款记录 + orderFineRecordMapper.insert(orderFineRecord); + + // 从子订单对应的财务单里扣除2元 + FinancialDetail orderFinancial = financialDetailService.selectByOrderDetailId(order.getId()); + orderFinancial.setPayMoney(orderFinancial.getPayMoney().subtract(TIMEOUT_MONEY)); + financialDetailService.updateFinancialDetail(orderFinancial); // 生成对应的扣款明细 + FinancialDetail fineFinancial = new FinancialDetail(); + fineFinancial.setDeptId(orderFinancial.getDeptId()); + fineFinancial.setCode(financialDetailService.createCode()); + fineFinancial.setFinancialMasterId(orderFinancial.getFinancialMasterId()); + fineFinancial.setFinancialMasterCode(orderFinancial.getFinancialMasterCode()); + fineFinancial.setPayMoney(TIMEOUT_MONEY); + fineFinancial.setFinancialDetailType(FinancialDetailType.FINE_FEE.getCode()); + financialDetailService.insertFinancialDetail(fineFinancial); } + @Override public void finishOrder() { - // 查询符合自动确认的订单 - - // 更新符合自动确认订单的状态 - - // 调用分账动作 + OrderMaster orderMaster = new OrderMaster(); + orderMaster.setOrderStatus(OrderStatus.FINISH_CHECK.code()); + List orders = orderMasterService.selectOrderMasterList(orderMaster); + long now = System.currentTimeMillis(); + long day14ago = now - (14 * 24 * 60 * 60 * 1000L); + for (OrderMaster order : orders) { + // 查询符合自动确认的订单 + if (day14ago > order.getUpdateTime().getTime()) { + logger.info("订单自动完成[id={}, code={}]", order.getId(), order.getCode()); + try { + // 完单流程(分账与提现) + orderMasterService.finish(order.getId()); + // 修改订单状态 + orderMasterService.updateStatus(order.getId(), OrderStatus.FINISH.code()); + } catch (BaseAdaPayException e) { + logger.error("订单自动完成[id={}, code={}]出错", order.getId(), order.getCode(), e); + } + } + } } }