Commit 8d13ecc9c89014c336c92269249da23e948aa410

Authored by puhui999
1 parent f23e1b85

fix:优化订单发货逻辑使其支持一单分发

yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApi.java
@@ -19,6 +19,14 @@ public interface CombinationApi { @@ -19,6 +19,14 @@ public interface CombinationApi {
19 void createRecord(@Valid CombinationRecordReqDTO reqDTO); 19 void createRecord(@Valid CombinationRecordReqDTO reqDTO);
20 20
21 /** 21 /**
  22 + * 获取开团记录状态
  23 + *
  24 + * @param userId 用户编号
  25 + * @param orderId 订单编号
  26 + */
  27 + Integer getRecordStatus(Long userId, Long orderId);
  28 +
  29 + /**
22 * 更新开团记录状态 30 * 更新开团记录状态
23 * 31 *
24 * @param userId 用户编号 32 * @param userId 用户编号
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java
@@ -23,6 +23,11 @@ public class CombinationApiImpl implements CombinationApi { @@ -23,6 +23,11 @@ public class CombinationApiImpl implements CombinationApi {
23 } 23 }
24 24
25 @Override 25 @Override
  26 + public Integer getRecordStatus(Long userId, Long orderId) {
  27 + return activityService.getRecordStatus(userId, orderId);
  28 + }
  29 +
  30 + @Override
26 public void updateRecordStatus(Long userId, Long orderId, Integer status) { 31 public void updateRecordStatus(Long userId, Long orderId, Integer status) {
27 activityService.updateRecordStatusByUserIdAndOrderId(userId, orderId, status); 32 activityService.updateRecordStatusByUserIdAndOrderId(userId, orderId, status);
28 } 33 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java
@@ -109,4 +109,12 @@ public interface CombinationActivityService { @@ -109,4 +109,12 @@ public interface CombinationActivityService {
109 */ 109 */
110 void createRecord(CombinationRecordReqDTO reqDTO); 110 void createRecord(CombinationRecordReqDTO reqDTO);
111 111
  112 + /**
  113 + * 获得拼团状态
  114 + *
  115 + * @param userId 用户编号
  116 + * @param orderId 订单编号
  117 + * @return 拼团状态
  118 + */
  119 + Integer getRecordStatus(Long userId, Long orderId);
112 } 120 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
@@ -248,4 +248,10 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic @@ -248,4 +248,10 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
248 recordMapper.insert(recordDO); 248 recordMapper.insert(recordDO);
249 } 249 }
250 250
  251 + @Override
  252 + public Integer getRecordStatus(Long userId, Long orderId) {
  253 + CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId);
  254 + return recordDO.getStatus();
  255 + }
  256 +
