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

Merge branch 'zhongqi-delivery'

shish 8 месяцев назад
Родитель
Сommit
cdb5eb7091

+ 43 - 14
app-ghs/controllers/DeliveryController.php

@@ -251,19 +251,19 @@ class DeliveryController extends BaseController
 
 
         $post = $form->getAttributes();
         $post = $form->getAttributes();
         $orderId = $post['orderId'] ?? 0; // xhGhsOrder.id
         $orderId = $post['orderId'] ?? 0; // xhGhsOrder.id
-        $params = $post['allParams'] ?? '';
+        $params = $post['allParams'] ?? [];
         $platform = $params['en_name'] ?? '';// 平台英文名,$post['platform'] 是中文
         $platform = $params['en_name'] ?? '';// 平台英文名,$post['platform'] 是中文
         if (empty($platform)) {
         if (empty($platform)) {
             util::fail('请选择跑腿');
             util::fail('请选择跑腿');
         }
         }
-        $pickupTime = $post['pickupTime'] ?? '';
+        $pickupTime = $post['pickupTime'];
 
 
         $params['mainId'] = $this->mainId;
         $params['mainId'] = $this->mainId;
         $params['ip'] = Yii::$app->request->userIP;
         $params['ip'] = Yii::$app->request->userIP;
-        $params['weight'] = $post['weight'] ?? 1;
+        $params['weight'] = $post['weight'];
         $params['remark'] = $post['remark'] ?? '';
         $params['remark'] = $post['remark'] ?? '';
-        $params['total_price_fen'] = $post['price'] ?? 1;
-        $params['pickupTime'] = $pickupTime['value'] ?? '';
+        $params['total_price_fen'] = $post['price'];
+        $params['pickupTime'] = $pickupTime['value'];
 
 
         $ghsOrder = OrderClass::getById($orderId, true);
         $ghsOrder = OrderClass::getById($orderId, true);
         if (empty($ghsOrder)) {
         if (empty($ghsOrder)) {
@@ -297,6 +297,11 @@ class DeliveryController extends BaseController
                     'fee' => $ret['data']['fee'],
                     'fee' => $ret['data']['fee'],
                     'orderStatus' => 0
                     'orderStatus' => 0
                 ];
                 ];
+
+                if($platform == 'didi'){
+                    $data['createdAt'] = date('Y-m-d H:i:s', $ret['data']['timeStamp']);
+                }
+
                 GhsDeliveryOrderClass::add($data);
                 GhsDeliveryOrderClass::add($data);
             } else {
             } else {
                 Yii::info('重复创建订单');
                 Yii::info('重复创建订单');
@@ -410,33 +415,37 @@ class DeliveryController extends BaseController
         }
         }
         if ($platform == 'didi') {
         if ($platform == 'didi') {
             $order = OrderClass::getById($gdo->ghsOrderId, false, 'id,orderSn');
             $order = OrderClass::getById($gdo->ghsOrderId, false, 'id,orderSn');
-            $post['outOrderNo'] = $order['orderSn'];
+            $timeStamp = strtotime($gdo->createdAt);
+            $post['outOrderNo'] = \common\components\delivery\platform\didi\Didi::generateUniOroder($order['orderSn'], $timeStamp);
             $post['cancelSource'] = 1; // TODO 要增加取消码判断
             $post['cancelSource'] = 1; // TODO 要增加取消码判断
         }
         }
 
 
         $post['order_cancel_role'] = 1; //1:商户取消, 2:用户取消
         $post['order_cancel_role'] = 1; //1:商户取消, 2:用户取消
         $ret = $ds->cancelOrder($orderId, $post);
         $ret = $ds->cancelOrder($orderId, $post);
         if ($ret['code'] == 0) {
         if ($ret['code'] == 0) {
-            // 更新跑腿订单与批发订单状态
-            $gdo->orderStatus = -1;
+            $ghsOrder = OrderClass::getById($ghsOrderId, true, 'id, sendDistance, sendStatus, deliveryId, purchaseId, status');
+            $ghsOrder->sendDistance = 0;
+
+            // 测试发现取消配送没回调的平台,统一在这主动更新配送状态
+            if(in_array($platform, ['shunfeng'])){
+                $ghsOrder->sendStatus = -1;
+                OrderClass::cancelOrderSend($ghsOrder, ['staffId' => 0, 'staffName' => '']);
+
+                // 更新跑腿订单与批发订单状态
+                $gdo->orderStatus = -1;
+            }
             $gdo->cancelCost = $ret['platform'] !== 'fengniao' ? $ret['data']['deductionFee'] : $cancelCostCent; // 由于蜂鸟平台返回的扣费不一样造成
             $gdo->cancelCost = $ret['platform'] !== 'fengniao' ? $ret['data']['deductionFee'] : $cancelCostCent; // 由于蜂鸟平台返回的扣费不一样造成
             if (!$gdo->save()) {
             if (!$gdo->save()) {
                 Yii::error('保存配送订单失败: ' . json_encode($gdo->errors));
                 Yii::error('保存配送订单失败: ' . json_encode($gdo->errors));
                 util::fail('保存配送订单失败');
                 util::fail('保存配送订单失败');
             }
             }
 
 
-            $ghsOrder = OrderClass::getById($ghsOrderId, true, 'id, sendDistance, sendStatus, deliveryId, purchaseId, status');
-            $ghsOrder->sendDistance = 0;
-            if(in_array($platform, ['shunfeng'])){ // 测试发现取消配送没回调的平台,统一在这主动更新配送状态
-                $ghsOrder->sendStatus = -1;
-            }
             // $ghsOrder->deliveryId = ''; // 为了获取上一次的配送记录,不要置空
             // $ghsOrder->deliveryId = ''; // 为了获取上一次的配送记录,不要置空
             $ghsOrder->sendTip = 0;
             $ghsOrder->sendTip = 0;
             if (!$ghsOrder->save()) {
             if (!$ghsOrder->save()) {
                 Yii::error('保存批发订单失败: ' . json_encode($ghsOrder->errors));
                 Yii::error('保存批发订单失败: ' . json_encode($ghsOrder->errors));
                 util::fail('保存批发订单失败');
                 util::fail('保存批发订单失败');
             }
             }
-            OrderClass::cancelOrderSend($ghsOrder, ['staffId' => 0, 'staffName' => '']);
 
 
             util::success($ret['data'], "success");
             util::success($ret['data'], "success");
         }
         }
