Quellcode durchsuchen

app-hd(花掌柜)支持跑腿询价与跑腿下单

shizhongqi vor 8 Monaten
Ursprung
Commit
9ab42f9230

+ 1 - 1
app-ghs/controllers/DeliveryController.php

@@ -36,7 +36,7 @@ class DeliveryController extends BaseController
     {
         $platformList = [];
         $platformLogos = [
-            'data' => ['name'=>'达达', 'logo'=>'📦'],
+            'dada' => ['name'=>'达达', 'logo'=>'📦'],
             'shunfeng' => ['name'=>'顺丰同城', 'logo'=>'🚚'],
             'meituan' => ['name'=>'美团', 'logo'=>'🍱'] ,
             'fengniao' => ['name'=>'蜂鸟', 'logo'=>'🍜'],

+ 121 - 5
app-hd/controllers/DeliveryController.php

@@ -4,6 +4,9 @@ namespace hd\controllers;
 use biz\ghs\classes\GhsClass;
 use bizGhs\custom\classes\CustomClass;
 use bizGhs\express\classes\DeliveryAuthTokenClass;
+use bizHd\order\classes\OrderClass;
+use bizHd\express\classes\HdDeliveryOrderClass;
+use hd\models\delivery\CreateOrderForm;
 use Yii;
 use biz\shop\classes\ShopClass;
 use common\components\delivery\services\DispatchService;
@@ -16,7 +19,7 @@ class DeliveryController extends BaseController
     {
         $platformList = [];
         $platformLogos = [
-            'data' => ['name'=>'达达', 'logo'=>'📦'],
+            'dada' => ['name'=>'达达', 'logo'=>'📦'],
             'shunfeng' => ['name'=>'顺丰同城', 'logo'=>'🚚'],
             'meituan' => ['name'=>'美团', 'logo'=>'🍱'] ,
             'fengniao' => ['name'=>'蜂鸟', 'logo'=>'🍜'],
@@ -41,7 +44,39 @@ class DeliveryController extends BaseController
         util::success(['platformList'=>$platformList]);
     }
 
-    // 获取多个平台报价
+    // 花店发货 -- 获取多个平台报价
+    public function actionHdAllDeliveryQuotes()
+    {
+        $post = Yii::$app->request->post();
+        $orderTime = $post['pickupTime'];
+        $weight = $post['weight'];
+        $remark = $post['remark'] ?? '';
+
+        $adminId = $this->adminId;
+        util::checkRepeatCommit($adminId, 3);
+
+        $orderId = intval($post['orderId']);
+        $order = OrderClass::getById($orderId);
+        $shop = ShopClass::getById($this->shopId);
+        $order['weight'] = $weight;
+        $order['remark'] = $remark;
+
+        $ds = new DispatchService($this->mainId);
+        $platformQuotes = $ds->getAllPlatformPrice($order, $shop, $orderTime);
+        if(isset($platformQuotes['error'])){
+            util::fail($platformQuotes['error']);
+        }
+
+        // 格式化各平台报价为前端展示格式
+        $deliveryList = $ds->formatPlatformQuotesForDisplay($platformQuotes);
+        // 按 price 从低到高排序
+        ArrayHelper::multisort($deliveryList, 'price', SORT_ASC);
+
+        $ret['deliveryList'] = $deliveryList;
+        util::success($ret, "success");
+    }
+
+    // 花店向批发买花 -- 获取多个平台报价
     public function actionAllDeliveryQuotes()
     {
         $post = Yii::$app->request->post();
@@ -63,9 +98,7 @@ class DeliveryController extends BaseController
         $weight = $post['weight'] ?? 1;
 
         // 生成随机订单号
-        //$snData = ['shopId' => $ghsShopId, 'mainId' => $ghs->mainId, 'ghsId' => $ghsId, 'customId' => $customId];
-        //$orderSn = orderSn::getGhsOrderSn($snData);
-        $prefix = 'XSD_CS-';
+        $prefix = 'XSD_CS-' . $ghs->mainId . '-';
         $orderSn = $prefix . round(microtime(true) * 1000);
 
         //构建出 Order 数据
@@ -102,6 +135,89 @@ class DeliveryController extends BaseController
         util::success($ret, "success");
     }
 
+    // 创建订单(真实下单)
+    public function actionCreateOrder()
+    {
+        $form = new CreateOrderForm();
+        $form->loadAndValidate();
+
+        $post = $form->getAttributes();
+        $orderId = $post['orderId']; // xhOrder.id
+        $params = $post['allParams'];
+        $platform = $params['en_name'];// $post['platform'] 是中文
+        $pickupTime = $post['pickupTime'];
+
+        $params['mainId'] = $this->mainId;
+        $params['ip'] = Yii::$app->request->userIP;
+        $params['remark'] = $post['remark'];
+        $params['total_price_fen'] = $post['price'];
+        $params['pickupTime'] = $pickupTime['value'];
+        $shopId = $this->shopId;
+
+        $Order = OrderClass::getById($orderId, true);
+        if(!in_array($Order['sendStatus'], [-4, -1])) {
+            Yii::error('订单已经发过跑腿');
+            util::fail('订单已经发过跑腿');
+        }
+
+        $ds = new DispatchService($this->mainId, $platform);
+        $ret = $ds->createOrder($Order, $shopId, $params);
+
+        if (isset($ret['code']) && $ret['code'] == 0) {
+            $gdo = HdDeliveryOrderClass::getByCondition(['mainId'=>$this->mainId, 'orderId'=>$ret['data']['order_id']]);
+            if (empty($gdo)) {
+                $data = [
+                    'mainId' => $this->mainId,
+                    'shopId' => $this->shopId,
+                    'deliveryId' => $ret['platform'],
+                    'hdOrderId' => $orderId,
+                    'orderId' => $ret['data']['order_id'],
+                    'distance' => $ret['data']['distance'],
+                    'fee' => $ret['data']['fee'],
+                    'orderStatus' => 0
+                ];
+                HdDeliveryOrderClass::add($data);
+            } else {
+                Yii::info('重复创建订单');
+            }
+            //更新订单
+            $Order->sendDistance = $ret['data']['distance'];
+            $Order->sendStatus = 0;
+            $Order->deliveryId = $ret['platform'];
+            $Order->sendType = 2;// 2指跑腿
+            $Order->status = 3;// 3配送中
+            $save = $Order->save();
+            if($save){
+                util::success($ret, "success");
+            }else{
+                util::fail('创建跑腿失败(更新订单失败)');
+            }
+        } else {
+            if(isset($ret['msg'])){
+                util::fail($ret['msg']);
+            }
+            util::fail('创建跑腿失败');
+        }
+    }
+
+    public function actionAddress()
+    {
+        $post = Yii::$app->request->post();
+
+        $adminId = $this->adminId;
+        util::checkRepeatCommit($adminId, 4);
+
+        $orderId = intval($post['orderId']);
+        $order = OrderClass::getById($orderId, false, 'fullAddress');
+        $shop = ShopClass::getById($this->shopId, false, 'fullAddress');
+
+        $ret = [
+            "send_address" => $shop['fullAddress'],
+            "receive_address" => $order['fullAddress']
+        ];
+        util::success($ret, "success");
+    }
+
     public function actionCancelAuth()
     {
         // 有平台有对应的取消授权接口,有的没有。

+ 39 - 0
app-hd/models/BaseForm.php

@@ -1,6 +1,7 @@
 <?php
 namespace hd\models;
 
+use Yii;
 use yii\base\Model;
 use common\components\util;
 
@@ -24,4 +25,42 @@ class BaseForm extends Model
         }
         return true;
     }
+
+    /**
+     * 自动加载并验证请求数据
+     *
+     * 自动检测请求类型(GET 或 POST),加载对应的数据并进行验证。
+     * 相比手动指定 $method 参数,使用 $request->isGet 和 $request->isPost
+     * 是 Yii 框架推荐的做法,更符合框架风格。
+     *
+     * 使用示例:
+     * - POST 请求自动加载:$form->loadAndValidate();
+     * - GET 请求自动加载:$form->loadAndValidate();
+     *
+     * @param string $formName 表单名称,用于嵌套数据
+     * @return bool 验证成功返回 true,失败自动输出错误响应
+     * @throws \yii\base\InvalidConfigException
+     */
+    public function loadAndValidate($formName = '')
+    {
+        $request = Yii::$app->request;
+
+        // ✨ 优化:使用 Yii 提供的方法检查请求类型
+        // 相比手动字符串比较 ($method === 'get'),这种方式更符合框架风格
+        if ($request->isGet) {
+            $data = $request->get();
+        } elseif ($request->isPost) {
+            $data = $request->post();
+        } else {
+            util::fail('不支持的请求方法');
+            return false;
+        }
+
+        if (!$this->load($data, '')) {
+            util::fail('数据加载失败');
+            return false;
+        }
+
+        return $this->validateForm();
+    }
 }

+ 68 - 0
app-hd/models/delivery/CreateOrderForm.php

@@ -0,0 +1,68 @@
+<?php
+namespace hd\models\delivery;
+
+use bizHd\order\classes\OrderClass;
+use hd\models\BaseForm;
+use Yii;
+
+/**
+ * 创建配送订单表单模型
+ * 用于 actionCreateOrder 的参数验证
+ */
+class CreateOrderForm extends BaseForm
+{
+    public $orderId;           // xhGhsOrder.id
+    public $remark;            // 订单备注
+    public $price;             // 配送费(单位:分)
+    public $pickupTime;        // 取件时间
+    public $allParams;         // 配送平台所需的所有参数
+
+    public function rules()
+    {
+        return [
+            [['orderId', 'price'], 'required'],
+            [['orderId', 'price'], 'integer'],
+            ['orderId', 'validateOrderId'],
+            ['pickupTime', 'safe'],
+            ['allParams', 'safe'],
+            ['remark', 'string', 'max' => 500],
+        ];
+    }
+
+    public function attributeLabels()
+    {
+        return [
+            'orderId' => '订单ID',
+            'remark' => '备注',
+            'price' => '配送费用',
+            'pickupTime' => '取件时间',
+            'allParams' => '配送参数',
+        ];
+    }
+
+    /**
+     * 验证订单ID是否存在且属于当前商户
+     * @param $attribute
+     */
+    public function validateOrderId($attribute)
+    {
+        if (!$this->hasErrors()) {
+            $order = OrderClass::getById($this->orderId, false, 'id, mainId, sendStatus');
+            if (empty($order)) {
+                $this->addError($attribute, '订单不存在');
+                return;
+            }
+            
+            if ($order['mainId'] != Yii::$app->controller->mainId) {
+                $this->addError($attribute, '订单不属于当前商户');
+                return;
+            }
+
+            // 检查订单是否已发过跑腿
+            if (!in_array($order['sendStatus'], [-4, -1])) {
+                $this->addError($attribute, '订单已经发过跑腿');
+            }
+        }
+    }
+}
+

+ 23 - 0
biz-hd/express/classes/HdDeliveryOrderClass.php

@@ -0,0 +1,23 @@
+<?php
+namespace bizHd\express\classes;
+
+use bizHd\base\classes\BaseClass;
+
+class HdDeliveryOrderClass extends BaseClass
+{
+    public static $baseFile = HdDeliveryOrderAR::class;
+}
+
+// 在同文件末尾追加一个内联的 AR 类
+class HdDeliveryOrderAR extends \bizHd\base\models\Base
+{
+    public static function tableName()
+    {
+        return 'xhHdDeliveryOrder';
+    }
+}
+
+// 可选:为了兼容历史直接引用 models 的代码(如果存在),做一个别名映射
+if (!class_exists('\bizHd\express\models\HdDeliveryOrder')) {
+    class_alias(\bizHd\express\classes\HdDeliveryOrderAR::class, '\bizHd\express\models\HdDeliveryOrder');
+}

+ 1 - 1
common/components/delivery/platform/dada/Auth.php

@@ -39,7 +39,7 @@ class Auth
      */
     public function __construct()
     {
-        $isProduction = getenv('YII_ENV') == 'dev'; // TODO
+        $isProduction = getenv('YII_ENV') == 'production'; // TODO
         
         if ($isProduction) {
             // 生产环境配置(需要替换为实际的生产环境凭证)

+ 36 - 6
common/components/delivery/platform/dada/Dada.php

@@ -7,7 +7,6 @@ class Dada
     // API 配置常量
     const API_VERSION = '1.0';
     const FORMAT = 'json';
-    const RESPONSE_TYPE = 'code';
 
     // 测试环境和生产环境基础 URL
     const TEST_BASE_URL = 'https://newopen.qa.imdada.cn';
@@ -23,9 +22,9 @@ class Dada
      * 初始化达达适配器
      * 根据运行环境加载对应的配置信息
      */
-    public function __construct()
+    public function __construct($token='')
     {
-        $isProduction = getenv('YII_ENV') == 'dev'; // TODO
+        $isProduction = getenv('YII_ENV') == 'production'; // TODO
 
         if ($isProduction) {
             // 生产环境配置(需要替换为实际的生产环境凭证)
@@ -99,9 +98,9 @@ class Dada
         $str = '';
         foreach ($params as $key => $value) {
             // 跳过 null 值,但保留空字符串(如 body 为空时)
-            if ($value === null) {
-                continue;
-            }
+//            if ($value === null) {
+//                continue;
+//            }
             $str .= $key . $value;
         }
 
@@ -111,4 +110,35 @@ class Dada
         // MD5 加密,返回 32 位大写字符串
         return strtoupper(md5($str));
     }
+
+    /**
+     * 发送请求,POST
+     * @param $url 指定URL完整路径地址
+     * @param $data 请求的数据
+     */
+    public function getHttpRequestWithPost($api, $data){
+        $url = $this->baseUrl . '/' . $api;
+
+        // json
+        $headers = array(
+            'Content-Type: application/json',
+        );
+        $curl = curl_init($url);
+        curl_setopt($curl, CURLOPT_URL, $url);
+        curl_setopt($curl, CURLOPT_HEADER, false);
+        curl_setopt($curl, CURLOPT_POST, true);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
+        curl_setopt($curl, CURLOPT_TIMEOUT, 3);
+        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+        $resp = curl_exec($curl);
+        //var_dump( curl_error($curl) );//如果在执行curl的过程中出现异常,可以打开此开关查看异常内容。
+        $info = curl_getinfo($curl);
+        curl_close($curl);
+
+        if (isset($info['http_code']) && $info['http_code'] == 200) {
+            return $resp;
+        }
+        return '';
+    }
 }

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

@@ -4,6 +4,8 @@ namespace common\components\delivery\platform\fengniao;
 use bizGhs\express\classes\DeliveryAuthTokenClass;
 use bizGhs\express\classes\GhsDeliveryOrderClass;
 use bizGhs\order\classes\OrderClass;
+use bizHd\express\classes\HdDeliveryOrderClass;
+use bizHd\order\classes\OrderClass as HdOrderClass;
 use Yii;
 
 //回调业务类型
@@ -47,22 +49,28 @@ class CallBackNotify
      */
     private function handleOrderStatusNotify($data)
     {
-        $deliveryOrder = GhsDeliveryOrderClass::getByCondition(['deliveryId'=>'fengniao', 'orderId'=>$data['order_id']], true);
+        $deliveryOrder = $this->getDeliveryOrder($data['order_id']);
         // 将蜂鸟平台的订单状态转换为系统内的 orderStatus
         $sendStatus = OrderStatusUtil::convertOrderStatus($data['order_status']);
         $deliveryOrder->orderStatus = $sendStatus;
         $deliveryOrder->save();
 
-        $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendType,sendStatus,deliveryId,purchaseId,customId,status');
-        $order->sendStatus = $sendStatus;
-        $order->save();
-
-        // 确认送达或取消订单,更新主订单状态
-        if ($sendStatus == 5) {
-            OrderClass::confirmReach($order, ['staffId' => 0, 'staffName' => '']);
-        }
-        if ($sendStatus == -1 || $sendStatus == -2) {
-            OrderClass::cancelOrderSend($order, ['staffId' => 0, 'staffName' => '']);
+        if(property_exists($deliveryOrder, 'ghsOrderId')){ // 批发
+            $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendType,sendStatus,deliveryId,purchaseId,customId,status');
+            $order->sendStatus = $sendStatus;
+            $order->save();
+
+            // 确认送达或取消订单,更新主订单状态
+            if ($sendStatus == 5) {
+                OrderClass::confirmReach($order, ['staffId' => 0, 'staffName' => '']);
+            }
+            if ($sendStatus == -1 || $sendStatus == -2) {
+                OrderClass::cancelOrderSend($order, ['staffId' => 0, 'staffName' => '']);
+            }
+        }elseif(property_exists($deliveryOrder, 'hdOrderId')){ // 零售
+            $order = HdOrderClass::getById($deliveryOrder->hdOrderId, true, 'id,sendType,sendStatus,deliveryId,customId,status');
+            $order->sendStatus = $sendStatus;
+            $order->save();
         }
 
         return true;
@@ -176,4 +184,29 @@ class CallBackNotify
         Yii::info('蜂鸟门店营业时间变更回调: ' . json_encode($data, JSON_UNESCAPED_UNICODE), 'fengniao');
         return $data;
     }
+
+     /**
+     * 根据订单号查找配送订单
+     *
+     * @param string $orderId
+     * @return object|null
+     */
+    private function getDeliveryOrder($orderId)
+    {
+        // 查找批发配送订单
+        $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
+            'deliveryId' => 'fengniao',
+            'orderId' => $orderId
+        ], true);
+
+        if ($deliveryOrder) {
+            return $deliveryOrder;
+        }
+
+        // 查找零售配送订单
+        return HdDeliveryOrderClass::getByCondition([
+            'deliveryId' => 'fengniao',
+            'orderId' => $orderId
+        ], true);
+    }
 }

+ 54 - 18
common/components/delivery/platform/huolala/CallBackHandler.php

@@ -3,6 +3,8 @@ namespace common\components\delivery\platform\huolala;
 
 use bizGhs\express\classes\GhsDeliveryOrderClass;
 use bizGhs\order\classes\OrderClass;
+use bizHd\express\classes\HdDeliveryOrderClass;
+use bizHd\order\classes\OrderClass as HdOrderClass;
 use Yii;
 
 class CallBackHandler
@@ -38,11 +40,7 @@ class CallBackHandler
                 return true;
             }
 
