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,4 +137,14 @@ public class ProductSpuRespDTO { | ||
| 137 | */ | 137 | */ |
| 138 | private Integer clickCount; | 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,7 +9,6 @@ import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBroke | ||
| 9 | import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert; | 9 | import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert; |
| 10 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; | 10 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; |
| 11 | import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService; | 11 | import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService; |
| 12 | -import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService; | ||
| 13 | import io.swagger.v3.oas.annotations.Operation; | 12 | import io.swagger.v3.oas.annotations.Operation; |
| 14 | import io.swagger.v3.oas.annotations.tags.Tag; | 13 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 15 | import lombok.extern.slf4j.Slf4j; | 14 | import lombok.extern.slf4j.Slf4j; |
| @@ -32,8 +31,6 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLogi | @@ -32,8 +31,6 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLogi | ||
| 32 | @Slf4j | 31 | @Slf4j |
| 33 | public class AppBrokerageRecordController { | 32 | public class AppBrokerageRecordController { |
| 34 | @Resource | 33 | @Resource |
| 35 | - private BrokerageUserService brokerageUserService; | ||
| 36 | - @Resource | ||
| 37 | private BrokerageRecordService brokerageRecordService; | 34 | private BrokerageRecordService brokerageRecordService; |
| 38 | 35 | ||
| 39 | @GetMapping("/page") | 36 | @GetMapping("/page") |
| @@ -45,15 +42,10 @@ public class AppBrokerageRecordController { | @@ -45,15 +42,10 @@ public class AppBrokerageRecordController { | ||
| 45 | return success(BrokerageRecordConvert.INSTANCE.convertPage02(pageResult)); | 42 | return success(BrokerageRecordConvert.INSTANCE.convertPage02(pageResult)); |
| 46 | } | 43 | } |
| 47 | 44 | ||
| 48 | - // TODO @疯狂:这里还有一个漏网之鱼~ | ||
| 49 | @GetMapping("/get-product-brokerage-price") | 45 | @GetMapping("/get-product-brokerage-price") |
| 50 | @Operation(summary = "获得商品的分销金额") | 46 | @Operation(summary = "获得商品的分销金额") |
| 51 | public CommonResult<AppBrokerageProductPriceRespVO> getProductBrokeragePrice(@RequestParam("spuId") Long spuId) { | 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 | package cn.iocoder.yudao.module.trade.convert.order; | 1 | package cn.iocoder.yudao.module.trade.convert.order; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.util.BooleanUtil; | ||
| 3 | import cn.hutool.core.util.StrUtil; | 4 | import cn.hutool.core.util.StrUtil; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 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,6 +15,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDT | ||
| 14 | import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | 15 | import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; |
| 15 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | 16 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 16 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; | 17 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; |
| 18 | +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | ||
| 17 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; | 19 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; |
| 18 | import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; | 20 | import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; |
| 19 | import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; | 21 | import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; |
| @@ -266,11 +268,16 @@ public interface TradeOrderConvert { | @@ -266,11 +268,16 @@ public interface TradeOrderConvert { | ||
| 266 | 268 | ||
| 267 | TradeOrderDO convert(TradeOrderRemarkReqVO reqVO); | 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 | .setBasePrice(item.getPayPrice() * item.getCount()) | 274 | .setBasePrice(item.getPayPrice() * item.getCount()) |
| 272 | .setTitle(StrUtil.format("{}成功购买{}", user.getNickname(), item.getSpuName())) | 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 | TradeBeforeOrderCreateReqBO convert(AppTradeOrderCreateReqVO createReqVO); | 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,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.brokerage; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO; | 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 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO; | 6 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO; |
| 6 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO; | 7 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO; |
| 7 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; | 8 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; |
| @@ -110,4 +111,12 @@ public interface BrokerageRecordService { | @@ -110,4 +111,12 @@ public interface BrokerageRecordService { | ||
| 110 | */ | 111 | */ |
| 111 | Integer getUserRankByPrice(Long userId, LocalDateTime[] times); | 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 | package cn.iocoder.yudao.module.trade.service.brokerage; | 1 | package cn.iocoder.yudao.module.trade.service.brokerage; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | +import cn.hutool.core.collection.ListUtil; | ||
| 4 | import cn.hutool.core.util.ArrayUtil; | 5 | import cn.hutool.core.util.ArrayUtil; |
| 5 | import cn.hutool.core.util.BooleanUtil; | 6 | import cn.hutool.core.util.BooleanUtil; |
| 6 | import cn.hutool.core.util.ObjectUtil; | 7 | import cn.hutool.core.util.ObjectUtil; |
| @@ -9,7 +10,12 @@ import cn.hutool.extra.spring.SpringUtil; | @@ -9,7 +10,12 @@ import cn.hutool.extra.spring.SpringUtil; | ||
| 9 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 10 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 10 | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; | 11 | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; |
| 11 | import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; | 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 | import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO; | 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 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO; | 19 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO; |
| 14 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO; | 20 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO; |
| 15 | import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert; | 21 | import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert; |
| @@ -36,6 +42,9 @@ import java.util.Objects; | @@ -36,6 +42,9 @@ import java.util.Objects; | ||
| 36 | import java.util.Optional; | 42 | import java.util.Optional; |
| 37 | 43 | ||
| 38 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 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 | import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH; | 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,6 +64,11 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | ||
| 55 | @Resource | 64 | @Resource |
| 56 | private BrokerageUserService brokerageUserService; | 65 | private BrokerageUserService brokerageUserService; |
| 57 | 66 | ||
| 67 | + @Resource | ||
| 68 | + private ProductSpuApi productSpuApi; | ||
| 69 | + @Resource | ||
| 70 | + private ProductSkuApi productSkuApi; | ||
| 71 | + | ||
| 58 | @Override | 72 | @Override |
| 59 | public BrokerageRecordDO getBrokerageRecord(Integer id) { | 73 | public BrokerageRecordDO getBrokerageRecord(Integer id) { |
| 60 | return brokerageRecordMapper.selectById(id); | 74 | return brokerageRecordMapper.selectById(id); |
| @@ -293,6 +307,50 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | @@ -293,6 +307,50 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | ||
| 293 | return true; | 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 | * 获得自身的代理对象,解决 AOP 生效问题 | 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,7 +849,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 849 | // 每一个订单项,都会去生成分销记录 | 849 | // 每一个订单项,都会去生成分销记录 |
| 850 | List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(orderId); | 850 | List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(orderId); |
| 851 | List<BrokerageAddReqBO> addList = convertList(orderItems, | 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 | brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, addList); | 854 | brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, addList); |
| 854 | } | 855 | } |
| 855 | 856 |