@@ -651,6 +660,26 @@ class DeliveryController extends BaseController
         }
         }
     }
     }
 
 
+    /**
+     * 滴滴回调接口
+     */
+    public function actionDidiCallback()
+    {
+        $post = Yii::$app->request->post();
+        Yii::info('didi callback: ' . json_encode($post));
+        $cbh = new \common\components\delivery\platform\didi\CallBackHandler();
+        $ret = $cbh->handle($post);// 各回调处理
+        if ($ret) {
+            if(is_array($ret)){
+                return $this->asJson($ret);
+            }
+            return $this->asJson(['error_code' => 0, 'error_msg' => 'success']);
+        } else {
+            Yii::error('滴滴回调失败: ' . json_encode($post, JSON_UNESCAPED_UNICODE));
+            return $this->asJson(['error_code' => -1, 'error_msg' => 'failed']);
+        }
+    }
+
 
 
     // ---------------------------------------------------- 授权回调接口 ----------------------------------------------------------
     // ---------------------------------------------------- 授权回调接口 ----------------------------------------------------------
 
 

+ 1 - 1
app-ghs/models/delivery/CancelOrderForm.php

@@ -22,7 +22,7 @@ class CancelOrderForm extends BaseForm
         return [
         return [
             ['ghsOrderId', 'required'],
             ['ghsOrderId', 'required'],
             ['ghsOrderId', 'integer'],
             ['ghsOrderId', 'integer'],
-            ['ghsOrderId', 'validateGhsOrderId'],
+            //['ghsOrderId', 'validateGhsOrderId'],
             ['orderId', 'string'],
             ['orderId', 'string'],
             ['platform', 'string'],
             ['platform', 'string'],
             ['order_cancel_code', 'string'],
             ['order_cancel_code', 'string'],

+ 9 - 8
app-hd/controllers/DeliveryController.php

@@ -279,22 +279,23 @@ class DeliveryController extends BaseController
         $post['order_cancel_role'] = 1; //1:商户取消, 2:用户取消
         $post['order_cancel_role'] = 1; //1:商户取消, 2:用户取消
         $ret = $ds->cancelOrder($orderId, $post);
         $ret = $ds->cancelOrder($orderId, $post);
         if ($ret['code'] == 0) {
         if ($ret['code'] == 0) {
-            // 更新跑腿订单与批发订单状态
-            $hdo->orderStatus = -1;
+            $Order = OrderClass::getById($hdOrderId, true, 'id, sendDistance, sendStatus, deliveryId');
+            $Order->sendDistance = 0;
+            if(in_array($platform, ['shunfeng'])){ // 测试发现取消配送没回调的平台,统一在这主动更新配送状态
+                $Order->sendStatus = -1;
+
+                // 更新跑腿订单与批发订单状态
+                $hdo->orderStatus = -1;
+            }
             $hdo->cancelCost = $ret['platform'] !== 'fengniao' ? $ret['data']['deductionFee'] : $cancelCostCent; // 由于蜂鸟平台返回的扣费不一样造成
             $hdo->cancelCost = $ret['platform'] !== 'fengniao' ? $ret['data']['deductionFee'] : $cancelCostCent; // 由于蜂鸟平台返回的扣费不一样造成
             if (!$hdo->save()) {
             if (!$hdo->save()) {
                 Yii::error('保存配送订单失败: ' . json_encode($hdo->errors));
                 Yii::error('保存配送订单失败: ' . json_encode($hdo->errors));
                 util::fail('保存配送订单失败');
                 util::fail('保存配送订单失败');
             }
             }
 
 
-            $Order = OrderClass::getById($hdOrderId, true, 'id, sendDistance, sendStatus, deliveryId');
-            $Order->sendDistance = 0;
-            if(in_array($platform, ['shunfeng'])){ // 测试发现取消配送没回调的平台,统一在这主动更新配送状态
-                $Order->sendStatus = -1;
-            }
             $Order->status = 2;
             $Order->status = 2;
             //$Order->deliveryId = '';
             //$Order->deliveryId = '';
-            $Order->sendTip = 0;
+            //$Order->sendTip = 0;
             if (!$Order->save()) {
             if (!$Order->save()) {
                 Yii::error('保存批发订单失败: ' . json_encode($Order->errors));
                 Yii::error('保存批发订单失败: ' . json_encode($Order->errors));
                 util::fail('保存批发订单失败');
                 util::fail('保存批发订单失败');

+ 368 - 1
common/components/delivery/platform/didi/CallBackHandler.php

@@ -1,7 +1,374 @@
 <?php
 <?php
 
 
+namespace common\components\delivery\platform\didi;
 
 
+use biz\common\classes\GhsNotifyClass;
+use biz\common\classes\HdNotifyClass;
+use biz\shop\classes\ShopClass;
+use bizGhs\express\classes\GhsDeliveryOrderClass;
+use bizHd\express\classes\HdDeliveryOrderClass;
+use bizGhs\order\classes\OrderClass;
+use bizHd\order\classes\OrderClass as HdOrderClass;
+use bizHd\purchase\classes\PurchaseClass;
+use common\components\delivery\services\adapter\Functions;
+use common\components\noticeUtil;
+use common\components\util;
+use Yii;
+
+/**
+ * 滴滴回调处理类
+ */
 class CallBackHandler
 class CallBackHandler
 {
 {
+    /**
+     * 处理滴滴回调
+     *
+     * @param array $post 回调数据
+     * @return bool|array 处理结果
+     */
+    public function handle($post)
+    {
+        try {
+            $data = json_decode($post['logisticsParam'], true);
+
+            // 验证签名 (如有需要请实现)
+            // if (!$this->verifySignature($data)) { ... }
+
+            // 区分业务类型
+            // 订单详情查询: 包含 orderNo 和 outOrderNo (且不包含 status/updateTime)
+            if (isset($data['orderNo']) && isset($data['outOrderNo'])) {
+                return $this->queryOrderDetails($data);
+            }
+
+            // 订单状态变更: 包含 didiOrderNo, status, updateTime
+            if (isset($data['didiOrderNo']) && isset($data['status'])) {
+                return $this->processOrderCallback($data);
+            }
+            
+            Yii::warning('滴滴回调未知类型: ' . json_encode($data, JSON_UNESCAPED_UNICODE), 'didi-callback');
+            return false;
+
+        } catch (\Exception $e) {
+            Yii::error('滴滴回调处理异常: ' . $e->getMessage() . ' | ' . $e->getTraceAsString(), 'didi-callback');
+            return false;
+        }
+    }
+
+    /**
+     * 查询订单详情 (返回给滴滴)
+     * 
+     * @param array $data
+     * @return array
+     */
+    private function queryOrderDetails($data)
+    {
+        $didiOrderNo = $data['orderNo'];
+        $outOrderNo = $data['outOrderNo'];
+        $outOrderNo = Didi::getSystemOrder($outOrderNo); //还原为数据库中的订单号
+
+        // 查找主订单
+        $order = OrderClass::getByCondition(['orderSn' => $outOrderNo], true);
+        $isGhs = true;
+
+        if (!$order) {
+            $order = HdOrderClass::getByCondition(['orderSn' => $outOrderNo], true);
+            $isGhs = false;
+        }
+
+        if (!$order) {
+            Yii::error('滴滴查询详情未找到对应订单: ' . $outOrderNo, 'didi-callback');
+            // 返回空或错误信息? 根据协议,这里应该返回错误,但方法定义返回数组。
+            // 暂时返回空数组或抛异常
+            return [];
+        }
+
+        // 查找配送订单以获取 shopId
+        $deliveryOrder = $this->getDeliveryOrder($order, $isGhs);
+        if (!$deliveryOrder) {
+            Yii::error('滴滴查询详情未找到配送订单: ' . $outOrderNo, 'didi-callback');
+            return [];
+        }
+
+        // 获取店铺信息
+        $shopId = isset($deliveryOrder->shopId) ? $deliveryOrder->shopId : 0;
+        if (empty($shopId) && isset($order->shopId)) { // 尝试从订单获取
+             $shopId = $order->shopId;
+        }
+
+        $shop = ShopClass::getById($shopId, false, 'id,merchantName,fullAddress,lat,long,city,dist,floor,mobile,address');
+        if (!$shop) {
+             Yii::error('滴滴查询详情未找到店铺: ' . $shopId, 'didi-callback');
+             // 构造一个兜底的 shop 信息?
+             $shop = [
+                 'merchantName' => '未知店铺',
+                 'mobile' => '',
+                 'fullAddress' => '',
+                 'lat' => 0,
+                 'long' => 0,
+                 'address' => '',
+                 'floor' => ''
+             ];
+        }
+
+        // 构造返回数据
+        // 1. 发货人信息 (Location Info)
+        $fromAddress = [
+            'name' => $shop['merchantName'], //联系名称
+            'poiName' => '', //地图获取的poi名称
+            'poiAddress' => $shop['fullAddress'],//地图获取的地址信息
+            'addressInfo' => $shop['floor'], //用户补充地址信息(门牌号等)
+            'latitude' => (float)$shop['lat'],
+            'longitude' => (float)$shop['long'],
+            'phone' => $shop['mobile'],
+            'virtualPhoneType' => 0,
+        ];
+
+        // 2. 收货人信息 (Location Info)
+        $toAddress = [
+            'name' => $order['customName'],
+            'poiName' => '', //地图获取的poi名称
+            'poiAddress' => $order['fullAddress'],
+            'addressInfo' => $order['floor'],
+            'latitude' => (float)$order['lat'],
+            'longitude' => (float)$order['long'],
+            'phone' => Functions::getMobile($order),
+            'virtualPhoneType' => 0,
+        ];
+
+        // 3. 计算费用
+        // 订单金额 (单位:分) - 这里取实际支付金额/商品金额
+        $fee = (int)($order['actPrice'] * 100); 
+        // 优惠金额 (单位:分)
+        $prePrice = isset($order['prePrice']) ? $order['prePrice'] : $order['actPrice'];
+        $discountFee = (int)(($prePrice - $order['actPrice']) * 100);
+        if ($discountFee < 0) $discountFee = 0;
+
+        // 重量 (单位:克)
+        $weight = isset($order['weight']) ? (int)($order['weight'] * 1000) : 1000;
+
+        Yii::info('滴滴订单返回成功', 'didi-callback');
+        return [
+            'didiOrderNo' => (int)$didiOrderNo, // Long
+            'outOrderNo' => (string)$outOrderNo,
+            'status' => $this->convertStatusToDidi($deliveryOrder->orderStatus), // 转换回滴滴状态? 或者直接返回当前状态
+            'fromAddress' => $fromAddress,
+            'toAddress' => $toAddress,
+            'weight' => $weight,
+            // 'size' => 0, // 非必填
+            'goodsType' => 'FLOWER',
+            'goodsPrice' => (int)($order['actPrice'] * 100), // 保价费物品价值
+            'remark' => $order['remark'] ?? '',
+            'fee' => $fee,
+            'discountFee' => $discountFee,
+        ];
+    }
+
+    /**
+     * 处理订单回调
+     */
+    private function processOrderCallback($data)
+    {
+        $didiOrderNo = isset($data['didiOrderNo']) ? $data['didiOrderNo'] : '';
+        $outOrderNo = isset($data['outOrderNo']) ? Didi::getSystemOrder($data['outOrderNo']) : ''; //还原为数据库中的订单号
+        $didiStatus = isset($data['status']) ? $data['status'] : '';
+        
+        if (empty($outOrderNo)) {
+             Yii::error('滴滴回调缺少outOrderNo', 'didi-callback');
+             return false;
+        }
+
+        // 查找主订单 (假设 outOrderNo 为 orderSn)
+        $order = OrderClass::getByCondition(['orderSn' => $outOrderNo], true);
+        $isGhs = true;
+
+        if (!$order) {
+            $order = HdOrderClass::getByCondition(['orderSn' => $outOrderNo], true);
+            $isGhs = false;
+        }
+
+        if (!$order) {
+            Yii::error('滴滴回调未找到对应订单: ' . $outOrderNo, 'didi-callback');
+            return false;
+        }
+
+        // 查找配送订单
+        $deliveryOrder = $this->getDeliveryOrder($order, $isGhs);
+        if (!$deliveryOrder) {
+            Yii::error("滴滴配送订单不存在: orderSn={$outOrderNo}, isGhs={$isGhs}, ghsOrderId={$order->id}", 'didi-callback');
+            return false;
+        }
+
+        // 更新 didiOrderNo
+        if (!empty($didiOrderNo) && empty($deliveryOrder->orderId)) {
+             $deliveryOrder->orderId = (string)$didiOrderNo;
+             $deliveryOrder->save();
+        }
+
+        $sendStatus = $this->convertOrderSendStatus($didiStatus);
+        
+        // 如果状态无法映射,则忽略
+        if ($sendStatus === null) {
+            return true; 
+        }
+
+        // 更新配送订单状态
+        $deliveryOrder->orderStatus = $sendStatus;
+        $deliveryOrder->save();
+
+        // 更新主订单
+        if ($isGhs) {
+            util::checkRepeatCommit('ghs_pt_' . $order->id . '_' . $sendStatus, 2);
+            
+            if ($order) {
+                // 已送达
+                if ($sendStatus == 5) {
+                     OrderClass::confirmReach($order, ['staffId' => 0, 'staffName' => '']);
+                }
+                // 取消/异常 (且当前状态未取消)
+                if (!in_array($order->sendStatus, [-2, -1]) && in_array($sendStatus, [-1, -2])) {
+                    OrderClass::cancelOrderSend($order, ['staffId' => 0, 'staffName' => '']);
+                    $event = $this->cancelFrom($data);
+                    GhsNotifyClass::ptErrorNotify($order->id, $event);
+                }
+
+                $cg = PurchaseClass::getById($order->purchaseId, true, 'id,sendStatus');
+                if ($cg) {
+                    $cg->sendStatus = $sendStatus;
+                    $cg->save();
+                }
+
+                $order->sendStatus = $sendStatus;
+                // 转换主订单状态
+                $orderStatus = $this->convertOrderStatus($didiStatus);
+                if ($orderStatus !== null) {
+                    $order->status = $orderStatus;
+                }
+                $order->save();
+            }
+        } else {
+             // 零售订单处理
+            util::checkRepeatCommit('hd_pt_' . $order->id . '_' . $sendStatus, 2);
+            
+            if (!in_array($order->sendStatus, [-2, -1]) && in_array($sendStatus, [-1, -2])) {
+                $event = $this->cancelFrom($data);
+                HdNotifyClass::ptErrorNotify($order->id, $event);
+            }
+
+            if ($order) {
+                $order->sendStatus = $sendStatus;
+                $orderStatus = $this->convertOrderStatus($didiStatus);
+                if ($orderStatus !== null) {
+                    $order->status = $orderStatus;
+                }
+                $order->save();
+            }
+        }
+
+        Yii::info('滴滴回调处理成功', 'didi-callback');
+        return true;
+    }
+
+    private function getDeliveryOrder($order, $isGhs)
+    {
+        if ($isGhs) {
+             $gdos = GhsDeliveryOrderClass::getAllByCondition([
+                'deliveryId' => 'didi',
+                'ghsOrderId' => $order->id,
+                'orderStatus!=' => -1
+            ], 'id DESC', '*', null, true);
+            if(count($gdos)>=2){
+                noticeUtil::push("xhGhsDeliveryOrder ghsOrderId={$order->id} 有两笔以上是在配送中");
+                $gdo = $gdos[0];
+            }elseif(count($gdos)==1){
+                $gdo = $gdos[0];
+            }else{
+                $gdo = null;
+            }
+            return $gdo;
+        } else {
+            $hdos = HdDeliveryOrderClass::getAllByCondition([
+                'deliveryId' => 'didi',
+                'hdOrderId' => $order->id,
+                'orderStatus!=' => -1
+            ], 'id DESC', '*', null, true);
+            if(count($hdos)>=2){
+                noticeUtil::push("xhHdDeliveryOrder hdOrderId={$order->id} 有两笔以上是在配送中");
+                $hdo = $hdos[0];
+            }elseif(count($hdos)==1){
+                $hdo = $hdos[0];
+            }else{
+                $hdo = null;
+            }
+            return $hdo;
+        }
+    }
+
+    private function convertOrderSendStatus($didiStatus)
+    {
+        $map = [
+            'WAIT_ACCEPT' => 2,         // 待接单 -> 派单中
+            'PAIRED_DRIVER' => 20,      // 已接单 -> 已分配骑手
+            'ARRIVED_FROM_ADDRESS' => 20, // 到达起点 -> 已分配骑手(或30骑手已到店)
+            'LEAVE_FROM_ADDRESS' => 4,  // 已取货 -> 配送中
+            'ARRIVED_TO_ADDRESS' => 4,  // 到达终点 -> 配送中
+            'SERVICE_FINISH' => 5,      // 已送达
+            'SUBMIT_CHARGE' => 5,       // 费用提交 -> 已送达
+            'COMPLETED' => 5,           // 已完成 -> 已送达
+            'CANCEL' => -1,             // 已取消
+        ];
+        return isset($map[$didiStatus]) ? $map[$didiStatus] : null;
+    }
+
+    private function convertOrderStatus($didiStatus)
+    {
+         // 对应 OrderClass 的 status
+         // 3: 配送中, 4: 已完成
+         $map = [
+             'WAIT_ACCEPT' => 3, 
+             'PAIRED_DRIVER' => 3,
+             'ARRIVED_FROM_ADDRESS' => 3,
+             'LEAVE_FROM_ADDRESS' => 3,
+             'ARRIVED_TO_ADDRESS' => 3,
+             'SERVICE_FINISH' => 4,
+             'SUBMIT_CHARGE' => 4,
+             'COMPLETED' => 4,
+         ];
+         return isset($map[$didiStatus]) ? $map[$didiStatus] : null;
+    }
+
+    /**
+     * 将系统状态转换为滴滴状态 (用于订单详情查询)
+     * 这里只能做近似映射,因为系统状态比滴滴状态少
+     */
+    private function convertStatusToDidi($sendStatus)
+    {
+        $map = [
+            2 => 'WAIT_ACCEPT',
+            20 => 'PAIRED_DRIVER',
+            30 => 'ARRIVED_FROM_ADDRESS',
+            4 => 'LEAVE_FROM_ADDRESS', // or ARRIVED_TO_ADDRESS
+            5 => 'COMPLETED',
+            -1 => 'CANCEL',
+            -2 => 'CANCEL', // 异常也暂视为取消? 或没有对应
+        ];
+        return isset($map[$sendStatus]) ? $map[$sendStatus] : 'WAIT_ACCEPT';
+    }
+
+    private function cancelFrom($data)
+    {
+        if (!isset($data['cancelInfo'])) {
+            return '未知原因';
+        }
 
 
-}
+        $info = $data['cancelInfo'];
+        $sourceMap = [
+            1 => '用户',
+            2 => '司机',
+            3 => '客服',
+            4 => '系统'
+        ];
+        $source = isset($sourceMap[$info['cancelSource']]) ? $sourceMap[$info['cancelSource']] : '未知';
+        $reason = isset($info['cancelReason']) ? $info['cancelReason'] : '';
+        return "{$source}-取消: {$reason}";
+    }
+}

+ 29 - 0
common/components/delivery/platform/didi/Didi.php

@@ -102,4 +102,33 @@ class Didi
         
         
         return $this->baseUrl . '/gateway?' . http_build_query($queryParams);
         return $this->baseUrl . '/gateway?' . http_build_query($queryParams);
     }
     }
+
+    /**
+     * 生成唯一的跑腿订单号
+     * @param $orderId
+     * @return string
+     */
+    public static function generateUniOroder($orderId, $timeStamp)
+    {
+        return $orderId . '-' . $timeStamp;
+    }
+
+    /**
+     * 还原为数据库中的订单号
+     * @param $orderId
+     * @return false|string
+     */
+    public static function getSystemOrder($orderId)
+    {
+        $pos = strpos($orderId, '-');
+        if ($pos !== false) {               // 确实找到了
+            $left  = substr($orderId, 0, $pos); // a-b-c
+            $right = substr($orderId, $pos + 1); // d
+        } else {
+            $left = $orderId;   // 没有 -
+            $right = '';
+        }
+
+        return $left;
+    }
 }
 }

+ 11 - 1
common/components/delivery/platform/fengniao/CallBackNotify.php

@@ -240,7 +240,17 @@ class CallBackNotify
         }
         }
 
 
         if($sendStatus == -2){
         if($sendStatus == -2){
-            return "异常code={$data['error_code']}, 异常描述:{$data['error_scene']}";
+            $errorScene =[
+                'ORDER_INFORMATION_INCORRECT' => '商户推单信息有误,创建蜂鸟运单失败',
+                'OUT_OF_DELIVERY_SERVICE' => '超出配送服务能力,创建蜂鸟运单失败',
+                'MERCHANT_STORE_ERROR' =>	'因商户原因导致无法继续配送',
+                'CUSTOMER_ERROR' =>	'因用户原因导致无法继续配送',
+                'CARRIER_ERROR' =>	'因运力原因导致无法继续配送',
+                'ELE_SYSTEM_ERROR' =>	'蜂鸟系统异常',
+                'UNKNOW_ERROR' =>	'其他未知错误'
+            ];
+            //return "异常code={$data['error_code']}, 异常描述:{$errorScene[$data['error_scene']]}";
+            return "{$data['detail_description']} -- {$data['description']}";
         }
         }
     }
     }
 }
 }