251 } 257 }
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
@@ -28,8 +28,9 @@ public interface ErrorCodeConstants { @@ -28,8 +28,9 @@ public interface ErrorCodeConstants {
28 ErrorCode ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED = new ErrorCode(1011000017, "交易订单发货失败,订单不是【待发货】状态"); 28 ErrorCode ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED = new ErrorCode(1011000017, "交易订单发货失败,订单不是【待发货】状态");
29 ErrorCode ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED = new ErrorCode(1011000018, "交易订单收货失败,订单不是【待收货】状态"); 29 ErrorCode ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED = new ErrorCode(1011000018, "交易订单收货失败,订单不是【待收货】状态");
30 ErrorCode ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED = new ErrorCode(1011000019, "创建交易订单项的评价失败,订单不是【已完成】状态"); 30 ErrorCode ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED = new ErrorCode(1011000019, "创建交易订单项的评价失败,订单不是【已完成】状态");
31 - ErrorCode ORDER_COMMENT_STATUS_NOT_FALSE = new ErrorCode(1011000019, "创建交易订单项的评价失败,订单已评价");  
32 - ErrorCode ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE = new ErrorCode(1011000017, "交易订单发货失败,订单已退款或部分退款"); 31 + ErrorCode ORDER_COMMENT_STATUS_NOT_FALSE = new ErrorCode(1011000020, "创建交易订单项的评价失败,订单已评价");
  32 + ErrorCode ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE = new ErrorCode(1011000021, "交易订单发货失败,订单已退款或部分退款");
  33 + ErrorCode ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS = new ErrorCode(1011000022, "交易订单发货失败,拼团未成功");
33 34
34 // ========== After Sale 模块 1011000100 ========== 35 // ========== After Sale 模块 1011000100 ==========
35 ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在"); 36 ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在");
@@ -66,8 +67,10 @@ public interface ErrorCodeConstants { @@ -66,8 +67,10 @@ public interface ErrorCodeConstants {
66 ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011005001, "运费模板不存在"); 67 ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011005001, "运费模板不存在");
67 68
68 // ========== 物流 PICK_UP 模块 1011006000 ========== 69 // ========== 物流 PICK_UP 模块 1011006000 ==========
69 -  
70 ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011006000, "自提门店不存在"); 70 ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011006000, "自提门店不存在");
71 71
72 - 72 + // ========== 物流 PICK_UP 模块 1011007000 ==========
  73 + ErrorCode ORDER_DELIVERY_FAILED_ITEMS_NOT_EMPTY = new ErrorCode(1011007000, "订单发货失败,请选择发货商品");
  74 + ErrorCode ORDER_DELIVERY_FAILED_ITEM_NOT_EXISTS = new ErrorCode(1011007001, "订单发货失败,所选发货商品不存在");
  75 + ErrorCode ORDER_DELIVERY_FAILED_ITEM_ALREADY_DELIVERY = new ErrorCode(1011007001, "订单发货失败,所选商品已发货");
73 } 76 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java
@@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema; @@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
6 import lombok.Data; 6 import lombok.Data;
7 7
8 import javax.validation.constraints.NotNull; 8 import javax.validation.constraints.NotNull;
  9 +import java.util.List;
9 10
10 @Schema(description = "管理后台 - 订单发货 Request VO") 11 @Schema(description = "管理后台 - 订单发货 Request VO")
11 @Data 12 @Data
@@ -26,6 +27,12 @@ public class TradeOrderDeliveryReqVO { @@ -26,6 +27,12 @@ public class TradeOrderDeliveryReqVO {
26 @Schema(description = "发货物流单号", example = "SF123456789") 27 @Schema(description = "发货物流单号", example = "SF123456789")
27 private String logisticsNo; 28 private String logisticsNo;
28 29
  30 + // TODO 订单项商品单独发货
  31 +
  32 + @Schema(description = "发货订单项", example = "[1,2,3]")
  33 + @NotNull(message = "发货订单项不能为空")
  34 + private List<Long> orderItemIds;
  35 +
29 // =============== 同城配送 ================ 36 // =============== 同城配送 ================
30 // TODO 37 // TODO
31 38
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
@@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; @@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;
18 import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; 18 import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
19 import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; 19 import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
20 import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; 20 import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
  21 +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
21 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO; 22 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO;
22 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO; 23 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO;
23 import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; 24 import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO;
@@ -26,6 +27,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderI @@ -26,6 +27,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderI
26 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; 27 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
27 import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; 28 import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
28 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 29 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
  30 +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDeliveryDO;
29 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; 31 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
30 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; 32 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
31 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; 33 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
@@ -334,4 +336,15 @@ public interface TradeOrderConvert { @@ -334,4 +336,15 @@ public interface TradeOrderConvert {
334 }) 336 })
335 CombinationRecordReqDTO convert(TradeOrderDO order, TradeOrderItemDO orderItem, AppTradeOrderCreateReqVO createReqVO, MemberUserRespDTO user); 337 CombinationRecordReqDTO convert(TradeOrderDO order, TradeOrderItemDO orderItem, AppTradeOrderCreateReqVO createReqVO, MemberUserRespDTO user);
336 338
  339 + TradeOrderDeliveryDO covert(Long orderId, Long orderItemId, Long userId, Integer deliveryType, Long logisticsId, String logisticsNo);
  340 +
  341 + default List<TradeOrderDeliveryDO> covert(TradeOrderDO order, TradeOrderDeliveryReqVO deliveryReqVO) {
  342 + ArrayList<TradeOrderDeliveryDO> arrayList = new ArrayList<>();
  343 + deliveryReqVO.getOrderItemIds().forEach(item -> {
  344 + arrayList.add(covert(order.getId(), item, order.getUserId(), deliveryReqVO.getType(),
  345 + deliveryReqVO.getLogisticsId(), deliveryReqVO.getLogisticsNo()));
  346 + });
  347 + return arrayList;
  348 + }
  349 +
