分销:根据商品,计算推广员可以得到的佣金

This commit is contained in:
owen 2023-09-24 22:27:24 +08:00
parent e9fd377772
commit 9856e17974
6 changed files with 90 additions and 13 deletions

View File

@ -137,4 +137,14 @@ public class ProductSpuRespDTO {
*/
private Integer clickCount;
// ========== 分销相关字段 =========
/**
* 分销类型
*
* false - 默认
* true - 自行设置
*/
private Boolean subCommissionType;
}

View File

@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBroke
import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert;
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService;
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
@ -31,8 +30,6 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLogi
@Validated
@Slf4j
public class AppBrokerageRecordController {
@Resource
private BrokerageUserService brokerageUserService;
@Resource
private BrokerageRecordService brokerageRecordService;
@ -45,15 +42,10 @@ public class AppBrokerageRecordController {
return success(BrokerageRecordConvert.INSTANCE.convertPage02(pageResult));
}
// TODO @疯狂这里还有一个漏网之鱼~
@GetMapping("/get-product-brokerage-price")
@Operation(summary = "获得商品的分销金额")
public CommonResult<AppBrokerageProductPriceRespVO> getProductBrokeragePrice(@RequestParam("spuId") Long spuId) {
AppBrokerageProductPriceRespVO respVO = new AppBrokerageProductPriceRespVO();
respVO.setEnabled(brokerageUserService.getUserBrokerageEnabled(getLoginUserId()));
respVO.setBrokerageMinPrice(1);
respVO.setBrokerageMaxPrice(2);
return success(respVO);
return success(brokerageRecordService.calculateProductBrokeragePrice(spuId, getLoginUserId()));
}
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.trade.convert.order;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
@ -14,6 +15,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDT
import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
@ -266,11 +268,16 @@ public interface TradeOrderConvert {
TradeOrderDO convert(TradeOrderRemarkReqVO reqVO);
default BrokerageAddReqBO convert(MemberUserRespDTO user, TradeOrderItemDO item, ProductSkuRespDTO sku) {
return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId())
default BrokerageAddReqBO convert(MemberUserRespDTO user, TradeOrderItemDO item,
ProductSpuRespDTO spu, ProductSkuRespDTO sku) {
BrokerageAddReqBO bo = new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId())
.setBasePrice(item.getPayPrice() * item.getCount())
.setTitle(StrUtil.format("{}成功购买{}", user.getNickname(), item.getSpuName()))
.setFirstFixedPrice(sku.getFirstBrokeragePrice()).setSecondFixedPrice(sku.getSecondBrokeragePrice());
.setFirstFixedPrice(0).setSecondFixedPrice(0);
if (BooleanUtil.isTrue(spu.getSubCommissionType())) {
bo.setFirstFixedPrice(sku.getFirstBrokeragePrice()).setSecondFixedPrice(sku.getSecondBrokeragePrice());
}
return bo;
}
TradeBeforeOrderCreateReqBO convert(AppTradeOrderCreateReqVO createReqVO);

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.brokerage;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageProductPriceRespVO;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
@ -110,4 +111,12 @@ public interface BrokerageRecordService {
*/
Integer getUserRankByPrice(Long userId, LocalDateTime[] times);
/**
* 计算商品被购买后推广员可以得到的佣金
*
* @param spuId 商品编号
* @param userId 用户编号
* @return 用户佣金
*/
AppBrokerageProductPriceRespVO calculateProductBrokeragePrice(Long spuId, Long userId);
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.trade.service.brokerage;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
@ -9,7 +10,12 @@ import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageProductPriceRespVO;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO;
import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert;
@ -36,6 +42,9 @@ import java.util.Objects;
import java.util.Optional;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMinValue;
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH;
/**
@ -55,6 +64,11 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
@Resource
private BrokerageUserService brokerageUserService;
@Resource
private ProductSpuApi productSpuApi;
@Resource
private ProductSkuApi productSkuApi;
@Override
public BrokerageRecordDO getBrokerageRecord(Integer id) {
return brokerageRecordMapper.selectById(id);
@ -293,6 +307,50 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
return true;
}
@Override
public AppBrokerageProductPriceRespVO calculateProductBrokeragePrice(Long spuId, Long userId) {
// 1. 构建默认的返回值
AppBrokerageProductPriceRespVO respVO = new AppBrokerageProductPriceRespVO().setEnabled(false)
.setBrokerageMinPrice(0).setBrokerageMaxPrice(0);
// 2.1 校验分销功能是否开启
TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig();
if (tradeConfig == null || !BooleanUtil.isTrue(tradeConfig.getBrokerageEnabled())) {
return respVO;
}
// 2.2 校验用户是否有分销资格
respVO.setEnabled(brokerageUserService.getUserBrokerageEnabled(getLoginUserId()));
if (!BooleanUtil.isTrue(respVO.getEnabled())) {
return respVO;
}
Integer fixedMinPrice = 0;
Integer fixedMaxPrice = 0;
Integer spuMinPrice = 0;
Integer spuMaxPrice = 0;
// 2.3 校验商品是否存在
ProductSpuRespDTO spu = productSpuApi.getSpu(spuId);
if (spu == null) {
return respVO;
}
List<ProductSkuRespDTO> skuList = productSkuApi.getSkuListBySpuId(ListUtil.of(spuId));
if (BooleanUtil.isTrue(spu.getSubCommissionType())) {
// 3.1 商品单独分佣模式
fixedMinPrice = getMinValue(skuList, ProductSkuRespDTO::getFirstBrokeragePrice);
fixedMaxPrice = getMaxValue(skuList, ProductSkuRespDTO::getFirstBrokeragePrice);
} else {
// 3.2 全局分佣模式根据商品价格比例计算
spuMinPrice = getMinValue(skuList, ProductSkuRespDTO::getPrice);
spuMaxPrice = getMaxValue(skuList, ProductSkuRespDTO::getPrice);
}
respVO.setBrokerageMinPrice(calculatePrice(spuMinPrice, tradeConfig.getBrokerageFirstPercent(), fixedMinPrice));
respVO.setBrokerageMaxPrice(calculatePrice(spuMaxPrice, tradeConfig.getBrokerageFirstPercent(), fixedMaxPrice));
return respVO;
}
/**
* 获得自身的代理对象解决 AOP 生效问题
*

View File

@ -849,7 +849,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
// 每一个订单项都会去生成分销记录
List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(orderId);
List<BrokerageAddReqBO> addList = convertList(orderItems,
item -> TradeOrderConvert.INSTANCE.convert(user, item, productSkuApi.getSku(item.getSkuId())));
item -> TradeOrderConvert.INSTANCE.convert(user, item,
productSpuApi.getSpu(item.getSpuId()), productSkuApi.getSku(item.getSkuId())));
brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, addList);
}