From e69e6d880b08e02b0d9c9ca9b8c166cc1ef0954b Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Thu, 15 Jun 2023 10:49:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BF=AB=E9=80=92=E4=BB=B7=E6=A0=BC=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=20review=20=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/enums/ErrorCodeConstants.java | 5 +- .../DeliveryExpressTemplateConvert.java | 7 +- .../DeliveryExpressTemplateChargeMapper.java | 8 +- .../DeliveryExpressTemplateFreeMapper.java | 9 ++- .../DeliveryExpressTemplateService.java | 12 ++- .../DeliveryExpressTemplateServiceImpl.java | 55 ++++++------- .../bo/DeliveryExpressTemplateChargeBO.java | 29 ------- .../bo/DeliveryExpressTemplateFreeBO.java | 26 ------ .../bo/DeliveryExpressTemplateRespBO.java | 79 +++++++++++++++++++ .../bo/SpuDeliveryExpressTemplateRespBO.java | 33 -------- .../price/bo/TradePriceCalculateRespBO.java | 5 ++ .../TradeDeliveryPriceCalculator.java | 46 ++++++----- .../TradePriceCalculatorHelper.java | 3 +- .../TradeDeliveryPriceCalculatorTest.java | 38 +++++---- 14 files changed, 172 insertions(+), 183 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateChargeBO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateFreeBO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 46ee636a5..800b5f239 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -51,13 +51,12 @@ public interface ErrorCodeConstants { ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011003002, "运费模板不存在"); ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003003, "已经存在该运费模板名"); - ErrorCode DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY = new ErrorCode(1011003004, "计算快递运费时,收件人地址编号为空"); // TODO @jaosn:这个错误码,放到 Price 这块 - ErrorCode PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND = new ErrorCode(1011003005, "找不到到商品对应的运费模板"); // TODO @jaosn:这个错误码,放到 Price 这块 ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011003006, "快递查询接口异常"); ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011003007, "快递查询返回失败, 原因:{}"); ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003008, "自提门店不存在"); // ========== Price 相关 1011004000 ============ ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011004000, "支付价格计算异常,原因:价格小于等于 0"); - + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY = new ErrorCode(1011004001, "计算快递运费异常,收件人地址编号为空"); + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1011004002, "计算快递运费异常,找不到对应的运费模板"); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java index 6ac562658..bbd57c62e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java @@ -6,8 +6,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplat import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateChargeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateFreeBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -49,7 +48,7 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateChargeDO convertTemplateCharge(DeliveryExpressTemplateUpdateReqVO.ExpressTemplateChargeUpdateVO vo); - DeliveryExpressTemplateChargeBO convertTemplateCharge(DeliveryExpressTemplateChargeDO bean); + DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO convertTemplateCharge(DeliveryExpressTemplateChargeDO bean); default List convertTemplateChargeList(Long templateId, Integer chargeMode, List list) { return CollectionUtils.convertList(list, vo -> convertTemplateCharge(templateId, chargeMode, vo)); @@ -61,7 +60,7 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateFreeDO convertTemplateFree(DeliveryExpressTemplateUpdateReqVO.ExpressTemplateFreeUpdateVO vo); - DeliveryExpressTemplateFreeBO convertTemplateFree(DeliveryExpressTemplateFreeDO bean); + DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO convertTemplateFree(DeliveryExpressTemplateFreeDO bean); List convertTemplateChargeList(List list); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java index dc96b24f2..985b418ac 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java @@ -5,10 +5,9 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.ibatis.annotations.Mapper; -import org.springframework.stereotype.Repository; +import java.util.Collection; import java.util.List; @Mapper @@ -23,6 +22,11 @@ public interface DeliveryExpressTemplateChargeMapper extends BaseMapperX() .eq(DeliveryExpressTemplateChargeDO::getTemplateId, templateId)); } + + default List selectByTemplateIds(Collection templateIds) { + return selectList(new LambdaQueryWrapperX() + .inIfPresent(DeliveryExpressTemplateChargeDO::getTemplateId, templateIds)); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java index 58caaf9af..5cc407354 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java @@ -2,13 +2,11 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.ibatis.annotations.Mapper; -import org.springframework.stereotype.Repository; +import java.util.Collection; import java.util.List; @Mapper @@ -23,6 +21,11 @@ public interface DeliveryExpressTemplateFreeMapper extends BaseMapperX() .eq(DeliveryExpressTemplateFreeDO::getTemplateId, templateId)); } + + default List selectListByTemplateIds(Collection ids) { + return selectList(new LambdaQueryWrapperX() + .inIfPresent(DeliveryExpressTemplateFreeDO::getTemplateId, ids)); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index 3c438df12..39edd823e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplat import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplatePageReqVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateUpdateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; import javax.validation.Valid; import java.util.Collection; @@ -83,14 +83,12 @@ public interface DeliveryExpressTemplateService { */ DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId); - // TODO @jason:可以把 spuIds 改成传递 ids 么?价格计算那,在 TradePriceCalculateRespBO 冗余好 templateId 字段。目的是,减少重复的查询 /** - * 基于指定的 SPU 编号数组和收件人地址区域编号. 获取匹配运费模板 + * 基于运费模板编号数组和收件人地址区域编号. 获取匹配运费模板 * - * @param spuIds SPU 编号列表 + * @param ids 编号列表 * @param areaId 区域编号 - * @return Map (spuId -> 运费模板设置) + * @return Map (templateId -> 运费模板设置) */ - Map getExpressTemplateMapBySpuIdsAndArea(Collection spuIds, Integer areaId); - + Map getExpressTemplateMapByIdsAndArea(Collection ids, Integer areaId); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index c7ddc9da6..c4aa22b8f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.trade.service.delivery; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.PageResult; -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.delivery.vo.expresstemplate.DeliveryExpressTemplateCreateReqVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateDetailRespVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplatePageReqVO; @@ -15,9 +13,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemp import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateChargeMapper; import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateFreeMapper; import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateMapper; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateChargeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateFreeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -46,8 +42,6 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla private DeliveryExpressTemplateChargeMapper expressTemplateChargeMapper; @Resource private DeliveryExpressTemplateFreeMapper expressTemplateFreeMapper; - @Resource - private ProductSpuApi productSpuApi; @Override @Transactional(rollbackFor = Exception.class) @@ -228,41 +222,40 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla } @Override - public Map getExpressTemplateMapBySpuIdsAndArea(Collection spuIds, Integer areaId) { + public Map getExpressTemplateMapByIdsAndArea(Collection ids, Integer areaId) { Assert.notNull(areaId, "区域编号 {} 不能为空", areaId); - List spuList = productSpuApi.getSpuList(spuIds); - if (CollUtil.isEmpty(spuList)) { + if (CollUtil.isEmpty(ids)) { return Collections.emptyMap(); } - Map spuMap = convertMap(spuList, ProductSpuRespDTO::getDeliveryTemplateId); - List templateList = expressTemplateMapper.selectBatchIds(spuMap.keySet()); - Map result = new HashMap<>(templateList.size()); + List templateList = expressTemplateMapper.selectBatchIds(ids); + // 查询 templateCharge + List templeChargeList = expressTemplateChargeMapper.selectByTemplateIds(ids); + Map> templateChargeMap = convertMultiMap(templeChargeList, + DeliveryExpressTemplateChargeDO::getTemplateId); + // 查询 templateFree + List templateFreeList = expressTemplateFreeMapper.selectListByTemplateIds(ids); + Map> templateFreeMap = convertMultiMap(templateFreeList, + DeliveryExpressTemplateFreeDO::getTemplateId); + // 组合运费模板配置 RespBO + Map result = new HashMap<>(templateList.size()); templateList.forEach(item -> { - ProductSpuRespDTO spu = spuMap.get(item.getId()); - if (spu == null) { - return; - } - // TODO @jason:避免循环查询;最好类似 expressTemplateMapper.selectBatchIds(spuMap.keySet()); 批量查询,内存组合; - SpuDeliveryExpressTemplateRespBO bo = new SpuDeliveryExpressTemplateRespBO() + DeliveryExpressTemplateRespBO bo = new DeliveryExpressTemplateRespBO() .setChargeMode(item.getChargeMode()) - .setTemplateCharge(findMatchExpressTemplateCharge(item.getId(), areaId)) - .setTemplateFree(findMatchExpressTemplateFree(item.getId(), areaId)); - result.put(spu.getId(), bo); + .setTemplateCharge(findMatchExpressTemplateCharge(templateChargeMap.get(item.getId()), areaId)) + .setTemplateFree(findMatchExpressTemplateFree(templateFreeMap.get(item.getId()), areaId)); + result.put(item.getId(), bo); }); return result; } - private DeliveryExpressTemplateChargeBO findMatchExpressTemplateCharge(Long templateId, Integer areaId) { - return INSTANCE.convertTemplateCharge(findFirst( - expressTemplateChargeMapper.selectListByTemplateId(templateId), item -> item.getAreaIds().contains(areaId) - ) - ); + private DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO findMatchExpressTemplateCharge( + List templateChargeList, Integer areaId) { + return INSTANCE.convertTemplateCharge(findFirst(templateChargeList, item -> item.getAreaIds().contains(areaId))); } - private DeliveryExpressTemplateFreeBO findMatchExpressTemplateFree(Long templateId, Integer areaId) { - return INSTANCE.convertTemplateFree(findFirst( - expressTemplateFreeMapper.selectListByTemplateId(templateId), item -> item.getAreaIds().contains(areaId) - )); + private DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO findMatchExpressTemplateFree( + List templateFreeList, Integer areaId) { + return INSTANCE.convertTemplateFree(findFirst(templateFreeList, item -> item.getAreaIds().contains(areaId))); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateChargeBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateChargeBO.java deleted file mode 100644 index 9dd908c41..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateChargeBO.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.delivery.bo; - -import lombok.Data; - -/** - * 快递运费模板费用配置 BO - * - * @author jason - */ -@Data -public class DeliveryExpressTemplateChargeBO { - - /** - * 首件数量(件数,重量,或体积) - */ - private Double startCount; - /** - * 起步价,单位:分 - */ - private Integer startPrice; - /** - * 续件数量(件, 重量,或体积) - */ - private Double extraCount; - /** - * 额外价,单位:分 - */ - private Integer extraPrice; -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateFreeBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateFreeBO.java deleted file mode 100644 index 6bccb038e..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateFreeBO.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.delivery.bo; - -import lombok.Data; - -/** - * 快递运费模板包邮配置 BO - * - * @author jason - */ -@Data -public class DeliveryExpressTemplateFreeBO { - - /** - * 包邮金额,单位:分 - * - * 订单总金额 > 包邮金额时,才免运费 - */ - private Integer freePrice; - - /** - * 包邮件数 - * - * 订单总件数 > 包邮件数时,才免运费 - */ - private Integer freeCount; -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java new file mode 100644 index 000000000..6c8764a5c --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java @@ -0,0 +1,79 @@ +package cn.iocoder.yudao.module.trade.service.delivery.bo; + +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; +import lombok.Data; + +/** + * 运费模板配置 Resp BO + * + * @author jason + */ +@Data +public class DeliveryExpressTemplateRespBO { + + /** + * 配送计费方式 + * + * 枚举 {@link DeliveryExpressChargeModeEnum} + */ + private Integer chargeMode; + + /** + * 运费模板快递运费设置 + */ + private DeliveryExpressTemplateChargeBO templateCharge; + + /** + * 运费模板包邮设置 + */ + private DeliveryExpressTemplateFreeBO templateFree; + + /** + * 快递运费模板费用配置 BO + * + * @author jason + */ + @Data + public static class DeliveryExpressTemplateChargeBO { + + /** + * 首件数量(件数,重量,或体积) + */ + private Double startCount; + /** + * 起步价,单位:分 + */ + private Integer startPrice; + /** + * 续件数量(件, 重量,或体积) + */ + private Double extraCount; + /** + * 额外价,单位:分 + */ + private Integer extraPrice; + } + + /** + * 快递运费模板包邮配置 BO + * + * @author jason + */ + @Data + public static class DeliveryExpressTemplateFreeBO { + + /** + * 包邮金额,单位:分 + * + * 订单总金额 > 包邮金额时,才免运费 + */ + private Integer freePrice; + + /** + * 包邮件数 + * + * 订单总件数 > 包邮件数时,才免运费 + */ + private Integer freeCount; + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java deleted file mode 100644 index 82a0274de..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.delivery.bo; - -import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; -import lombok.Data; - -/** - * SPU 运费模板配置 Resp BO - * - * @author jason - */ -@Data -public class SpuDeliveryExpressTemplateRespBO { - - /** - * 配送计费方式 - * - * 枚举 {@link DeliveryExpressChargeModeEnum} - */ - private Integer chargeMode; - - // TODO @jaosn:可以把 DeliveryExpressTemplateChargeBO 和 DeliveryExpressTemplateFreeBO 搞成内嵌的类。这样简洁一点 - - /** - * 运费模板快递运费设置 - */ - private DeliveryExpressTemplateChargeBO templateCharge; - - /** - * 运费模板包邮设置 - */ - private DeliveryExpressTemplateFreeBO templateFree; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java index 8231621bb..76fb68c1f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java @@ -180,6 +180,11 @@ public class TradePriceCalculateRespBO { */ private Long categoryId; + /** + * 运费模板 Id + */ + private Long deliveryTemplateId; + // ========== 商品 SKU 信息 ========== /** * 商品重量,单位:kg 千克 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java index 9f8e6afa7..1a0598c63 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java @@ -7,9 +7,7 @@ import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateChargeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateFreeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO.OrderItem; @@ -24,8 +22,8 @@ import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND; /** * 运费的 {@link TradePriceCalculator} 实现类 @@ -49,7 +47,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { return; } if (param.getAddressId() == null) { - throw exception(DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY); + throw exception(PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY); } // 1.2 得到收件地址区域 AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId()); @@ -57,29 +55,29 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { // 2. 过滤出已选中的商品SKU List selectedItem = filterList(result.getItems(), OrderItem::getSelected); - Set spuIds = convertSet(selectedItem, OrderItem::getSpuId); - Map spuExpressTemplateMap = - deliveryExpressTemplateService.getExpressTemplateMapBySpuIdsAndArea(spuIds, address.getAreaId()); + Set deliveryTemplateIds = convertSet(selectedItem, OrderItem::getDeliveryTemplateId); + Map expressTemplateMap = + deliveryExpressTemplateService.getExpressTemplateMapByIdsAndArea(deliveryTemplateIds, address.getAreaId()); // 3. 计算配送费用 - if (CollUtil.isEmpty(spuExpressTemplateMap)) { - log.error("[calculate][找不到商品 spuId{} areaId{} 对应的运费模板]", spuIds, address.getAreaId()); - throw exception(PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND); + if (CollUtil.isEmpty(expressTemplateMap)) { + log.error("[calculate][找不到商品 templateIds {} areaId{} 对应的运费模板]", deliveryTemplateIds, address.getAreaId()); + throw exception(PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND); } - calculateDeliveryPrice(selectedItem, spuExpressTemplateMap, result); + calculateDeliveryPrice(selectedItem, expressTemplateMap, result); } private void calculateDeliveryPrice(List selectedSkus, - Map spuExpressTemplateMap, + Map expressTemplateMap, TradePriceCalculateRespBO result) { - // 按 SPU 来计算商品的运费:一个 spuId 可能对应多条订单商品 SKU - Map> spuIdItemMap = convertMultiMap(selectedSkus, OrderItem::getSpuId); - // 依次计算每个 SPU 的快递运费 - for (Map.Entry> entry : spuIdItemMap.entrySet()) { - Long spuId = entry.getKey(); + // 按商品运费模板来计算商品的运费:相同的运费模板可能对应多条订单商品 SKU + Map> tplIdItemMap = convertMultiMap(selectedSkus, OrderItem::getDeliveryTemplateId); + // 依次计算快递运费 + for (Map.Entry> entry : tplIdItemMap.entrySet()) { + Long templateId = entry.getKey(); List orderItems = entry.getValue(); - SpuDeliveryExpressTemplateRespBO templateBO = spuExpressTemplateMap.get(spuId); + DeliveryExpressTemplateRespBO templateBO = expressTemplateMap.get(templateId); if (templateBO == null) { - log.error("不能计算快递运费。不能找到 spuId : {}. 对应的运费模板配置 Resp BO", spuId); + log.error("不能计算快递运费。不能找到 templateId : {}. 对应的运费模板配置 Resp BO", templateId); continue; } // 总件数, 总金额, 总重量, 总体积 @@ -117,7 +115,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param orderItems SKU 商品项目 */ private void calculateExpressFeeByChargeMode(double totalCount, double totalWeight, double totalVolume, - int chargeMode, DeliveryExpressTemplateChargeBO templateCharge, + int chargeMode, DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO templateCharge, List orderItems) { if (templateCharge == null) { log.error("计算快递运费时,不能找到对应的快递运费模板费用配置。无法计算以下商品 SKU 项目运费: {}", orderItems); @@ -147,7 +145,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param templateCharge 快递运费配置 * @param orderItems SKU 商品项目 */ - private void calculateExpressFee(double total, DeliveryExpressTemplateChargeBO templateCharge, List orderItems) { + private void calculateExpressFee(double total, DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO templateCharge, List orderItems) { int deliveryPrice; if (total <= templateCharge.getStartCount()) { deliveryPrice = templateCharge.getStartPrice(); @@ -192,7 +190,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param templateFree 包邮配置 */ private boolean isExpressFree(Integer chargeMode, int totalCount, double totalWeight, - double totalVolume, int totalPrice, DeliveryExpressTemplateFreeBO templateFree) { + double totalVolume, int totalPrice, DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO templateFree) { if (templateFree == null) { return false; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java index 7945c72eb..bd3d3b5be 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java @@ -56,7 +56,8 @@ public class TradePriceCalculatorHelper { orderItem.setPicUrl(sku.getPicUrl()).setProperties(sku.getProperties()) .setWeight(sku.getWeight()).setVolume(sku.getVolume()); // spu 信息 - orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId()); + orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId()) + .setDeliveryTemplateId(spu.getDeliveryTemplateId()); if (orderItem.getPicUrl() == null) { orderItem.setPicUrl(spu.getPicUrl()); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java index e6af92430..99fdac64e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java @@ -4,9 +4,7 @@ import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; import cn.iocoder.yudao.module.member.api.address.AddressApi; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateChargeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateFreeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import org.junit.jupiter.api.BeforeEach; @@ -44,9 +42,9 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { private TradePriceCalculateReqBO reqBO; private TradePriceCalculateRespBO resultBO; private AddressRespDTO addressResp; - private DeliveryExpressTemplateChargeBO chargeBO; - private DeliveryExpressTemplateFreeBO freeBO; - private SpuDeliveryExpressTemplateRespBO spuTemplateRespBO; + private DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO chargeBO; + private DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO freeBO; + private DeliveryExpressTemplateRespBO templateRespBO; @BeforeEach public void init(){ @@ -64,11 +62,11 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { .setPrice(new TradePriceCalculateRespBO.Price()) .setPromotions(new ArrayList<>()) .setItems(asList( - new TradePriceCalculateRespBO.OrderItem().setSpuId(1L).setSkuId(10L).setCount(2).setSelected(true) + new TradePriceCalculateRespBO.OrderItem().setDeliveryTemplateId(1L).setSkuId(10L).setCount(2).setSelected(true) .setWeight(10d).setVolume(10d).setPrice(100), - new TradePriceCalculateRespBO.OrderItem().setSpuId(1L).setSkuId(20L).setCount(10).setSelected(true) + new TradePriceCalculateRespBO.OrderItem().setDeliveryTemplateId(1L).setSkuId(20L).setCount(10).setSelected(true) .setWeight(10d).setVolume(10d).setPrice(200), - new TradePriceCalculateRespBO.OrderItem().setSpuId(1L).setSkuId(30L).setCount(1).setSelected(false) + new TradePriceCalculateRespBO.OrderItem().setDeliveryTemplateId(1L).setSkuId(30L).setCount(1).setSelected(false) .setWeight(10d).setVolume(10d).setPrice(300) )); // 保证价格被初始化上 @@ -77,13 +75,13 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { // 准备收件地址数据 addressResp = randomPojo(AddressRespDTO.class, item -> item.setAreaId(10)); // 准备运费模板费用配置数据 - chargeBO = randomPojo(DeliveryExpressTemplateChargeBO.class, + chargeBO = randomPojo(DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO.class, item -> item.setStartCount(10D).setStartPrice(1000).setExtraCount(10D).setExtraPrice(2000)); // 准备运费模板包邮配置数据 订单总件数 < 包邮件数时 12 < 20 - freeBO = randomPojo(DeliveryExpressTemplateFreeBO.class, + freeBO = randomPojo(DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO.class, item -> item.setFreeCount(20).setFreePrice(100)); // 准备 SP 运费模板 数据 - spuTemplateRespBO = randomPojo(SpuDeliveryExpressTemplateRespBO.class, + templateRespBO = randomPojo(DeliveryExpressTemplateRespBO.class, item -> item.setChargeMode(PIECE.getType()) .setTemplateCharge(chargeBO).setTemplateFree(freeBO)); } @@ -94,12 +92,12 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { // SKU 1 : 100 * 2 = 200 // SKU 2 :200 * 10 = 2000 // 运费 首件 1000 + 续件 2000 = 3000 - Map respMap = new HashMap<>(); - respMap.put(1L, spuTemplateRespBO); + Map respMap = new HashMap<>(); + respMap.put(1L, templateRespBO); // mock 方法 when(addressApi.getAddress(eq(10L), eq(1L))).thenReturn(addressResp); - when(deliveryExpressTemplateService.getExpressTemplateMapBySpuIdsAndArea(eq(asSet(1L)), eq(10))) + when(deliveryExpressTemplateService.getExpressTemplateMapByIdsAndArea(eq(asSet(1L)), eq(10))) .thenReturn(respMap); calculator.calculate(reqBO, resultBO); @@ -131,15 +129,15 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { // SKU 1 : 100 * 2 = 200 // SKU 2 :200 * 10 = 2000 // 运费 0 - Map respMap = new HashMap<>(); - respMap.put(1L, spuTemplateRespBO); + Map respMap = new HashMap<>(); + respMap.put(1L, templateRespBO); // 准备运费模板包邮配置数据 包邮 订单总件数 > 包邮件数时 12 > 10 - freeBO = randomPojo(DeliveryExpressTemplateFreeBO.class, + freeBO = randomPojo(DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO.class, item -> item.setFreeCount(10).setFreePrice(1000)); - spuTemplateRespBO.setTemplateFree(freeBO); + templateRespBO.setTemplateFree(freeBO); // mock 方法 when(addressApi.getAddress(eq(10L), eq(1L))).thenReturn(addressResp); - when(deliveryExpressTemplateService.getExpressTemplateMapBySpuIdsAndArea(eq(asSet(1L)), eq(10))) + when(deliveryExpressTemplateService.getExpressTemplateMapByIdsAndArea(eq(asSet(1L)), eq(10))) .thenReturn(respMap); calculator.calculate(reqBO, resultBO);