| | |
| | | package com.ruoyi.system.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.ruoyi.system.model.TAppUser; |
| | | import com.ruoyi.system.model.TCommissionTransactionFlow; |
| | | import com.ruoyi.system.mapper.TCommissionTransactionFlowMapper; |
| | | import com.ruoyi.system.model.THtmlConfig; |
| | | import com.ruoyi.system.service.TAppUserService; |
| | | import com.ruoyi.system.service.TCommissionTransactionFlowService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.system.service.THtmlConfigService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | * @author xiaochen |
| | | * @since 2025-12-08 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | public class TCommissionTransactionFlowServiceImpl extends ServiceImpl<TCommissionTransactionFlowMapper, TCommissionTransactionFlow> implements TCommissionTransactionFlowService { |
| | | |
| | | @Resource |
| | | private TAppUserService appUserService; |
| | | |
| | | @Resource |
| | | private THtmlConfigService htmlConfigService; |
| | | |
| | | @Override |
| | | public void calculateAndSaveCommission(Integer orderId, Integer orderType, BigDecimal orderPrice, Integer appUserId) { |
| | | try { |
| | | log.info("开始计算分佣,订单ID:{},订单类型:{},订单金额:{},用户ID:{}", orderId, orderType, orderPrice, appUserId); |
| | | |
| | | // 获取购买用户信息 |
| | | TAppUser buyer = appUserService.getById(appUserId); |
| | | if (buyer == null) { |
| | | log.error("用户不存在,用户ID:{}", appUserId); |
| | | return; |
| | | } |
| | | |
| | | // 获取分佣比例配置 |
| | | CommissionRate commissionRate = getCommissionRate(); |
| | | if (commissionRate == null) { |
| | | log.error("分佣比例配置不存在"); |
| | | return; |
| | | } |
| | | |
| | | log.info("分佣比例配置:营销员={}%,合伙人={}%", commissionRate.getSalesRate(), commissionRate.getPartnerRate()); |
| | | |
| | | // 根据用户类型计算分佣 |
| | | Integer buyerType = buyer.getUserType(); |
| | | Integer referrerUserId = buyer.getReferrerUserId(); |
| | | |
| | | if (buyerType == null || buyerType == 1) { |
| | | // 顾客(无身份)购买 |
| | | calculateForCustomer(orderId, orderType, orderPrice, referrerUserId, commissionRate); |
| | | } else if (buyerType == 2) { |
| | | // 营销员本人购买 |
| | | calculateForSales(orderId, orderType, orderPrice, appUserId, referrerUserId, commissionRate); |
| | | } else if (buyerType == 3) { |
| | | // 合伙人本人购买 |
| | | calculateForPartner(orderId, orderType, orderPrice, appUserId, commissionRate); |
| | | } |
| | | |
| | | log.info("分佣计算完成,订单ID:{}", orderId); |
| | | } catch (Exception e) { |
| | | log.error("分佣计算失败,订单ID:{},错误信息:{}", orderId, e.getMessage(), e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 顾客购买的分佣计算 |
| | | */ |
| | | private void calculateForCustomer(Integer orderId, Integer orderType, BigDecimal orderPrice, |
| | | Integer referrerUserId, CommissionRate commissionRate) { |
| | | if (referrerUserId == null) { |
| | | log.info("顾客无推荐人,无需分佣"); |
| | | return; |
| | | } |
| | | |
| | | // 获取推荐人信息 |
| | | TAppUser referrer = appUserService.getById(referrerUserId); |
| | | if (referrer == null) { |
| | | log.error("推荐人不存在,推荐人ID:{}", referrerUserId); |
| | | return; |
| | | } |
| | | |
| | | Integer referrerType = referrer.getUserType(); |
| | | if (referrerType == null || referrerType == 1) { |
| | | log.info("推荐人不是营销员或合伙人,无需分佣"); |
| | | return; |
| | | } |
| | | |
| | | if (referrerType == 2) { |
| | | // 直接营销员 |
| | | saveCommissionFlow(orderId, orderType, orderPrice, referrerUserId, 2, |
| | | commissionRate.getSalesRate()); |
| | | log.info("顾客购买,直接营销员分佣:{}%", commissionRate.getSalesRate()); |
| | | |
| | | // 查找直接合伙人 |
| | | Integer partnerUserId = findDirectPartner(referrer); |
| | | if (partnerUserId != null) { |
| | | saveCommissionFlow(orderId, orderType, orderPrice, partnerUserId, 3, |
| | | commissionRate.getPartnerRate()); |
| | | log.info("顾客购买,直接合伙人分佣:{}%", commissionRate.getPartnerRate()); |
| | | } |
| | | } else if (referrerType == 3) { |
| | | // 直接合伙人(无直接营销员) |
| | | BigDecimal totalRate = commissionRate.getSalesRate().add(commissionRate.getPartnerRate()); |
| | | saveCommissionFlow(orderId, orderType, orderPrice, referrerUserId, 3, totalRate); |
| | | log.info("顾客购买,直接合伙人(无营销员)分佣:{}%", totalRate); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 营销员本人购买的分佣计算 |
| | | */ |
| | | private void calculateForSales(Integer orderId, Integer orderType, BigDecimal orderPrice, |
| | | Integer salesUserId, Integer referrerUserId, CommissionRate commissionRate) { |
| | | // 营销员本人获得 8% |
| | | saveCommissionFlow(orderId, orderType, orderPrice, salesUserId, 2, |
| | | commissionRate.getSalesRate()); |
| | | log.info("营销员本人购买,本人分佣:{}%", commissionRate.getSalesRate()); |
| | | |
| | | // 查找直接合伙人 |
| | | TAppUser sales = appUserService.getById(salesUserId); |
| | | if (sales != null) { |
| | | Integer partnerUserId = findDirectPartner(sales); |
| | | if (partnerUserId != null) { |
| | | saveCommissionFlow(orderId, orderType, orderPrice, partnerUserId, 3, |
| | | commissionRate.getPartnerRate()); |
| | | log.info("营销员本人购买,直接合伙人分佣:{}%", commissionRate.getPartnerRate()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 合伙人本人购买的分佣计算 |
| | | */ |
| | | private void calculateForPartner(Integer orderId, Integer orderType, BigDecimal orderPrice, |
| | | Integer partnerUserId, CommissionRate commissionRate) { |
| | | // 合伙人本人获得 10% + 8% = 18% |
| | | BigDecimal totalRate = commissionRate.getSalesRate().add(commissionRate.getPartnerRate()); |
| | | saveCommissionFlow(orderId, orderType, orderPrice, partnerUserId, 3, totalRate); |
| | | log.info("合伙人本人购买,本人分佣:{}%", totalRate); |
| | | } |
| | | |
| | | /** |
| | | * 查找直接合伙人 |
| | | */ |
| | | private Integer findDirectPartner(TAppUser user) { |
| | | Integer referrerUserId = user.getReferrerUserId(); |
| | | if (referrerUserId == null) { |
| | | return null; |
| | | } |
| | | |
| | | TAppUser referrer = appUserService.getById(referrerUserId); |
| | | if (referrer == null) { |
| | | return null; |
| | | } |
| | | |
| | | // 如果推荐人是合伙人,直接返回 |
| | | if (referrer.getUserType() != null && referrer.getUserType() == 3) { |
| | | return referrerUserId; |
| | | } |
| | | |
| | | // 如果推荐人是营销员,继续向上查找 |
| | | if (referrer.getUserType() != null && referrer.getUserType() == 2) { |
| | | return findDirectPartner(referrer); |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 保存佣金流水记录 |
| | | */ |
| | | private void saveCommissionFlow(Integer orderId, Integer orderType, BigDecimal orderPrice, |
| | | Integer userId, Integer userType, BigDecimal commissionRate) { |
| | | // 计算佣金金额 |
| | | BigDecimal commissionAmount = orderPrice.multiply(commissionRate) |
| | | .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP); |
| | | |
| | | TCommissionTransactionFlow flow = new TCommissionTransactionFlow(); |
| | | flow.setAppUserId(userId); |
| | | flow.setAppUserType(userType); |
| | | flow.setCommissionRate(commissionRate); |
| | | flow.setOrderId(orderId); |
| | | flow.setOrderType(orderType); |
| | | flow.setOrderPrice(orderPrice); |
| | | flow.setCommissionAmount(commissionAmount); |
| | | flow.setCreateTime(LocalDateTime.now()); |
| | | |
| | | save(flow); |
| | | log.info("保存佣金流水成功,用户ID:{},佣金金额:{}", userId, commissionAmount); |
| | | } |
| | | |
| | | /** |
| | | * 获取分佣比例配置 |
| | | */ |
| | | private CommissionRate getCommissionRate() { |
| | | LambdaQueryWrapper<THtmlConfig> wrapper = new LambdaQueryWrapper<>(); |
| | | wrapper.eq(THtmlConfig::getConfigType, 5); |
| | | THtmlConfig config = htmlConfigService.getOne(wrapper); |
| | | |
| | | if (config == null || config.getContent() == null || config.getContent().isEmpty()) { |
| | | return null; |
| | | } |
| | | |
| | | try { |
| | | String[] rates = config.getContent().split(","); |
| | | if (rates.length != 2) { |
| | | log.error("分佣比例配置格式错误:{}", config.getContent()); |
| | | return null; |
| | | } |
| | | |
| | | BigDecimal salesRate = new BigDecimal(rates[0].trim()); |
| | | BigDecimal partnerRate = new BigDecimal(rates[1].trim()); |
| | | |
| | | return new CommissionRate(salesRate, partnerRate); |
| | | } catch (Exception e) { |
| | | log.error("解析分佣比例配置失败:{}", config.getContent(), e); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 分佣比例配置类 |
| | | */ |
| | | private static class CommissionRate { |
| | | private final BigDecimal salesRate; |
| | | private final BigDecimal partnerRate; |
| | | |
| | | public CommissionRate(BigDecimal salesRate, BigDecimal partnerRate) { |
| | | this.salesRate = salesRate; |
| | | this.partnerRate = partnerRate; |
| | | } |
| | | |
| | | public BigDecimal getSalesRate() { |
| | | return salesRate; |
| | | } |
| | | |
| | | public BigDecimal getPartnerRate() { |
| | | return partnerRate; |
| | | } |
| | | } |
| | | } |