337 } 350 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDeliveryDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.dal.dataobject.order;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +
  10 +/**
  11 + * 交易订单发货记录 DO
  12 + *
  13 + * @author HUIHUI
  14 + */
  15 +@TableName("trade_order_delivery")
  16 +@KeySequence("trade_order_delivery_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +@Builder
  21 +@NoArgsConstructor
  22 +@AllArgsConstructor
  23 +public class TradeOrderDeliveryDO extends BaseDO {
  24 +
  25 + /**
  26 + * 订单发货记录 id
  27 + */
  28 + private Long id;
  29 + /**
  30 + * 订单 id
  31 + */
  32 + private Long orderId;
  33 + /**
  34 + * 订单项 id TODO 要不要一个发货记录可对应多个订单项?
  35 + */
  36 + private Long orderItemId;
  37 + /**
  38 + * 用户编号
  39 + *
  40 + * 关联 MemberUserDO 的 id 编号
  41 + */
  42 + private Long userId;
  43 + /**
  44 + * 配送方式
  45 + *
  46 + * 枚举 {@link DeliveryTypeEnum}
  47 + */
  48 + private Integer deliveryType;
  49 + /**
  50 + * 发货物流公司编号
  51 + */
  52 + private Long logisticsId;
  53 + /**
  54 + * 发货物流单号
  55 + */
  56 + private String logisticsNo;
  57 +
  58 + // TODO 同城配送
  59 +
  60 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderDeliveryMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.dal.mysql.order;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDeliveryDO;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * 交易订单发货记录 Mapper
  12 + *
  13 + * @author HUIHUI
  14 + */
  15 +@Mapper
  16 +public interface TradeOrderDeliveryMapper extends BaseMapperX<TradeOrderDeliveryDO> {
  17 +
  18 + default List<TradeOrderDeliveryDO> selsectListByOrderIdAndItemIds(Long orderId, List<Long> orderItemIds) {
  19 + return selectList(new LambdaQueryWrapperX<TradeOrderDeliveryDO>()
  20 + .eq(TradeOrderDeliveryDO::getOrderId, orderId).in(TradeOrderDeliveryDO::getOrderItemId, orderItemIds));
  21 + }
  22 +
  23 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
@@ -38,7 +38,9 @@ import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; @@ -38,7 +38,9 @@ import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
38 import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; 38 import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
39 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; 39 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
40 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 40 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
  41 +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDeliveryDO;
41 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; 42 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
  43 +import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderDeliveryMapper;
42 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; 44 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper;
43 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; 45 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper;
44 import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants; 46 import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants;
@@ -107,6 +109,8 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -107,6 +109,8 @@ public class TradeOrderServiceImpl implements TradeOrderService {
107 109
108 @Resource 110 @Resource
109 private CombinationApi combinationApi; 111 private CombinationApi combinationApi;
  112 + @Resource
  113 + private TradeOrderDeliveryMapper orderDeliveryMapper;
110 // =================== Order =================== 114 // =================== Order ===================
111 115
112 @Override 116 @Override
@@ -243,7 +247,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -243,7 +247,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
243 247
244 /** 248 /**
245 * 执行创建完创建完订单后的逻辑 249 * 执行创建完创建完订单后的逻辑
246 - * <p> 250 + *
247 * 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等 251 * 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等
248 * 252 *
249 * @param userId 用户编号 253 * @param userId 用户编号
@@ -256,7 +260,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -256,7 +260,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
256 TradePriceCalculateRespBO calculateRespBO) { 260 TradePriceCalculateRespBO calculateRespBO) {
257 // 下单时扣减商品库存 261 // 下单时扣减商品库存
258 productSkuApi.updateSkuStock(new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(orderItems))); 262 productSkuApi.updateSkuStock(new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(orderItems)));
259 - 263 + // TODO puhui:扣减活动库存
260 // 删除购物车商品 TODO 芋艿:待实现 264 // 删除购物车商品 TODO 芋艿:待实现
261 265
262 // 扣减积分,抵扣金额 TODO 芋艿:待实现 266 // 扣减积分,抵扣金额 TODO 芋艿:待实现
@@ -267,7 +271,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -267,7 +271,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
267 .setOrderId(tradeOrderDO.getId())); 271 .setOrderId(tradeOrderDO.getId()));
268 } 272 }
269 273
270 - // 生成预支付 274 + // 生成预支付 TODO puhui: 活动支付金额怎么算?
271 createPayOrder(tradeOrderDO, orderItems, calculateRespBO); 275 createPayOrder(tradeOrderDO, orderItems, calculateRespBO);
272 276
273 // 增加订单日志 TODO 芋艿:待实现 277 // 增加订单日志 TODO 芋艿:待实现
@@ -313,7 +317,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -313,7 +317,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
313 317
314 /** 318 /**
315 * 校验交易订单满足被支付的条件 319 * 校验交易订单满足被支付的条件
316 - * <p> 320 + *
317 * 1. 交易订单未支付 321 * 1. 交易订单未支付
318 * 2. 支付单已支付 322 * 2. 支付单已支付
319 * 323 *
@@ -367,29 +371,50 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -367,29 +371,50 @@ public class TradeOrderServiceImpl implements TradeOrderService {
367 return new KeyValue<>(order, payOrder); 371 return new KeyValue<>(order, payOrder);
368 } 372 }
369 373
370 - // TODO 芋艿:如果无需发货,需要怎么存储? fix:更改订单发货类型为无需发货更改发货类型为等待自提,等待用户自提后更改订单状态为已完成  
371 @Override 374 @Override
  375 + @Transactional(rollbackFor = Exception.class)
372 public void deliveryOrder(Long userId, TradeOrderDeliveryReqVO deliveryReqVO) { 376 public void deliveryOrder(Long userId, TradeOrderDeliveryReqVO deliveryReqVO) {
373 // 校验并获得交易订单(可发货) 377 // 校验并获得交易订单(可发货)
374 TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId()); 378 TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId());
375 - // TODO 判断发货类型,根据发货类型发货  
376 - DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId());  
377 - if (deliveryExpress == null) {  
378 - throw exception(EXPRESS_NOT_EXISTS); 379 +
  380 + TradeOrderDO tradeOrderDO = new TradeOrderDO();
  381 + List<TradeOrderDeliveryDO> deliveryDOs = new ArrayList<>();
  382 + /* TODO
  383 + * fix: 首先需要店铺设置配送方式如: 自提 、配送、物流-配送、物流-配送-自提、商家配送
  384 + * 1.如果店铺有设置配送方式用户只填写收货地址的情况下店家后台自己选择配送方式
  385 + * 2.如果店铺只支持到店自提那么下单后默认发货不需要物流
  386 + * 3.如果店铺支持 物流-配送-自提 的情况下后台不需要选择配送方式按前端用户选择的配送方式发货即可
  387 + */
  388 + // 判断发货类型
  389 + // 快递发货
  390 + if (ObjectUtil.equal(deliveryReqVO.getType(), DeliveryTypeEnum.EXPRESS.getMode())) {
  391 + deliveryDOs = express(order, deliveryReqVO);
  392 + tradeOrderDO.setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo());
  393 + }
  394 + // 用户自提
  395 + if (ObjectUtil.equal(deliveryReqVO.getType(), DeliveryTypeEnum.PICK_UP.getMode())) {
  396 + deliveryDOs = pickUp(order, deliveryReqVO);
  397 + // 重置一下确保快递公司和快递单号为空
  398 + tradeOrderDO.setLogisticsId(null).setLogisticsNo("");
  399 + }
  400 + // TODO 芋艿:如果无需发货,需要怎么存储?
  401 + if (ObjectUtil.equal(deliveryReqVO.getType(), DeliveryTypeEnum.NULL.getMode())) {
  402 + // TODO 情况一:正常走发货逻辑和用户自提有点像 不同点:不需要自提门店只需要用户确认收货
  403 + // TODO 情况二:用户下单付款后直接确认收货或等待用户确认收货
379 } 404 }
380 405
381 // 更新 TradeOrderDO 状态为已发货,等待收货 406 // 更新 TradeOrderDO 状态为已发货,等待收货
382 - int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(),  
383 - new TradeOrderDO().setStatus(TradeOrderStatusEnum.DELIVERED.getStatus())  
384 - .setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo())  
385 - .setDeliveryStatus(TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()).setDeliveryTime(LocalDateTime.now())); 407 + tradeOrderDO.setStatus(TradeOrderStatusEnum.DELIVERED.getStatus())
  408 + .setDeliveryStatus(TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()).setDeliveryTime(LocalDateTime.now());
  409 + int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), tradeOrderDO);