-            $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
-                'deliveryId' => 'huolala',
-                'orderId' => $orderDisplayId,
-            ], true);
-
+            $deliveryOrder = $this->getDeliveryOrder($orderDisplayId);
             if (!$deliveryOrder) {
                 Yii::error('货拉拉配送订单不存在: order_display_id=' . $orderDisplayId, 'huolala-callback');
                 return false;
@@ -54,22 +52,35 @@ class CallBackHandler
                 return false;
             }
 
-            $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendStatus,deliveryId,purchaseId,customId,status');
-            if ($order) {
-                $order->sendStatus = $orderStatus;
-                if (!$order->save()) {
-                    Yii::warning('更新主订单配送状态失败: ' . json_encode($order->getErrors(), JSON_UNESCAPED_UNICODE), 'huolala-callback');
-                }
 
-                // 确认送达或取消订单,更新主订单状态
-                if ($orderStatus == 5) {
-                    OrderClass::confirmReach($order, ['staffId' => 0, 'staffName' => '']);
+            if(property_exists($deliveryOrder, 'ghsOrderId')){ // 批发
+                $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendStatus,deliveryId,purchaseId,customId,status');
+                if ($order) {
+                    $order->sendStatus = $orderStatus;
+                    if (!$order->save()) {
+                        Yii::warning('更新主订单配送状态失败: ' . json_encode($order->getErrors(), JSON_UNESCAPED_UNICODE), 'huolala-callback');
+                    }
+
+                    // 确认送达或取消订单,更新主订单状态
+                    if ($orderStatus == 5) {
+                        OrderClass::confirmReach($order, ['staffId' => 0, 'staffName' => '']);
+                    }
+                    if ($orderStatus == -1 || $orderStatus == -2) {
+                        OrderClass::cancelOrderSend($order, ['staffId' => 0, 'staffName' => '']);
+                    }
+                } else {
+                    Yii::warning('未找到主订单: ghsOrderId=' . $deliveryOrder->ghsOrderId, 'huolala-callback');
                 }
-                if ($orderStatus == -1 || $orderStatus == -2) {
-                    OrderClass::cancelOrderSend($order, ['staffId' => 0, 'staffName' => '']);
+            }elseif(property_exists($deliveryOrder, 'hdOrderId')){ // 零售
+                $order = HdOrderClass::getById($deliveryOrder->hdOrderId, true, 'id,sendType,sendStatus,deliveryId,customId,status');
+                if ($order) {
+                    $order->sendStatus = $orderStatus;
+                    if (!$order->save()) {
+                        Yii::warning('更新主订单配送状态失败: ' . json_encode($order->getErrors(), JSON_UNESCAPED_UNICODE), 'huolala-callback');
+                    }
+                } else {
+                    Yii::warning('未找到主订单: hdOrderId=' . $deliveryOrder->hdOrderId, 'huolala-callback');
                 }
-            } else {
-                Yii::warning('未找到主订单: ghsOrderId=' . $deliveryOrder->ghsOrderId, 'huolala-callback');
             }
 
             Yii::info(sprintf('货拉拉配送状态更新成功: order_display_id=%s, event_type=%s, orderStatus=%s', $orderDisplayId, $eventType, $orderStatus), 'huolala-callback');
@@ -110,4 +121,29 @@ class CallBackHandler
 
         return $map[$eventType] ?? null;
     }
+
+     /**
+     * 根据订单号查找配送订单
+     *
+     * @param string $orderId
+     * @return object|null
+     */
+    private function getDeliveryOrder($orderId)
+    {
+        // 查找批发配送订单
+        $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
+            'deliveryId' => 'huolala',
+            'orderId' => $orderId
+        ], true);
+
+        if ($deliveryOrder) {
+            return $deliveryOrder;
+        }
+
+        // 查找零售配送订单
+        return HdDeliveryOrderClass::getByCondition([
+            'deliveryId' => 'huolala',
+            'orderId' => $orderId
+        ], true);
+    }
 }

