package org.springblade.payment.handle; import cn.hutool.core.convert.Convert; import org.springblade.common.enums.AppConstant; import org.springblade.common.enums.OrderType; import org.springblade.common.enums.ResCode; import org.springblade.core.log.exception.ServiceException; import org.springblade.ldt.bills.entity.Bills; import org.springblade.ldt.user.service.IUserChannelPointService; import org.springblade.payment.handle.entity.HandleData; import org.springblade.payment.handle.entity.Order; import org.springblade.payment.handle.handler.*; import org.springblade.ldt.activity.service.IActivityService; import org.springblade.ldt.activity.service.IJoinRecordService; import org.springblade.ldt.bills.service.IBalanceBillsService; import org.springblade.ldt.bills.service.IBillsService; import org.springblade.ldt.bills.service.IPointBillsService; import org.springblade.ldt.shop.service.IShopService; import org.springblade.payment.entity.SuccessParams; import org.springblade.payment.service.IPaymentService; import org.springblade.webSocket.WebSocketServer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; /** * @author: lianghanqiang * @description: 交易处理,总控交易处理链 * @since: 8/26/21 -- 5:53 PM */ @Component public class Trade { @Autowired private IBillsService billsService; @Autowired private IPointBillsService pointBillsService; @Autowired private IBalanceBillsService balanceBillsService; @Autowired private WebSocketServer webSocketServer; @Autowired private IPaymentService paymentService; @Autowired private IShopService shopService; @Autowired private IActivityService activityService; @Autowired private IJoinRecordService joinRecordService; @Autowired private IUserChannelPointService userChannelPointService ; @Autowired private DataHandle dataHandle ; @Transactional public boolean tradeForPayCode(Order order, long channelId) throws Exception { /** * 交易处理链,每个handle处理负责一个业务节点 * 1、处理各种商家折扣,计算实际交易金额 * 2、用户渠道积分用以抵消交易金额 * 3、用户账户余额抵消交易金额 * 4、剩余金额用户微信支付 * */ List chain = new ArrayList(){{ add(new DiscountHandle(shopService,activityService,joinRecordService)); add(new ChannelPointHandle(pointBillsService,userChannelPointService)); add(new BalanceHandle(balanceBillsService)); add(new WxPayHandle(billsService,webSocketServer,dataHandle)); }} ; BigDecimal remain = order.getMoney(); Bills bills = initBill(order,channelId); //支付参数 SuccessParams successParams = SuccessParams.builder() .orderType(OrderType.USER_PAY.name()) .status(AppConstant.BillPayStatus.待付款.name()) .userId(order.getLoginUser().getId()) .totalPrice(order.getMoney()) .bills(bills) .shopId(order.getShopId()) .channelId(channelId) .build(); //处理各个节点 for (BaseHandle node: chain) { HandleData res = node.handle(remain, order,successParams); Assert.isTrue(res.isSuccess(),()->{throw new ServiceException(ResCode.TRADE_ERROR);}); remain = res.getRemain(); successParams = res.getSuccessParams(); if(remain.compareTo(BigDecimal.ZERO)==0){ //处理积分余额数据变更 paymentService.success(successParams); break; } } return true; } @Transactional public SuccessParams tradeForScanPay(Order order, long channelId) throws Exception { /** * 交易处理链,每个handle处理负责一个业务节点 * 1、处理各种商家折扣,计算实际交易金额 * 2、用户渠道积分用以抵消交易金额 * 3、用户账户余额抵消交易金额 * 4、保存订单信息 * */ List chain = new ArrayList(){{ add(new DiscountHandle(shopService,activityService,joinRecordService)); add(new ChannelPointHandle(pointBillsService,userChannelPointService)); add(new BalanceHandle(balanceBillsService)); }} ; BigDecimal remain = order.getMoney(); Bills bills = initBill(order,channelId); //支付参数 SuccessParams successParams = SuccessParams.builder() .orderType(OrderType.USER_PAY.name()) .status(AppConstant.BillPayStatus.待付款.name()) .userId(order.getLoginUser().getId()) .totalPrice(order.getMoney()) .bills(bills) .shopId(order.getShopId()) .channelId(channelId) .build(); //处理各个节点 for (BaseHandle node: chain) { HandleData res = node.handle(remain, order,successParams); Assert.isTrue(res.isSuccess(),()->{throw new ServiceException(ResCode.TRADE_ERROR);}); remain = res.getRemain(); successParams = res.getSuccessParams(); if(remain.compareTo(BigDecimal.ZERO)==0){ //处理积分余额数据变更 paymentService.success(successParams); break; } } if(remain.compareTo(BigDecimal.ZERO)>0){ bills.setPrice(remain); Assert.isTrue(billsService.saveOrUpdate(successParams.getBills()),()->{throw new ServiceException(ResCode.TRADE_ERROR);}); } return successParams; } /** * 初始化交易账单 * */ private Bills initBill(Order order, long channelId){ Bills bills = new Bills(); bills.setPayStatus(AppConstant.BillPayStatus.待付款.name()); bills.setAppid(order.getAppId()); bills.setCost(order.getMoney()); bills.setOpenid(order.getOpenId()); bills.setChannelId(Convert.toStr(channelId)); bills.setType(OrderType.USER_PAY.name()); bills.setPrice(BigDecimal.ZERO); bills.setOpenid(order.getLoginUser().getOpenid()); bills.setFee(BigDecimal.ZERO); bills.setPointFee(BigDecimal.ZERO); bills.setTitle(order.getBillsTitle()); bills.setPayId(order.getLoginUser().getId()); bills.setReceiveId(order.getShopId()); bills.setMallId(order.getMallId()); return bills; } }