+ 2 - 2
common/components/delivery/platform/huolala/CallBackHandler.php

@@ -202,7 +202,7 @@ class CallBackHandler
         $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
         $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
             'deliveryId' => 'huolala',
             'deliveryId' => 'huolala',
             'orderId' => $orderId
             'orderId' => $orderId
-        ], true);
+        ], true, 'id DESC');
 
 
         if ($deliveryOrder) {
         if ($deliveryOrder) {
             return $deliveryOrder;
             return $deliveryOrder;
@@ -212,7 +212,7 @@ class CallBackHandler
         return HdDeliveryOrderClass::getByCondition([
         return HdDeliveryOrderClass::getByCondition([
             'deliveryId' => 'huolala',
             'deliveryId' => 'huolala',
             'orderId' => $orderId
             'orderId' => $orderId
-        ], true);
+        ], true, 'id DESC');
     }
     }
 
 
     private function cancelFrom($sendStatus, $eventType)
     private function cancelFrom($sendStatus, $eventType)

+ 2 - 2
common/components/delivery/platform/shansong/OrderStatusCallBack.php

@@ -243,7 +243,7 @@ class OrderStatusCallBack
         $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
         $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
             'deliveryId' => 'shansong',
             'deliveryId' => 'shansong',
             'orderId' => $orderId
             'orderId' => $orderId