+ 33 - 6
common/components/delivery/platform/shansong/OrderStatusCallBack.php

@@ -3,6 +3,8 @@ namespace common\components\delivery\platform\shansong;
 
 use bizGhs\express\classes\GhsDeliveryOrderClass;
 use bizGhs\order\classes\OrderClass;
+use bizHd\express\classes\HdDeliveryOrderClass;
+use bizHd\order\classes\OrderClass as HdOrderClass;
 use Yii;
 
 /**
@@ -31,11 +33,7 @@ class OrderStatusCallBack
             }
             
             // 查找配送订单
-            $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
-                'deliveryId' => 'shansong', 
-                'orderId' => $data['issOrderNo']
-            ], true);
-            
+            $deliveryOrder = $this->getDeliveryOrder($data['issOrderNo']);
             if (!$deliveryOrder) {
                 Yii::error('闪送订单不存在: issOrderNo=' . $data['issOrderNo'], 'shansong-callback');
                 return false;
@@ -60,7 +58,11 @@ class OrderStatusCallBack
             $deliveryOrder->save();
             
             // 更新主订单状态
-            $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendType,sendStatus,deliveryId,purchaseId,customId,status');
+            if(property_exists($deliveryOrder, 'ghsOrderId')){ // 批发
+                $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendType,sendStatus,deliveryId,purchaseId,customId,status');
+            }elseif(property_exists($deliveryOrder, 'hdOrderId')){ // 零售
+                $order = HdOrderClass::getById($deliveryOrder->hdOrderId, true, 'id,sendType,sendStatus,deliveryId,customId,status');
+            }
             if ($order) {
                 $order->sendStatus = $sendStatus;
                 $order->save();
@@ -202,4 +204,29 @@ class OrderStatusCallBack
             // $deliveryOrder->deliveryPassword = $deliveryPassword;
         }
     }
+
+    /**
+     * 根据订单号查找配送订单
+     *
+     * @param string $orderId
+     * @return object|null
+     */
+    private function getDeliveryOrder($orderId)
+    {
+        // 查找批发配送订单
+        $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
+            'deliveryId' => 'shansong',
+            'orderId' => $orderId
+        ], true);
+
+        if ($deliveryOrder) {
+            return $deliveryOrder;
+        }
+
+        // 查找零售配送订单
+        return HdDeliveryOrderClass::getByCondition([
+            'deliveryId' => 'shansong',
+            'orderId' => $orderId
+        ], true);
+    }
 }