386 if (updateCount == 0) { 410 if (updateCount == 0) {
387 throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED); 411 throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED);
388 } 412 }
389 - 413 + // 发货成功记录发货表
  414 + orderDeliveryMapper.insertBatch(deliveryDOs);
390 // TODO 芋艿:发送订单变化的消息 415 // TODO 芋艿:发送订单变化的消息
391 416
392 - // TODO 芋艿:发送站内信 fix 417 + // 发送站内信
393 // 1、构造消息 418 // 1、构造消息
394 Map<String, Object> msgMap = new HashMap<>(); 419 Map<String, Object> msgMap = new HashMap<>();
395 msgMap.put("orderId", deliveryReqVO.getId()); 420 msgMap.put("orderId", deliveryReqVO.getId());
@@ -400,16 +425,59 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -400,16 +425,59 @@ public class TradeOrderServiceImpl implements TradeOrderService {
400 .setUserId(userId) 425 .setUserId(userId)
401 .setTemplateCode("order_delivery") 426 .setTemplateCode("order_delivery")
402 .setTemplateParams(msgMap)); 427 .setTemplateParams(msgMap));
403 - // TODO 芋艿:OrderLog  
404 428
405 - // TODO 设计:like:是否要单独一个 delivery 发货单表??? fix: 确实单独一张发货表就能解决整单发货和单独发货的问题  
406 - // TODO 设计:niu:要不要支持一个订单下,多个 order item 单独发货,类似有赞 429 + // TODO 芋艿:OrderLog
407 // TODO 设计:lili:是不是发货后,才支持售后? 430 // TODO 设计:lili:是不是发货后,才支持售后?
408 } 431 }
409 432
  433 + private List<TradeOrderDeliveryDO> express(TradeOrderDO order, TradeOrderDeliveryReqVO deliveryReqVO) {
  434 + // 校验快递公司
  435 + DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId());
  436 + if (deliveryExpress == null) {
  437 + throw exception(EXPRESS_NOT_EXISTS);
  438 + }
  439 + // 校验发货商品
  440 + validateDeliveryOrderItem(order, deliveryReqVO);
  441 + // 创建发货记录
  442 + return TradeOrderConvert.INSTANCE.covert(order, deliveryReqVO);
  443 + }
  444 +
  445 + private List<TradeOrderDeliveryDO> pickUp(TradeOrderDO order, TradeOrderDeliveryReqVO deliveryReqVO) {
  446 + // TODO 校验自提门店是否存在
  447 + // 重置一下确保快递公司和快递单号为空
  448 + deliveryReqVO.setLogisticsId(null);
  449 + deliveryReqVO.setLogisticsNo("");
  450 + // 校验发货商品
  451 + validateDeliveryOrderItem(order, deliveryReqVO);
  452 + // 创建发货记录
  453 + return TradeOrderConvert.INSTANCE.covert(order, deliveryReqVO);
  454 + }
  455 +
  456 + private void validateDeliveryOrderItem(TradeOrderDO order, TradeOrderDeliveryReqVO deliveryReqVO) {
  457 + // TODO 设计:like:是否要单独一个 delivery 发货单表??? fix: 多商品可分开单独发货,添加 trade_order_delivery 交易订单发货日志表关联发货所选订单项设置物流单号
  458 + // TODO 设计:niu:要不要支持一个订单下,多个 order item 单独发货,类似有赞 fix
  459 + // 校验发货商品
  460 + if (CollUtil.isEmpty(deliveryReqVO.getOrderItemIds())) {
  461 + throw exception(ORDER_DELIVERY_FAILED_ITEMS_NOT_EMPTY);
  462 + }
  463 + // 校验发货商品是否存在
  464 + List<TradeOrderItemDO> orderItemDOs = tradeOrderItemMapper.selectListByOrderId(order.getId());
  465 + Set<Long> itemIds = convertSet(orderItemDOs, TradeOrderItemDO::getId);
  466 + if (!itemIds.containsAll(deliveryReqVO.getOrderItemIds())) {
  467 + throw exception(ORDER_DELIVERY_FAILED_ITEM_NOT_EXISTS);
  468 + }
  469 + // 校验所选订单项是否存在有已发货的
  470 + List<TradeOrderDeliveryDO> deliveryDOList = orderDeliveryMapper.selsectListByOrderIdAndItemIds(order.getId(), deliveryReqVO.getOrderItemIds());
  471 + if (CollUtil.isNotEmpty(deliveryDOList)) {
  472 + HashSet<Long> hashSet = CollUtil.newHashSet(deliveryReqVO.getOrderItemIds());
  473 + hashSet.retainAll(convertSet(deliveryDOList, TradeOrderDeliveryDO::getOrderItemId));
  474 + throw exception(ORDER_DELIVERY_FAILED_ITEM_ALREADY_DELIVERY);
  475 + }
  476 + }
  477 +
