Browse Source

一键自提

xw 1 week ago
parent
commit
dc2179639b

+ 18 - 1
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreHealthOrderScrmController.java

@@ -69,7 +69,7 @@ public class FsStoreHealthOrderScrmController extends BaseController {
     @Autowired
     private IFsStoreOrderStatusScrmService orderStatusService;
     @Autowired
-    private TokenService tokenService;
+    TokenService tokenService;
 
     @Autowired
     IErpOrderService erpOrderService;
@@ -596,4 +596,21 @@ public class FsStoreHealthOrderScrmController extends BaseController {
             return AjaxResult.error("查询小程序列表失败:" + e.getMessage());
         }
     }
+
+    /**
+     * 一键发货 - 将所有待发货订单标记为已发货并同步到微信物流
+     */
+    @Log(title = "一键发货", businessType = BusinessType.UPDATE)
+    @PostMapping("/batchDeliveryAllPendingOrders")
+    public R batchDeliveryAllPendingOrders(@RequestParam(name = "shipmentType", required = false, defaultValue = "4") Integer shipmentType) {
+        try {
+            // 调用服务层一键发货功能
+            R result = fsStoreOrderService.batchDeliveryAllPendingOrders(shipmentType);
+            logger.info("一键发货操作完成: {}", result);
+            return result;
+        } catch (Exception e) {
+            logger.error("一键发货操作失败", e);
+            return R.error("一键发货操作失败:" + e.getMessage());
+        }
+    }
 }

+ 7 - 0
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java

@@ -372,4 +372,11 @@ public interface IFsStoreOrderScrmService
     void cancelOrderByCode(String outerPayId);
 
     void updateFsStoreOrderDb(FsStoreOrderScrm order);
+
+    /**
+     * 一键发货 - 将所有待发货订单标记为已发货并同步到微信物流
+     * @param shipmentType 发货类型,默认为2(用户自提)
+     * @return R
+     */
+    R batchDeliveryAllPendingOrders(Integer shipmentType);
 }