+ 104 - 57
common/components/delivery/platform/shunfeng/CallBackHandler.php

@@ -3,7 +3,9 @@ namespace common\components\delivery\platform\shunfeng;
 
 use bizGhs\express\classes\DeliveryAuthTokenClass;
 use bizGhs\express\classes\GhsDeliveryOrderClass;
+use bizHd\express\classes\HdDeliveryOrderClass;
 use bizGhs\order\classes\OrderClass;
+use bizHd\order\classes\OrderClass as HdOrderClass;
 use Yii;
 
 /**
@@ -97,11 +99,7 @@ class CallBackHandler
         $orderId = $data['sf_order_id'];
         
         // 查找配送订单
-        $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
-            'deliveryId' => 'shunfeng',
-            'orderId' => $orderId
-        ], true);
-        
+        $deliveryOrder = $this->getDeliveryOrder($orderId);
         if (!$deliveryOrder) {
             Yii::error('顺丰配送订单不存在: sf_order_id=' . $orderId, 'shunfeng-callback');
             return false;
@@ -126,10 +124,18 @@ class CallBackHandler
             $deliveryOrder->save();
             
             // 更新主订单的配送状态
-            $order = OrderClass::getById($deliveryOrder->ghsOrderId, true);
-            if ($order) {
-                $order->sendStatus = $sendStatus;
-                $order->save();
+            if(property_exists($deliveryOrder, 'ghsOrderId')){ // 批发
+                $order = OrderClass::getById($deliveryOrder->ghsOrderId, true);
+                if ($order) {
+                    $order->sendStatus = $sendStatus;
+                    $order->save();
+                }
+            }elseif(property_exists($deliveryOrder, 'hdOrderId')){ // 零售
+                $order = HdOrderClass::getById($deliveryOrder->hdOrderId, true);
+                if ($order) {
+                    $order->sendStatus = $sendStatus;
+                    $order->save();
+                }
             }
         } else {
             return false;
@@ -156,13 +162,8 @@ class CallBackHandler
         }
         
         $orderId = $data['sf_order_id'];
-        
         // 查找配送订单
-        $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
-            'deliveryId' => 'shunfeng',
-            'orderId' => $orderId
-        ], true);
-        
+        $deliveryOrder = $this->getDeliveryOrder($orderId);
         if (!$deliveryOrder) {
             Yii::error('顺丰配送订单不存在: sf_order_id=' . $orderId, 'shunfeng-callback');
             return false;
@@ -177,15 +178,24 @@ class CallBackHandler
         $deliveryOrder->save();
         
         // 更新主订单状态为已送达
-        $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendStatus,deliveryId,purchaseId,customId,status');
-        if ($order) {
-            $order->sendStatus = $sendStatus;
-            $order->save();
+        if(property_exists($deliveryOrder, 'ghsOrderId')){ // 批发
+            $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendStatus,deliveryId,purchaseId,customId,status');
+            if ($order) {
+                $order->sendStatus = $sendStatus;
+                $order->save();
 
-            // 确认送达,更新主订单状态
-            if ($sendStatus == 5) {
-                OrderClass::confirmReach($order, ['staffId' => 0, 'staffName' => '']);
+                // 确认送达,更新主订单状态
+                if ($sendStatus == 5) {
+                    OrderClass::confirmReach($order, ['staffId' => 0, 'staffName' => '']);
+                }
             }
+        }elseif(property_exists($deliveryOrder, 'hdOrderId')){ // 零售
+            $order = HdOrderClass::getById($deliveryOrder->hdOrderId, true);
+            if ($order) {
+                $order->sendStatus = $sendStatus;
+                $order->save();
+            }
+            // TODO
         }
         
         return true;
@@ -209,13 +219,8 @@ class CallBackHandler
         }
         
         $orderId = $data['sf_order_id'];
-        
         // 查找配送订单
-        $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
-            'deliveryId' => 'shunfeng',
-            'orderId' => $orderId
-        ], true);
-        
+        $deliveryOrder = $this->getDeliveryOrder($orderId);
         if (!$deliveryOrder) {
             Yii::error('顺丰配送订单不存在: sf_order_id=' . $orderId, 'shunfeng-callback');
             return false;
@@ -230,15 +235,24 @@ class CallBackHandler
         $deliveryOrder->save();
         
         // 更新主订单状态为取消
-        $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendStatus,deliveryId,purchaseId,customId,status');
-        if ($order) {
+        if(property_exists($deliveryOrder, 'ghsOrderId')) { // 批发
+            $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendStatus,deliveryId,purchaseId,customId,status');
+            if($order) {
+                $order->sendStatus = $sendStatus;
+                $order->save();
+
+                // 更新主订单状态为取消
+                if($sendStatus == -1) {
+                    OrderClass::cancelOrderSend($order, ['staffId' => 0, 'staffName' => '']);
+                }
+            }
+        }elseif(property_exists($deliveryOrder, 'hdOrderId')){ // 零售
+            $order = HdOrderClass::getById($deliveryOrder->hdOrderId, true);
+            if ($order) {
             $order->sendStatus = $sendStatus;
             $order->save();
-
-            // 更新主订单状态为取消
-            if ($sendStatus == -1) {
-                OrderClass::cancelOrderSend($order, ['staffId' => 0, 'staffName' => '']);
             }
+            // TODO
         }
         
         return true;
@@ -262,13 +276,8 @@ class CallBackHandler
         }
         
         $orderId = $data['sf_order_id'];
-        
         // 查找配送订单
-        $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
-            'deliveryId' => 'shunfeng',
-            'orderId' => $orderId
-        ], true);
-        
+        $deliveryOrder = $this->getDeliveryOrder($orderId);
         if (!$deliveryOrder) {
             Yii::error('顺丰配送订单不存在: sf_order_id=' . $orderId, 'shunfeng-callback');
             return false;
@@ -283,15 +292,24 @@ class CallBackHandler
         $deliveryOrder->save();
 
         // 更新主订单状态为异常
-        $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendStatus,deliveryId,purchaseId,customId,status');
-        if ($order) {
-            $order->sendStatus = $sendStatus;
-            $order->save();
+        if(property_exists($deliveryOrder, 'ghsOrderId')) { // 批发
+            $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendStatus,deliveryId,purchaseId,customId,status');
+            if($order) {
+                $order->sendStatus = $sendStatus;
+                $order->save();
 
-            // 更新主订单状态为异常
-            if ($sendStatus == -2) {
-                OrderClass::cancelOrderSend($order, ['staffId' => 0, 'staffName' => '']);
+                // 更新主订单状态为异常
+                if($sendStatus == -2) {
+                    OrderClass::cancelOrderSend($order, ['staffId' => 0, 'staffName' => '']);
+                }
             }
+        }elseif(property_exists($deliveryOrder, 'hdOrderId')){ // 零售
+            $order = HdOrderClass::getById($deliveryOrder->hdOrderId, true);
+            if ($order) {
+                $order->sendStatus = $sendStatus;
+                $order->save();
+            }
+            // TODO
         }
         
         return true;
@@ -315,13 +333,8 @@ class CallBackHandler
         }
         
         $shopOrderId = $data['shop_order_id'];
-        
         // 查找配送订单
-        $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
-            'deliveryId' => 'shunfeng',
-            'orderId' => $shopOrderId
-        ], true);
-        
+        $deliveryOrder = $this->getDeliveryOrder($shopOrderId);
         if (!$deliveryOrder) {
             Yii::error('顺丰配送订单不存在: shop_order_id=' . $shopOrderId, 'shunfeng-callback');
             return false;
@@ -336,10 +349,19 @@ class CallBackHandler
         $deliveryOrder->save();
 
         // 更新主订单状态为派单中
-        $order = OrderClass::getById($deliveryOrder->ghsOrderId, true);
-        if ($order) {
-            $order->sendStatus = $sendStatus;
-            $order->save();
+        if(property_exists($deliveryOrder, 'ghsOrderId')) { // 批发
+            $order = OrderClass::getById($deliveryOrder->ghsOrderId, true);
+            if($order) {
+                $order->sendStatus = $sendStatus;
+                $order->save();
+            }
+        }elseif(property_exists($deliveryOrder, 'hdOrderId')){ // 零售
+            $order = HdOrderClass::getById($deliveryOrder->hdOrderId, true);
+            if ($order) {
+                $order->sendStatus = $sendStatus;
+                $order->save();
+            }
+            // TODO
         }
         
         return true;
@@ -478,4 +500,29 @@ class CallBackHandler
         
         return $statusMap[$sfOrderStatus] ?? null;
     }
+
+    /**
+     * 根据顺丰订单号查找配送订单
+     * 
+     * @param string $orderId
+     * @return object|null
+     */
+    private function getDeliveryOrder($orderId)
+    {
+        // 查找批发配送订单
+        $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
+            'deliveryId' => 'shunfeng',
+            'orderId' => $orderId
+        ], true);
+
+        if ($deliveryOrder) {
+            return $deliveryOrder;
+        }
+
+        // 查找零售配送订单
+        return HdDeliveryOrderClass::getByCondition([
+            'deliveryId' => 'shunfeng',
+            'orderId' => $orderId
+        ], true);
+    }
 }