410 /** 478 /**
411 * 校验交易订单满足被发货的条件 479 * 校验交易订单满足被发货的条件
412 - * <p> 480 + *
413 * 1. 交易订单未发货 481 * 1. 交易订单未发货
414 * 482 *
415 * @param id 交易订单编号 483 * @param id 交易订单编号
@@ -432,7 +500,10 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -432,7 +500,10 @@ public class TradeOrderServiceImpl implements TradeOrderService {
432 } 500 }
433 // 校验订单拼团是否成功 501 // 校验订单拼团是否成功
434 if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { 502 if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
435 - 503 + // TODO 用户 ID 使用当前登录用户的还是订单保存的?
  504 + if (ObjectUtil.notEqual(combinationApi.getRecordStatus(order.getUserId(), order.getId()), CombinationRecordStatusEnum.SUCCESS.getStatus())) {
  505 + throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS);
  506 + }
436 } 507 }
437 // TODO puhui999: 校验订单砍价是否成功 508 // TODO puhui999: 校验订单砍价是否成功
438 return order; 509 return order;
@@ -466,7 +537,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -466,7 +537,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
466 537
467 /** 538 /**
468 * 校验交易订单满足可售货的条件 539 * 校验交易订单满足可售货的条件
469 - * <p> 540 + *
470 * 1. 交易订单待收货 541 * 1. 交易订单待收货
471 * 542 *
472 * @param userId 用户编号 543 * @param userId 用户编号