+ 153 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -4210,6 +4210,159 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         return 1;
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public R batchDeliveryAllPendingOrders(Integer shipmentType) {
+        try {
+            DeliveryNoteImportResultDTO result = new DeliveryNoteImportResultDTO();
+
+            // 默认使用自提方式
+            if (shipmentType == null) {
+                shipmentType = 4;
+            }
+
+            // 获取商城配置
+            String json = configService.selectConfigByKey("store.config");
+            StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
+
+            // 1. 查询所有待发货订单
+            FsStoreOrderScrm condition = new FsStoreOrderScrm();
+            condition.setStatus(OrderInfoEnum.STATUS_1.getValue()); // 待发货状态
+            List<FsStoreOrderScrm> pendingOrders = fsStoreOrderMapper.selectFsStoreOrderList(condition);
+
+            if (pendingOrders.isEmpty()) {
+                return R.ok("暂无待发货订单");
+            }
+
+            List<FsOrderDeliveryNoteDTO> successList = new ArrayList<>(pendingOrders.size());
+            List<FsOrderDeliveryNoteDTO> updateList = new ArrayList<>(pendingOrders.size());
+            // 提取所有订单号
+            List<String> orderCodeList = new ArrayList<>(pendingOrders.size());
+
+
+            for (int i = 0; i < pendingOrders.size(); i++) {
+                FsStoreOrderScrm order = pendingOrders.get(i);
+                FsOrderDeliveryNoteDTO dto = new FsOrderDeliveryNoteDTO();
+
+
+                String orderCode = order.getOrderCode();
+                dto.setOrderNumber(orderCode);
+                dto.setDeliveryName("用户自提");
+                dto.setDeliveryId("ZT" + order.getId());
+                dto.setDeliverySn("ZT");
+
+                orderCodeList.add(orderCode);
+                successList.add(dto);
+            }
+
+
+            if (orderCodeList.isEmpty()) {
+                return R.ok(result.buildResultMessage());
+            }
+
+            List<FsStoreOrderCodeOpenIdVo> orderCodeOpenIdVoList = fsStoreOrderMapper.selectOrderCodeOpenIdInOrderCode(orderCodeList);
+            Map<String, OrderOpenIdTransDTO> orderMap = new HashMap<>(orderCodeOpenIdVoList.size());
+            Map<String, List<FsStoreOrderCodeOpenIdVo>> orderDetailsMap = new HashMap<>(orderCodeOpenIdVoList.size());
+
+            for (FsStoreOrderCodeOpenIdVo vo : orderCodeOpenIdVoList) {
+                orderMap.computeIfAbsent(vo.getOrderCode(), k -> {
+                    OrderOpenIdTransDTO dto = new OrderOpenIdTransDTO();
+                    dto.setOpenId(vo.getOpenId());
+                    dto.setTransactionId(vo.getOutTransId());
+                    return dto;
+                });
+
+                orderDetailsMap
+                        .computeIfAbsent(vo.getOrderCode(), k -> new ArrayList<>())
+                        .add(vo);
+            }
+
+            // 4. 按小程序appId分组订单(从支付记录中获取)
+            Map<String, List<FsOrderDeliveryNoteDTO>> ordersByAppId = new HashMap<>();
+            for (FsOrderDeliveryNoteDTO dto : successList) {
+                String orderNumber = dto.getOrderNumber();
+                // 通过订单号查询订单
+                FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(orderNumber);
+                if (order != null) {
+                    // 查询订单的支付记录获取appId
+                    List<FsStorePaymentScrm> paymentList = fsStorePaymentMapper.selectFsStorePaymentByOrderId(order.getId());
+                    if (!paymentList.isEmpty() && paymentList.get(0).getAppId() != null) {
+                        String orderAppId = paymentList.get(0).getAppId();
+                        ordersByAppId.computeIfAbsent(orderAppId, k -> new ArrayList<>()).add(dto);
+                        log.debug("订单号: {} 关联小程序appId: {}", orderNumber, orderAppId);
+                    } else {
+                        log.warn("订单号: {} 无法获取appId,跳过处理", orderNumber);
+                        result.addFailure(0, orderNumber, dto.getDeliveryId(), "无法获取订单对应的小程序appId,请确保订单已支付");
+                    }
+                } else {
+                    log.warn("订单号: {} 不存在,跳过处理", orderNumber);
+                    result.addFailure(0, orderNumber, dto.getDeliveryId(), "订单不存在");
+                }
+            }
+
+            if (ordersByAppId.isEmpty()) {
+                return R.error("所有订单都无法获取对应的小程序appId,请确保订单已支付");
+            }
+
+            log.info("待发货订单涉及{}个小程序,开始分组处理", ordersByAppId.size());
+
+            // 5. 按小程序分组批量上传微信发货信息
+            for (Map.Entry<String, List<FsOrderDeliveryNoteDTO>> entry : ordersByAppId.entrySet()) {
+                String currentAppId = entry.getKey();
+                List<FsOrderDeliveryNoteDTO> appOrders = entry.getValue();
+
+                log.info("处理小程序appId: {},订单数: {}", currentAppId, appOrders.size());
+
+                final WxMaService wxService = WxMaConfiguration.getMaService(currentAppId);
+                String uploadTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"))
+                        .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+
+                for (int i = 0; i < appOrders.size(); i++) {
+                    FsOrderDeliveryNoteDTO dto = appOrders.get(i);
+                    int rowNum = successList.indexOf(dto) + 2;
+                    if (StringUtils.isEmpty(dto.getOrderNumber())) {
+                        continue;
+                    }
+
+                    // 检查订单是否存在
+                    String orderNumber = dto.getOrderNumber();
+                    OrderOpenIdTransDTO orderInfo = orderMap.get(orderNumber);
+                    if (orderInfo == null) {
+                        result.addFailure(rowNum, orderNumber, dto.getDeliveryId(), "订单号不存在");
+                        continue;
+                    }
+
+                    // 验证是否开启微信发货
+                    if (config.getIsWeChatShipping() != null && config.getIsWeChatShipping()) {
+                        // 上传物流信息到微信
+                        List<FsStoreOrderCodeOpenIdVo> orderDetails = orderDetailsMap.get(orderNumber);
+                        WxShippingUploadResult uploadResult = uploadShippingInfoToWechat(wxService, orderInfo, orderDetails, dto, uploadTime, shipmentType);
+                        if (uploadResult.isSuccess()) {
+                            updateList.add(dto);
+                            result.addSuccess();
+                        } else {
+                            String failureReason = uploadResult.getErrorDesc();
+                            result.addFailure(rowNum, orderNumber, dto.getDeliveryId(), failureReason);
+                        }
+                    } else {
+                        updateList.add(dto);
+                        result.addSuccess();
+                    }
+                }
+            }
+
+            // 6. 批量更新发货记录
+            if (!updateList.isEmpty()) {
+                batchUpdateDeliveryNotes(updateList);
+            }
+
+            return R.ok(result.buildResultMessage());
+        } catch (Exception e) {
+            log.error("一键发货操作失败", e);
+            return R.error("一键发货操作失败:" + e.getMessage());
+        }
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public R importDeliveryNoteExpress(List<FsStoreOrderDeliveryNoteExportVO> voList, String appId,Integer shipmentType) {

+ 7 - 6
fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml

@@ -902,19 +902,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <set>
             delivery_sn = CASE
             <foreach collection="list" item="item">
-                WHEN id = #{item.orderNumber} THEN #{item.deliverySn}
+                WHEN order_code = #{item.orderNumber} THEN #{item.deliverySn}
             </foreach>
             ELSE delivery_sn
             END,
             delivery_name = CASE
             <foreach collection="list" item="item">
-                WHEN id = #{item.orderNumber} THEN #{item.logisticsCompany}
+                WHEN order_code = #{item.orderNumber} THEN #{item.logisticsCompany}
             </foreach>
             ELSE delivery_name
             END,
             delivery_id = CASE
             <foreach collection="list" item="item">
-                WHEN id = #{item.orderNumber} THEN #{item.deliveryId}
+                WHEN order_code = #{item.orderNumber} THEN #{item.deliveryId}
             </foreach>
             ELSE delivery_id
             END,
@@ -922,9 +922,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             WHEN status = 1 THEN 2
             ELSE status
             END,
-            delivery_send_time = NOW()
+            delivery_send_time = NOW(),
+            delivery_import_time = NOW()
         </set>
-        WHERE id IN
+        WHERE order_code IN
         <foreach collection="list" item="item" open="(" separator="," close=")">
             #{item.orderNumber}
         </foreach>
@@ -963,7 +964,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         INNER JOIN fs_user fu ON os.user_id = fu.user_id
         INNER JOIN fs_store_order_item_scrm ois ON ois.order_id = os.id
         INNER JOIN fs_store_payment_scrm sps ON os.id=sps.order_id
-                                                  WHERE os.is_del = 0 and os.id IN <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+                                                  WHERE os.is_del = 0 and os.order_code IN <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
         #{item}
     </foreach>
     AND  sps.`status` = 1