-        ], true);
+        ], true, 'id DESC');
 
 
         if ($deliveryOrder) {
         if ($deliveryOrder) {
             return $deliveryOrder;
             return $deliveryOrder;
@@ -253,7 +253,7 @@ class OrderStatusCallBack
         return HdDeliveryOrderClass::getByCondition([
         return HdDeliveryOrderClass::getByCondition([
             'deliveryId' => 'shansong',
             'deliveryId' => 'shansong',
             'orderId' => $orderId
             'orderId' => $orderId
-        ], true);
+        ], true, 'id DESC');
     }
     }
 
 
     private function cancelFrom($sendStatus, $abortType)
     private function cancelFrom($sendStatus, $abortType)

+ 3 - 2
common/components/delivery/services/DispatchService.php

@@ -168,7 +168,8 @@ class DispatchService
 
 
         if ($adapter instanceof DidiAdapter) {
         if ($adapter instanceof DidiAdapter) {
             $deliveryOrder = $this->getDeliveryOrder($orderId, 'didi');
             $deliveryOrder = $this->getDeliveryOrder($orderId, 'didi');
-            return $adapter->selectOrder($deliveryOrder['orderId'], $thirdOrderNo);
+            $timeStamp = strtoTime($deliveryOrder->createdAt);
+            return $adapter->selectOrder($deliveryOrder['orderId'], $thirdOrderNo, $timeStamp);
         }
         }
 
 
         return $adapter->selectOrder($orderId);
         return $adapter->selectOrder($orderId);
