Просмотр исходного кода

Merge branch 'zhongqi-delivery' into dev

shizhongqi 9 месяцев назад
Родитель
Сommit
e5a3bb7083

+ 8 - 3
app-ghs/controllers/DeliveryController.php

@@ -525,9 +525,14 @@ class DeliveryController extends BaseController
         }
         Yii::info('shansong 回调 -- post: ' . json_encode($callbackData, JSON_UNESCAPED_UNICODE));
 
-        $get = Yii::$app->request->get();
-        Yii::info('shansong 回调 -- get: ' . json_encode($get, JSON_UNESCAPED_UNICODE));
-        return $this->asJson(['status' => 200, 'msg' => 'OK', "data"=> null]);
+        $obj = new \common\components\delivery\platform\shanSong\OrderStatusCallBack();
+        $ret = $obj->handle($callbackData);
+        if($ret) {
+            return $this->asJson(['status' => 200, 'msg' => 'OK', "data"=> null]);
+        } else {
+            Yii::error('闪送回调失败: ' . json_encode($callbackData, JSON_UNESCAPED_UNICODE));
+            return $this->asJson(['status' => 200, 'msg' => '回调失败', "data"=> null]);
+        }
     }
 
     /**

+ 197 - 0
common/components/delivery/platform/shansong/OrderStatusCallBack.php

@@ -0,0 +1,197 @@
+<?php
+namespace common\components\delivery\platform\shanSong;
+
+use bizGhs\express\classes\GhsDeliveryOrderClass;
+use bizGhs\order\classes\OrderClass;
+use Yii;
+
+/**
+ * 闪送订单状态回调处理类
+ * Class OrderStatusCallBack
+ * @package common\components\delivery\platform\shanSong
+ */
+class OrderStatusCallBack
+{
+    /**
+     * 处理闪送订单状态回调
+     * 
+     * @param array $data 回调数据
+     * @return bool 处理结果
+     */
+    public function handle($data)
+    {
+        try {
+            // 记录回调原始数据
+            Yii::info('闪送订单状态回调 - 原始数据: ' . json_encode($data, JSON_UNESCAPED_UNICODE), 'shansong-callback');
+            
+            // 验证必要参数
+            if (empty($data['issOrderNo']) || !isset($data['status'])) {
+                Yii::error('闪送回调参数不完整: ' . json_encode($data, JSON_UNESCAPED_UNICODE), 'shansong-callback');
+                return false;
+            }
+            
+            // 查找配送订单
+            $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
+                'deliveryId' => 'shansong', 
+                'orderId' => $data['issOrderNo']
+            ], true);
+            
+            if (!$deliveryOrder) {
+                Yii::error('闪送订单不存在: issOrderNo=' . $data['issOrderNo'], 'shansong-callback');
+                return false;
+            }
+            
+            // 将闪送平台的订单状态转换为系统内的 orderStatus
+            $subStatus = isset($data['subStatus']) ? $data['subStatus'] : null;
+            $sendStatus = OrderStatusUtil::convertOrderStatus($data['status'], $subStatus);
+            
+            
+            // 处理骑手信息
+            $this->handleCourierInfo($data, $deliveryOrder);
+            // 处理取消信息
+            $this->handleCancelInfo($data, $deliveryOrder);
+            // 处理费用信息
+            $this->handleFeeInfo($data, $deliveryOrder);
+            // 处理密码信息
+            $this->handlePasswordInfo($data, $deliveryOrder);
+            
+            // 更新配送订单状态
+            $deliveryOrder->orderStatus = $sendStatus;
+            $deliveryOrder->save();
+            
+            // 更新主订单状态
+            $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendType,sendStatus,deliveryId');
+            if ($order) {
+                $order->sendStatus = $sendStatus;
+                $order->save();
+            }
+            
+            Yii::info('闪送订单状态更新成功: issOrderNo=' . $data['issOrderNo'] . 
+                     ', status=' . $data['status'] . 
+                     ', sendStatus=' . $sendStatus, 'shansong-callback');
+            return true;
+        } catch (\Exception $e) {
+            Yii::error('闪送回调处理异常: ' . $e->getMessage() . 
+                      ' | Trace: ' . $e->getTraceAsString(), 'shansong-callback');
+            return false;
+        }
+    }
+    
+    /**
+     * 处理骑手信息
+     * 
+     * @param array $data 回调数据
+     * @param object $deliveryOrder 配送订单对象
+     */
+    private function handleCourierInfo($data, $deliveryOrder)
+    {
+        if (isset($data['courier']) && is_array($data['courier'])) {
+            $courier = $data['courier'];
+            
+            Yii::info($data['issOrderNo'] . '-闪送骑手信息: ' . json_encode([
+                'name' => $courier['name'] ?? '',
+                'mobile' => $courier['mobile'] ?? '',
+                'id' => $courier['id'] ?? '',
+                'headIcon' => $courier['headIcon'] ?? '',
+                'latitude' => $courier['latitude'] ?? '',
+                'longitude' => $courier['longitude'] ?? '',
+                'time' => $courier['time'] ?? '',
+                'orderCount' => $courier['orderCount'] ?? 0,
+                'estimateDeliveryTimeTip' => $courier['estimateDeliveryTimeTip'] ?? '',
+            ], JSON_UNESCAPED_UNICODE), 'shansong-callback');
+            
+            // TODO: 保存到数据库字段
+            // $deliveryOrder->courierName = $courier['name'] ?? '';
+            // $deliveryOrder->courierPhone = $courier['mobile'] ?? '';
+            // $deliveryOrder->courierId = $courier['id'] ?? '';
+            // $deliveryOrder->courierHeadIcon = $courier['headIcon'] ?? '';
+            // $deliveryOrder->courierLatitude = $courier['latitude'] ?? '';
+            // $deliveryOrder->courierLongitude = $courier['longitude'] ?? '';
+            // $deliveryOrder->courierTime = $courier['time'] ?? '';
+            // $deliveryOrder->estimateDeliveryTimeTip = $courier['estimateDeliveryTimeTip'] ?? '';
+            
+            // 处理配送轨迹(如需要)
+            if (isset($courier['deliveryProcessTrail']) && is_array($courier['deliveryProcessTrail'])) {
+                Yii::info('闪送配送轨迹: ' . json_encode($courier['deliveryProcessTrail'], JSON_UNESCAPED_UNICODE), 'shansong-callback');
+                // TODO: 如需要可以保存到单独的轨迹表或JSON字段
+            }
+        }
+    }
+    
+    /**
+     * 处理取消信息
+     * 
+     * @param array $data 回调数据
+     * @param object $deliveryOrder 配送订单对象
+     */
+    private function handleCancelInfo($data, $deliveryOrder)
+    {
+        // 订单取消时(status=60)会返回取消相关信息
+        if (isset($data['status']) && $data['status'] == 60) {
+            $abortType = $data['abortType'] ?? null;
+            $punishType = $data['punishType'] ?? null;
+            $abortReason = $data['abortReason'] ?? '';
+            
+            Yii::info($data['issOrderNo'] . '-闪送取消信息: ' . json_encode([
+                'abortType' => $abortType,
+                'abortTypeDesc' => $abortType ? OrderStatusUtil::getAbortTypeDesc($abortType) : '',
+                'punishType' => $punishType,
+                'punishTypeDesc' => $punishType ? OrderStatusUtil::getPunishTypeDesc($punishType) : '',
+                'abortReason' => $abortReason,
+            ], JSON_UNESCAPED_UNICODE), 'shansong-callback');
+            
+            // TODO: 保存到数据库字段
+            // $deliveryOrder->abortType = $abortType;
+            // $deliveryOrder->punishType = $punishType;
+            // $deliveryOrder->abortReason = $abortReason;
+        }
+    }
+    
+    /**
+     * 处理费用信息
+     * 
+     * @param array $data 回调数据
+     * @param object $deliveryOrder 配送订单对象
+     */
+    private function handleFeeInfo($data, $deliveryOrder)
+    {
+        $deductAmount = $data['deductAmount'] ?? 0;
+        $drawback = $data['drawback'] ?? 0;
+        $sendBackFee = $data['sendBackFee'] ?? 0;
+        
+        // 记录费用信息(金额单位:分)
+        if ($deductAmount > 0 || $drawback > 0 || $sendBackFee > 0) {
+            Yii::info($data['issOrderNo'] . '-闪送费用信息: ' . json_encode([
+                'deductAmount' => $deductAmount, // 扣款金额
+                'drawback' => $drawback, // 退款金额
+                'sendBackFee' => $sendBackFee, // 送回费
+            ], JSON_UNESCAPED_UNICODE), 'shansong-callback');
+            
+            // 保存到数据库字段 | 扣款金额 + 送回费
+            $deliveryOrder->cancelCost = $deductAmount + $sendBackFee;
+        }
+    }
+    
+    /**
+     * 处理密码信息
+     * 
+     * @param array $data 回调数据
+     * @param object $deliveryOrder 配送订单对象
+     */
+    private function handlePasswordInfo($data, $deliveryOrder)
+    {
+        $pickupPassword = $data['pickupPassword'] ?? '';
+        $deliveryPassword = $data['deliveryPassword'] ?? '';
+        
+        if (!empty($pickupPassword) || !empty($deliveryPassword)) {
+            Yii::info($data['issOrderNo'] . '-闪送密码信息: ' . json_encode([
+                'pickupPassword' => $pickupPassword,
+                'deliveryPassword' => $deliveryPassword,
+            ], JSON_UNESCAPED_UNICODE), 'shansong-callback');
+            
+            // TODO: 保存到数据库字段
+            // $deliveryOrder->pickupPassword = $pickupPassword;
+            // $deliveryOrder->deliveryPassword = $deliveryPassword;
+        }
+    }
+}

