Procházet zdrojové kódy

feat(alibaba): 添加物流信息获取功能并优化日志记录

- 新增 getLogisticsInfosBuyerView 方法用于获取1688订单物流信息
- 添加 formatLogisticsInfosResult 方法用于格式化物流信息返回结果
- 优化日志记录格式,将数组参数改为字符串拼接方式
- 统一错误处理和异常捕获的日志记录方式
- 在异常处理中同时记录到默认日志渠道以防配置问题
- 完善物流信息处理流程中的日志记录内容
shichen před 2 měsíci
rodič
revize
6f48ad380e

+ 18 - 37
app/controller/api/AlibabaNotify.php

@@ -33,7 +33,7 @@ class AlibabaNotify
33
         // 获取原始POST数据
33
         // 获取原始POST数据
34
         $postData = request()->post();
34
         $postData = request()->post();
35
 
35
 
36
-        Log::channel('alibaba')->info('[订阅消息通知] 收到请求', ['data' => json_encode($postData, JSON_UNESCAPED_UNICODE)]);
36
+        Log::channel('alibaba')->info('[订阅消息通知] 收到请求, data:' . json_encode($postData, JSON_UNESCAPED_UNICODE));
37
 
37
 
38
         if (empty($postData['message'])) {
38
         if (empty($postData['message'])) {
39
             Log::channel('alibaba')->error('[订阅消息通知] message参数为空');
39
             Log::channel('alibaba')->error('[订阅消息通知] message参数为空');
@@ -43,28 +43,28 @@ class AlibabaNotify
43
         // 解析message
43
         // 解析message
44
         $message = json_decode($postData['message'], true);
44
         $message = json_decode($postData['message'], true);
45
         if (json_last_error() !== JSON_ERROR_NONE) {
45
         if (json_last_error() !== JSON_ERROR_NONE) {
46
-            Log::channel('alibaba')->error('[订阅消息通知] message JSON解析失败', ['message' => $postData['message']]);
46
+            Log::channel('alibaba')->error('[订阅消息通知] message JSON解析失败, message:' . $postData['message']);
47
             return response('fail: message json decode error');
47
             return response('fail: message json decode error');
48
         }
48
         }
49
 
49
 
50
         $type = $message['type'] ?? '';
50
         $type = $message['type'] ?? '';
51
-        Log::channel('alibaba')->info('[订阅消息通知] 消息类型', ['type' => $type, 'message' => $message]);
51
+        Log::channel('alibaba')->info('[订阅消息通知] 消息类型:' . $type . ', message:' . json_encode($message, JSON_UNESCAPED_UNICODE));
52
 
52
 
53
         try {
53
         try {
54
             switch ($type) {
54
             switch ($type) {
55
                 case 'ORDER_BUYER_VIEW_ANNOUNCE_SENDGOODS':
55
                 case 'ORDER_BUYER_VIEW_ANNOUNCE_SENDGOODS':
56
                     return $this->handleOrderSendGoods($message);
56
                     return $this->handleOrderSendGoods($message);
57
                 default:
57
                 default:
58
-                    Log::channel('alibaba')->warning('[订阅消息通知] 未知消息类型', ['type' => $type]);
58
+                    Log::channel('alibaba')->warning('[订阅消息通知] 未知消息类型, type:' . $type);
59
                     return response('success: unknown type');
59
                     return response('success: unknown type');
60
             }
60
             }
61
         } catch (\Throwable $e) {
61
         } catch (\Throwable $e) {
62
-            Log::channel('alibaba')->error('[订阅消息通知] 处理异常', [
63
-                'type'    => $type,
64
-                'error'   => $e->getMessage(),
65
-                'trace'   => $e->getTraceAsString(),
66
-            ]);
67
-            return response('fail: exception - ' . $e->getMessage());
62
+            $errorMsg = $e->getMessage();
63
+            $traceStr = $e->getTraceAsString();
64
+            Log::channel('alibaba')->error('[订阅消息通知] 处理异常, type:' . $type . ', error:' . $errorMsg . ', file:' . $e->getFile() . ':' . $e->getLine() . ', trace:' . $traceStr);
65
+            // 同时记录到默认日志,防止渠道日志配置问题
66
+            Log::error('[AlibabaNotify] 处理异常: ' . $errorMsg . ' | file: ' . $e->getFile() . ':' . $e->getLine());
67
+            return response('fail: exception - ' . $errorMsg);
68
         }
68
         }
69
     }
69
     }
70
 
70
 
@@ -104,15 +104,11 @@ class AlibabaNotify
104
         $orderId = $data['orderId'] ?? 0;
104
         $orderId = $data['orderId'] ?? 0;
105
 
105
 
106
         if (empty($orderId)) {
106
         if (empty($orderId)) {
107
-            Log::channel('alibaba')->error('[发货通知] data.orderId为空', ['message' => $message]);
107
+            Log::channel('alibaba')->error('[发货通知] data.orderId为空, message:' . json_encode($message, JSON_UNESCAPED_UNICODE));
108
             return response('fail: orderId is empty');
108
             return response('fail: orderId is empty');
109
         }
109
         }
