From f6b9d92c4e8085c87632fc61c0c3a0ff400fc13c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A2=A8=E5=A4=A7=E5=8F=94?= <494979559@qq.com> Date: Fri, 27 Sep 2024 09:13:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/ruoyi/ss/bonus/domain/Bonus.java | 8 ++ .../ruoyi/ss/bonus/mapper/BonusMapper.java | 9 +- .../com/ruoyi/ss/bonus/mapper/BonusMapper.xml | 26 ++++- .../ruoyi/ss/bonus/service/BonusService.java | 10 +- .../bonus/service/impl/BonusServiceImpl.java | 15 ++- .../service/TransactionAssembler.java | 11 ++ .../service/impl/RechargePayHandler.java | 9 +- .../impl/TransactionAssemblerImpl.java | 40 +++++++ .../impl/TransactionBillServiceImpl.java | 100 +++++++++++++++--- .../controller/app/AppTimeBillController.java | 11 -- 10 files changed, 199 insertions(+), 40 deletions(-) diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/domain/Bonus.java b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/domain/Bonus.java index 7c61d8e7..79558296 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/domain/Bonus.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/domain/Bonus.java @@ -91,4 +91,12 @@ public class Bonus extends BaseEntity @JsonView(JsonViewProfile.AppMch.class) private LocalDateTime prePayTime; + @Excel(name = "已分成金额") + @ApiModelProperty("已分成金额") + private BigDecimal payedAmount; + + @Excel(name = "待分成金额") + @ApiModelProperty("待分成金额") + private BigDecimal waitAmount; + } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.java b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.java index edeb9b14..dccf148d 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.java @@ -97,9 +97,14 @@ public interface BonusMapper List selectProvideBonus(@Param("query") BonusProvideQuery query); /** - * 增加退款金额 + * 当未分成时退款 */ - int addRefundAmount(@Param("id") Long id, @Param("amount") BigDecimal amount); + int refundWhenWaitDivide(@Param("id") Long id, @Param("amount") BigDecimal amount); + + /** + * 当已分成时退款 + */ + int refundWhenDividend(@Param("id") Long id, @Param("amount") BigDecimal amount); /** * 按月查询 diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.xml b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.xml index cf74d210..ba481ebe 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.xml +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.xml @@ -22,7 +22,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" sb.create_time, sb.pay_time, sb.dept_id, - sb.pre_pay_time + sb.pre_pay_time, + sb.payed_amount, + sb.wait_amount @@ -178,6 +180,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" pay_time, dept_id, pre_pay_time, + payed_amount, + wait_amount, #{billId}, @@ -194,6 +198,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{payTime}, #{deptId}, #{prePayTime}, + #{payedAmount}, + #{waitAmount}, @@ -249,11 +255,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + update ss_bonus - set refund_amount = refund_amount + #{amount} - where id = #{id} and amount >= refund_amount + #{amount} - + set refund_amount = refund_amount + #{amount}, + wait_amount = wait_amount - #{amount} + where id = #{id} and wait_amount >= #{amount} and status = '2' and amount >= refund_amount + #{amount} + + + + update ss_bonus + set refund_amount = refund_amount + #{amount}, + payed_amount = payed_amount - #{amount} + where id = #{id} and payed_amount >= #{amount} and status = '3' and amount >= refund_amount + #{amount} + update ss_bonus @@ -319,6 +333,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" pay_time = #{data.payTime}, dept_id = #{data.deptId}, pre_pay_time = #{data.prePayTime}, + payed_amount = #{data.payedAmount}, + wait_amount = #{data.waitAmount}, diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/BonusService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/BonusService.java index caaf020b..6a5afa65 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/BonusService.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/BonusService.java @@ -105,9 +105,14 @@ public interface BonusService List selectProvideBonus(BonusProvideQuery query); /** - * 增加已退款金额 + * 当未分成时退款 */ - int addRefundAmount(Long id, BigDecimal amount); + int refundWhenWaitDivide(Long id, BigDecimal amount); + + /** + * 当已分成时退款 + */ + int refundWhenDividend(Long id, BigDecimal amount); /** * 数据隔离过滤 @@ -123,4 +128,5 @@ public interface BonusService * 按日查询分成 */ List selectDailyAmount(BonusQuery query); + } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/impl/BonusServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/impl/BonusServiceImpl.java index c8346415..4285190f 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/impl/BonusServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/impl/BonusServiceImpl.java @@ -26,7 +26,6 @@ import com.ruoyi.ss.store.service.StoreService; import com.ruoyi.ss.user.domain.SmUserVo; import com.ruoyi.ss.user.service.ISmUserService; import com.ruoyi.ss.user.service.UserAssembler; -import com.ruoyi.system.domain.enums.config.ConfigKey; import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysDeptService; import org.springframework.beans.factory.annotation.Autowired; @@ -210,6 +209,7 @@ public class BonusServiceImpl implements BonusService for (BonusVO bonus : bonusList) { BigDecimal amount = money.multiply(bonus.getPoint()).divide(decimal100, 2, RoundingMode.HALF_UP); bonus.setAmount(amount); + bonus.setWaitAmount(amount); bonus.setStatus(BonusStatus.WAIT_DIVIDE.getStatus()); // 预计分成时间 if (BonusArrivalType.userList().contains(bonus.getArrivalType())) { @@ -258,12 +258,21 @@ public class BonusServiceImpl implements BonusService } @Override - public int addRefundAmount(Long id, BigDecimal amount) { + public int refundWhenWaitDivide(Long id, BigDecimal amount) { if (id == null) { return 0; } ServiceUtil.assertion(amount.compareTo(BigDecimal.ZERO) < 0, "退款金额必须大于0"); - return bonusMapper.addRefundAmount(id, amount); + return bonusMapper.refundWhenWaitDivide(id, amount); + } + + @Override + public int refundWhenDividend(Long id, BigDecimal amount) { + if (id == null) { + return 0; + } + ServiceUtil.assertion(amount.compareTo(BigDecimal.ZERO) < 0, "退款金额必须大于0"); + return bonusMapper.refundWhenDividend(id, amount); } @Override diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/TransactionAssembler.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/TransactionAssembler.java index 5b14b0bd..9a590946 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/TransactionAssembler.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/TransactionAssembler.java @@ -20,4 +20,15 @@ public interface TransactionAssembler { * 拼接套餐剩余时长/度数 */ void assembleSuitSurplus(List list); + + /** + * 拼接分成信息 + */ + void assembleBonusList(TransactionBillVO bill); + + /** + * 拼接分成信息 + * @param list + */ + void assembleBonusList(List list); } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/RechargePayHandler.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/RechargePayHandler.java index 40ec506c..b0f7d212 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/RechargePayHandler.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/RechargePayHandler.java @@ -15,6 +15,7 @@ import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery; import com.ruoyi.ss.transactionBill.domain.bo.PaySuccessBO; import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus; import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO; +import com.ruoyi.ss.transactionBill.service.TransactionAssembler; import com.ruoyi.ss.transactionBill.service.TransactionBillService; import com.ruoyi.ss.user.service.ISmUserService; import org.springframework.beans.factory.annotation.Autowired; @@ -47,6 +48,9 @@ public class RechargePayHandler implements AfterPay, AfterRefund { @Autowired private BonusService bonusService; + @Autowired + private TransactionAssembler transactionAssembler; + @Override public int onPaySuccess(PayBillVO payBill) { TransactionBillVO bill = transactionBillService.selectSmTransactionBillByBillId(payBill.getBstId()); @@ -57,6 +61,8 @@ public class RechargePayHandler implements AfterPay, AfterRefund { PaySuccessBO bo = new PaySuccessBO(); bo.setOrder(bill); bo.setPayBill(payBill); + // 拼接分成列表 + transactionAssembler.assembleBonusList(bill); if (SuitFeeType.singleList().contains(bill.getSuitFeeType())) { return transactionBillService.rechargeSuccess(bo); @@ -93,9 +99,6 @@ public class RechargePayHandler implements AfterPay, AfterRefund { int update = transactionBillService.updateByQuery(data, query); ServiceUtil.assertion(update != 1, "修改订单状态失败"); - // 商户余额增加 -// userService.addBalance(order.getMchId(), order.getArrivalAmount(), StringUtils.format("分时段订单%s", order.getBillNo()), RecordBalanceBstType.RECHARGE, order.getBillId()); - // 处理分成 bonusService.partBonus(order.getBonusList(), order.getMoney()); diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionAssemblerImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionAssemblerImpl.java index 130e64a3..018a92a0 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionAssemblerImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionAssemblerImpl.java @@ -1,6 +1,10 @@ package com.ruoyi.ss.transactionBill.service.impl; +import com.github.pagehelper.PageHelper; import com.ruoyi.common.utils.collection.CollectionUtils; +import com.ruoyi.ss.bonus.domain.BonusQuery; +import com.ruoyi.ss.bonus.domain.BonusVO; +import com.ruoyi.ss.bonus.service.BonusService; import com.ruoyi.ss.channel.domain.Channel; import com.ruoyi.ss.channel.domain.ChannelQuery; import com.ruoyi.ss.channel.domain.ChannelVO; @@ -16,6 +20,7 @@ import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.time.Duration; import java.time.LocalDateTime; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -31,6 +36,9 @@ public class TransactionAssemblerImpl implements TransactionAssembler { @Autowired private ChannelService channelService; + @Autowired + private BonusService bonusService; + /** * 拼接渠道名称 * @@ -82,4 +90,36 @@ public class TransactionAssemblerImpl implements TransactionAssembler { } } } + + @Override + public void assembleBonusList(TransactionBillVO bill) { + if (bill == null) { + return; + } + this.assembleBonusList(Collections.singletonList(bill)); + } + + @Override + public void assembleBonusList(List list) { + if (CollectionUtils.isEmptyElement(list)) { + return; + } + + PageHelper.orderBy(" arrival_type desc"); + + BonusQuery query = new BonusQuery(); + query.setBillIds(CollectionUtils.map(list, TransactionBillVO::getBillId)); + Map> group = bonusService.selectBonusList(query) + .stream().collect(Collectors.groupingBy(BonusVO::getBillId)); + + for (TransactionBillVO bill : list) { + List bonusList = group.get(bill.getBillId()); + if (CollectionUtils.isNotEmpty(bonusList)) { + bill.setBonusList(bonusList); + } else { + bill.setBonusList(Collections.emptyList()); + } + } + } + } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java index 933eaf6d..6c97fcf6 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java @@ -12,6 +12,9 @@ import com.ruoyi.iot.domain.response.CommandResponse; import com.ruoyi.iot.service.IotService; import com.ruoyi.ss.account.domain.AccountVO; import com.ruoyi.ss.bonus.domain.Bonus; +import com.ruoyi.ss.bonus.domain.BonusVO; +import com.ruoyi.ss.bonus.domain.enums.BonusArrivalType; +import com.ruoyi.ss.bonus.domain.enums.BonusStatus; import com.ruoyi.ss.bonus.service.BonusConverter; import com.ruoyi.ss.bonus.service.BonusService; import com.ruoyi.ss.channel.domain.ChannelVO; @@ -29,13 +32,10 @@ import com.ruoyi.ss.payBill.domain.enums.PayBillBstType; import com.ruoyi.ss.payBill.domain.vo.DoPayVO; import com.ruoyi.ss.payBill.service.PayBillConverter; import com.ruoyi.ss.payBill.service.PayBillService; -import com.ruoyi.ss.receiveBill.service.ReceiveBillService; import com.ruoyi.ss.record.time.domain.enums.RecordTimeType; import com.ruoyi.ss.record.time.service.IRecordTimeService; import com.ruoyi.ss.record.time.service.RecordTimeConverter; import com.ruoyi.ss.recordBalance.domain.enums.RecordBalanceBstType; -import com.ruoyi.ss.refund.service.RefundConverter; -import com.ruoyi.ss.refund.service.RefundService; import com.ruoyi.ss.store.domain.StoreVo; import com.ruoyi.ss.suit.domain.SuitVO; import com.ruoyi.ss.suit.domain.enums.SuitFeeMode; @@ -51,10 +51,7 @@ import com.ruoyi.ss.transactionBill.domain.vo.UserRechargeServiceVO; import com.ruoyi.ss.transactionBill.domain.vo.UserWithdrawServiceVO; import com.ruoyi.ss.transactionBill.domain.enums.*; import com.ruoyi.ss.transactionBill.mapper.TransactionBillMapper; -import com.ruoyi.ss.transactionBill.service.TransactionBillConverter; -import com.ruoyi.ss.transactionBill.service.TransactionBillService; -import com.ruoyi.ss.transactionBill.service.TransactionBillValidator; -import com.ruoyi.ss.transactionBill.service.WithdrawValidator; +import com.ruoyi.ss.transactionBill.service.*; import com.ruoyi.ss.transfer.domain.TransferVO; import com.ruoyi.ss.transfer.interfaces.AfterTransfer; import com.ruoyi.ss.transfer.service.TransferConverter; @@ -159,6 +156,9 @@ public class TransactionBillServiceImpl implements TransactionBillService, After @Autowired private BonusService bonusService; + @Autowired + private TransactionAssembler transactionAssembler; + /** * 查询充值记录 * @@ -1532,6 +1532,9 @@ public class TransactionBillServiceImpl implements TransactionBillService, After ServiceUtil.assertion(dto.getRefundAmount().compareTo(bill.getMoney()) > 0, "退款金额不允许大于订单金额"); ServiceUtil.assertion(!TransactionBillStatus.SUCCESS.getStatus().equals(bill.getStatus()), "当前订单状态不允许退款"); + // 拼接分成列表 + transactionAssembler.assembleBonusList(bill); + Integer result = transactionTemplate.execute(status -> { // 修改订单状态 TransactionBill data = new TransactionBill(); @@ -1542,16 +1545,16 @@ public class TransactionBillServiceImpl implements TransactionBillService, After int updateBill = this.updateByQuery(data, billQuery); ServiceUtil.assertion(updateBill != 1, "退款时修改订单状态失败,订单状态已发生改变,请刷新后重试"); - // 商户余额按照比例扣减 + // 分成方余额按照比例扣减 // 按比例计算退款金额 - BigDecimal refundAmount = dto.getRefundAmount(); - BigDecimal refundRate = refundAmount.divide(bill.getMoney(), 2, RoundingMode.HALF_UP); // 退款金额比例 - BigDecimal refundServiceAmount = bill.getServiceCharge().multiply(refundRate).setScale(2, RoundingMode.HALF_UP); // 退款的手续费 - BigDecimal refundMchAmount = refundAmount.subtract(refundServiceAmount); // 退款的商户余额 - userService.subtractBalance(bill.getMchId(), refundMchAmount, dto.getRefundReason(), RecordBalanceBstType.RECHARGE, bill.getBillId()); + BigDecimal refundAmount = dto.getRefundAmount(); // 总退款金额 + if (CollectionUtils.isNotEmptyElement(bill.getBonusList())) { + int updateRefundBonus = this.updateRefundBonus(bill.getBonusList(), refundAmount); + ServiceUtil.assertion(updateRefundBonus != bill.getBonusList().size(), "商户余额更新失败"); + } // 修改原订单的退款金额和退款手续费 - int updateRefundAmount = this.addRefundAmount(bill.getBillId(), refundAmount, refundMchAmount, refundServiceAmount); + int updateRefundAmount = this.addRefundAmount(bill.getBillId(), refundAmount, refundAmount, BigDecimal.ZERO); ServiceUtil.assertion(updateRefundAmount != 1, "修改原订单的退款金额和退款手续费失败"); // 发起退款 @@ -1568,6 +1571,75 @@ public class TransactionBillServiceImpl implements TransactionBillService, After return result == null ? 0 : result; } + /** + * 更新分成的退款金额 + */ + private int updateRefundBonus(List bonusList, BigDecimal refundAmount) { + if (CollectionUtils.isEmptyElement(bonusList)) { + return 0; + } + + BigDecimal decimal100 = BigDecimal.valueOf(100); + + // 构建退款列表 + List refundList = new ArrayList<>(); // 退款的列表 + BigDecimal dividedAmount = BigDecimal.ZERO; // 已分配金额 + for (BonusVO bonus : bonusList) { + if (bonus == null) { + continue; + } + // 计算扣减金额 + BigDecimal bonusRefundAmount = refundAmount.multiply(bonus.getPoint()).divide(decimal100, 2, RoundingMode.HALF_UP); + bonus.setRefundAmount(bonusRefundAmount); + refundList.add(bonus); + + dividedAmount = dividedAmount.add(bonusRefundAmount); + } + + // 平台吃掉误差 + Bonus platform = refundList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())).findFirst().orElse(null); + ServiceUtil.assertion(platform == null, "平台不存在"); + if (dividedAmount.compareTo(refundAmount) != 0) { + BigDecimal subtract = refundAmount.subtract(dividedAmount); // 误差值 + platform.setRefundAmount(platform.getRefundAmount().add(subtract)); + } + + BigDecimal sum = refundList.stream().map(Bonus::getRefundAmount).reduce(BigDecimal.ZERO, BigDecimal::add); + ServiceUtil.assertion(sum.compareTo(refundAmount) != 0, "退款金额分配出错"); + + Integer result = transactionTemplate.execute(status -> { + int update = 0; + + for (Bonus bonus : refundList) { + // 根据分成状态来决定是否扣减用户余额(给用户加余额前需要判断分成状态是否为待分成) + if (BonusStatus.WAIT_DIVIDE.getStatus().equals(bonus.getStatus())) { + // 待分成,扣减待分成金额,加上退款金额 + int refund = bonusService.refundWhenWaitDivide(bonus.getId(), bonus.getRefundAmount()); + ServiceUtil.assertion(refund != 1, "可退款金额不足"); + } else if (BonusStatus.DIVIDEND.getStatus().equals(bonus.getStatus())) { + // 已分成,扣减已分成金额,加上退款金额 + int refund = bonusService.refundWhenDividend(bonus.getId(), bonus.getRefundAmount()); + ServiceUtil.assertion(refund != 1, "可退款金额不足"); + + // 扣减分成方余额 + if (BonusArrivalType.userList().contains(bonus.getArrivalType())) { + userService.subtractBalance(bonus.getArrivalId(), bonus.getRefundAmount(), String.format("订单退款:%s", bonus.getBillNo()), RecordBalanceBstType.RECHARGE, bonus.getBillId()); + } else if (BonusArrivalType.deptList().contains(bonus.getArrivalType())) { +// deptService.subtractBalance(bonus.getArrivalId(), bonus.getRefundAmount(), String.format("订单退款:%s", bonus.getBillNo()), RecordBalanceBstType.RECHARGE, bonus.getBillId()); + } + } + + update++; + } + + return update; + }); + + return result == null ? 0 : result; + } + + + @Override public int updateByQuery(TransactionBill data, TransactionBillQuery query) { if (query == null) { diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppTimeBillController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppTimeBillController.java index e3f12371..010659a1 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppTimeBillController.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppTimeBillController.java @@ -44,15 +44,4 @@ public class AppTimeBillController extends BaseController { return toAjax(timeBillService.close(bill)); } - @ApiOperation("支付订单") - @PutMapping("/pay") - public AjaxResult pay(@RequestBody @Validated TimeBillPayDTO dto) { - TimeBillVO bill = timeBillService.selectTimeBillByBillId(dto.getBillId()); - if (!timeBillValidator.canPay(bill, getUserId())) { - return error("您无权支付该订单"); - } - dto.setChannelId(TransactionBillPayType.WECHAT.getType()); - return success(timeBillService.pay(dto)); - } - }