+ 74 - 4
common/components/delivery/services/DispatchService.php

@@ -5,7 +5,11 @@ use biz\shop\classes\ShopClass;
 use bizGhs\express\classes\DeliveryAuthTokenClass;
 use bizGhs\order\classes\OrderItemClass;
 use common\components\delivery\helpers\HttpClient;
-use common\components\delivery\services\adapter\{ ShansongAdapter,  HuolalaAdapter, FengniaoAdapter, ShunfengAdapter}; // MeituanAdapter, DadaAdapter, UUAdapter,
+use common\components\delivery\services\adapter\{DadaAdapter,
+    ShansongAdapter,
+    HuolalaAdapter,
+    FengniaoAdapter,
+    ShunfengAdapter}; // MeituanAdapter, DadaAdapter, UUAdapter,
 use Yii;
 
 /**
@@ -40,6 +44,10 @@ class DispatchService
                     case 'shunfeng':
                         $this->adapters['shunfeng'] = new ShunfengAdapter($pt['accessToken'], $pt['shopId']);
                         break;
+                    case 'dada':
+                        $this->adapters['dada'] = new DadaAdapter($pt['accessToken']);
+                        $this->adapters['dada']->setShopNo($pt['shopId']);
+                        break;
                 }
 
                 //检测 token 是否即将过期
@@ -69,6 +77,10 @@ class DispatchService
                 case 'shunfeng':
                     $this->adapters['shunfeng'] = new ShunfengAdapter($authPlatform['accessToken'], $authPlatform['shopId']);
                     break;
+                case 'dada':
+                    $this->adapters['dada'] = new DadaAdapter($authPlatform['accessToken']);
+                    $this->adapters['dada']->setShopNo($authPlatform['shopId']);
+                    break;
             }
             $this->platformName = $platform;
             if($authPlatform['expiresAt'] < time() + 86400 * 5) {
@@ -215,6 +227,17 @@ class DispatchService
             }
         }
 
+        // 准备达达订单数据
+        if (isset($this->adapters['dada'])) {
+            try {
+                $dadaAdapter = $this->adapters['dada'];
+                $shopNo = $dadaAdapter->getShopNo();
+                $preparedData['dada'] = $this->prepareDadaData($order, $shop, $shopNo);
+            } catch (\Exception $e) {
+                Yii::warning("Dada 数据准备失败: {$e->getMessage()}");
+            }
+        }
+
         return $preparedData;
     }
 
@@ -280,7 +303,7 @@ class DispatchService
                         'district_name' => $order['dist'],
                         'house_number' => $order['floor'],
                         'contacts_name' => $order['customName'],
-                        'contacts_phone_no' => $order['customMobile'],
+                        'contacts_phone_no' => isset($order['customMobile']) ? $order['customMobile'] : isset($order['receiveMobile']) ? $order['receiveMobile'] : '',
                         'lat_lon' => ['lat' => (float)$order['lat'], 'lon' => (float)$order['long']],
                     ]
                 ],
@@ -324,7 +347,7 @@ class DispatchService
         return [
             'platform' => 'fengniao',
             'partner_order_code' => $order['orderSn'],
-            'receiver_primary_phone' => $order['customMobile'],
+            'receiver_primary_phone' => isset($order['customMobile']) ? $order['customMobile'] : isset($order['receiveMobile']) ? $order['receiveMobile'] : '',
             'receiver_name' => $order['customName'],
             'receiver_latitude' => (float)$order['lat'],
             'receiver_longitude' => (float)$order['long'],
@@ -363,7 +386,7 @@ class DispatchService
                     'toAddress' => $order['address'],
                     'toAddressDetail' => $order['floor'],
                     'toReceiverName' => $order['customName'],
-                    'toMobile' => $order['customMobile'],
+                    'toMobile' => isset($order['customMobile']) ? $order['customMobile'] : isset($order['receiveMobile']) ? $order['receiveMobile'] : '',
                     'toLatitude' => (float)$order['lat'],
                     'toLongitude' => (float)$order['long'],
                     'goodType' => 7,
@@ -439,6 +462,44 @@ class DispatchService
         ];
     }
 
+    /**
+     * 准备达达订单数据
+     */
+    private function prepareDadaData($order, $shop, $shopNo)
+    {
+        $productList = [];
+        $itemInfos = OrderItemClass::getAllByCondition(['orderSn' => $order['orderSn']], null, 'id, name, unitPrice, num, bigNum, smallNum, xhUnitName');
+        foreach ($itemInfos as $item) {
+            $productList[] = [
+                'sku_name' => $item['name'],
+                'src_product_no' => (string)$item['id'],
+                'count' => (float)$item['num'],
+                'unit' => $item['xhUnitName'],
+            ];
+        }
+
+        // 默认回调地址
+        $callbackUrl = Yii::$app->params['dada_callback'] ?? 'https://api.shop.hzghd.com/delivery/dada-callback';
+
+        return [
+            'platform' => 'dada',
+            'shop_no' => $shopNo,
+            'origin_id' => $order['orderSn'],
+            'cargo_price' => (float)$order['actPrice'],
+            'is_prepay' => 0, // 是否需要垫付 1:是 0:否 (垫付订单金额,非运费)
+            'receiver_name' => $order['customName'],
+            'receiver_address' => $order['fullAddress'],
+            'receiver_lat' => (float)$order['lat'],
+            'receiver_lng' => (float)$order['long'],
+            'callback' => $callbackUrl,
+            'cargo_weight' => isset($order['weight']) ? (float)$order['weight'] : 1.0,
+            'receiver_phone' => isset($order['customMobile']) ? $order['customMobile'] : isset($order['receiveMobile']) ? $order['receiveMobile'] : '',
+            'tips' => 0,
+            'info' => $order['remark'] ?? '',
+            'product_list' => $productList,
+        ];
+    }
+
     /**
      * 并发获取各平台报价(核心实现)
      * 
@@ -710,6 +771,15 @@ class DispatchService
                         ];
                     }
                     break;
+                case 'dada':
+                    $deliveryList[] = [
+                        'name' => '达达',
+                        'en_name' => 'dada',
+                        'price' => $item['deliver_fee'],
+                        'distance' => $item['distance'],
+                        'type' => 'dada',
+                    ];
+                    break;
             }
         }
 

+ 94 - 2
common/components/delivery/services/adapter/DadaAdapter.php

@@ -2,7 +2,6 @@
 namespace common\components\delivery\services\adapter;
 
 use common\components\delivery\helpers\HttpClient;
-use common\components\delivery\helpers\SignHelper;
 use common\components\delivery\platform\dada\Dada;
 use Yii;
 
@@ -14,6 +13,8 @@ use Yii;
  */
 class DadaAdapter extends Dada implements Adapter
 {
+    protected $shopNo;
+
     /**
      * 获取已开通城市列表
      * 
@@ -245,8 +246,99 @@ class DadaAdapter extends Dada implements Adapter
         // TODO: Implement addTip() method.
     }
 
+
+    public function setShopNo($shopNo)
+    {
+        $this->shopNo = $shopNo;
+    }
+
+    public function getShopNo()
+    {
+        return $this->shopNo;
+    }
+
+    /**
+     * 构建运费报价请求信息
+     *
+     * @param array $data 预处理后的订单数据
+     * @param string $orderTime 配送时间
+     * @return array
+     */
     public function buildPriceRequest($data, $orderTime)
     {
-        // TODO: Implement buildPriceRequest() method.
+        // 1. 准备业务参数
+        $apiData = [
+            'shop_no' => $data['shop_no'] ?? $this->getShopNo(),
+            'origin_id' => $data['origin_id'],
+            'cargo_price' => (float)$data['cargo_price'],
+            'is_prepay' => (int)$data['is_prepay'],
+            'receiver_name' => $data['receiver_name'],
+            'receiver_address' => $data['receiver_address'],
+            'receiver_lat' => (double)$data['receiver_lat'],
+            'receiver_lng' => (double)$data['receiver_lng'],
+            'callback' => $data['callback'],
+            'cargo_weight' => (double)$data['cargo_weight'],
+            'receiver_phone' => $data['receiver_phone'],
+        ];
+
+        // 添加可选参数
+        if (isset($data['tips'])) {
+            $apiData['tips'] = (float)$data['tips'];
+        }
+        if (isset($data['info'])) {
+            $apiData['info'] = $data['info'];
+        }
+        if (isset($data['cargo_type'])) {
+            $apiData['cargo_type'] = (int)$data['cargo_type'];
+        }
+        if (isset($data['cargo_num'])) {
+            $apiData['cargo_num'] = (int)$data['cargo_num'];
+        }
+        if (isset($data['is_use_insurance'])) {
+            $apiData['is_use_insurance'] = (int)$data['is_use_insurance'];
+        }
+        if (isset($data['product_list']) && !empty($data['product_list'])) {
+            $apiData['product_list'] = $data['product_list'];
+        }
+        // 处理预约单
+        if (isset($data['delay_publish_time'])) {
+            $apiData['delay_publish_time'] = (int)$data['delay_publish_time'];
+            $apiData['is_expect_finish_order'] = 1; // 预约单
+            // expect_finish_time_limit 也是需要的吗?文档说 delay_publish_time 是预约发单时间
+        }
+
+        // 2. 构建完整请求 Payload (含签名)
+        $body = json_encode($apiData, JSON_UNESCAPED_UNICODE);
+        $payload = $this->buildRequestPayload('order/queryDeliverFee', $body);
+
+        // 3. 返回请求配置 (供 HttpClient::postConcurrent 使用)
+        return [
+            'url' => $this->baseUrl . '/api/order/queryDeliverFee',
+            'data' => $payload,
+            'headers' => ['Content-Type' => 'application/json'],
+            'timeout' => 5.0,
+        ];
+    }
+
+    public function processPriceResponse($resp)
+    {
+        Yii::info("[DadaAdapter] processPriceResponse: " . json_encode($resp));
+        if (isset($resp['code']) && $resp['code'] == 0 && isset($resp['result'])) {
+            $result = $resp['result'];
+            return [
+                'platform' => 'dada',
+                'deliver_fee' => $result['deliver_fee'],
+                'distance' => $result['distance'],
+                'duration' => $result['duration'],
+                'tips' => $result['tips'],
+            ];
+        }
+
+        return [
+            'code' => $resp['code'] ?? -1,
+            'msg' => $resp['msg'] ?? 'Unknown error',
+            'data' => null
+        ];
     }
+
 }