+ 197 - 0
common/components/delivery/platform/shansong/OrderStatusUtil.php

@@ -0,0 +1,197 @@
+<?php
+namespace common\components\delivery\platform\shanSong;
+
+/**
+ * Class OrderStatusUtil
+ * 闪送配送平台状态转换工具类
+ * @package common\components\delivery\platform\shanSong
+ */
+class OrderStatusUtil
+{
+    /**
+     * 闪送平台订单状态到系统 orderStatus 的转换映射
+     * 
+     * 闪送平台状态码说明:
+     * 20 - 派单中(转单改派中)
+     *      subStatus: 1-派单中, 2-转单改派中
+     * 30 - 待取货(已就位)
+     *      subStatus: 1-待取货, 2-已就位
+     * 40 - 闪送中(申请取消中、物品送回中、取消单客服介入中)
+     *      subStatus: 1-闪送中, 2-申请取消中, 3-物品送回中, 4-取消单客服介入中
+     * 50 - 已完成(已退款)
+     *      subStatus: 1-已完成, 2-已退款
+     * 60 - 已取消
+     * 
+     * 系统内 orderStatus 状态码说明:
+     *  0 - 订单生成
+     *  1 - 系统已接单
+     *  2 - 派单中
+     *  3 - 待取货
+     *  4 - 配送中
+     *  5 - 已送达
+     * -1 - 已取消
+     * -2 - 异常
+     * 10 - 改派中
+     * 20 - 已分配骑手
+     * 30 - 骑手已到店
+     * 40 - 申请取消中
+     * 50 - 客服介入处理中
+     */
+    const STATUS_MAPPING = [
+        20 => 2,   // 派单中 -> 派单中
+        30 => 3,   // 待取货 -> 待取货
+        40 => 4,   // 闪送中 -> 配送中
+        50 => 5,   // 已完成 -> 已送达
+        60 => -1,  // 已取消 -> 已取消
+    ];
+
+    /**
+     * 子状态到系统状态的特殊映射
+     * 格式:[主状态 => [子状态 => 系统状态]]
+     */
+    const SUB_STATUS_MAPPING = [
+        20 => [
+            1 => 2,   // 派单中 -> 派单中
+            2 => 10,  // 转单改派中 -> 改派中
+        ],
+        30 => [
+            1 => 3,   // 待取货 -> 待取货
+            2 => 30,  // 已就位 -> 骑手已到店
+        ],
+        40 => [
+            1 => 4,   // 闪送中 -> 配送中
+            2 => 40,  // 申请取消中 -> 申请取消中
+            3 => 4,   // 物品送回中 -> 配送中
+            4 => 50,  // 取消单客服介入中 -> 客服介入处理中
+        ],
+        50 => [
+            1 => 5,   // 已完成 -> 已送达
+            2 => 5,   // 已退款 -> 已送达
+        ],
+    ];
+
+    /**
+     * 将闪送平台的订单状态转换为系统内的 orderStatus
+     * 
+     * @param int $shansongStatus 闪送平台的订单状态码
+     * @param int|null $subStatus 闪送平台的订单子状态码(可选)
+     * @return int 转换后的系统 orderStatus 状态码
+     * @throws \Exception 当状态码无法转换时抛出异常
+     */
+    public static function convertOrderStatus($shansongStatus, $subStatus = null)
+    {
+        $shansongStatus = (int)$shansongStatus;
+        
+        // 如果提供了子状态,优先使用子状态映射
+        if ($subStatus !== null) {
+            $subStatus = (int)$subStatus;
+            if (isset(self::SUB_STATUS_MAPPING[$shansongStatus][$subStatus])) {
+                return self::SUB_STATUS_MAPPING[$shansongStatus][$subStatus];
+            }
+        }
+        
+        // 使用主状态映射
+        if (!isset(self::STATUS_MAPPING[$shansongStatus])) {
+            throw new \Exception("无效的闪送订单状态码:{$shansongStatus}");
+        }
+        
+        return self::STATUS_MAPPING[$shansongStatus];
+    }
+
+    /**
+     * 获取闪送平台的状态描述
+     * 
+     * @param int $shansongStatus 闪送平台的订单状态码
+     * @param int|null $subStatus 闪送平台的订单子状态码(可选)
+     * @return string 状态描述
+     */
+    public static function getStatusDesc($shansongStatus, $subStatus = null)
+    {
+        $mainStatusDescMap = [
+            20 => '派单中',
+            30 => '待取货',
+            40 => '闪送中',
+            50 => '已完成',
+            60 => '已取消',
+        ];
+        
+        $subStatusDescMap = [
+            20 => [1 => '派单中', 2 => '转单改派中'],
+            30 => [1 => '待取货', 2 => '已就位'],
+            40 => [1 => '闪送中', 2 => '申请取消中', 3 => '物品送回中', 4 => '取消单客服介入中'],
+            50 => [1 => '已完成', 2 => '已退款'],
+        ];
+        
+        $mainDesc = $mainStatusDescMap[$shansongStatus] ?? '未知状态';
+        
+        if ($subStatus !== null && isset($subStatusDescMap[$shansongStatus][$subStatus])) {
+            return $subStatusDescMap[$shansongStatus][$subStatus];
+        }
+        
+        return $mainDesc;
+    }
+
+    /**
+     * 获取系统 orderStatus 的状态描述
+     * 
+     * @param int $orderStatus 系统的 orderStatus 状态码
+     * @return string 状态描述
+     */
+    public static function getOrderStatusDesc($orderStatus)
+    {
+        $statusDescMap = [
+            0   => '订单生成',
+            1   => '系统已接单',
+            2   => '派单中',
+            3   => '待取货',
+            4   => '配送中',
+            5   => '已送达',
+            -1  => '已取消',
+            -2  => '异常',
+            10  => '改派中',
+            20  => '已分配骑手',
+            30  => '骑手已到店',
+            40  => '申请取消中',
+            50  => '客服介入处理中',
+        ];
+        
+        return $statusDescMap[$orderStatus] ?? '未知状态';
+    }
+
+    /**
+     * 获取取消发起人描述
+     * 
+     * @param int $abortType 取消发起人类型
+     * @return string 描述
+     */
+    public static function getAbortTypeDesc($abortType)
+    {
+        $descMap = [
+            1  => '客户发起取消',
+            3  => '闪送员发起取消',
+            10 => '系统自动发起取消',
+        ];
+        
+        return $descMap[$abortType] ?? '未知';
+    }
+
+    /**
+     * 获取取消责任人描述
+     * 
+     * @param int $punishType 取消责任人类型
+     * @return string 描述
+     */
+    public static function getPunishTypeDesc($punishType)
+    {
+        $descMap = [
+            1  => '因客户',
+            2  => '因服务',
+            3  => '因闪送员',
+            10 => '因系统自动取消',
+            99 => '因其它',
+        ];
+        
+        return $descMap[$punishType] ?? '未知';
+    }
+}
+