Commit 9856e179741730ff185212da37d60dc89efe5372
1 parent
e9fd3777
分销:根据商品,计算推广员可以得到的佣金
Showing
6 changed files
with
90 additions
and
13 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java
| ... | ... | @@ -137,4 +137,14 @@ public class ProductSpuRespDTO { |
| 137 | 137 | */ |
| 138 | 138 | private Integer clickCount; |
| 139 | 139 | |
| 140 | + | |
| 141 | + // ========== 分销相关字段 ========= | |
| 142 | + | |
| 143 | + /** | |
| 144 | + * 分销类型 | |
| 145 | + * | |
| 146 | + * false - 默认 | |
| 147 | + * true - 自行设置 | |
| 148 | + */ | |
| 149 | + private Boolean subCommissionType; | |
| 140 | 150 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java
| ... | ... | @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBroke |
| 9 | 9 | import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert; |
| 10 | 10 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; |
| 11 | 11 | import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService; |
| 12 | -import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService; | |
| 13 | 12 | import io.swagger.v3.oas.annotations.Operation; |
| 14 | 13 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 15 | 14 | import lombok.extern.slf4j.Slf4j; |
| ... | ... | @@ -32,8 +31,6 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLogi |
| 32 | 31 | @Slf4j |
| 33 | 32 | public class AppBrokerageRecordController { |
| 34 | 33 | @Resource |
| 35 | - private BrokerageUserService brokerageUserService; | |
| 36 | - @Resource | |
| 37 | 34 | private BrokerageRecordService brokerageRecordService; |
| 38 | 35 | |
| 39 | 36 | @GetMapping("/page") |
| ... | ... | @@ -45,15 +42,10 @@ public class AppBrokerageRecordController { |
| 45 | 42 | return success(BrokerageRecordConvert.INSTANCE.convertPage02(pageResult)); |
| 46 | 43 | } |
| 47 | 44 | |
| 48 | - // TODO @疯狂:这里还有一个漏网之鱼~ | |
| 49 | 45 | @GetMapping("/get-product-brokerage-price") |
| 50 | 46 | @Operation(summary = "获得商品的分销金额") |
| 51 | 47 | public CommonResult<AppBrokerageProductPriceRespVO> getProductBrokeragePrice(@RequestParam("spuId") Long spuId) { |
| 52 | - AppBrokerageProductPriceRespVO respVO = new AppBrokerageProductPriceRespVO(); | |
| 53 | - respVO.setEnabled(brokerageUserService.getUserBrokerageEnabled(getLoginUserId())); | |
| 54 | - respVO.setBrokerageMinPrice(1); | |
| 55 | - respVO.setBrokerageMaxPrice(2); | |
| 56 | - return success(respVO); | |
| 48 | + return success(brokerageRecordService.calculateProductBrokeragePrice(spuId, getLoginUserId())); | |
| 57 | 49 | } |
| 58 | 50 | |
| 59 | 51 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.convert.order; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.util.BooleanUtil; | |
| 3 | 4 | import cn.hutool.core.util.StrUtil; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| ... | ... | @@ -14,6 +15,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDT |
| 14 | 15 | import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; |
| 15 | 16 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 16 | 17 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; |
| 18 | +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | |
| 17 | 19 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; |
| 18 | 20 | import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; |
| 19 | 21 | import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; |
| ... | ... | @@ -266,11 +268,16 @@ public interface TradeOrderConvert { |
| 266 | 268 | |
| 267 | 269 | TradeOrderDO convert(TradeOrderRemarkReqVO reqVO); |
| 268 | 270 | |
| 269 | - default BrokerageAddReqBO convert(MemberUserRespDTO user, TradeOrderItemDO item, ProductSkuRespDTO sku) { | |
| 270 | - return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId()) | |
| 271 | + default BrokerageAddReqBO convert(MemberUserRespDTO user, TradeOrderItemDO item, | |
| 272 | + ProductSpuRespDTO spu, ProductSkuRespDTO sku) { | |
| 273 | + BrokerageAddReqBO bo = new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId()) | |
| 271 | 274 | .setBasePrice(item.getPayPrice() * item.getCount()) |
| 272 | 275 | .setTitle(StrUtil.format("{}成功购买{}", user.getNickname(), item.getSpuName())) |
| 273 | - .setFirstFixedPrice(sku.getFirstBrokeragePrice()).setSecondFixedPrice(sku.getSecondBrokeragePrice()); | |
| 276 | + .setFirstFixedPrice(0).setSecondFixedPrice(0); | |
| 277 | + if (BooleanUtil.isTrue(spu.getSubCommissionType())) { | |
| 278 | + bo.setFirstFixedPrice(sku.getFirstBrokeragePrice()).setSecondFixedPrice(sku.getSecondBrokeragePrice()); | |
| 279 | + } | |
| 280 | + return bo; | |
| 274 | 281 | } |
| 275 | 282 | |
| 276 | 283 | TradeBeforeOrderCreateReqBO convert(AppTradeOrderCreateReqVO createReqVO); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java
| ... | ... | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.brokerage; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO; |
| 5 | +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageProductPriceRespVO; | |
| 5 | 6 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO; |
| 6 | 7 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO; |
| 7 | 8 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; |
| ... | ... | @@ -110,4 +111,12 @@ public interface BrokerageRecordService { |
| 110 | 111 | */ |
| 111 | 112 | Integer getUserRankByPrice(Long userId, LocalDateTime[] times); |
| 112 | 113 | |
| 114 | + /** | |
| 115 | + * 计算商品被购买后,推广员可以得到的佣金 | |
| 116 | + * | |
| 117 | + * @param spuId 商品编号 | |
| 118 | + * @param userId 用户编号 | |
| 119 | + * @return 用户佣金 | |
| 120 | + */ | |
| 121 | + AppBrokerageProductPriceRespVO calculateProductBrokeragePrice(Long spuId, Long userId); | |
| 113 | 122 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.service.brokerage; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | +import cn.hutool.core.collection.ListUtil; | |
| 4 | 5 | import cn.hutool.core.util.ArrayUtil; |
| 5 | 6 | import cn.hutool.core.util.BooleanUtil; |
| 6 | 7 | import cn.hutool.core.util.ObjectUtil; |
| ... | ... | @@ -9,7 +10,12 @@ import cn.hutool.extra.spring.SpringUtil; |
| 9 | 10 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 10 | 11 | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; |
| 11 | 12 | import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; |
| 13 | +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | |
| 14 | +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | |
| 15 | +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | |
| 16 | +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | |
| 12 | 17 | import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO; |
| 18 | +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageProductPriceRespVO; | |
| 13 | 19 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO; |
| 14 | 20 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO; |
| 15 | 21 | import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert; |
| ... | ... | @@ -36,6 +42,9 @@ import java.util.Objects; |
| 36 | 42 | import java.util.Optional; |
| 37 | 43 | |
| 38 | 44 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 45 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue; | |
| 46 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMinValue; | |
| 47 | +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; | |
| 39 | 48 | import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH; |
| 40 | 49 | |
| 41 | 50 | /** |
| ... | ... | @@ -55,6 +64,11 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { |
| 55 | 64 | @Resource |
| 56 | 65 | private BrokerageUserService brokerageUserService; |
| 57 | 66 | |
| 67 | + @Resource | |
| 68 | + private ProductSpuApi productSpuApi; | |
| 69 | + @Resource | |
| 70 | + private ProductSkuApi productSkuApi; | |
| 71 | + | |
| 58 | 72 | @Override |
| 59 | 73 | public BrokerageRecordDO getBrokerageRecord(Integer id) { |
| 60 | 74 | return brokerageRecordMapper.selectById(id); |
| ... | ... | @@ -293,6 +307,50 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { |
| 293 | 307 | return true; |
| 294 | 308 | } |
| 295 | 309 | |
| 310 | + @Override | |
| 311 | + public AppBrokerageProductPriceRespVO calculateProductBrokeragePrice(Long spuId, Long userId) { | |
| 312 | + // 1. 构建默认的返回值 | |
| 313 | + AppBrokerageProductPriceRespVO respVO = new AppBrokerageProductPriceRespVO().setEnabled(false) | |
| 314 | + .setBrokerageMinPrice(0).setBrokerageMaxPrice(0); | |
| 315 | + | |
| 316 | + // 2.1 校验分销功能是否开启 | |
| 317 | + TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig(); | |
| 318 | + if (tradeConfig == null || !BooleanUtil.isTrue(tradeConfig.getBrokerageEnabled())) { | |
| 319 | + return respVO; | |
| 320 | + } | |
| 321 | + | |
| 322 | + // 2.2 校验用户是否有分销资格 | |
| 323 | + respVO.setEnabled(brokerageUserService.getUserBrokerageEnabled(getLoginUserId())); | |
| 324 | + if (!BooleanUtil.isTrue(respVO.getEnabled())) { | |
| 325 | + return respVO; | |
| 326 | + } | |
| 327 | + | |
| 328 | + Integer fixedMinPrice = 0; | |
| 329 | + Integer fixedMaxPrice = 0; | |
| 330 | + Integer spuMinPrice = 0; | |
| 331 | + Integer spuMaxPrice = 0; | |
| 332 | + // 2.3 校验商品是否存在 | |
| 333 | + ProductSpuRespDTO spu = productSpuApi.getSpu(spuId); | |
| 334 | + if (spu == null) { | |
| 335 | + return respVO; | |
| 336 | + } | |
| 337 | + | |
| 338 | + List<ProductSkuRespDTO> skuList = productSkuApi.getSkuListBySpuId(ListUtil.of(spuId)); | |
| 339 | + if (BooleanUtil.isTrue(spu.getSubCommissionType())) { | |
| 340 | + // 3.1 商品单独分佣模式 | |
| 341 | + fixedMinPrice = getMinValue(skuList, ProductSkuRespDTO::getFirstBrokeragePrice); | |
| 342 | + fixedMaxPrice = getMaxValue(skuList, ProductSkuRespDTO::getFirstBrokeragePrice); | |
| 343 | + } else { | |
| 344 | + // 3.2 全局分佣模式(根据商品价格比例计算) | |
| 345 | + spuMinPrice = getMinValue(skuList, ProductSkuRespDTO::getPrice); | |
| 346 | + spuMaxPrice = getMaxValue(skuList, ProductSkuRespDTO::getPrice); | |
| 347 | + } | |
| 348 | + | |
| 349 | + respVO.setBrokerageMinPrice(calculatePrice(spuMinPrice, tradeConfig.getBrokerageFirstPercent(), fixedMinPrice)); | |
| 350 | + respVO.setBrokerageMaxPrice(calculatePrice(spuMaxPrice, tradeConfig.getBrokerageFirstPercent(), fixedMaxPrice)); | |
| 351 | + return respVO; | |
| 352 | + } | |
| 353 | + | |
| 296 | 354 | /** |
| 297 | 355 | * 获得自身的代理对象,解决 AOP 生效问题 |
| 298 | 356 | * | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
| ... | ... | @@ -849,7 +849,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 849 | 849 | // 每一个订单项,都会去生成分销记录 |
| 850 | 850 | List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(orderId); |
| 851 | 851 | List<BrokerageAddReqBO> addList = convertList(orderItems, |
| 852 | - item -> TradeOrderConvert.INSTANCE.convert(user, item, productSkuApi.getSku(item.getSkuId()))); | |
| 852 | + item -> TradeOrderConvert.INSTANCE.convert(user, item, | |
| 853 | + productSpuApi.getSpu(item.getSpuId()), productSkuApi.getSku(item.getSkuId()))); | |
| 853 | 854 | brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, addList); |
| 854 | 855 | } |
| 855 | 856 | ... | ... |