mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 15:21:53 +08:00
mall + trade:review 物流计算
This commit is contained in:
parent
f2d803c111
commit
25bea4920c
@ -83,10 +83,11 @@ public interface DeliveryExpressTemplateService {
|
||||
*/
|
||||
DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId);
|
||||
|
||||
// TODO @jason 方法名可以改成 getExpressTemplateMapBySpuIdsAndArea
|
||||
/**
|
||||
* 基于指定的 SPU 编号数组和收件人地址区域编号. 获取匹配运费模板
|
||||
*
|
||||
* @param ids SPU 编号列表
|
||||
* @param ids SPU 编号列表 // TODO @jason:模版编号?
|
||||
* @param areaId 区域编号
|
||||
* @return Map (spuId -> 运费模板设置)
|
||||
*/
|
||||
|
@ -5,7 +5,10 @@ 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.*;
|
||||
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;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateUpdateReqVO;
|
||||
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;
|
||||
@ -234,14 +237,16 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla
|
||||
List<DeliveryExpressTemplateDO> templateList = expressTemplateMapper.selectBatchIds(spuMap.keySet());
|
||||
Map<Long, SpuDeliveryExpressTemplateRespBO> result = new HashMap<>(templateList.size());
|
||||
templateList.forEach(item -> {
|
||||
// TODO @jason:if return ,更简洁哈;
|
||||
if (spuMap.containsKey(item.getId())) {
|
||||
ProductSpuRespDTO spuDTO = spuMap.get(item.getId());
|
||||
ProductSpuRespDTO spu = spuMap.get(item.getId());
|
||||
SpuDeliveryExpressTemplateRespBO bo = new SpuDeliveryExpressTemplateRespBO()
|
||||
.setSpuId(spuDTO.getId()).setAreaId(areaId)
|
||||
.setSpuId(spu.getId()).setAreaId(areaId)
|
||||
.setChargeMode(item.getChargeMode())
|
||||
// TODO @jason:是不是只要查询到一个,就不用查询下一个了;TemplateCharge 和 TemplateFree
|
||||
.setTemplateCharge(findMatchExpressTemplateCharge(item.getId(), areaId))
|
||||
.setTemplateFree(findMatchExpressTemplateFree(item.getId(), areaId));
|
||||
result.put(spuDTO.getId(), bo);
|
||||
result.put(spu.getId(), bo);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
@ -249,6 +254,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla
|
||||
|
||||
private DeliveryExpressTemplateChargeDO findMatchExpressTemplateCharge(Long templateId, Integer areaId) {
|
||||
List<DeliveryExpressTemplateChargeDO> list = expressTemplateChargeMapper.selectListByTemplateId(templateId);
|
||||
// TODO @jason:可以使用 CollectionUtils.findFirst()
|
||||
for (DeliveryExpressTemplateChargeDO item : list) {
|
||||
// 第一个匹配的返回。 areaId 不能重复
|
||||
if (item.getAreaIds().contains(areaId)) {
|
||||
@ -260,6 +266,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla
|
||||
|
||||
private DeliveryExpressTemplateFreeDO findMatchExpressTemplateFree(Long templateId, Integer areaId) {
|
||||
List<DeliveryExpressTemplateFreeDO> list = expressTemplateFreeMapper.selectListByTemplateId(templateId);
|
||||
// TODO @jason:可以使用 CollectionUtils.findFirst()
|
||||
for (DeliveryExpressTemplateFreeDO item : list) {
|
||||
// 第一个匹配的返回。 areaId 不能重复
|
||||
if (item.getAreaIds().contains(areaId)) {
|
||||
|
@ -13,9 +13,11 @@ import lombok.Data;
|
||||
@Data
|
||||
public class SpuDeliveryExpressTemplateRespBO {
|
||||
|
||||
// TODO @jason:是不是可以简单一点;是否包邮;然后直接把 templateCharge、templateFree 需要的字段平铺开
|
||||
|
||||
/**
|
||||
* 配送计费方式
|
||||
* <p>
|
||||
*
|
||||
* 枚举 {@link DeliveryExpressChargeModeEnum}
|
||||
*/
|
||||
private Integer chargeMode;
|
||||
@ -30,6 +32,7 @@ public class SpuDeliveryExpressTemplateRespBO {
|
||||
*/
|
||||
private DeliveryExpressTemplateFreeDO templateFree;
|
||||
|
||||
// TODO @jason:下面两个字段不用返回也可以呀
|
||||
/**
|
||||
* SPU 编号
|
||||
* <p>
|
||||
|
@ -54,33 +54,34 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
|
||||
AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId());
|
||||
Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId());
|
||||
|
||||
//1.3 过滤出已选中的商品SKU
|
||||
// 2. 过滤出已选中的商品SKU
|
||||
List<OrderItem> selectedItem = filterList(result.getItems(), OrderItem::getSelected);
|
||||
|
||||
Set<Long> spuIds = convertSet(selectedItem, OrderItem::getSpuId);
|
||||
Map<Long, SpuDeliveryExpressTemplateRespBO> spuExpressTemplateMap =
|
||||
deliveryExpressTemplateService.getExpressTemplateBySpuIdsAndArea(
|
||||
convertSet(selectedItem, OrderItem::getSpuId), address.getAreaId());
|
||||
deliveryExpressTemplateService.getExpressTemplateBySpuIdsAndArea(spuIds, address.getAreaId());
|
||||
|
||||
// 1.4 计算配送费用
|
||||
// 3. 计算配送费用
|
||||
// TODO @jason:这里应该不能判断空;如果找不到模版,就要报错;不然配送费就亏了
|
||||
if (CollUtil.isNotEmpty(spuExpressTemplateMap)) {
|
||||
calculateDeliveryPrice(selectedItem, spuExpressTemplateMap, result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void calculateDeliveryPrice(List<OrderItem> selectedSkus,
|
||||
Map<Long, SpuDeliveryExpressTemplateRespBO> spuExpressTemplateMap,
|
||||
TradePriceCalculateRespBO result) {
|
||||
// 得到 SKU 详情
|
||||
// TODO @jason:可以去掉这里的读取;在 TradePriceCalculateRespBO 初始化的时候,把 weight、volume 拿到
|
||||
Set<Long> skuIds = convertSet(selectedSkus, OrderItem::getSkuId);
|
||||
// 得到SKU 详情。得到 重量体积
|
||||
Map<Long, ProductSkuRespDTO> skuRespMap = convertMap(productSkuApi.getSkuList(skuIds), ProductSkuRespDTO::getId);
|
||||
// 按spu 来计算商品的运费 一个 spuId 可能对应多条订单商品 SKU,
|
||||
// 按 SPU 来计算商品的运费:一个 spuId 可能对应多条订单商品 SKU
|
||||
Map<Long, List<OrderItem>> spuIdItemMap = convertMultiMap(selectedSkus, OrderItem::getSpuId);
|
||||
|
||||
// 依次计算每个 SPU 的快递运费
|
||||
for (Map.Entry<Long, List<OrderItem>> entry : spuIdItemMap.entrySet()) {
|
||||
Long spuId = entry.getKey();
|
||||
List<OrderItem> orderItems = entry.getValue();
|
||||
// TODO @jason:如果找不到,则打印 error log
|
||||
SpuDeliveryExpressTemplateRespBO templateBO = spuExpressTemplateMap.get(spuId);
|
||||
if (templateBO == null) {
|
||||
// 记录错误日志
|
||||
@ -93,18 +94,18 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
|
||||
double totalVolume = 0;
|
||||
for (OrderItem orderItem : orderItems) {
|
||||
totalCount += orderItem.getCount();
|
||||
totalPrice += orderItem.getPayPrice(); // 先按应付总金额来算,后面确认一下
|
||||
totalPrice += orderItem.getPayPrice(); // 先按应付总金额来算,后面确认一下 TODO @jason:是的哈
|
||||
ProductSkuRespDTO skuResp = skuRespMap.get(orderItem.getSkuId());
|
||||
if (skuResp != null) {
|
||||
totalWeight = totalWeight + skuResp.getWeight() * orderItem.getCount();
|
||||
totalVolume = totalVolume + skuResp.getVolume() * orderItem.getCount();
|
||||
}
|
||||
// TODO @jason:是不是要保持风格统一,都用 +=
|
||||
totalWeight = totalWeight + skuResp.getWeight() * orderItem.getCount();
|
||||
totalVolume = totalVolume + skuResp.getVolume() * orderItem.getCount();
|
||||
}
|
||||
// 优先判断是否包邮. 如果包邮不计算快递运费
|
||||
if (checkExpressFree(templateBO.getChargeMode(), totalCount, totalWeight,
|
||||
totalVolume, totalPrice, templateBO.getTemplateFree())) {
|
||||
continue;
|
||||
}
|
||||
// TODO @jason:这块判断,可以收到 calculateExpressFeeByChargeMode 里;另外找不到,要打 error log
|
||||
if (templateBO.getTemplateCharge() == null) {
|
||||
continue;
|
||||
}
|
||||
@ -175,6 +176,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
|
||||
* @param orderItems SKU 商品
|
||||
*/
|
||||
private void divideDeliveryPrice(int deliveryPrice, List<OrderItem> orderItems) {
|
||||
// TODO @jason:分摊的话,是不是要按照比例呀?重量、价格、数量等等
|
||||
int dividePrice = deliveryPrice / orderItems.size();
|
||||
for (OrderItem item : orderItems) {
|
||||
// 更新快递运费
|
||||
@ -192,6 +194,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
|
||||
* @param totalPrice 总金额
|
||||
* @param templateFree 包邮配置
|
||||
*/
|
||||
// TODO @jason:isExpressFree 更合适;因为 check 是一种校验,往往抛出异常;
|
||||
private boolean checkExpressFree(Integer chargeMode, int totalCount, double totalWeight,
|
||||
double totalVolume, int totalPrice, DeliveryExpressTemplateFreeDO templateFree) {
|
||||
if (templateFree == null) {
|
||||
@ -206,7 +209,8 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
|
||||
}
|
||||
break;
|
||||
case WEIGHT:
|
||||
// freeCount 是不是应该是 double ??
|
||||
// freeCount 是不是应该是 double ??
|
||||
// TODO @jason:要不配置的时候,把它的单位和商品对齐?到底是 kg、还是斤
|
||||
if (totalWeight >= templateFree.getFreeCount()
|
||||
&& totalPrice >= templateFree.getFreePrice()) {
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user