Ver Fonte

批量更新聚水潭订单

yuhongqi há 1 dia atrás
pai
commit
785ddeb9ea

+ 10 - 11
fs-admin/src/main/java/com/fs/task/LiveTask.java

@@ -312,8 +312,12 @@ public class LiveTask {
     public void syncExpress() {
         List<Long> ids = liveOrderService.selectSyncExpressIds();
         for (Long id : ids) {
-            liveOrderService.syncExpress(id);
-            fsStoreDeliverService.finishOrder(id,1);
+            try {
+                liveOrderService.syncExpress(id);
+                fsStoreDeliverService.finishOrder(id, 1);
+            } catch (Exception e) {
+                logger.error("直播同步物流状态失败 {}", id, e);
+            }
         }
     }
 
@@ -322,16 +326,11 @@ public class LiveTask {
      */
     @QuartzRunnable(name = "直播发货任务")
     public void updateExpress() {
-        List<LiveOrder> list = liveOrderService.selectUpdateExpress();
-
-        for (LiveOrder order : list) {
-            try{
-                liveOrderService.syncDeliveryOrder(order);
-            }catch (Exception e) {
-                logger.error("获取订单是否发货失败!原因: ",e);
-            }
+        try {
+            liveOrderService.batchSyncDeliveryOrders(liveOrderService.selectUpdateExpress()); // 可以修改为工厂类,方便拓展
+        } catch (Exception e) {
+            logger.error("获取订单是否发货失败!原因: ", e);
         }
-
     }
     /**
      * 更新流量

+ 11 - 17
fs-admin/src/main/java/com/fs/task/StoreTask.java

@@ -43,7 +43,6 @@ import com.fs.system.service.ISysConfigService;
 import com.fs.wx.domain.FsWxExpressTask;
 import com.fs.wx.mapper.FsWxExpressTaskMapper;
 import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.RateLimiter;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang.ObjectUtils;
 import org.apache.http.util.Asserts;
@@ -618,9 +617,13 @@ public class StoreTask {
         List<Long> ids = fsStoreOrderMapper.selectSyncExpressIds();
 
         for (Long id : ids) {
-            FsStoreOrderExpressEditParam param = new FsStoreOrderExpressEditParam();
-            param.setOrderId(id);
-            fsStoreOrderService.syncExpress(param);
+            try {
+                FsStoreOrderExpressEditParam param = new FsStoreOrderExpressEditParam();
+                param.setOrderId(id);
+                fsStoreOrderService.syncExpress(param);
+            } catch (Exception e) {
+                logger.error("同步物流状态失败 {}", id, e);
+            }
         }
 
     }
@@ -681,25 +684,16 @@ public class StoreTask {
     }
 
 
-    private final RateLimiter rateLimiter = RateLimiter.create(1.3);
-
     /**
      * 更新发货状态
      */
     @QuartzRunnable(name = "发货任务")
     public void updateExpress() {
-        List<FsStoreOrder> list = fsStoreOrderMapper.selectUpdateExpress();
-
-        for (FsStoreOrder order : list) {
-            try{
-                rateLimiter.acquire();
-                orderService.syncDeliveryOrder(order);
-            }catch (Exception e) {
-                logger.error("获取订单是否发货失败!原因: ",e);
-
-            }
+        try {
+            orderService.batchSyncDeliveryOrders(orderService.selectUpdateExpress());// 可以修改为工厂类,方便拓展
+        } catch (Exception e) {
+            logger.error("获取订单是否发货失败!原因: ", e);
         }
-
     }
 
 }

+ 12 - 4
fs-service-system/src/main/java/com/fs/erp/service/impl/JSTErpOrderServiceImpl.java

@@ -258,8 +258,14 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
     public ErpOrderQueryResponse getOrderLive(ErpOrderQueryRequert param) {
         // 1. 构建查询请求DTO
         OrderQueryRequestDTO requestDTO = new OrderQueryRequestDTO();
-        requestDTO.setOIds(Collections.singletonList(Long.valueOf(param.getCode())));
-
+        if (StringUtils.isNotEmpty(param.getCode())) {
+            requestDTO.setOIds(Collections.singletonList(Long.valueOf(param.getCode())));
+        } else {
+            requestDTO.setOIds(param.getO_ids());
+            requestDTO.setShopId(Integer.parseInt(param.getShop_id()));
+            requestDTO.setPageIndex(param.getPage_index());
+            requestDTO.setPageSize(param.getPage_size());
+        }
 
         // 2. 调用ERP服务查询订单
         OrderQueryResponseDTO query = jstErpHttpService.query(requestDTO);
@@ -267,8 +273,6 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
         // 3. 构建响应对象
         ErpOrderQueryResponse response = new ErpOrderQueryResponse();
 
-        // 4. 设置基本响应信息
-
         // 5. 转换订单数据
         if (query.getOrders() != null && !query.getOrders().isEmpty()) {
             List<ErpOrderQuery> erpOrders = query.getOrders().stream()
@@ -276,6 +280,7 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
                     .collect(Collectors.toList());
 
             response.setOrders(erpOrders);
+            response.setHasNext(query.getHasNext());
         } else {
             response.setOrders(Collections.emptyList());
         }
@@ -377,6 +382,9 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
 
         // 设置基本订单信息
         erpOrder.setCode(order.getSoId());
+        if (order.getOId() != null) {
+            erpOrder.setO_id(order.getOId().intValue());
+        }
 
         // 计算订单总数量
         if (order.getItems() != null && !order.getItems().isEmpty()) {

+ 2 - 0
fs-service-system/src/main/java/com/fs/live/mapper/LiveOrderMapper.java

@@ -149,4 +149,6 @@ public interface LiveOrderMapper {
 
     @Select("SELECT DISTINCT user_id FROM live_order WHERE create_time >= DATE_SUB(NOW(), INTERVAL #{days} DAY) AND user_id IS NOT NULL AND user_id != ''")
     List<String> selectDistinctUserIdsFromRecentOrders(@Param("days") int days);
+
+    void updateUpdateTimeByExtendIds(@Param("batch") List<String> batch);
 }

+ 2 - 0
fs-service-system/src/main/java/com/fs/live/service/ILiveOrderService.java

@@ -183,6 +183,8 @@ public interface ILiveOrderService {
 
     void syncDeliveryOrder(LiveOrder order);
 
+    void batchSyncDeliveryOrders(List<LiveOrder> orders);
+
     List<Long> selectSyncExpressIds();
 
     List<Long> selectOrderIdByNoErp();

+ 165 - 24
fs-service-system/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java

@@ -85,6 +85,8 @@ import com.fs.system.service.ISysConfigService;
 import com.fs.wx.domain.FsWxExpressTask;
 import com.fs.wx.mapper.FsWxExpressTaskMapper;
 import lombok.Data;
+import com.fs.wx.service.ShippingService;
+import com.google.common.collect.Lists;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang.ObjectUtils;
@@ -117,6 +119,9 @@ import static com.fs.store.enums.BillDetailEnum.CATEGORY_3;
 @Slf4j
 public class LiveOrderServiceImpl implements ILiveOrderService {
 
+    private static final int DELIVERY_SYNC_BATCH_SIZE = 30;
+    private static final String JST_SHOP_ID = "18675245";
+
     private final RedisCache redisCache;
     @Autowired
     private LiveOrderMapper baseMapper;
@@ -1397,33 +1402,167 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     public void syncDeliveryOrder(LiveOrder order) {
         log.info("[发货任务] 当前单号: {}", order.getOrderCode());
-        ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-        request.setCode(order.getExtendOrderId());
-        // 根据仓库code找erp
-        if (com.fs.common.utils.StringUtils.isNotBlank(order.getStoreHouseCode())) {
+        try {
+            setErpContext(order);
+            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
+            request.setCode(order.getExtendOrderId());
+            ErpOrderQueryResponse response = erpOrderService.getOrderLive(request);
+            handleLiveErpOrderQueryResponse(order, response);
+        } finally {
+            ErpContextHolder.clear();
+        }
+    }
+
+    @Override
+    public void batchSyncDeliveryOrders(List<LiveOrder> orders) {
+        if (CollectionUtils.isEmpty(orders)) {
+            return;
+        }
+        Map<String, List<LiveOrder>> erpOrderMap = orders.stream()
+                .collect(Collectors.groupingBy(this::resolveErpType));
+        for (Map.Entry<String, List<LiveOrder>> entry : erpOrderMap.entrySet()) {
+            String erpType = entry.getKey();
+            List<LiveOrder> erpOrders = entry.getValue();
+            try {
+                if (ErpTypeConstant.JST_ERP.equals(erpType)) {
+                    batchSyncJstDeliveryOrders(erpOrders);
+                } else {
+                    batchSyncSingleDeliveryOrders(erpOrders);
+                }
+            } catch (Exception e) {
+                log.error("[发货任务] 直播订单 ERP类型 {} 批量同步失败", erpType, e);
+            }
+        }
+    }
+
+    private String resolveErpType(LiveOrder order) {
+        if (StringUtils.isNotBlank(order.getStoreHouseCode())) {
             String erp = fsWarehousesMapper.selectErpByCode(order.getStoreHouseCode());
-            ErpContextHolder.setErpType(erp);
+            if (StringUtils.isNotBlank(erp)) {
+                return erp;
+            }
         }
-        ErpOrderQueryResponse response = erpOrderService.getOrderLive(request);
-        if (CollectionUtils.isNotEmpty(response.getOrders())) {
-            for (ErpOrderQuery orderQuery : response.getOrders()) {
-                // 部分发货或者全部发货
-                if (ObjectUtils.equals(orderQuery.getDelivery_state(), 1) || ObjectUtils.equals(orderQuery.getDelivery_state(), 2)) {
+        return ErpTypeConstant.GY_ERP;
+    }
 
-                    liveOrderLogsService.create(order.getOrderId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
-                            OrderLogEnum.DELIVERY_GOODS.getDesc());
-                    for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
-                        if (delivery.getDelivery()) {
-                            this.deliveryOrder(order.getOrderCode(), delivery.getMail_no(),
-                                    delivery.getExpress_code(), delivery.getExpress_name());
-                        }
-                    }
+    private void setErpContext(LiveOrder order) {
+        ErpContextHolder.setErpType(resolveErpType(order));
+    }
 
+    private void handleLiveErpOrderQueryResponse(LiveOrder order, ErpOrderQueryResponse response) {
+        if (response == null || CollectionUtils.isEmpty(response.getOrders())) {
+            return;
+        }
+        for (ErpOrderQuery orderQuery : response.getOrders()) {
+            processLiveErpOrderQuery(order, orderQuery);
+        }
+    }
+
+    private void processLiveErpOrderQuery(LiveOrder order, ErpOrderQuery orderQuery) {
+        if (orderQuery == null) {
+            return;
+        }
+        if (!ObjectUtils.equals(orderQuery.getDelivery_state(), 1) && !ObjectUtils.equals(orderQuery.getDelivery_state(), 2)) {
+            return;
+        }
+        liveOrderLogsService.create(order.getOrderId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
+                OrderLogEnum.DELIVERY_GOODS.getDesc());
+        if (CollectionUtils.isEmpty(orderQuery.getDeliverys())) {
+            return;
+        }
+        for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
+            if (Boolean.TRUE.equals(delivery.getDelivery())) {
+                this.deliveryOrder(order.getOrderCode(), delivery.getMail_no(),
+                        delivery.getExpress_code(), delivery.getExpress_name());
+            }
+        }
+    }
+
+    private void batchSyncJstDeliveryOrders(List<LiveOrder> orders) throws InterruptedException {
+        ErpContextHolder.setErpType(ErpTypeConstant.JST_ERP);
+        try {
+            Map<Long, LiveOrder> extendOrderMap = new HashMap<>();
+            List<Long> oIds = new ArrayList<>();
+            for (LiveOrder order : orders) {
+                if (StringUtils.isBlank(order.getExtendOrderId())) {
+                    continue;
+                }
+                try {
+                    Long oId = Long.parseLong(order.getExtendOrderId());
+                    oIds.add(oId);
+                    extendOrderMap.put(oId, order);
+                } catch (NumberFormatException e) {
+                    log.warn("[发货任务] 直播订单 extendOrderId非法 orderCode={}", order.getOrderCode());
                 }
             }
+            if (CollectionUtils.isEmpty(oIds)) {
+                return;
+            }
+            for (List<Long> batch : Lists.partition(oIds, DELIVERY_SYNC_BATCH_SIZE)) {
+                Thread.sleep(300);
+                List<String> extendIds = batch.stream().map(String::valueOf).collect(Collectors.toList());
+                updateUpdateTimeByExtendIds(extendIds);
+
+                ErpOrderQueryRequert request = new ErpOrderQueryRequert();
+                request.setShop_id(JST_SHOP_ID);
+                request.setO_ids(new ArrayList<>(batch));
+                request.setPage_size(DELIVERY_SYNC_BATCH_SIZE);
+
+                int pageIndex = 1;
+                boolean hasNext;
+                do {
+                    request.setPage_index(pageIndex);
+                    ErpOrderQueryResponse response = erpOrderService.getOrderLive(request);
+                    handleJstBatchLiveDeliveryResponse(batch, extendOrderMap, response);
+                    hasNext = response != null && response.hasNextSafe();
+                    pageIndex++;
+                } while (hasNext);
+            }
+        } finally {
+            ErpContextHolder.clear();
         }
     }
 
+    private void handleJstBatchLiveDeliveryResponse(List<Long> batch, Map<Long, LiveOrder> extendOrderMap,
+                                                    ErpOrderQueryResponse response) {
+        if (response == null || CollectionUtils.isEmpty(response.getOrders())) {
+            return;
+        }
+        Map<String, LiveOrder> orderCodeMap = batch.stream()
+                .map(extendOrderMap::get)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toMap(LiveOrder::getOrderCode, order -> order, (a, b) -> a));
+        for (ErpOrderQuery orderQuery : response.getOrders()) {
+            LiveOrder order = orderCodeMap.get(orderQuery.getCode());
+            if (order == null && orderQuery.getO_id() != null) {
+                order = extendOrderMap.get(orderQuery.getO_id().longValue());
+            }
+            if (order != null) {
+                log.info("[发货任务] 当前单号: {}", order.getOrderCode());
+                processLiveErpOrderQuery(order, orderQuery);
+            }
+        }
+    }
+
+    private void batchSyncSingleDeliveryOrders(List<LiveOrder> orders) {
+        for (List<LiveOrder> batch : Lists.partition(orders, DELIVERY_SYNC_BATCH_SIZE)) {
+            for (LiveOrder order : batch) {
+                try {
+                    syncDeliveryOrder(order);
+                } catch (Exception e) {
+                    log.error("[发货任务] 直播订单同步发货失败 orderCode={}", order.getOrderCode(), e);
+                }
+            }
+        }
+    }
+
+    private void updateUpdateTimeByExtendIds(List<String> batch) {
+        if (CollectionUtils.isEmpty(batch)) {
+            return;
+        }
+        baseMapper.updateUpdateTimeByExtendIds(batch);
+    }
+
     @Override
     public List<Long> selectSyncExpressIds() {
         return baseMapper.selectSyncExpressIds();
@@ -1830,6 +1969,13 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
             fsWxExpressTask.setType(1);
             fsWxExpressTaskMapper.insert(fsWxExpressTask);
 
+            //订阅物流回调
+            String lastFourNumber = "";
+            if (StringUtils.equals(express.getCode(), ShipperCodeEnum.SF.getValue()) || StringUtils.equals(express.getCode(), ShipperCodeEnum.ZTO.getValue())) {
+                lastFourNumber = PhoneUtils.getLastFourNum(order.getUserPhone());
+            }
+            expressService.subscribeEspress(order.getOrderCode(), express.getCode(), deliveryId, lastFourNumber, 1);
+
             // 微信消息通知
             TemplateBean templateBean = TemplateBean.builder()
                     .orderId(order.getOrderId().toString())
@@ -1841,12 +1987,7 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
                     .build();
             publisher.publishEvent(new TemplateEvent(this, templateBean));
 
-            //订阅物流回调
-            String lastFourNumber = "";
-            if (StringUtils.equals(express.getCode(), ShipperCodeEnum.SF.getValue()) || StringUtils.equals(express.getCode(), ShipperCodeEnum.ZTO.getValue())) {
-                lastFourNumber = PhoneUtils.getLastFourNum(order.getUserPhone());
-            }
-            expressService.subscribeEspress(order.getOrderCode(), express.getCode(), deliveryId, lastFourNumber, 1);
+
         }
     }
 

+ 5 - 0
fs-service-system/src/main/java/com/fs/store/service/IFsStoreOrderService.java

@@ -114,6 +114,11 @@ public interface IFsStoreOrderService
     void deliveryOrder(String orderCode,String deliveryId,String deliverCode,String deliverName);
 
     void syncDeliveryOrder(FsStoreOrder order);
+
+    List<FsStoreOrder> selectUpdateExpress();
+
+    void batchSyncDeliveryOrders(List<FsStoreOrder> orders);
+
     void updateDeliveryOrder(Long id,String deliveryId,String deliverCode,String deliverName);
 
     List<FsMyStoreOrderListQueryVO> selectFsMyStoreOrderListVO(FsMyStoreOrderQueryParam param);

+ 155 - 22
fs-service-system/src/main/java/com/fs/store/service/impl/FsStoreOrderServiceImpl.java

@@ -104,6 +104,7 @@ import com.fs.wx.miniapp.config.WxMaConfiguration;
 import com.fs.wx.miniapp.config.WxMaProperties;
 import com.fs.wx.service.OrderQueryService;
 import com.fs.wx.service.ShippingService;
+import com.google.common.collect.Lists;
 import lombok.Synchronized;
 import me.chanjar.weixin.common.error.WxErrorException;
 import org.apache.commons.collections4.CollectionUtils;
@@ -135,6 +136,9 @@ import static com.fs.store.constants.StoreConstants.DELIVERY;
 public class FsStoreOrderServiceImpl implements IFsStoreOrderService
 {
 
+    private static final int DELIVERY_SYNC_BATCH_SIZE = 30;
+    private static final String JST_SHOP_ID = "18675245";
+
     Logger logger= LoggerFactory.getLogger(getClass());
     @Autowired
     private CompanyMoneyLogsMapper moneyLogsMapper;
@@ -1267,32 +1271,161 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService
     @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
     public void syncDeliveryOrder(FsStoreOrder order) {
         logger.info("[发货任务] 当前单号: {}", order.getOrderCode());
-        ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-        request.setCode(order.getExtendOrderId());
-        // 根据仓库code找erp
-        if(com.fs.common.utils.StringUtils.isNotBlank(order.getStoreHouseCode())){
+        try {
+            setErpContext(order);
+            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
+            request.setCode(order.getExtendOrderId());
+            ErpOrderQueryResponse response = erpOrderService.getOrder(request);
+            handleErpOrderQueryResponse(order, response);
+        } finally {
+            ErpContextHolder.clear();
+        }
+    }
+
+    @Override
+    public List<FsStoreOrder> selectUpdateExpress() {
+        return fsStoreOrderMapper.selectUpdateExpress();
+    }
+
+    @Override
+    public void batchSyncDeliveryOrders(List<FsStoreOrder> orders) {
+        if (CollectionUtils.isEmpty(orders)) {
+            return;
+        }
+        Map<String, List<FsStoreOrder>> erpOrderMap = orders.stream()
+                .collect(Collectors.groupingBy(this::resolveErpType));
+        for (Map.Entry<String, List<FsStoreOrder>> entry : erpOrderMap.entrySet()) {
+            String erpType = entry.getKey();
+            List<FsStoreOrder> erpOrders = entry.getValue();
+            try {
+                if (ErpTypeConstant.JST_ERP.equals(erpType)) {
+                    batchSyncJstDeliveryOrders(erpOrders);
+                } else {
+                    batchSyncSingleDeliveryOrders(erpOrders);
+                }
+            } catch (Exception e) {
+                logger.error("[发货任务] ERP类型 {} 批量同步失败", erpType, e);
+            }
+        }
+    }
+
+    private String resolveErpType(FsStoreOrder order) {
+        if (StringUtils.isNotBlank(order.getStoreHouseCode())) {
             String erp = fsWarehousesMapper.selectErpByCode(order.getStoreHouseCode());
-            ErpContextHolder.setErpType(erp);
+            if (StringUtils.isNotBlank(erp)) {
+                return erp;
+            }
         }
+        return ErpTypeConstant.GY_ERP;
+    }
 
-        ErpOrderQueryResponse response = erpOrderService.getOrder(request);
-        if (CollectionUtils.isNotEmpty(response.getOrders())) {
-            for (ErpOrderQuery orderQuery : response.getOrders()) {
-                // 部分发货或者全部发货
-                if (ObjectUtils.equals(orderQuery.getDelivery_state(), 1) || ObjectUtils.equals(orderQuery.getDelivery_state(), 2)) {
-                    // 订单状态变更
-                    orderStatusService.create(order.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
-                            OrderLogEnum.DELIVERY_GOODS.getDesc());
-
-                    redisCache.deleteObject(DELIVERY + ":" + order.getExtendOrderId());
-
-                    for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
-                        if (delivery.getDelivery()) {
-                            orderService.deliveryOrder(order.getOrderCode(), delivery.getMail_no(),
-                                    delivery.getExpress_code(), delivery.getExpress_name());
-                        }
-                    }
+    private void setErpContext(FsStoreOrder order) {
+        ErpContextHolder.setErpType(resolveErpType(order));
+    }
+
+    private void handleErpOrderQueryResponse(FsStoreOrder order, ErpOrderQueryResponse response) {
+        if (response == null || CollectionUtils.isEmpty(response.getOrders())) {
+            return;
+        }
+        for (ErpOrderQuery orderQuery : response.getOrders()) {
+            processErpOrderQuery(order, orderQuery);
+        }
+    }
+
+    private void processErpOrderQuery(FsStoreOrder order, ErpOrderQuery orderQuery) {
+        if (orderQuery == null) {
+            return;
+        }
+        if (!ObjectUtils.equals(orderQuery.getDelivery_state(), 1) && !ObjectUtils.equals(orderQuery.getDelivery_state(), 2)) {
+            return;
+        }
+        orderStatusService.create(order.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
+                OrderLogEnum.DELIVERY_GOODS.getDesc());
+        redisCache.deleteObject(DELIVERY + ":" + order.getExtendOrderId());
+        if (CollectionUtils.isEmpty(orderQuery.getDeliverys())) {
+            return;
+        }
+        for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
+            if (Boolean.TRUE.equals(delivery.getDelivery())) {
+                orderService.deliveryOrder(order.getOrderCode(), delivery.getMail_no(),
+                        delivery.getExpress_code(), delivery.getExpress_name());
+            }
+        }
+    }
+
+    private void batchSyncJstDeliveryOrders(List<FsStoreOrder> orders) throws InterruptedException {
+        ErpContextHolder.setErpType(ErpTypeConstant.JST_ERP);
+        try {
+            Map<Long, FsStoreOrder> extendOrderMap = new HashMap<>();
+            List<Long> oIds = new ArrayList<>();
+            for (FsStoreOrder order : orders) {
+                if (StringUtils.isBlank(order.getExtendOrderId())) {
+                    continue;
+                }
+                try {
+                    Long oId = Long.parseLong(order.getExtendOrderId());
+                    oIds.add(oId);
+                    extendOrderMap.put(oId, order);
+                } catch (NumberFormatException e) {
+                    logger.warn("[发货任务] extendOrderId非法 orderCode={}", order.getOrderCode());
+                }
+            }
+            if (CollectionUtils.isEmpty(oIds)) {
+                return;
+            }
+            for (List<Long> batch : Lists.partition(oIds, DELIVERY_SYNC_BATCH_SIZE)) {
+                Thread.sleep(300);
+                List<String> extendIds = batch.stream().map(String::valueOf).collect(Collectors.toList());
+                updateUpdateTimeByExtendIds(extendIds);
+
+                ErpOrderQueryRequert request = new ErpOrderQueryRequert();
+                request.setShop_id(JST_SHOP_ID);
+                request.setO_ids(new ArrayList<>(batch));
+                request.setPage_size(DELIVERY_SYNC_BATCH_SIZE);
+
+                int pageIndex = 1;
+                boolean hasNext;
+                do {
+                    request.setPage_index(pageIndex);
+                    ErpOrderQueryResponse response = erpOrderService.getOrder(request);
+                    handleJstBatchDeliveryResponse(batch, extendOrderMap, response);
+                    hasNext = response != null && response.hasNextSafe();
+                    pageIndex++;
+                } while (hasNext);
+            }
+        } finally {
+            ErpContextHolder.clear();
+        }
+    }
 
+    private void handleJstBatchDeliveryResponse(List<Long> batch, Map<Long, FsStoreOrder> extendOrderMap,
+                                                ErpOrderQueryResponse response) {
+        if (response == null || CollectionUtils.isEmpty(response.getOrders())) {
+            return;
+        }
+        Map<String, FsStoreOrder> orderCodeMap = batch.stream()
+                .map(extendOrderMap::get)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toMap(FsStoreOrder::getOrderCode, order -> order, (a, b) -> a));
+        for (ErpOrderQuery orderQuery : response.getOrders()) {
+            FsStoreOrder order = orderCodeMap.get(orderQuery.getCode());
+            if (order == null && orderQuery.getO_id() != null) {
+                order = extendOrderMap.get(orderQuery.getO_id().longValue());
+            }
+            if (order != null) {
+                logger.info("[发货任务] 当前单号: {}", order.getOrderCode());
+                processErpOrderQuery(order, orderQuery);
+            }
+        }
+    }
+
+    private void batchSyncSingleDeliveryOrders(List<FsStoreOrder> orders) {
+        for (List<FsStoreOrder> batch : Lists.partition(orders, DELIVERY_SYNC_BATCH_SIZE)) {
+            for (FsStoreOrder order : batch) {
+                try {
+                    syncDeliveryOrder(order);
+                } catch (Exception e) {
+                    logger.error("[发货任务] 同步发货失败 orderCode={}", order.getOrderCode(), e);
                 }
             }
         }

+ 8 - 0
fs-service-system/src/main/resources/mapper/live/LiveOrderMapper.xml

@@ -642,4 +642,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </foreach>
     </select>
 
+    <update id="updateUpdateTimeByExtendIds">
+        UPDATE live_order SET update_time = NOW()
+        WHERE extend_order_id IN
+        <foreach item="item" collection="batch" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </update>
+
 </mapper>