110
 
110
 
111
-        Log::channel('alibaba')->info('[发货通知] 开始处理', [
112
-            'alibaba_order_id' => $orderId,
113
-            'currentStatus'    => $data['currentStatus'] ?? '',
114
-            'msgSendTime'      => $data['msgSendTime'] ?? '',
115
-        ]);
111
+        Log::channel('alibaba')->info('[发货通知] 开始处理, alibaba_order_id:' . $orderId . ', currentStatus:' . ($data['currentStatus'] ?? '') . ', msgSendTime:' . ($data['msgSendTime'] ?? ''));
116
 
112
 
117
         // 1. 根据1688订单号查询本地订单
113
         // 1. 根据1688订单号查询本地订单
118
         $storeOrder = Db::name('store_order')
114
         $storeOrder = Db::name('store_order')
@@ -120,22 +116,15 @@ class AlibabaNotify
120
             ->find();
116
             ->find();
121
 
117
 
122
         if (empty($storeOrder)) {
118
         if (empty($storeOrder)) {
123
-            Log::channel('alibaba')->warning('[发货通知] 未找到匹配的本地订单', ['alibaba_order_id' => $orderId]);
119
+            Log::channel('alibaba')->warning('[发货通知] 未找到匹配的本地订单, alibaba_order_id:' . $orderId);
124
             return response('success: order not found locally');
120
             return response('success: order not found locally');
125
         }
121
         }
126
 
122
 
127
-        Log::channel('alibaba')->info('[发货通知] 找到本地订单', [
128
-            'order_id'  => $storeOrder['order_id'],
129
-            'order_sn'  => $storeOrder['order_sn'],
130
-        ]);
123
+        Log::channel('alibaba')->info('[发货通知] 找到本地订单, order_id:' . $storeOrder['order_id'] . ', order_sn:' . $storeOrder['order_sn']);
131
 
124
 
132
         // 2. 如果已有物流信息,跳过
125
         // 2. 如果已有物流信息,跳过
133
         if (!empty($storeOrder['delivery_name']) && !empty($storeOrder['delivery_id'])) {
126
         if (!empty($storeOrder['delivery_name']) && !empty($storeOrder['delivery_id'])) {
134
-            Log::channel('alibaba')->info('[发货通知] 订单已有物流信息,跳过更新', [
135
-                'order_id'       => $storeOrder['order_id'],
136
-                'delivery_name'  => $storeOrder['delivery_name'],
137
-                'delivery_id'    => $storeOrder['delivery_id'],
138
-            ]);
127
+            Log::channel('alibaba')->info('[发货通知] 订单已有物流信息,跳过更新, order_id:' . $storeOrder['order_id'] . ', delivery_name:' . $storeOrder['delivery_name'] . ', delivery_id:' . $storeOrder['delivery_id']);
139
             return response('success: already has logistics info');
128
             return response('success: already has logistics info');
140
         }
129
         }
141
 
130
 
@@ -146,10 +135,7 @@ class AlibabaNotify
146
         ]);
135
         ]);
147
 
136
 
148
         if ($logisticsResult === false || empty($logisticsResult['logisticsItems'])) {
137
         if ($logisticsResult === false || empty($logisticsResult['logisticsItems'])) {
149
-            Log::channel('alibaba')->warning('[发货通知] 获取物流信息失败或物流信息为空', [
150
-                'alibaba_order_id' => $orderId,
151
-                'result'           => $logisticsResult,
152
-            ]);
138
+            Log::channel('alibaba')->warning('[发货通知] 获取物流信息失败或物流信息为空, alibaba_order_id:' . $orderId . ', result:' . json_encode($logisticsResult, JSON_UNESCAPED_UNICODE));
153
             return response('success: no logistics info yet');
139
             return response('success: no logistics info yet');
154
         }
140
         }
155
 
141
 
@@ -159,7 +145,7 @@ class AlibabaNotify
159
         $deliveryId   = $firstLogistics['logisticsCode'] ?? '';
145
         $deliveryId   = $firstLogistics['logisticsCode'] ?? '';
160
 
146
 
161
         if (empty($deliveryName) || empty($deliveryId)) {
147
         if (empty($deliveryName) || empty($deliveryId)) {
162
-            Log::channel('alibaba')->warning('[发货通知] 物流信息不完整', ['logistics' => $firstLogistics]);
148
+            Log::channel('alibaba')->warning('[发货通知] 物流信息不完整, logistics:' . json_encode($firstLogistics, JSON_UNESCAPED_UNICODE));
163
             return response('success: logistics info incomplete');
149
             return response('success: logistics info incomplete');
164
         }
150
         }
165
 
151
 
@@ -177,12 +163,7 @@ class AlibabaNotify
177
 
163
 
178
         app()->make(StoreOrderStatusRepository::class)->status($storeOrder['order_id'], 'delivery_0', '订单以配送【快递名称】:' . $deliveryName . '; 【快递单号】:' . $deliveryId);
