diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysTenant.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysTenant.java index c14b74c0f..2499e5e37 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysTenant.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysTenant.java @@ -8,6 +8,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serial; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Date; @@ -131,4 +132,14 @@ public class SysTenant extends BaseEntity { private LocalDateTime joinTime; private Long accountId; + + /** + * 分账比例 + */ + private BigDecimal divideRate; + + /** + * 是否承担手续费 + */ + private Integer bearFeeFlag; } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantVo.java index ab6bc1947..59b422f73 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantVo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantVo.java @@ -1,5 +1,6 @@ package org.dromara.system.domain.vo; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Date; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; @@ -173,4 +174,16 @@ public class SysTenantVo implements Serializable { @ExcelProperty(value = "入驻时间") private LocalDateTime joinTime; + /** + * 分账是否承担手续费 + */ + @Schema(description = "分账是否承担手续费") + private Integer bearFeeFlag; + + /** + * 分账比例 + */ + @Schema(description = "分账比例") + private BigDecimal divideRate; + } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/DivideRuleBO.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/DivideRuleBO.java index b35ce9756..c989fb021 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/DivideRuleBO.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/DivideRuleBO.java @@ -40,13 +40,6 @@ public class DivideRuleBO extends BaseBO { @ExcelProperty(value ="名称", order = 3) private String name; - @Schema(description ="是否分配手续费") - @ExcelProperty(value ="是否分配手续费", order = 4) - private Integer divideFeeFlag; - - @Schema(description ="手续费分配方式") - @ExcelProperty(value ="手续费分配方式", order = 5) - private Integer feeType; /** * 状态 @@ -61,6 +54,13 @@ public class DivideRuleBO extends BaseBO { @ExcelProperty(value ="类型", order = 8) private Integer type; + + @Schema(description = "区域id") + private Long regionId; + + + + private List details=new ArrayList<>(); } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/DivideRule.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/DivideRule.java index 2ac2ba9cc..e1ac46677 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/DivideRule.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/DivideRule.java @@ -40,13 +40,11 @@ public class DivideRule extends BaseEntity { @ExcelProperty(value ="名称", order = 3) private String name; - @Schema(description ="是否分配手续费") - @ExcelProperty(value ="是否分配手续费", order = 4) - private Integer divideFeeFlag; - @Schema(description ="手续费分配方式") - @ExcelProperty(value ="手续费分配方式", order = 5) - private Integer feeType; + + @Schema(description = "区域id") + private Long regionId; + /** * 状态 diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/vo/DivideRuleVO.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/vo/DivideRuleVO.java index 651365247..805bd3418 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/vo/DivideRuleVO.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/vo/DivideRuleVO.java @@ -45,20 +45,17 @@ public class DivideRuleVO extends BaseEntity { @ExcelProperty(value ="名称", order = 3) private String name; - @Schema(description ="是否分配手续费") - @ExcelProperty(value ="是否分配手续费", order = 4) - private Integer divideFeeFlag; - - @Schema(description ="手续费分配方式") - @ExcelProperty(value ="手续费分配方式", order = 5) - private Integer feeType; - /** * 状态 */ @Schema(description ="状态") @ExcelProperty(value ="状态", order = 7) private Integer status; + + + @Schema(description = "区域id") + private Long regionId; + /** * 类型 */ diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/DivideServiceImpl.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/DivideServiceImpl.java index d17bc1657..49ca82d5f 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/DivideServiceImpl.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/DivideServiceImpl.java @@ -15,10 +15,11 @@ import com.wzj.soopin.transaction.convert.DivideDetailConvert; import com.wzj.soopin.transaction.domain.bo.DivideBO; import com.wzj.soopin.transaction.domain.po.Divide; import com.wzj.soopin.transaction.domain.po.DivideDetail; +import com.wzj.soopin.transaction.domain.po.DivideRuleDetail; +import com.wzj.soopin.transaction.domain.vo.DivideRuleDetailVO; import com.wzj.soopin.transaction.domain.vo.DivideRuleVO; import com.wzj.soopin.transaction.domain.vo.DivideVO; import com.wzj.soopin.transaction.enums.DivideRuleDetailType; -import com.wzj.soopin.transaction.enums.DivideRuleFeeType; import com.wzj.soopin.transaction.enums.DivideStatus; import com.wzj.soopin.transaction.mapper.DivideDetailMapper; import com.wzj.soopin.transaction.mapper.DivideMapper; @@ -31,6 +32,7 @@ import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.service.ConfigService; import org.dromara.system.domain.vo.SysTenantVo; import org.dromara.system.service.ISysTenantService; +import org.slf4j.Logger; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -161,36 +163,157 @@ public class DivideServiceImpl extends ServiceImpl impleme throw new ServiceException("未找到分账规则"); } //开始分账 - //计算订单可分配金额,订单只考虑整单退,不考虑单独退,所以直接计算订单金额 + + //根据易生支付的合同查看手续费金额 BigDecimal totalAmount = order.getTotalAmount(); BigDecimal totalFee = new BigDecimal(0); String feeRate = configService.getConfigValue("transaction.divide.feeRate"); if (StringUtils.isNotBlank(feeRate)) { totalFee = totalAmount.multiply(new BigDecimal(feeRate)).divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP); } - + BigDecimal actualMoney = totalAmount.subtract(totalFee); + //计算订单可分配金额,订单只考虑整单退,不考虑单独退,所以直接计算订单金额 //先生成主表信息 divide = Divide.builder() .ruleId(rule.getId()) .orderMoney(totalAmount) .fee(totalFee) - .actualMoney(totalAmount.subtract(totalFee)) + .actualMoney(actualMoney) .orderSn(order.getOrderSn()) .status(DivideStatus.PENDING.getCode()) .build(); super.save(divide); - //生成分账明细信息 - List details = saveDetails(order, divide.getId(), totalFee, totalAmount, rule); + //计算商户的手续费 + SysTenantVo tenant = sysTenantService.queryById(order.getTenantId()); + if (tenant == null) { + throw new ServiceException("租户信息不存在"); + } + BigDecimal sellerFee = new BigDecimal(0); + BigDecimal platformFee = new BigDecimal(0); + if (tenant.getBearFeeFlag() == 1) { + //如果承担手续费,计算手续费 + sellerFee = totalFee; + } else { + platformFee = totalFee; + } + + //生成商户的分账明细 + BigDecimal sellerAmount = divideSeller(actualMoney, sellerFee, divide.getId(), tenant); + + + BigDecimal platformAmount = actualMoney.subtract(sellerAmount); + BigDecimal finalAmount = new BigDecimal(0); + //按规则进行分账 + //先分代理 然后达人 最后的剩余都给平台 + DivideRuleDetailVO divideRuleDetail = rule.getDetails().stream().filter(item -> item.getType() == DivideRuleDetailType.PROXY.getValue()).findFirst().orElse(null); + + if ((divideRuleDetail != null)) { + finalAmount = platformAmount.subtract(divideproxy(platformAmount, divideRuleDetail, divide.getId(), order.getTenantId())); + } + divideRuleDetail = rule.getDetails().stream().filter(item -> item.getType() == DivideRuleDetailType.REFERENCE.getValue()).findFirst().orElse(null); + + if ((divideRuleDetail != null)) { + finalAmount = finalAmount.subtract(divideDarren(platformAmount, divideRuleDetail, divide.getId(), order.getMemberId())); + } + dividePlatform(finalAmount, platformFee, divideRuleDetail, divide.getId(), tenant.getBearFeeFlag() == 1); //同步订单状态 syncOrderStatus(order); //同步易生支付 - syncYisheng(details); + syncYisheng(null); return true; } + private BigDecimal divideSeller(BigDecimal actualMoney, BigDecimal sellerFee, Long divideId, SysTenantVo tenant) { + //获取商户的账户信息 + Map account = getSellerAccount(tenant.getId()); + if (account == null) { + log.error("商户信息不存在,不参与分账"); + } + //计算商户的分账金额 + BigDecimal divideRate = tenant.getDivideRate(); + Integer bearFeeFlag = tenant.getBearFeeFlag(); + + //计算商户的分账金额 + BigDecimal sellerAmount = actualMoney.multiply(divideRate).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP); + + //生成商户的分账明细 + DivideDetail sellerDetail = DivideDetail.builder() + .divideId(divideId) + .money(sellerAmount) + .fee(sellerFee) + .feePercent(bearFeeFlag == 1 ? new BigDecimal(100) : new BigDecimal(0)) + .moneyPercent(divideRate) + .type(DivideRuleDetailType.SELLER.getValue()).build(); + + detailMapper.insert(sellerDetail); + + return sellerAmount; + } + + private BigDecimal divideproxy(BigDecimal platformMoney, DivideRuleDetailVO rule, Long divideId, Long tenantId) { + //获取代理人的账户信息 + Map account = getProxyAccount(tenantId); + if (account == null) { + log.error("代理人信息不存在,不参与分账"); + return new BigDecimal(0); + } + //计算代理人的分账金额 + BigDecimal proxyAmount = platformMoney.multiply(rule.getMoneyPercent()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP); + DivideDetail proxyDetail = DivideDetail.builder() + .divideId(divideId) + .money(proxyAmount) + .fee(new BigDecimal(0)) + .feePercent(new BigDecimal(0)) + .moneyPercent(rule.getMoneyPercent()) + .type(DivideRuleDetailType.PROXY.getValue()) + .build(); + detailMapper.insert(proxyDetail); + return proxyAmount; + } + + private BigDecimal divideDarren(BigDecimal platformMoney, DivideRuleDetailVO rule, Long divideId, Long tenantId) { + //获取达人的账户信息 + Map account = getReferenceAccount(tenantId); + if (account == null) { + log.error("达人信息不存在,不参与分账"); + return new BigDecimal(0); + } + //计算达人的分账金额 + BigDecimal proxyAmount = platformMoney.multiply(rule.getMoneyPercent()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP); + DivideDetail proxyDetail = DivideDetail.builder() + .divideId(divideId) + .money(proxyAmount) + .fee(new BigDecimal(0)) + .feePercent(new BigDecimal(0)) + .moneyPercent(rule.getMoneyPercent()) + .type(DivideRuleDetailType.REFERENCE.getValue()) + .build(); + detailMapper.insert(proxyDetail); + return proxyAmount; + } + + private void dividePlatform(BigDecimal platformMoney, BigDecimal fee, DivideRuleDetailVO rule, Long divideId, boolean feeFlag) { + //获取平台的账户信息 + Map account = getPlatformAccount(); + if (account == null) { + log.error("平台信息不存在,不参与分账"); + } + //计算平台的分账金额 + BigDecimal proxyAmount = platformMoney.multiply(rule.getMoneyPercent()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP); + DivideDetail proxyDetail = DivideDetail.builder() + .divideId(divideId) + .money(proxyAmount) + .fee(fee) + .feePercent(feeFlag ? new BigDecimal(100) : new BigDecimal(0)) + .moneyPercent(rule.getMoneyPercent()) + .type(DivideRuleDetailType.REFERENCE.getValue()) + .build(); + detailMapper.insert(proxyDetail); + } + @Override public boolean cancelDivide(String orderNo) { return false; @@ -206,60 +329,6 @@ public class DivideServiceImpl extends ServiceImpl impleme return false; } - private List saveDetails(Order order, Long divideId, BigDecimal totalFee, BigDecimal totalAmount, DivideRuleVO rule) { - List details = rule.getDetails().stream().map(item -> { - //计算金额 - BigDecimal amount = totalAmount.multiply(item.getMoneyPercent()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP); - - //如果需要分配手续费,计算手续费 - BigDecimal fee = new BigDecimal(0); - // - if (rule.getDivideFeeFlag() == 1) { - - if (rule.getFeeType() == DivideRuleFeeType.PLATFORM.getValue() && item.getType() == DivideRuleDetailType.PLATFORM.getValue()) { - fee = totalFee; - } else if (rule.getFeeType() == DivideRuleFeeType.PROXY.getValue() && item.getType() == DivideRuleDetailType.PROXY.getValue()) { - fee = totalFee; - } else if (rule.getFeeType() == DivideRuleFeeType.SELLER.getValue() && item.getType() == DivideRuleDetailType.SELLER.getValue()) { - fee = totalFee; - } else { - fee = totalFee.multiply(item.getFeePercent()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP); - } - } - - DivideDetail detail = DivideDetail.builder() - .divideId(divideId) - .money(amount) - .fee(fee) - .feePercent(item.getFeePercent()) - .moneyPercent(item.getMoneyPercent()) - .type(item.getType()) - .orderId(order.getId()) - .orderSn(order.getOrderSn()) - .build(); - - Map account = new HashMap<>(); - //如果是平台,代理,卖家,直接分配 - if (item.getType() == DivideRuleDetailType.PLATFORM.getValue()) { - account = getPlatformAccount(); - } else if (item.getType() == DivideRuleDetailType.PROXY.getValue()) { - account = getProxyAccount(Long.valueOf(order.getTenantId())); - } else if (item.getType() == DivideRuleDetailType.SELLER.getValue()) { - account = getSellerAccount(Long.valueOf(order.getTenantId())); - } else if (item.getType() == DivideRuleDetailType.REFERENCE.getValue()) { - account = getReferenceAccount(order.getMemberId()); - } - if (account == null) { - detail.setAccountId(Long.parseLong(account.get("accountId"))); - detail.setAccountName(account.get("accountName")); - return detail; - } else { - throw new ServiceException(StringUtils.format("%s未找到分账账户", DivideRuleDetailType.getEnum(item.getType()))); - } - }).collect(Collectors.toList()); - detailMapper.insertBatch(details); - return details; - } private Map getPlatformAccount() { return new HashMap<>() {{ @@ -297,16 +366,14 @@ public class DivideServiceImpl extends ServiceImpl impleme /** * 获取代理的账户信息 * - * @param sellerId + * @param * @return */ - private Map getProxyAccount(Long sellerId) { - SysTenantVo tenant = sysTenantService.queryById(sellerId); - Long inviteUserId = tenant.getInviteUserId(); - if (inviteUserId != null) { + private Map getProxyAccount(Long memberId) { + if (memberId != null) { return null; } - MemberAccount account = accountService.getMemberAccount(inviteUserId); + MemberAccount account = accountService.getMemberAccount(memberId); if (account == null) { return null;