From ae1471f378f399f76518539ec8992e64a3673436 Mon Sep 17 00:00:00 2001 From: 陶杰 <1378534974@qq.com> Date: 星期三, 08 一月 2025 15:26:06 +0800 Subject: [PATCH] 1.订单提交:订单最小金额配置 --- src/main/java/com/mzl/flower/service/payment/OrderSettlementService.java | 210 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 196 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/mzl/flower/service/payment/OrderSettlementService.java b/src/main/java/com/mzl/flower/service/payment/OrderSettlementService.java index 5f9e44a..6e65c03 100644 --- a/src/main/java/com/mzl/flower/service/payment/OrderSettlementService.java +++ b/src/main/java/com/mzl/flower/service/payment/OrderSettlementService.java @@ -6,6 +6,7 @@ import com.mzl.flower.config.exception.ValidationException; import com.mzl.flower.config.security.SecurityUtils; import com.mzl.flower.constant.Constants; +import com.mzl.flower.constant.LockConstants; import com.mzl.flower.dto.request.payment.*; import com.mzl.flower.dto.response.payment.OrderSettlementDTO; import com.mzl.flower.dto.response.payment.OrderSettlementDetailDTO; @@ -16,22 +17,35 @@ import com.mzl.flower.entity.supplier.Station; import com.mzl.flower.entity.supplier.Supplier; import com.mzl.flower.entity.system.UserWechat; +import com.mzl.flower.entity.wallet.WalletBillRecordDO; +import com.mzl.flower.entity.wallet.WalletDO; import com.mzl.flower.mapper.flower.FlowerSupplierSaleNumMapper; import com.mzl.flower.mapper.payment.*; import com.mzl.flower.mapper.supplier.StationMapper; import com.mzl.flower.mapper.system.UserWechatMapper; +import com.mzl.flower.mapper.wallet.WalletBillRecordDetailMapper; +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.wallet.WalletService; +import com.mzl.flower.utils.ExcelExportUtil; import com.mzl.flower.utils.UUIDGenerator; import lombok.extern.slf4j.Slf4j; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ObjectUtils; +import javax.servlet.http.HttpServletResponse; import java.math.BigDecimal; import java.math.RoundingMode; +import java.net.URLEncoder; import java.time.LocalDateTime; import java.util.*; +import java.util.concurrent.TimeUnit; @Slf4j @Service @@ -73,6 +87,27 @@ @Autowired private OrderItemSettlementMapper orderItemSettlementMapper; + + @Autowired + private TransferMapper transferMapper; + + @Autowired + private TransferDetailMapper transferDetailMapper; + + @Autowired + private WalletBillRecordMapper walletBillRecordMapper; + + @Autowired + private WalletMapper walletMapper; + + @Autowired + private WalletBillRecordDetailMapper walletBillRecordDetailMapper; + + @Autowired + private WalletService walletService; + + @Autowired + RedissonClient redissonClient; public Page<OrderSettlementListDTO> selectSettlementList(Page page, OrderSettlementQueryDTO dto){ dto.setStartDate(parseLocalDateTime(dto.getStartDateStr(), true)); @@ -117,19 +152,34 @@ } String type = settlement.getType(); + //2024-10-23 + //供应商新的结算逻辑不结算供应商的钱。 + if (Constants.SETTLEMENT_TYPE.supplier.name().equals(type)) { + throw new ValidationException("供应商不需要手动结算"); + } + String status = settlement.getStatus(); + if(Constants.SETTLEMENT_STATUS.PROCESSING.name().equals(status)){ + throw new ValidationException("结算中,不用重复结算"); + } + if(Constants.SETTLEMENT_STATUS.COMPLETED.name().equals(status)){ + throw new ValidationException("结算成功,不用重复结算"); + } + + String name = ""; + if(Constants.SETTLEMENT_TYPE.supplier.name().equals(type)){ + Supplier s = supplierMapper.selectOne(new QueryWrapper<Supplier>() + .eq("user_id", settlement.getUserId())); + name = "供应商" + s.getName(); + } else { + Partner p = partnerMapper.selectOne(new QueryWrapper<Partner>() + .eq("user_id", settlement.getUserId())); + name = "合伙人" + p.getName(); + } + UserWechat wechat = wechatMapper.selectOne(new QueryWrapper<UserWechat>() .eq("user_id", settlement.getUserId())); if(wechat == null){ - String msg; - if(Constants.SETTLEMENT_TYPE.supplier.name().equals(type)){ - Supplier s = supplierMapper.selectOne(new QueryWrapper<Supplier>() - .eq("user_id", settlement.getUserId())); - msg = "供应商" + s.getName() + "未绑定账号无法结算"; - } else { - Partner p = partnerMapper.selectOne(new QueryWrapper<Partner>() - .eq("user_id", settlement.getUserId())); - msg = "合伙人" + p.getName() + "未绑定账号无法结算"; - } + String msg = name + "未绑定账号无法结算"; log.error(msg); throw new ValidationException(msg); } @@ -138,8 +188,7 @@ LocalDateTime now = LocalDateTime.now(); String day = format(now, "yyyy-MM-dd"); - String remarks = Constants.SETTLEMENT_TYPE.supplier.name().equals(type) - ? "供应商账单结算" : "合伙人账单结算"; + String remarks = name + "账单结算"; String appId = Constants.SETTLEMENT_TYPE.supplier.name().equals(type) ? PyamentV3Configurer.supplier_app_id : PyamentV3Configurer.partner_app_id; @@ -174,10 +223,37 @@ } settlement.setTransferTime(LocalDateTime.now()); - settlement.setStatus(Constants.SETTLEMENT_STATUS.COMPLETED.name()); + settlement.setStatus(Constants.SETTLEMENT_STATUS.PROCESSING.name()); settlement.update(SecurityUtils.getUserId()); settlementMapper.updateById(settlement); + } + + public void updateSettlementStatus(String transferId){ + Transfer t = transferMapper.selectById(transferId); + if("FINISHED".equals(t.getStatus())){ + OrderSettlement settlement = settlementMapper.selectOne(new QueryWrapper<OrderSettlement>() + .eq("transfer_id", transferId)); + if(settlement == null){ + return; + } + String transferDetailId = settlement.getTransferDetailId(); + TransferDetail td = transferDetailMapper.selectById(transferDetailId); + if(td == null){ + log.warn("未找到对应明细"); + return; + } + String dStatus = td.getStatus(); + if("SUCCESS".equals(dStatus)){ + settlement.setStatus(Constants.SETTLEMENT_STATUS.COMPLETED.name()); + settlement.update("sys"); + settlementMapper.updateById(settlement); + } else if ("FAIL".equals(dStatus)){ + settlement.setStatus(Constants.SETTLEMENT_STATUS.FAILED.name()); + settlement.update("sys"); + settlementMapper.updateById(settlement); + } + } } public void doSettlement(){//弃用 @@ -641,6 +717,13 @@ detail.create(); settlementDetailMapper.insert(detail); + //2024-10-23 + //copy信息到t_wallet_bill_record_detail +// WalletBillRecordDetail walletBillRecordDetail = new WalletBillRecordDetail(); +// BeanUtils.copyProperties(detail, walletBillRecordDetail, "id"); +// walletBillRecordDetail.setBillRecordId(walletBillRecord.getId()); +// walletBillRecordDetailMapper.insert(walletBillRecordDetail); + flowerNum += oi.getNum(); totalAmount = totalAmount.add(detail.getTotalAmount()); checkFee = checkFee.add(detail.getCheckFee()); @@ -651,6 +734,51 @@ serviceFee = serviceFee.add(ois.getServiceFee()); serviceFeeRate = ois.getServiceFeeRate(); settlementAmount = settlementAmount.add(ois.getIncomeSupplier()); + WalletDO walletDO = walletService.getOrCreateBySupplierId(supplierId); + RLock lock = redissonClient.getLock(String.format(LockConstants.WALLET_ID_KEY, walletDO.getId())); + try { + if (lock.tryLock(10, 30, TimeUnit.SECONDS)) { + try { + //2024-10-28 直接保存到walletBillRecord + //新增WalletBillRecordDO + if(ois.getIncomeSupplier().compareTo(BigDecimal.ZERO) > 0) { + WalletBillRecordDO walletBillRecord = new WalletBillRecordDO(); + walletBillRecord.setId(UUIDGenerator.getUUID()); + WalletDO walletDOInfo = walletService.getBySupplierId(supplierId); + //增加供应商结算金额保存到钱包 + walletBillRecord.setSupplierId(supplierId); + walletBillRecord.setWalletId(walletDOInfo.getId()); + walletBillRecord.setSettlementId(settlement.getId()); + walletBillRecord.setOrderItemId(detail.getOrderItemId()); + //变动金额等于供应商收入 + walletBillRecord.setTotalAmount(ois.getIncomeSupplier()); + walletBillRecord.setType(Constants.BILL_CHANGE_TYPE.settlement.name()); + walletBillRecord.setMethod(Constants.BILL_CHANGE_METHOD.add.name()); + walletBillRecord.setOriginalAmount(walletDOInfo.getTotalAmount()); + walletBillRecord.setChangeAmount(ois.getIncomeSupplier()); + walletBillRecord.setBalance(walletDOInfo.getWithdrawableAmount().add(ois.getIncomeSupplier())); + Order order = orderMapper.selectById(detail.getOrderId()); + if (!ObjectUtils.isEmpty(order)) { + walletBillRecord.setRemark("订单完成(订单号" + order.getOrderNo() + ")" + ",获得收入"); + walletBillRecord.setOrderNo(order.getOrderNo()); + } + //更新钱包 + //可提现金额=钱包余额=结算金额 + walletDOInfo.setWithdrawableAmount(walletDOInfo.getWithdrawableAmount().add(ois.getIncomeSupplier())); + walletDOInfo.setTotalAmount(walletDOInfo.getWithdrawableAmount()); + //已结算金额 + walletDOInfo.setSettledAmount(walletDOInfo.getSettledAmount().add(ois.getIncomeSupplier())); + walletMapper.updateById(walletDOInfo); + walletBillRecord.create(); + walletBillRecordMapper.insert(walletBillRecord); + } + } finally { + lock.unlock(); + } + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } settlement.setFlowerNum(flowerNum); @@ -678,7 +806,13 @@ settlement.setSettlementAmount(settlementAmount); settlement.create(); + //2024-10-23 + //计算到钱包后订单状态变成已结算 + //旧逻辑转账的时候才会标记状态为结算中 + //新逻辑不是立即转账。不走结算后转账逻辑。此时没有转账时间、openID、转账ID、转账明细ID,直接标记结算状态完成,存金额到钱包中 + settlement.setStatus(Constants.SETTLEMENT_STATUS.COMPLETED.name()); settlementMapper.insert(settlement); + } /* ******************************************************************** */ @@ -716,7 +850,7 @@ detail.setOrderId(oi.getOrderId()); detail.setOrderItemId(itemId); - detail.setPrice(oi.getMarkupPartner()); + detail.setPrice(getAmount(oi.getMarkupPartner())); detail.setNum(oi.getNum()); detail.setTotalAmount(detail.getPrice().multiply(new BigDecimal(detail.getNum()))); detail.setCheckFee(new BigDecimal(0)); @@ -772,4 +906,52 @@ orderMapper.updateById(o); } } + + public void exportSettlementList(HttpServletResponse response, OrderSettlementQueryDTO dto) { + dto.setStartDate(parseLocalDateTime(dto.getStartDateStr(), true)); + dto.setEndDate(parseLocalDateTime(dto.getEndDateStr(), false)); + List<OrderSettlementListDTO> ls = settlementMapper.selectSettlementListInfo(null, dto); + + String[] rowsName = new String[]{"序号","结算人", "结算金额(元)", "订单数量", "买家数量", "商品数量", "结算合计(元)", "结算均价(元)", "降级扣款(元)", + "缺货扣款(元)", "补货扣款(元)", "售后理赔(元)", "服务费(元)", "集货站运费(元)", "结算类型", "结算状态", "结算时间"}; + List<Object[]> dataList = new ArrayList<>(); + int sn = 1; + for (OrderSettlementListDTO o : ls) { + Object[] objs = new Object[rowsName.length]; + int a = 0; + objs[a++] = sn; + objs[a++] = o.getUserName(); + objs[a++] = o.getSettlementAmount(); + objs[a++] = o.getOrderNum(); + objs[a++] = o.getCustomerNum(); + objs[a++] = o.getFlowerNum(); + objs[a++] = o.getTotalAmount(); + objs[a++] = o.getPrice(); + objs[a++] = o.getCheckFee(); + objs[a++] = o.getLackFee(); + objs[a++] = o.getReplaceFee(); + objs[a++] = o.getSalesFee(); + objs[a++] = o.getServiceFee(); + objs[a++] = o.getStationFee(); + objs[a++] = o.getTypeStr(); + objs[a++] = o.getStatusStr(); + objs[a++] = o.getTransferTime(); + dataList.add(objs); + + sn++; + } + ExcelExportUtil excelExportUtil = new ExcelExportUtil("结算列表", rowsName, dataList, response); + try { + response.addHeader("filename", URLEncoder.encode("结算列表.xls", "UTF-8")); + response.addHeader("Access-Control-Expose-Headers", "filename"); + excelExportUtil.export(); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + + } + + public OrderSettlement selectOrderSettlementById(String id) { + return settlementMapper.selectOrderSettlementById(id); + } } -- Gitblit v1.9.3