164
         app()->make(StoreOrderStatusRepository::class)->status($storeOrder['order_id'], 'delivery_0', '订单以配送【快递名称】:' . $deliveryName . '; 【快递单号】:' . $deliveryId);
179
 
165
 
180
-        Log::channel('alibaba')->info('[发货通知] 物流信息更新成功', [
181
-            'order_id'       => $storeOrder['order_id'],
182
-            'order_sn'       => $storeOrder['order_sn'],
183
-            'delivery_name'  => $deliveryName,
184
-            'delivery_id'    => $deliveryId,
185
-        ]);
166
+        Log::channel('alibaba')->info('[发货通知] 物流信息更新成功, order_id:' . $storeOrder['order_id'] . ', order_sn:' . $storeOrder['order_sn'] . ', delivery_name:' . $deliveryName . ', delivery_id:' . $deliveryId);
186
 
167
 
187
         return response('success');
168
         return response('success');
188
     }
169
     }

+ 91 - 0
app/services/ThirdParty/AlibabaAgent/OrderService.php

@@ -397,4 +397,95 @@ class OrderService extends AlibabaAgentBaseService
397
             'districtCode'   => $districtCode,
397
             'districtCode'   => $districtCode,
398
         ];
398
         ];
399
     }
399
     }
400
+
401
+    /**
402
+     * 获取交易订单的物流信息(买家视角)
403
+     *
404
+     * API: com.alibaba.trade:alibaba.trade.get.logisticsInfos.buyerView-1
405
+     *
406
+     * 接口文档: https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade%3Aalibaba.trade.get.logisticsInfos.buyerView-1
407
+     *
408
+     * 请求参数:
409
+     *   - orderId: 1688订单ID(必填)
410
+     *   - webSite: 1688站点(可选,默认"1688")
411
+     *
412
+     * 返回示例:
413
+     * {
414
+     *   "result": {
415
+     *     "logisticsItems": [{
416
+     *       "logisticsId": "LP001",
417
+     *       "logisticsCode": "SF1234567890",   // 物流单号
418
+     *       "logisticsName": "顺丰速运",        // 物流公司名称
419
+     *       "logisticsCompany": "shunfeng",     // 物流公司编码
420
+     *       "status": "accept",                 // 物流状态
421
+     *       "gmtCreate": "2018-05-30 19:34:27"
422
+     *     }]
423
+     *   },
424
+     *   "success": true
425
+     * }
426
+     *
427
+     * @param array $params 请求参数(orderId 必填)
428
+     * @return array|false
429
+     */
430
+    public function getLogisticsInfosBuyerView(array $params = [])
431
+    {
432
+        // --- 参数校验 ---
433
+        if (empty($params['orderId'])) {
434
+            Log::channel('alibaba')->error('[获取物流信息] orderId不能为空');
435
+            return false;
436
+        }
437
+
438
+        $businessParams = [
439
+            'orderId' => (string)$params['orderId'],
440
+            'webSite' => $params['webSite'] ?? '1688',
441
+        ];
442
+
443
+        // --- 调用API ---
444
+        $result = $this->executeParam2(
445
+            self::NAMESPACE,
446
+            'alibaba.trade.get.logisticsInfos.buyerView',
447
+            1,
448
+            $businessParams
449
+        );
450
+
451
+        if ($result === false) {
452
+            Log::channel('alibaba')->error('[获取物流信息] API请求失败, params:' . json_encode($businessParams, JSON_UNESCAPED_UNICODE));
453
+            return false;
454
+        }
455
+
456
+        Log::channel('alibaba')->info('[获取物流信息] API请求成功, result:' . json_encode($result, JSON_UNESCAPED_UNICODE));
457
+
458
+        return $this->formatLogisticsInfosResult($result);
459
+    }
460
+
461
+    /**
462
+     * 格式化物流信息返回结果
463
+     *
464
+     * @param array $result API原始返回数据
465
+     * @return array
466
+     */
467
+    protected function formatLogisticsInfosResult(array $result): array
468
+    {
469
+        $success = $result['success'] ?? false;
470
+        $logisticsItems = [];
471
+
472
+        if (isset($result['result']['logisticsItems']) && is_array($result['result']['logisticsItems'])) {
473
+            foreach ($result['result']['logisticsItems'] as $item) {
474
+                $logisticsItems[] = [
475
+                    'logisticsId'      => $item['logisticsId'] ?? '',
476
+                    'logisticsCode'    => $item['logisticsCode'] ?? '',    // 物流单号
477
+                    'logisticsName'    => $item['logisticsName'] ?? '',    // 物流公司名称
478
+                    'logisticsCompany' => $item['logisticsCompany'] ?? '', // 物流公司编码
479
+                    'status'           => $item['status'] ?? '',
480
+                    'gmtCreate'        => $item['gmtCreate'] ?? '',
481
+                ];
482
+            }
483
+        }
484
+
485
+        return [
486
+            'success'         => $success,
487
+            'logisticsItems'  => $logisticsItems,
488
+            'rawData'         => $result,
489
+        ];
490
+    }
400
 }
491
 }