| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- <?php
- /**
- * 1688订阅消息通知处理
- *
- * 处理1688开放平台推送的订阅消息,包括订单发货通知等
- *
- * @author: yourname
- * @day: 2026/05/08
- */
- namespace app\controller\api;
- use app\common\repositories\store\order\StoreOrderStatusRepository;
- use app\services\ThirdParty\AlibabaAgent\OrderService;
- use think\facade\Db;
- use think\facade\Log;
- class AlibabaNotify
- {
- /**
- * 1688订阅消息入口
- *
- * 接收1688开放平台推送的HTTP POST通知
- * 请求格式: application/x-www-form-urlencoded
- * 参数:
- * - message: JSON字符串,包含订阅消息内容
- * - _aop_signature: 签名
- *
- * @return \think\Response
- */
- public function notify()
- {
- // 获取原始POST数据
- $postData = request()->post();
- Log::channel('alibaba')->info('[订阅消息通知] 收到请求, data:' . json_encode($postData, JSON_UNESCAPED_UNICODE));
- if (empty($postData['message'])) {
- Log::channel('alibaba')->error('[订阅消息通知] message参数为空');
- return response('fail: message is empty');
- }
- // 解析message
- $message = json_decode($postData['message'], true);
- if (json_last_error() !== JSON_ERROR_NONE) {
- Log::channel('alibaba')->error('[订阅消息通知] message JSON解析失败, message:' . $postData['message']);
- return response('fail: message json decode error');
- }
- $type = $message['type'] ?? '';
- Log::channel('alibaba')->info('[订阅消息通知] 消息类型:' . $type . ', message:' . json_encode($message, JSON_UNESCAPED_UNICODE));
- try {
- switch ($type) {
- case 'ORDER_BUYER_VIEW_ANNOUNCE_SENDGOODS':
- return $this->handleOrderSendGoods($message);
- default:
- Log::channel('alibaba')->warning('[订阅消息通知] 未知消息类型, type:' . $type);
- return response('success: unknown type');
- }
- } catch (\Throwable $e) {
- $errorMsg = $e->getMessage();
- $traceStr = $e->getTraceAsString();
- Log::channel('alibaba')->error('[订阅消息通知] 处理异常, type:' . $type . ', error:' . $errorMsg . ', file:' . $e->getFile() . ':' . $e->getLine() . ', trace:' . $traceStr);
- // 同时记录到默认日志,防止渠道日志配置问题
- Log::error('[AlibabaNotify] 处理异常: ' . $errorMsg . ' | file: ' . $e->getFile() . ':' . $e->getLine());
- return response('fail: exception - ' . $errorMsg);
- }
- }
- /**
- * 处理订单发货通知
- *
- * 订阅消息类型: ORDER_BUYER_VIEW_ANNOUNCE_SENDGOODS
- *
- * 消息内容示例:
- * {
- * "bizKey": "3300284931845138963",
- * "data": {
- * "buyerMemberId": "b2b-665170100",
- * "orderId": 3300284931845138963,
- * "currentStatus": "waitbuyerreceive",
- * "sellerMemberId": "b2b-1676547900b7bb3",
- * "msgSendTime": "2018-05-30 19:34:27"
- * },
- * "gmtBorn": 1778221635003,
- * "msgId": 189049289670,
- * "type": "ORDER_BUYER_VIEW_ANNOUNCE_SENDGOODS",
- * "userInfo": "b2b-22210711363891dff5"
- * }
- *
- * 处理流程:
- * 1. 记录日志
- * 2. 根据 data.orderId 查询本地 store_order 表(alibaba_order_id)
- * 3. 请求1688获取物流信息接口,获取物流公司和物流单号
- * 4. 更新 store_order 表的 delivery_name(快递名称)和 delivery_id(快递单号)
- *
- * @param array $message 消息内容
- * @return \think\Response
- */
- protected function handleOrderSendGoods(array $message)
- {
- $data = $message['data'] ?? [];
- $orderId = $data['orderId'] ?? 0;
- if (empty($orderId)) {
- Log::channel('alibaba')->error('[发货通知] data.orderId为空, message:' . json_encode($message, JSON_UNESCAPED_UNICODE));
- return response('fail: orderId is empty');
- }
- Log::channel('alibaba')->info('[发货通知] 开始处理, alibaba_order_id:' . $orderId . ', currentStatus:' . ($data['currentStatus'] ?? '') . ', msgSendTime:' . ($data['msgSendTime'] ?? ''));
- // 1. 根据1688订单号查询本地订单
- $storeOrder = Db::name('store_order')
- ->where('alibaba_order_id', (string)$orderId)
- ->find();
- if (empty($storeOrder)) {
- Log::channel('alibaba')->warning('[发货通知] 未找到匹配的本地订单, alibaba_order_id:' . $orderId);
- return response('success: order not found locally');
- }
- Log::channel('alibaba')->info('[发货通知] 找到本地订单, order_id:' . $storeOrder['order_id'] . ', order_sn:' . $storeOrder['order_sn']);
- // 2. 如果已有物流信息,跳过
- if (!empty($storeOrder['delivery_name']) && !empty($storeOrder['delivery_id'])) {
- Log::channel('alibaba')->info('[发货通知] 订单已有物流信息,跳过更新, order_id:' . $storeOrder['order_id'] . ', delivery_name:' . $storeOrder['delivery_name'] . ', delivery_id:' . $storeOrder['delivery_id']);
- return response('success: already has logistics info');
- }
- // 3. 请求1688获取物流信息
- $orderService = new OrderService();
- $logisticsResult = $orderService->getLogisticsInfosBuyerView([
- 'orderId' => $orderId,
- ]);
- if ($logisticsResult === false || empty($logisticsResult['logisticsItems'])) {
- Log::channel('alibaba')->warning('[发货通知] 获取物流信息失败或物流信息为空, alibaba_order_id:' . $orderId . ', result:' . json_encode($logisticsResult, JSON_UNESCAPED_UNICODE));
- return response('success: no logistics info yet');
- }
- // 4. 取第一条物流信息
- $firstLogistics = $logisticsResult['logisticsItems'][0];
- $deliveryName = $firstLogistics['logisticsName'] ?? '';
- $deliveryId = $firstLogistics['logisticsCode'] ?? '';
- if (empty($deliveryName) || empty($deliveryId)) {
- Log::channel('alibaba')->warning('[发货通知] 物流信息不完整, logistics:' . json_encode($firstLogistics, JSON_UNESCAPED_UNICODE));
- return response('success: logistics info incomplete');
- }
- // 5. 更新 store_order 表
- $updateData = [
- 'delivery_type' => 1,
- 'delivery_name' => $deliveryName,
- 'delivery_id' => $deliveryId,
- 'status' => 1, // 待收货
- ];
- Db::name('store_order')
- ->where('order_id', $storeOrder['order_id'])
- ->update($updateData);
- app()->make(StoreOrderStatusRepository::class)->status($storeOrder['order_id'], 'delivery_0', '订单以配送【快递名称】:' . $deliveryName . '; 【快递单号】:' . $deliveryId);
- Log::channel('alibaba')->info('[发货通知] 物流信息更新成功, order_id:' . $storeOrder['order_id'] . ', order_sn:' . $storeOrder['order_sn'] . ', delivery_name:' . $deliveryName . ', delivery_id:' . $deliveryId);
- return response('success');
- }
- }
|