...
|
...
|
@@ -37,10 +37,7 @@ import com.yohoufo.order.event.BuyerOrderSellerDeliveryCheckEvent; |
|
|
import com.yohoufo.order.event.ErpBuyerOrderEvent;
|
|
|
import com.yohoufo.order.model.OperateTransferExpressInfo;
|
|
|
import com.yohoufo.order.model.response.AppraiseAddressResp;
|
|
|
import com.yohoufo.order.service.IBuyerOrderMetaService;
|
|
|
import com.yohoufo.order.service.IExpressCompanyService;
|
|
|
import com.yohoufo.order.service.IExpressInfoService;
|
|
|
import com.yohoufo.order.service.IGoodsService;
|
|
|
import com.yohoufo.order.service.*;
|
|
|
import com.yohoufo.order.service.cache.CacheCleaner;
|
|
|
import com.yohoufo.order.service.cache.CacheKeyBuilder;
|
|
|
import com.yohoufo.order.service.proxy.*;
|
...
|
...
|
@@ -153,6 +150,9 @@ public class ExpressInfoServiceImpl implements IExpressInfoService { |
|
|
@Autowired
|
|
|
private BuyerOrderAssistant buyerOrderAssistant;
|
|
|
|
|
|
@Autowired
|
|
|
private IBuyerOrderService buyerOrderService;
|
|
|
|
|
|
private static String EXPRESS_MQ_SEND = "third.logistics.logistics_data";
|
|
|
|
|
|
//物流文案设置
|
...
|
...
|
@@ -171,8 +171,6 @@ public class ExpressInfoServiceImpl implements IExpressInfoService { |
|
|
@Autowired
|
|
|
private SkupService skupService;
|
|
|
|
|
|
@Autowired
|
|
|
private ProductProxyService productProxyService;
|
|
|
|
|
|
|
|
|
/**
|
...
|
...
|
@@ -285,7 +283,6 @@ public class ExpressInfoServiceImpl implements IExpressInfoService { |
|
|
int updateOrderCnt = 0;
|
|
|
String sellerMobile;
|
|
|
String depositCode = req.getDepositCode();
|
|
|
Integer buyerUid;
|
|
|
switch (orderCodeType){
|
|
|
case BUYER_TYPE:
|
|
|
BuyerOrderAssistant.PreparedData preparedData = buyerOrderAssistant.prepare(orderCode);
|
...
|
...
|
@@ -294,7 +291,6 @@ public class ExpressInfoServiceImpl implements IExpressInfoService { |
|
|
LOGGER.warn("deliverToDepot getOrderInfo order not exist, orderCode is {}", orderCode);
|
|
|
throw new ServiceException(ServiceError.ORDER_NULL);
|
|
|
}
|
|
|
buyerUid = buyerOrder.getUid();
|
|
|
sellerMobile = Optional.of(preparedData.getBuyerOrderGoods())
|
|
|
.map(e -> sellerAddressService.getNoHiddenAddressInfo(sellerUid, e.getSkup()))
|
|
|
.map(AddressInfo::getMobile)
|
...
|
...
|
@@ -302,11 +298,9 @@ public class ExpressInfoServiceImpl implements IExpressInfoService { |
|
|
//目前校验现货订单 和 现货寄存订单
|
|
|
BuyerOrderAssistant.DepositSkuCheckNode dscNode = buyerOrderAssistant.checkExistDepositSku(buyerOrder, preparedData.getSellerOrderGoods(), depositCode);
|
|
|
boolean existDepositGoods = dscNode.isExistDepositGoods();
|
|
|
|
|
|
if(existDepositGoods){
|
|
|
//set depot num
|
|
|
depotNum = DepotType.NJ.getCode();
|
|
|
|
|
|
//生成内部使用的物流单号
|
|
|
wayBillCode = new StringBuilder()
|
|
|
.append(orderCode)
|
...
|
...
|
@@ -318,10 +312,22 @@ public class ExpressInfoServiceImpl implements IExpressInfoService { |
|
|
if (isHKLargeSettlementSuper(sellerUid)) {
|
|
|
depotNum = DepotType.HK.getCode();
|
|
|
}
|
|
|
//博弈 以下步骤若非原子操作,谁先谁后
|
|
|
//o1.更新订单状态->已发货 o2.更新寄存商品->待捡货
|
|
|
//竞争操作: a:买家取消订单 a1:更新寄存商品->重回货架 b:寄存商品被购买
|
|
|
//o1 pk a的结果, (1.1) a失败 o1成功; (1.2)a成功,o1失败
|
|
|
//o2 pk b的结果, (2.1) o2 success, b fail, (2.2) o2 fail , b success
|
|
|
//case 1: 先o1后o2: 1.1 正常流程走下去 1.2 回滚
|
|
|
//case 2: 先o2后o1: 2.1(需要考虑a1导致的并发,由服务提供方保证) & 2.2(需要回滚已操作的业务)
|
|
|
//采用分布式锁解决寄存商品的并发问题
|
|
|
//思路 用寄存码加锁
|
|
|
//采用case 2 当使用寄存商品发货时 o2操作前加锁;a操作发现是寄存商品发货的订单 检查锁;b操作 下单 计算 支付回调均要检查
|
|
|
//合理的方案将 加锁 释放锁抽成独立的工具类,使用者引用
|
|
|
//o1 & o2 捆绑在一个数据库的事务里 用于保证业务本地的原子操作
|
|
|
updateOrderCnt = processBuyerOrder(preparedData, expressCompanyId, expressType, wayBillCode, depotNum);
|
|
|
if (updateOrderCnt>0){
|
|
|
try {
|
|
|
processOrderDeliverByDepositGoods(preparedData, dscNode);
|
|
|
buyerOrderService.processOrderDeliverByDepositGoods(preparedData, dscNode);
|
|
|
}catch (Exception ex){
|
|
|
LOGGER.warn("deliverToDepot processOrderDeliverByDepositGoods fail ,req {} error {}",
|
|
|
req, Throwables.getStackTraceAsString(ex));
|
...
|
...
|
@@ -372,29 +378,7 @@ public class ExpressInfoServiceImpl implements IExpressInfoService { |
|
|
LOGGER.info("deliverToDepot update buyer order status, orderCode {} result {} ", orderCode, updateOrderCnt);
|
|
|
}
|
|
|
|
|
|
private void processOrderDeliverByDepositGoods(BuyerOrderAssistant.PreparedData preparedData,
|
|
|
BuyerOrderAssistant.DepositSkuCheckNode dscNode){
|
|
|
if (!dscNode.isExistDepositGoods()){
|
|
|
return;
|
|
|
}
|
|
|
BuyerOrder buyerOrder = preparedData.getBuyerOrder();
|
|
|
Integer buyerUid = buyerOrder.getUid();
|
|
|
Long orderCode = buyerOrder.getOrderCode();
|
|
|
String depositCode = dscNode.getDepositCode();
|
|
|
//bind deposit code 2 buyer order
|
|
|
buyerOrderMetaService.saveDepositCode(depositCode, buyerUid, orderCode);
|
|
|
//TODO skup 下架
|
|
|
StorageDeposit psd = dscNode.getPsd();
|
|
|
Integer skup;
|
|
|
Integer productId;
|
|
|
if (Objects.nonNull(skup = psd.getNewSkup())){
|
|
|
// 减库存
|
|
|
productProxyService.subtractStorage(productId=psd.getProductId(), skup);
|
|
|
//
|
|
|
skupService.saleOut(skup);
|
|
|
}
|
|
|
//TODO 寄存商品 出库准备
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
...
|
...
|
@@ -469,7 +453,13 @@ public class ExpressInfoServiceImpl implements IExpressInfoService { |
|
|
* @param wayBillCode
|
|
|
* @param expressType
|
|
|
*/
|
|
|
private void saveExpressRecordAndOperateTransferExpressInfo(Integer uid, Integer expressCompanyId, Long orderCode, String wayBillCode, Integer expressType, EnumExpressDataType expressDataType, EnumExpressDataOperateTransferCode operateTransferCode, Integer depotNum) {
|
|
|
private void saveExpressRecordAndOperateTransferExpressInfo(Integer uid, Integer expressCompanyId,
|
|
|
Long orderCode,
|
|
|
String wayBillCode,
|
|
|
Integer expressType,
|
|
|
EnumExpressDataType expressDataType,
|
|
|
EnumExpressDataOperateTransferCode operateTransferCode,
|
|
|
Integer depotNum) {
|
|
|
ExpressRecord record = new ExpressRecord();
|
|
|
record.setUid(uid);/// 存卖家的uid
|
|
|
record.setOrderCode(orderCode);
|
...
|
...
|
|