@@ -924,7 +925,7 @@ class DispatchService
                         //车型信息
                         //车型信息
                         $vehicleAttr = $priceInfo['vehicle_info']['vehicle_attr'] ?? [];
                         $vehicleAttr = $priceInfo['vehicle_info']['vehicle_attr'] ?? [];
                         if(empty($vehicleAttr)){
                         if(empty($vehicleAttr)){
-                            Yii::info('货拉拉 报价数据 vehicleAttr 为空:' . json_encode($priceInfo) . ' key: ' . $key);
+                            Yii::info('货拉拉 报价数据 vehicleAttr 为空:' . ' key: ' . $key); //json_encode($priceInfo) .
                         }
                         }
 
 
                         $deliveryList[] = [
                         $deliveryList[] = [

+ 6 - 6
common/components/delivery/services/adapter/DidiAdapter.php

@@ -1,9 +1,6 @@
 <?php
 <?php
 namespace common\components\delivery\services\adapter;
 namespace common\components\delivery\services\adapter;
 
 
-use bizGhs\express\classes\DeliveryOrderClass;
-use bizGhs\express\classes\GhsDeliveryOrderClass;
-use bizGhs\order\classes\OrderClass;
 use common\components\delivery\helpers\HttpClient;
 use common\components\delivery\helpers\HttpClient;
 use common\components\delivery\platform\didi\Didi;
 use common\components\delivery\platform\didi\Didi;
 use Yii;
 use Yii;
@@ -270,9 +267,10 @@ class DidiAdapter extends Didi implements Adapter
         $goodsType = self::GOODS_TYPE_MAP[$goodTypeInt] ?? 'OTHER';
         $goodsType = self::GOODS_TYPE_MAP[$goodTypeInt] ?? 'OTHER';
 
 
         // ------------------ 入参构建 ------------------
         // ------------------ 入参构建 ------------------
+        $timeStamp = time();
         $businessParams = [
         $businessParams = [
             'estimateIdList' => [$estimateId], // 预估ID
             'estimateIdList' => [$estimateId], // 预估ID
-            'outOrderNo' => $order['issOrderNo'], // 接入方订单号
+            'outOrderNo' => self::generateUniOroder($order['issOrderNo'], $timeStamp), // 接入方订单号
             'fromAddress' => $fromAddress,
             'fromAddress' => $fromAddress,
             'toAddress' => $toAddress,
             'toAddress' => $toAddress,
             'goodsType' => $goodsType,
             'goodsType' => $goodsType,
@@ -298,6 +296,7 @@ class DidiAdapter extends Didi implements Adapter
                     'distance' => 0,
                     'distance' => 0,
                     'fee' => 0,
                     'fee' => 0,
                     // 可以附带其他信息
                     // 可以附带其他信息
+                    'timeStamp' => $timeStamp,
                 ]
                 ]
             ];
             ];
         }
         }
@@ -404,11 +403,12 @@ class DidiAdapter extends Didi implements Adapter
     /**
     /**
      * 查询订单详情
      * 查询订单详情
      */
      */
-    public function selectOrder($orderId, $thirdOrderNo = '')
+    public function selectOrder($orderId, $thirdOrderNo = '', $timeStamp)
     {
     {
+        $thirdOrderNo = Didi::generateUniOroder($thirdOrderNo, $timeStamp);
         $businessParams = [
         $businessParams = [
             'didiOrderNo' => (int)$orderId,
             'didiOrderNo' => (int)$orderId,
-            'outOrderNo' => (string)$thirdOrderNo,
+            'outOrderNo' => $thirdOrderNo,
         ];
         ];
 
 
         $payload = $this->buildRequestPayload($businessParams);
         $payload = $this->buildRequestPayload($businessParams);