+ 33 - 15
common/components/delivery/services/adapter/FengniaoAdapter.php

@@ -2,6 +2,7 @@
 namespace common\components\delivery\services\adapter;
 
 use bizGhs\order\classes\OrderItemClass;
+use bizHd\order\classes\OrderGoodsClass;
 use common\components\delivery\helpers\HttpClient;
 use common\components\delivery\platform\fengniao\Fengniao;
 use Yii;
@@ -63,27 +64,44 @@ class FengniaoAdapter extends Fengniao implements Adapter
         }
 
         $sn = $order['orderSn'];
-        $itemInfos = OrderItemClass::getAllByCondition(['orderSn' => $sn], null, 'id, name, unitPrice, num, unitWeight');
-
-        $goodsWeight = 0;
-        $goodsItemList = [];
-        foreach ($itemInfos as $item){
-            $goodsItemList[] = [
-                'item_actual_amount_cent' => $item['unitPrice'] * 100 * $item['num'],
-                'item_amount_cent' => $item['unitPrice'] * 100,
-                'item_id' => $item['id'],
-                'item_name' => $item['name'],
-                'item_quantity' => $item['num'],
-            ];
-            $goodsWeight += $item['unitWeight'];
+        // 批发
+        if(strstr($sn, 'XSD_CS')){
+            $itemInfos = OrderItemClass::getAllByCondition(['orderSn' => $sn], null, 'id, name, unitPrice, num, unitWeight');
+            $goodsWeight = 0;
+            $goodsItemList = [];
+            foreach ($itemInfos as $item){
+                $goodsItemList[] = [
+                    'item_actual_amount_cent' => $item['unitPrice'] * 100 * $item['num'],
+                    'item_amount_cent' => $item['unitPrice'] * 100,
+                    'item_id' => $item['id'],
+                    'item_name' => $item['name'],
+                    'item_quantity' => $item['num'],
+                ];
+                $goodsWeight += $item['unitWeight'];
+            }
+            $goodsCount = count($goodsItemList);
+        // 零售
+        }else if(strstr($sn, 'KD_CS')){
+            $itemInfos = OrderGoodsClass::getAllByCondition(['orderSn' => $sn], null, 'id, name, unitPrice, num');
+            $goodsWeight = 0;
+            $goodsItemList = [];
+            foreach ($itemInfos as $item){
+                $goodsItemList[] = [
+                    'item_actual_amount_cent' => $item['unitPrice'] * 100 * $item['num'],
+                    'item_amount_cent' => $item['unitPrice'] * 100,
+                    'item_id' => $item['id'],
+                    'item_name' => $item['name'],
+                    'item_quantity' => $item['num'],
+                ];
+            }
+            $goodsCount = count($goodsItemList);
         }
 
-        $goodsCount = count($goodsItemList);
         // TODO: 需要实现 goods_item_list 的商品信息补充
         $orderData = [
             //'out_shop_code' => $params['mainId'], // 当使用门店发单 out_shop_code 和 chain_store_id 必填1个
             'partner_order_code' => $order['orderSn'],
-            'receiver_primary_phone' => $order['customMobile'],
+            'receiver_primary_phone' => isset($order['customMobile']) ? $order['customMobile'] : isset($order['receiveMobile']) ? $order['receiveMobile'] : '',
             'receiver_name' => $order['customName'],
             'receiver_latitude' => (float)$order['lat'],
             'receiver_longitude' => (float)$order['long'],

+ 1 - 2
common/components/delivery/services/adapter/HuolalaAdapter.php

@@ -1,7 +1,6 @@
 <?php
 namespace common\components\delivery\services\adapter;
 
-use common\components\delivery\services\DispatchService;
 use Yii;
 use common\components\delivery\helpers\HttpClient;
 use common\components\delivery\platform\huolala\Huolala;
@@ -223,7 +222,7 @@ class HuolalaAdapter extends Huolala implements Adapter
                      'district_name' => $order['dist'],
                      'house_number' => $order['floor'],
                      'contacts_name' => $order['customName'],
-                     'contacts_phone_no' => $order['customMobile'],
+                     'contacts_phone_no' => isset($order['customMobile']) ? $order['customMobile'] : isset($order['receiveMobile']) ? $order['receiveMobile'] : '',
                  ]
             ],
             'vehicle_std' => $params['vehicle_std'],