mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 23:31:52 +08:00
review 价格运算修改.
This commit is contained in:
parent
dd93215139
commit
36c45bd44e
@ -103,6 +103,15 @@ public class ProductSpuRespDTO {
|
|||||||
*/
|
*/
|
||||||
private Integer stock;
|
private Integer stock;
|
||||||
|
|
||||||
|
// ========== 物流相关字段 =========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物流配置模板编号
|
||||||
|
*
|
||||||
|
* 对应 TradeDeliveryExpressTemplateDO 的 id 编号
|
||||||
|
*/
|
||||||
|
private Long deliveryTemplateId;
|
||||||
|
|
||||||
// ========== 统计相关字段 =========
|
// ========== 统计相关字段 =========
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,10 +6,12 @@ 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.DeliveryExpressTemplatePageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateUpdateReqVO;
|
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.dal.dataobject.delivery.DeliveryExpressTemplateDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 快递运费模板 Service 接口
|
* 快递运费模板 Service 接口
|
||||||
@ -73,11 +75,21 @@ public interface DeliveryExpressTemplateService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验快递运费模板
|
* 校验快递运费模板
|
||||||
*
|
* <p>
|
||||||
* 如果校验不通过,抛出 {@link cn.iocoder.yudao.framework.common.exception.ServiceException} 异常
|
* 如果校验不通过,抛出 {@link cn.iocoder.yudao.framework.common.exception.ServiceException} 异常
|
||||||
*
|
*
|
||||||
* @param templateId 模板编号
|
* @param templateId 模板编号
|
||||||
* @return 快递运费模板
|
* @return 快递运费模板
|
||||||
*/
|
*/
|
||||||
DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId);
|
DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基于指定的 SPU 编号数组和收件人地址区域编号. 获取匹配运费模板
|
||||||
|
*
|
||||||
|
* @param ids SPU 编号列表
|
||||||
|
* @param areaId 区域编号
|
||||||
|
* @return Map (spuId -> 运费模板设置)
|
||||||
|
*/
|
||||||
|
Map<Long, SpuDeliveryExpressTemplateRespBO> getExpressTemplateBySpuIdsAndArea(Collection<Long> ids, Integer areaId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package cn.iocoder.yudao.module.trade.service.delivery;
|
package cn.iocoder.yudao.module.trade.service.delivery;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
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.*;
|
import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.*;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO;
|
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.DeliveryExpressTemplateDO;
|
||||||
@ -9,6 +12,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.DeliveryExpressTemplateChargeMapper;
|
||||||
import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateFreeMapper;
|
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.dal.mysql.delivery.DeliveryExpressTemplateMapper;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@ -17,6 +21,7 @@ import javax.annotation.Resource;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||||
import static cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressTemplateConvert.INSTANCE;
|
import static cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressTemplateConvert.INSTANCE;
|
||||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_TEMPLATE_NAME_DUPLICATE;
|
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_TEMPLATE_NAME_DUPLICATE;
|
||||||
@ -37,6 +42,8 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla
|
|||||||
private DeliveryExpressTemplateChargeMapper expressTemplateChargeMapper;
|
private DeliveryExpressTemplateChargeMapper expressTemplateChargeMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private DeliveryExpressTemplateFreeMapper expressTemplateFreeMapper;
|
private DeliveryExpressTemplateFreeMapper expressTemplateFreeMapper;
|
||||||
|
@Resource
|
||||||
|
private ProductSpuApi productSpuApi;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@ -216,4 +223,50 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla
|
|||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Long, SpuDeliveryExpressTemplateRespBO> getExpressTemplateBySpuIdsAndArea(Collection<Long> spuIds, Integer areaId) {
|
||||||
|
Assert.notNull(areaId, "区域编号 {} 不能为空", areaId);
|
||||||
|
List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(spuIds);
|
||||||
|
if (CollUtil.isEmpty(spuList)) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getDeliveryTemplateId);
|
||||||
|
List<DeliveryExpressTemplateDO> templateList = expressTemplateMapper.selectBatchIds(spuMap.keySet());
|
||||||
|
Map<Long, SpuDeliveryExpressTemplateRespBO> result = new HashMap<>(templateList.size());
|
||||||
|
templateList.forEach(item -> {
|
||||||
|
if (spuMap.containsKey(item.getId())) {
|
||||||
|
ProductSpuRespDTO spuDTO = spuMap.get(item.getId());
|
||||||
|
SpuDeliveryExpressTemplateRespBO bo = new SpuDeliveryExpressTemplateRespBO()
|
||||||
|
.setSpuId(spuDTO.getId()).setAreaId(areaId)
|
||||||
|
.setChargeMode(item.getChargeMode())
|
||||||
|
.setTemplateCharge(findMatchExpressTemplateCharge(item.getId(), areaId))
|
||||||
|
.setTemplateFree(findMatchExpressTemplateFree(item.getId(), areaId));
|
||||||
|
result.put(spuDTO.getId(), bo);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeliveryExpressTemplateChargeDO findMatchExpressTemplateCharge(Long templateId, Integer areaId) {
|
||||||
|
List<DeliveryExpressTemplateChargeDO> list = expressTemplateChargeMapper.selectListByTemplateId(templateId);
|
||||||
|
for (DeliveryExpressTemplateChargeDO item : list) {
|
||||||
|
// 第一个匹配的返回。 areaId 不能重复
|
||||||
|
if (item.getAreaIds().contains(areaId)) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeliveryExpressTemplateFreeDO findMatchExpressTemplateFree(Long templateId, Integer areaId) {
|
||||||
|
List<DeliveryExpressTemplateFreeDO> list = expressTemplateFreeMapper.selectListByTemplateId(templateId);
|
||||||
|
for (DeliveryExpressTemplateFreeDO item : list) {
|
||||||
|
// 第一个匹配的返回。 areaId 不能重复
|
||||||
|
if (item.getAreaIds().contains(areaId)) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.service.delivery.bo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SPU 运费模板配置 Resp BO
|
||||||
|
*
|
||||||
|
* @author jason
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SpuDeliveryExpressTemplateRespBO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配送计费方式
|
||||||
|
* <p>
|
||||||
|
* 枚举 {@link DeliveryExpressChargeModeEnum}
|
||||||
|
*/
|
||||||
|
private Integer chargeMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 运费模板快递运费设置
|
||||||
|
*/
|
||||||
|
private DeliveryExpressTemplateChargeDO templateCharge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 运费模板包邮设置
|
||||||
|
*/
|
||||||
|
private DeliveryExpressTemplateFreeDO templateFree;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SPU 编号
|
||||||
|
* <p>
|
||||||
|
* 关联 ProductSpuDO 的 id 编号
|
||||||
|
*/
|
||||||
|
private Long spuId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 区域编号
|
||||||
|
*/
|
||||||
|
private Integer areaId;
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package cn.iocoder.yudao.module.trade.service.price.bo;
|
package cn.iocoder.yudao.module.trade.service.price.bo;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO;
|
|
||||||
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
|
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
|
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -53,14 +52,6 @@ public class TradePriceCalculateReqBO {
|
|||||||
*/
|
*/
|
||||||
private Integer deliveryType;
|
private Integer deliveryType;
|
||||||
|
|
||||||
/**
|
|
||||||
* 配送模板编号
|
|
||||||
*
|
|
||||||
* 关联 {@link DeliveryExpressTemplateDO#getId()}
|
|
||||||
*/
|
|
||||||
// TODO @jason:运费模版,是不是每个 SKU 传入哈
|
|
||||||
private Long templateId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品 SKU 数组
|
* 商品 SKU 数组
|
||||||
*/
|
*/
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
package cn.iocoder.yudao.module.trade.service.price.calculator;
|
package cn.iocoder.yudao.module.trade.service.price.calculator;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.iocoder.yudao.module.member.api.address.AddressApi;
|
import cn.iocoder.yudao.module.member.api.address.AddressApi;
|
||||||
import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
|
import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
|
||||||
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
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.sku.dto.ProductSkuRespDTO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO;
|
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.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO;
|
||||||
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.enums.delivery.DeliveryExpressChargeModeEnum;
|
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
|
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.DeliveryExpressTemplateService;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO;
|
||||||
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
|
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;
|
||||||
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO.OrderItem;
|
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO.OrderItem;
|
||||||
@ -19,7 +19,6 @@ import org.springframework.core.annotation.Order;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -39,14 +38,8 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
|
|||||||
private AddressApi addressApi;
|
private AddressApi addressApi;
|
||||||
@Resource
|
@Resource
|
||||||
private ProductSkuApi productSkuApi;
|
private ProductSkuApi productSkuApi;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private DeliveryExpressTemplateService deliveryExpressTemplateService;
|
private DeliveryExpressTemplateService deliveryExpressTemplateService;
|
||||||
// TODO @jason:走 Service 哈。Mapper 只允许自己的 Service 调用,保护好数据结构;
|
|
||||||
@Resource
|
|
||||||
private DeliveryExpressTemplateChargeMapper templateChargeMapper;
|
|
||||||
@Resource
|
|
||||||
private DeliveryExpressTemplateFreeMapper templateFreeMapper;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
|
public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
|
||||||
@ -54,66 +47,45 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
|
|||||||
if (param.getDeliveryType() == null || DeliveryTypeEnum.PICK_UP.getMode().equals(param.getDeliveryType())) {
|
if (param.getDeliveryType() == null || DeliveryTypeEnum.PICK_UP.getMode().equals(param.getDeliveryType())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 1.2 得到收件地址区域
|
||||||
if (param.getTemplateId() == null || param.getAddressId() == null) {
|
if (param.getAddressId() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 1.2 校验运费模板是否存在
|
|
||||||
DeliveryExpressTemplateDO template = deliveryExpressTemplateService.validateDeliveryExpressTemplate(param.getTemplateId());
|
|
||||||
|
|
||||||
// 得到包邮配置
|
|
||||||
List<DeliveryExpressTemplateFreeDO> expressTemplateFreeList = templateFreeMapper.selectListByTemplateId(template.getId());
|
|
||||||
Map<Integer, DeliveryExpressTemplateFreeDO> areaTemplateFreeMap = new HashMap<>();
|
|
||||||
expressTemplateFreeList.forEach(item -> {
|
|
||||||
for (Integer areaId : item.getAreaIds()) {
|
|
||||||
// TODO 需要保证 areaId 不能重复
|
|
||||||
if (!areaTemplateFreeMap.containsKey(areaId)) {
|
|
||||||
areaTemplateFreeMap.put(areaId, item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 得到快递运费配置
|
|
||||||
List<DeliveryExpressTemplateChargeDO> expressTemplateChargeList = templateChargeMapper.selectListByTemplateId(template.getId());
|
|
||||||
Map<Integer, DeliveryExpressTemplateChargeDO> areaTemplateChargeMap = new HashMap<>();
|
|
||||||
expressTemplateChargeList.forEach(item -> {
|
|
||||||
for (Integer areaId : item.getAreaIds()) {
|
|
||||||
// areaId 不能重复
|
|
||||||
if (!areaTemplateChargeMap.containsKey(areaId)) {
|
|
||||||
areaTemplateChargeMap.put(areaId, item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 得到收件地址区域
|
|
||||||
AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId());
|
AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId());
|
||||||
// 1.3 计算快递费用
|
Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId());
|
||||||
calculateDeliveryPrice(address.getAreaId(), template.getChargeMode(),
|
|
||||||
areaTemplateFreeMap, areaTemplateChargeMap, result);
|
//1.3 过滤出已选中的商品SKU
|
||||||
|
List<OrderItem> selectedItem = filterList(result.getItems(), OrderItem::getSelected);
|
||||||
|
|
||||||
|
Map<Long, SpuDeliveryExpressTemplateRespBO> spuExpressTemplateMap =
|
||||||
|
deliveryExpressTemplateService.getExpressTemplateBySpuIdsAndArea(
|
||||||
|
convertSet(selectedItem, OrderItem::getSpuId), address.getAreaId());
|
||||||
|
|
||||||
|
// 1.4 计算配送费用
|
||||||
|
if (CollUtil.isNotEmpty(spuExpressTemplateMap)) {
|
||||||
|
calculateDeliveryPrice(selectedItem, spuExpressTemplateMap, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
}
|
||||||
* 校验订单是否满足包邮条件
|
|
||||||
*
|
private void calculateDeliveryPrice(List<OrderItem> selectedSkus,
|
||||||
* @param receiverAreaId 收件人地区的区域编号
|
Map<Long, SpuDeliveryExpressTemplateRespBO> spuExpressTemplateMap,
|
||||||
* @param chargeMode 配送计费方式
|
|
||||||
* @param areaTemplateFreeMap 运费模板包邮区域设置 Map
|
|
||||||
* @param areaTemplateChargeMap 运费模板快递费用设置 Map
|
|
||||||
*/
|
|
||||||
private void calculateDeliveryPrice(Integer receiverAreaId,
|
|
||||||
Integer chargeMode,
|
|
||||||
Map<Integer, DeliveryExpressTemplateFreeDO> areaTemplateFreeMap,
|
|
||||||
Map<Integer, DeliveryExpressTemplateChargeDO> areaTemplateChargeMap,
|
|
||||||
TradePriceCalculateRespBO result) {
|
TradePriceCalculateRespBO result) {
|
||||||
// 过滤出已选中的商品SKU
|
Set<Long> skuIds = convertSet(selectedSkus, OrderItem::getSkuId);
|
||||||
List<OrderItem> selectedItem = filterList(result.getItems(), OrderItem::getSelected);
|
|
||||||
Set<Long> skuIds = convertSet(selectedItem, OrderItem::getSkuId);
|
|
||||||
// 得到SKU 详情。得到 重量体积
|
// 得到SKU 详情。得到 重量体积
|
||||||
Map<Long, ProductSkuRespDTO> skuRespMap = convertMap(productSkuApi.getSkuList(skuIds), ProductSkuRespDTO::getId);
|
Map<Long, ProductSkuRespDTO> skuRespMap = convertMap(productSkuApi.getSkuList(skuIds), ProductSkuRespDTO::getId);
|
||||||
// 一个 spuId 可能对应多条订单商品 SKU
|
// 按spu 来计算商品的运费 一个 spuId 可能对应多条订单商品 SKU,
|
||||||
// TODO @jason:得确认下,按照 sku 算,还是 spu 算;
|
Map<Long, List<OrderItem>> spuIdItemMap = convertMultiMap(selectedSkus, OrderItem::getSpuId);
|
||||||
Map<Long, List<OrderItem>> spuIdItemMap = convertMultiMap(selectedItem, OrderItem::getSpuId);
|
|
||||||
// 依次计算每个 SPU 的快递运费
|
// 依次计算每个 SPU 的快递运费
|
||||||
for (Map.Entry<Long, List<OrderItem>> entry : spuIdItemMap.entrySet()) {
|
for (Map.Entry<Long, List<OrderItem>> entry : spuIdItemMap.entrySet()) {
|
||||||
|
Long spuId = entry.getKey();
|
||||||
List<OrderItem> orderItems = entry.getValue();
|
List<OrderItem> orderItems = entry.getValue();
|
||||||
|
SpuDeliveryExpressTemplateRespBO templateBO = spuExpressTemplateMap.get(spuId);
|
||||||
|
if (templateBO == null) {
|
||||||
|
// 记录错误日志
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// 总件数, 总金额, 总重量, 总体积
|
// 总件数, 总金额, 总重量, 总体积
|
||||||
int totalCount = 0;
|
int totalCount = 0;
|
||||||
int totalPrice = 0;
|
int totalPrice = 0;
|
||||||
@ -121,51 +93,67 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
|
|||||||
double totalVolume = 0;
|
double totalVolume = 0;
|
||||||
for (OrderItem orderItem : orderItems) {
|
for (OrderItem orderItem : orderItems) {
|
||||||
totalCount += orderItem.getCount();
|
totalCount += orderItem.getCount();
|
||||||
totalPrice += orderItem.getPrice(); // TODO jason:应该按照 payPrice?
|
totalPrice += orderItem.getPayPrice(); // 先按应付总金额来算,后面确认一下
|
||||||
ProductSkuRespDTO skuResp = skuRespMap.get(orderItem.getSkuId());
|
ProductSkuRespDTO skuResp = skuRespMap.get(orderItem.getSkuId());
|
||||||
if (skuResp != null) {
|
if (skuResp != null) {
|
||||||
totalWeight = totalWeight + skuResp.getWeight(); // TODO @jason:* 数量
|
totalWeight = totalWeight + skuResp.getWeight() * orderItem.getCount();
|
||||||
totalVolume = totalVolume + skuResp.getVolume();
|
totalVolume = totalVolume + skuResp.getVolume() * orderItem.getCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 优先判断是否包邮. 如果包邮不计算快递运费
|
// 优先判断是否包邮. 如果包邮不计算快递运费
|
||||||
if (areaTemplateFreeMap.containsKey(receiverAreaId) &&
|
if (checkExpressFree(templateBO.getChargeMode(), totalCount, totalWeight,
|
||||||
checkExpressFree(chargeMode, totalCount, totalWeight,
|
totalVolume, totalPrice, templateBO.getTemplateFree())) {
|
||||||
totalVolume, totalPrice, areaTemplateFreeMap.get(receiverAreaId))) {
|
continue;
|
||||||
|
}
|
||||||
|
if (templateBO.getTemplateCharge() == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 计算快递运费
|
// 计算快递运费
|
||||||
// TODO @jason:貌似也可以抽成 checkExpressFree 类似方法
|
calculateExpressFeeByChargeMode(totalCount, totalWeight, totalVolume,
|
||||||
if (areaTemplateChargeMap.containsKey(receiverAreaId)) {
|
templateBO.getChargeMode(), templateBO.getTemplateCharge(), orderItems);
|
||||||
DeliveryExpressTemplateChargeDO templateCharge = areaTemplateChargeMap.get(receiverAreaId);
|
|
||||||
DeliveryExpressChargeModeEnum chargeModeEnum = DeliveryExpressChargeModeEnum.valueOf(chargeMode);
|
|
||||||
switch (chargeModeEnum) {
|
|
||||||
case PIECE: {
|
|
||||||
calculateExpressFeeBySpu(totalCount, templateCharge, orderItems);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WEIGHT: {
|
|
||||||
calculateExpressFeeBySpu(totalWeight, templateCharge, orderItems);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VOLUME: {
|
|
||||||
calculateExpressFeeBySpu(totalVolume, templateCharge, orderItems);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
TradePriceCalculatorHelper.recountAllPrice(result);
|
TradePriceCalculatorHelper.recountAllPrice(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按 spu 来计算快递费用
|
* 按配送方式来计算运费
|
||||||
|
*
|
||||||
|
* @param totalCount 总件数
|
||||||
|
* @param totalWeight 总重量
|
||||||
|
* @param totalVolume 总体积
|
||||||
|
* @param chargeMode 配送计费方式
|
||||||
|
* @param templateCharge 快递运费配置
|
||||||
|
* @param orderItems SKU 商品项目
|
||||||
|
*/
|
||||||
|
private void calculateExpressFeeByChargeMode(double totalCount, double totalWeight, double totalVolume,
|
||||||
|
int chargeMode, DeliveryExpressTemplateChargeDO templateCharge,
|
||||||
|
List<OrderItem> orderItems) {
|
||||||
|
DeliveryExpressChargeModeEnum chargeModeEnum = DeliveryExpressChargeModeEnum.valueOf(chargeMode);
|
||||||
|
switch (chargeModeEnum) {
|
||||||
|
case PIECE: {
|
||||||
|
calculateExpressFee(totalCount, templateCharge, orderItems);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WEIGHT: {
|
||||||
|
calculateExpressFee(totalWeight, templateCharge, orderItems);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VOLUME: {
|
||||||
|
calculateExpressFee(totalVolume, templateCharge, orderItems);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算 SKU 商品快递费用
|
||||||
*
|
*
|
||||||
* @param total 总件数/总重量/总体积
|
* @param total 总件数/总重量/总体积
|
||||||
* @param templateCharge 快递运费配置
|
* @param templateCharge 快递运费配置
|
||||||
* @param orderItems SKU 商品项目
|
* @param orderItems SKU 商品项目
|
||||||
*/
|
*/
|
||||||
private void calculateExpressFeeBySpu(double total, DeliveryExpressTemplateChargeDO templateCharge, List<OrderItem> orderItems) {
|
private void calculateExpressFee(double total, DeliveryExpressTemplateChargeDO templateCharge, List<OrderItem> orderItems) {
|
||||||
int deliveryPrice;
|
int deliveryPrice;
|
||||||
if (total <= templateCharge.getStartCount()) {
|
if (total <= templateCharge.getStartCount()) {
|
||||||
deliveryPrice = templateCharge.getStartPrice();
|
deliveryPrice = templateCharge.getStartPrice();
|
||||||
@ -176,8 +164,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
|
|||||||
int extraPrice = templateCharge.getExtraPrice() * extraNum;
|
int extraPrice = templateCharge.getExtraPrice() * extraNum;
|
||||||
deliveryPrice = templateCharge.getStartPrice() + extraPrice;
|
deliveryPrice = templateCharge.getStartPrice() + extraPrice;
|
||||||
}
|
}
|
||||||
// TODO @芋艿 分摊快递费用到 SKU. 是不是搞复杂了;
|
// 分摊快递费用到 SKU. 退费的时候,可能按照 SKU 考虑退费金额
|
||||||
// TODO @jason:因为退费的时候,可能按照 SKU 考虑退费金额
|
|
||||||
divideDeliveryPrice(deliveryPrice, orderItems);
|
divideDeliveryPrice(deliveryPrice, orderItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,6 +194,9 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
|
|||||||
*/
|
*/
|
||||||
private boolean checkExpressFree(Integer chargeMode, int totalCount, double totalWeight,
|
private boolean checkExpressFree(Integer chargeMode, int totalCount, double totalWeight,
|
||||||
double totalVolume, int totalPrice, DeliveryExpressTemplateFreeDO templateFree) {
|
double totalVolume, int totalPrice, DeliveryExpressTemplateFreeDO templateFree) {
|
||||||
|
if (templateFree == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
DeliveryExpressChargeModeEnum chargeModeEnum = DeliveryExpressChargeModeEnum.valueOf(chargeMode);
|
DeliveryExpressChargeModeEnum chargeModeEnum = DeliveryExpressChargeModeEnum.valueOf(chargeMode);
|
||||||
switch (chargeModeEnum) {
|
switch (chargeModeEnum) {
|
||||||
case PIECE:
|
case PIECE:
|
||||||
|
Loading…
Reference in New Issue
Block a user