src/main/java/com/mzl/flower/dto/response/payment/OrderSettlementDetailDTO.java
@@ -57,4 +57,11 @@ private String orderNo; private String orderId; private Long supplierId;//供应商id private String settlementId; private String orderItemId; } src/main/java/com/mzl/flower/mapper/payment/OrderSettlementDetailMapper.java
@@ -11,4 +11,6 @@ @Repository public interface OrderSettlementDetailMapper extends BaseMapper<OrderSettlementDetail> { List<OrderSettlementDetailDTO> selectSettlementDetailList(@Param("settlementId") String settlementId); List<OrderSettlementDetailDTO> selectSettlementDetailLists(); } src/main/java/com/mzl/flower/mapper/wallet/WalletBillRecordMapper.java
@@ -7,6 +7,7 @@ import com.mzl.flower.dto.response.wallet.WalletBillRecordVO; import com.mzl.flower.entity.wallet.WalletBillRecordDO; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; import java.util.List; @@ -28,5 +29,10 @@ List<WalletBillRecordVO> getPage(Page page, @Param("dto") QueryWalletBillDTO dto); List<WalletBillRecordVO> getPageByDesc(Page page, @Param("dto") QueryWalletBillDTO dto); @Select("select * from t_wallet_withdraw_record where withdraw_record_id = #{withdrawRecordId}") WalletBillRecordDO getBillRecordByWithdrawRecordId(Long withdrawRecordId); } src/main/java/com/mzl/flower/schedule/ScheduleService.java
@@ -3,15 +3,22 @@ import com.aliyuncs.exceptions.ClientException; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.mzl.flower.constant.Constants; import com.mzl.flower.constant.LockConstants; import com.mzl.flower.dto.response.member.MemberGrowthRecordVO; import com.mzl.flower.dto.response.payment.OrderSettlementDetailDTO; import com.mzl.flower.entity.flower.FlowerCategory; import com.mzl.flower.entity.partner.Partner; import com.mzl.flower.entity.payment.Order; import com.mzl.flower.entity.payment.Transfer; import com.mzl.flower.entity.wallet.WalletBillRecordDO; import com.mzl.flower.entity.wallet.WalletDO; import com.mzl.flower.mapper.flower.FlowerCategoryMapper; import com.mzl.flower.mapper.member.MemberGrowthRecordMapper; import com.mzl.flower.mapper.partner.PartnerMapper; import com.mzl.flower.mapper.payment.OrderMapper; import com.mzl.flower.mapper.payment.OrderSettlementDetailMapper; import com.mzl.flower.mapper.wallet.WalletBillRecordMapper; import com.mzl.flower.mapper.wallet.WalletMapper; import com.mzl.flower.service.BaseService; import com.mzl.flower.service.coupon.CouponRecordService; import com.mzl.flower.service.coupon.CouponTemplateService2; @@ -19,21 +26,28 @@ import com.mzl.flower.service.menber.impl.GrowthValueDealService; import com.mzl.flower.service.payment.*; import com.mzl.flower.service.wallet.WalletBillRecordService; import com.mzl.flower.service.wallet.WalletService; import com.mzl.flower.thread.FlowerCategoryPriceThread; import com.mzl.flower.utils.SmsUtil; import com.mzl.flower.utils.UUIDGenerator; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.time.DateFormatUtils; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; @Component @Slf4j @@ -86,6 +100,21 @@ @Autowired private WalletBillRecordService walletBillRecordService; @Autowired private OrderSettlementDetailMapper orderSettlementDetailMapper; @Autowired private WalletService walletService; @Autowired private RedissonClient redissonClient; @Autowired private WalletBillRecordMapper walletBillRecordMapper; @Autowired private WalletMapper walletMapper; @Scheduled(cron = "1 1 0/2 * * ?") @@ -291,4 +320,72 @@ log.info("供应商下单供货提示结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } public void dealHistoryAmount() { log.info("处理历史结算金额开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); List<OrderSettlementDetailDTO> orderSettlementDetailDTOS = orderSettlementDetailMapper.selectSettlementDetailLists(); orderSettlementDetailDTOS.forEach(o->{ BigDecimal totalAmount = new BigDecimal(0);//交易合计 BigDecimal checkFee = new BigDecimal(0);//降级扣款 BigDecimal lackFee = new BigDecimal(0);//缺货扣款 BigDecimal replaceFee = new BigDecimal(0);//补货扣款 BigDecimal stationFee = new BigDecimal(0);//集货站运费 BigDecimal salesFee = new BigDecimal(0);//售后理赔 totalAmount = totalAmount.add(o.getTotalAmount()); checkFee = checkFee.add(o.getCheckFee()); lackFee = lackFee.add(o.getLackFee() == null ? new BigDecimal(0): o.getLackFee()); replaceFee = replaceFee.add(o.getReplaceFee() == null ? new BigDecimal(0): o.getReplaceFee()); stationFee = stationFee.add(o.getStationFee()); salesFee = salesFee.add(o.getSalesFee()); BigDecimal settlementAmount = totalAmount.subtract(checkFee).subtract(lackFee).subtract(replaceFee) .subtract(salesFee).subtract(stationFee);//结算金额 WalletDO walletDO = walletService.getOrCreateBySupplierId(o.getSupplierId()); RLock lock = redissonClient.getLock(String.format(LockConstants.WALLET_ID_KEY, walletDO.getId())); try { if (lock.tryLock(10, 30, TimeUnit.SECONDS)) { try { if(settlementAmount.compareTo(BigDecimal.ZERO) > 0) { WalletBillRecordDO walletBillRecord = new WalletBillRecordDO(); walletBillRecord.setId(UUIDGenerator.getUUID()); WalletDO walletDOInfo = walletService.getBySupplierId(o.getSupplierId()); //增加供应商结算金额保存到钱包 walletBillRecord.setSupplierId(o.getSupplierId()); walletBillRecord.setWalletId(walletDOInfo.getId()); walletBillRecord.setSettlementId(o.getSettlementId()); walletBillRecord.setOrderItemId(o.getOrderItemId()); //变动金额等于供应商收入 walletBillRecord.setTotalAmount(settlementAmount); walletBillRecord.setType(Constants.BILL_CHANGE_TYPE.settlement.name()); walletBillRecord.setMethod(Constants.BILL_CHANGE_METHOD.add.name()); walletBillRecord.setOriginalAmount(walletDOInfo.getTotalAmount()); walletBillRecord.setChangeAmount(settlementAmount); walletBillRecord.setBalance(walletDOInfo.getWithdrawableAmount().add(settlementAmount)); Order order = orderMapper.selectById(o.getOrderId()); if (!ObjectUtils.isEmpty(order)) { walletBillRecord.setRemark("订单完成(订单号" + order.getOrderNo() + ")" + ",获得收入"); walletBillRecord.setOrderNo(order.getOrderNo()); } //更新钱包 //可提现金额=钱包余额=结算金额 walletDOInfo.setWithdrawableAmount(walletDOInfo.getWithdrawableAmount().add(settlementAmount)); walletDOInfo.setTotalAmount(walletDOInfo.getWithdrawableAmount()); //已结算金额 walletDOInfo.setSettledAmount(walletDOInfo.getSettledAmount().add(settlementAmount)); walletMapper.updateById(walletDOInfo); walletBillRecord.create(); walletBillRecordMapper.insert(walletBillRecord); } } finally { lock.unlock(); } } } catch (InterruptedException e) { throw new RuntimeException(e); } }); log.info("处理历史结算金额完成:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } } src/main/java/com/mzl/flower/service/impl/wallet/WalletBillRecordServiceImpl.java
@@ -98,47 +98,48 @@ if ("SUCCESS".equals(dStatus)) { walletBillRecordDO.setTransferState(Constants.SETTLEMENT_STATUS.COMPLETED.name()); walletBillRecordDO.update("sys"); walletBillRecordDO.setRemark("微信商户转账成功"); walletBillRecordMapper.updateById(walletBillRecordDO); //更新钱包 WalletDO walletDO = walletService.getOrCreateBySupplierId(walletBillRecordDO.getWalletId()); RLock lock = redissonClient.getLock(String.format(LockConstants.WALLET_ID_KEY, walletDO.getId())); try { if (lock.tryLock(10, 30, TimeUnit.SECONDS)) { try { if (!ObjectUtils.isEmpty(walletDO)) { WalletBillRecordDO walletBillRecordDO2 = new WalletBillRecordDO(); walletBillRecordDO2.setId(UUIDGenerator.getUUID()); walletBillRecordDO2.setSupplierId(walletDO.getSupplierId()); walletBillRecordDO2.setWalletId(walletDO.getId()); walletBillRecordDO2.setType(Constants.BILL_CHANGE_TYPE.withdraw.name()); // 发起提现 walletBillRecordDO2.setWithdrawType(Constants.BILL_WITHDRAW_TYPE.success.name()); walletBillRecordDO2.setMethod(Constants.BILL_CHANGE_METHOD.reduce.name()); walletBillRecordDO2.setOriginalAmount(walletDO.getWithdrawableAmount()); walletBillRecordDO2.setChangeAmount(BigDecimal.ZERO); walletBillRecordDO2.setBalance(walletDO.getWithdrawableAmount()); walletBillRecordDO2.create(SecurityUtils.getUserId()); walletBillRecordDO.setId(UUIDGenerator.getUUID()); // 保存账单明细 walletBillRecordService.save(walletBillRecordDO); //提现中金额:减少提现中金额 walletDO.setWithdrawingAmount(walletDO.getWithdrawingAmount().subtract(walletBillRecordDO.getChangeAmount())); //已提现金额:增加已提现金额 walletDO.setWithdrawnAmount(walletDO.getWithdrawnAmount().add(walletBillRecordDO.getChangeAmount())); walletMapper.updateById(walletDO); } } finally { lock.unlock(); } } } catch (InterruptedException e) { throw new RuntimeException(e); } // WalletDO walletDO = walletService.getOrCreateBySupplierId(walletBillRecordDO.getWalletId()); // RLock lock = redissonClient.getLock(String.format(LockConstants.WALLET_ID_KEY, walletDO.getId())); // try { // if (lock.tryLock(10, 30, TimeUnit.SECONDS)) { // try { // if (!ObjectUtils.isEmpty(walletDO)) { // WalletBillRecordDO walletBillRecordDO2 = new WalletBillRecordDO(); // walletBillRecordDO2.setId(UUIDGenerator.getUUID()); // walletBillRecordDO2.setSupplierId(walletDO.getSupplierId()); // walletBillRecordDO2.setWalletId(walletDO.getId()); // walletBillRecordDO2.setType(Constants.BILL_CHANGE_TYPE.withdraw.name()); // // 发起提现 // walletBillRecordDO2.setWithdrawType(Constants.BILL_WITHDRAW_TYPE.success.name()); // walletBillRecordDO2.setMethod(Constants.BILL_CHANGE_METHOD.reduce.name()); // walletBillRecordDO2.setOriginalAmount(walletDO.getWithdrawableAmount()); // walletBillRecordDO2.setChangeAmount(BigDecimal.ZERO); // walletBillRecordDO2.setBalance(walletDO.getWithdrawableAmount()); // walletBillRecordDO2.create(SecurityUtils.getUserId()); // walletBillRecordDO.setId(UUIDGenerator.getUUID()); // // 保存账单明细 // walletBillRecordService.save(walletBillRecordDO); // //提现中金额:减少提现中金额 // walletDO.setWithdrawingAmount(walletDO.getWithdrawingAmount().subtract(walletBillRecordDO.getChangeAmount())); // //已提现金额:增加已提现金额 // walletDO.setWithdrawnAmount(walletDO.getWithdrawnAmount().add(walletBillRecordDO.getChangeAmount())); // walletMapper.updateById(walletDO); // } // } finally { // lock.unlock(); // } // } // } catch (InterruptedException e) { // throw new RuntimeException(e); // } //回写提现状态 if (StringUtils.isEmpty(walletBillRecordDO.getWithdrawRecordId())) { WalletWithdrawRecordDO withdrawRecordDO = walletWithdrawRecordMapper.selectById(walletBillRecordDO.getWithdrawRecordId()); withdrawRecordDO.setWithdrawState(Constants.BILL_WITHDRAW_TYPE.success.name()); walletBillRecordDO.setRemark("账户资金提现完成"); walletBillRecordDO.setRemark("微信商户转账成功"); walletWithdrawRecordMapper.updateById(withdrawRecordDO); } @@ -166,6 +167,7 @@ walletBillRecordDO2.setBalance(walletDO.getWithdrawableAmount().add(walletBillRecordDO.getActualTransferAmount())); walletBillRecordDO2.create(SecurityUtils.getUserId()); walletBillRecordDO.setId(UUIDGenerator.getUUID()); walletBillRecordDO.setRemark("微信商户转账失败,余额返还钱包"); // 保存账单明细 walletBillRecordService.save(walletBillRecordDO); //提现中金额:减少提现中金额 @@ -185,7 +187,7 @@ if (StringUtils.isEmpty(walletBillRecordDO.getWithdrawRecordId())) { WalletWithdrawRecordDO withdrawRecordDO = walletWithdrawRecordMapper.selectById(walletBillRecordDO.getWithdrawRecordId()); withdrawRecordDO.setWithdrawState(Constants.BILL_WITHDRAW_TYPE.fail.name()); walletBillRecordDO.setRemark("账户资金提现失败"); walletBillRecordDO.setRemark("微信商户转账失败,余额返还钱包"); walletWithdrawRecordMapper.updateById(withdrawRecordDO); } } @@ -245,4 +247,9 @@ page.setRecords(list); return page; } @Override public WalletBillRecordDO getBillRecordByWithdrawRecordId(Long withdrawRecordId) { return walletBillRecordMapper.getBillRecordByWithdrawRecordId(withdrawRecordId); } } src/main/java/com/mzl/flower/service/impl/wallet/WalletWithdrawRecordServiceImpl.java
@@ -150,6 +150,8 @@ walletBillRecordDO.setChangeAmount(dto.getAmount()); walletBillRecordDO.setBalance(walletDO.getWithdrawableAmount().subtract(dto.getAmount())); walletBillRecordDO.create(SecurityUtils.getUserId()); walletBillRecordDO.setWithdrawRecordId(withdrawRecordDO.getId()); walletBillRecordDO.setRemark("提现中"); // 保存账单明细 walletBillRecordService.save(walletBillRecordDO); @@ -252,17 +254,21 @@ transferReqDTO.setRemarks(remarks); //保存账单信息 WalletBillRecordDO walletBillRecordDO = new WalletBillRecordDO(); walletBillRecordDO.setSupplierId(s.getId()); walletBillRecordDO.setType(Constants.BILL_CHANGE_TYPE.withdraw.name()); walletBillRecordDO.setWithdrawType(Constants.BILL_WITHDRAW_TYPE.success.name()); walletBillRecordDO.setMethod(Constants.BILL_CHANGE_METHOD.reduce.name()); walletBillRecordDO.setTransferId(transferReqDTO.getId()); walletBillRecordDO.setWithdrawRecordId(withdrawRecordDO.getId()); walletBillRecordDO.create(); walletBillRecordDO.setOriginalAmount(walletDO.getWithdrawableAmount()); walletBillRecordDO.setChangeAmount(BigDecimal.ZERO); walletBillRecordDO.setBalance(walletDO.getWithdrawableAmount()); // WalletBillRecordDO walletBillRecordDO = new WalletBillRecordDO(); // walletBillRecordDO.setSupplierId(s.getId()); // walletBillRecordDO.setType(Constants.BILL_CHANGE_TYPE.withdraw.name()); // walletBillRecordDO.setWithdrawType(Constants.BILL_WITHDRAW_TYPE.success.name()); // walletBillRecordDO.setMethod(Constants.BILL_CHANGE_METHOD.reduce.name()); // walletBillRecordDO.setTransferId(transferReqDTO.getId()); // walletBillRecordDO.setWithdrawRecordId(withdrawRecordDO.getId()); // walletBillRecordDO.create(); // walletBillRecordDO.setOriginalAmount(walletDO.getWithdrawableAmount()); // walletBillRecordDO.setChangeAmount(BigDecimal.ZERO); // walletBillRecordDO.setBalance(walletDO.getWithdrawableAmount()); WalletBillRecordDO walletBillRecordDO = walletBillRecordService.getBillRecordByWithdrawRecordId(withdrawRecordDO.getId()); if(ObjectUtils.isEmpty(walletBillRecordDO)){ throw new ValidationException("提现没有对应的账单信息"); } //提现金额 BigDecimal withdrawAmount = withdrawRecordDO.getAmount(); @@ -283,17 +289,18 @@ transferReqDTO.setDetails(details); try { //发起转账 // paymentV3Service.doBatchTransfer(transferReqDTO, SecurityUtils.getUserId()); paymentV3Service.doBatchTransfer(transferReqDTO, SecurityUtils.getUserId()); } catch (Exception e) { throw new ValidationException(e.getMessage()); } } //记录转账状态,定时任务定时获取状态并更新钱包交易记录表信息 walletBillRecordDO.setRemark("账户资金提现中"); walletBillRecordDO.setRemark("微信商户转账中"); walletBillRecordDO.setActualTransferAmount(withdrawAmount); walletBillRecordDO.setId(UUIDGenerator.getUUID()); walletBillRecordMapper.insert(walletBillRecordDO); walletBillRecordService.updateById(walletBillRecordDO); // walletBillRecordMapper.insert(walletBillRecordDO); //不需要更新结算单了,此时提现的金额和计算单上的金额不一致 } } finally { @@ -336,6 +343,7 @@ walletBillRecordDO.setBalance(walletDO.getWithdrawableAmount().add(withdrawRecordDO.getAmount())); walletBillRecordDO.create(SecurityUtils.getUserId()); walletBillRecordDO.setId(UUIDGenerator.getUUID()); walletBillRecordDO.setRemark("平台审核拒绝,余额返还钱包"); // 保存账单明细 walletBillRecordService.save(walletBillRecordDO); src/main/java/com/mzl/flower/service/wallet/WalletBillRecordService.java
@@ -34,4 +34,6 @@ Page<WalletBillRecordVO> getPage(Page page, QueryWalletBillDTO dto); Page<WalletBillRecordVO> getPageByDesc(Page page, QueryWalletBillDTO dto); WalletBillRecordDO getBillRecordByWithdrawRecordId(Long withdrawRecordId); } src/main/resources/mapper/payment/OrderSettlementDetailMapper.xml
@@ -12,4 +12,18 @@ ORDER BY o.receive_time desc, o.id, oi.flower_name </select> <select id="selectSettlementDetailLists" resultType="com.mzl.flower.dto.response.payment.OrderSettlementDetailDTO"> SELECT s.*, oi.flower_name, oi.flower_level, o.receive_time, oi.check_time, o.order_no, s.order_id, oi.supplier_id FROM t_order_settlement_detail s join t_order_item oi on oi.id = s.order_item_id join t_order o on o.id = s.order_id join t_order_settlement os on os.id = s.settlement_id WHERE s.deleted = 0 and o.status = 'COMPLETED' AND os.type = 'supplier' AND os.status in ('PENDING','FAILED') ORDER BY o.receive_time desc, o.id, oi.flower_name </select> </mapper>