Browse Source

同城配送相关的代码优化

shizhongqi 10 tháng trước cách đây
mục cha
commit
c527e947b7

+ 21 - 43
app-ghs/controllers/IntraCityController.php

@@ -68,10 +68,10 @@ class IntraCityController extends BaseController
             }
 
             // 创建门店前,检查是否已经 开通门店权限 (有wxStoreId,即说明开通了)
-            $shopExt = MainClass::getById($this->mainId, true, 'id, wxStoreId');
+            $main = MainClass::getById($this->mainId, true, 'id, wxStoreId');
 
             // 查询是否存在 wx_store_id,不存在则执行apply
-            if ($shopExt->wxStoreId == '') {
+            if ($main->wxStoreId == '') {
                 $re = IntraCityExpress::applyStore();
                 if (!is_array($re)) {
                     $re = Json::decode($re, true);
@@ -85,8 +85,8 @@ class IntraCityController extends BaseController
             $result = IntraCityExpress::createStore($storeData);
             if ($result['errcode'] === 0) {
                 // 保存微信门店编号(wx_store_id)
-                $shopExt->wxStoreId = $result['wx_store_id'];
-                $shopExt->save();
+                $main->wxStoreId = $result['wx_store_id'];
+                $main->save();
 
                 util::success($result, "门店创建成功");
             } else {
@@ -106,14 +106,14 @@ class IntraCityController extends BaseController
     {
         $shopId = $this->shopId;
         // 首先从门店扩展表查询是否已经创建
-        $shopExt = MainClass::getById($this->mainId, true, 'id, wxStoreId');
-        if ($shopExt->wxStoreId == '') { // 不存在,则从微信接口查询
+        $main = MainClass::getById($this->mainId, true, 'id, wxStoreId');
+        if ($main->wxStoreId == '') { // 不存在,则从微信接口查询
             $result = IntraCityExpress::getStore($this->mainId);
             if ($result['errcode'] === 0) {
                 $store = $result['store_list'][0];
                 // 保存 wx_store_id
-                $shopExt->wxStoreId = $store['wx_store_id'];
-                $shopExt->save();
+                $main->wxStoreId = $store['wx_store_id'];
+                $main->save();
 
                 util::success($store, "门店查询成功");
             } else {
@@ -123,7 +123,7 @@ class IntraCityController extends BaseController
         } else {
             $field = 'province, city, dist, lat, long, floor, address';
             $shop = ShopClass::getById($shopId, false, $field);
-            $data = array_merge($shop, $shopExt->toArray());
+            $data = array_merge($shop, $main->toArray());
             util::success($data, "门店查询成功");
         }
     }
@@ -134,8 +134,8 @@ class IntraCityController extends BaseController
     public function actionUpdateStore()
     {
         // 首先从门店扩展表查询是否已经创建
-        $shopExt = MainClass::getById($this->mainId, false, 'id, wxStoreId');
-        if ($shopExt['wxStoreId'] == '') {
+        $main = MainClass::getById($this->mainId, false, 'id, wxStoreId');
+        if ($main['wxStoreId'] == '') {
             util::fail('未创建门店,请先创建');
         }
 
@@ -145,7 +145,7 @@ class IntraCityController extends BaseController
         $name = $shopName == '首店' ? $sjName : $sjName . ' ' . $shopName;
 
         $storeData = [
-            'keys' => ['wx_store_id' => $shopExt['wxStoreId']],
+            'keys' => ['wx_store_id' => $main['wxStoreId']],
             'content' => [
                 'store_name' => $name,
                 'address_info' => [
@@ -330,8 +330,6 @@ class IntraCityController extends BaseController
             $sn = $order['orderSn'];
             $itemInfoList = OrderItemClass::getAllByCondition(['orderSn'=>$sn], null,'id, name, cover, num');
             $itemList = [];
-            $orderType = 2; // 默认是 2。说明:1花束订单 2花材订单 3花束和花材都有
-
             $itemCount = 0;
             foreach ($itemInfoList as $itemInfo) {
                 $itemList[] = [
@@ -348,25 +346,15 @@ class IntraCityController extends BaseController
                 util::fail("微信门店不存在");
             }
 
-            $cargoName = '花材'; // 商品名称,默认是花材
-            $goodsInfoList = OrderGoodsClass::getListBySn($sn);
-            if (count($goodsInfoList) == 1) {
-                $goodsInfo = $goodsInfoList[0];
-                $cargoName = $goodsInfo['name'];
-            } else {
-                if ($orderType != 2) {
-                    Yii::error('订单商品数量不正确');
-                    util::fail("订单商品数量不正确");
-                }
-            }
-
-            // 通过 userId 获取 openid(小程序OpenId)
+            // 获取 openid(小程序OpenId)
             $user = UserClass::getByCondition(['mobile'=>$order['customMobile']], false, false,'id, miniOpenId');
             if (empty($user)) {
+                noticeUtil::push("通过手机号-".$order['customMobile'].",获取小程序OpenId失败");
                 Yii::error('获取用户openId出错');
                 util::fail('数据出错');
             }
 
+            $cargoName = '花材'; // 商品名称
             $cargo = [
                 'cargo_name' => $cargoName,
                 'cargo_weight' => intval($post['weight'] * 1000),
@@ -383,8 +371,6 @@ class IntraCityController extends BaseController
                 $query = (new Query())
                     ->from('xhGhsExpressOrder')
                     ->where(['orderId' => $orderId]);
-                // $command = $query->createCommand();
-                // $sql = $command->sql;
                 $copyOrderCount = $query->count();
                 $copyOrderCount += 1;
                 //区分线上线下
@@ -395,7 +381,6 @@ class IntraCityController extends BaseController
                 }
             }
 
-
             $callbackUrl = Yii::$app->params['ghsHost'] . '/intra-city/callback';
             $orderData = [
                 'wx_store_id' => $shopExt['wxStoreId'],
@@ -487,21 +472,14 @@ class IntraCityController extends BaseController
             // 检查是否存在重复的订单:如果存在,则使用最后一个订单的 store_order_id
             $storeOrderId = $orderId; // ------------------------------------- 注意区分:$storeOrderId , $orderId 。它们有可能不相同
             $query = (new Query())
-                ->from('xhExpressOrder')
-                ->where(['and',
-                    new \yii\db\Expression('storeOrderId LIKE CONCAT(:prefix, "%")', [':prefix' => $orderId . '_copy_']),
-                    ['status' => 1]
-                ])->andWhere(['mainId' => $this->mainId])
-                ->orderBy('addTime DESC');
+                ->from('xhGhsExpressOrder')
+                ->where(['orderId' => $orderId])
+                ->andWhere(['mainId' => $this->mainId]);
             $esDatas = $query->all();
             $count = count($esDatas);
             if ($count > 0) {
                 $es = $esDatas[0];
                 $storeOrderId = $es['storeOrderId'];
-
-                if ($count > 1) {
-                    noticeUtil::push('同城配送订单重复多于1个. store_order_id:' . $orderId . ',wx_store_id:' . $wxStoreId);
-                }
             }
 
 
@@ -563,7 +541,7 @@ class IntraCityController extends BaseController
                 $storeOrderId = $es['storeOrderId'];
 
                 if ($count > 1) {
-                    noticeUtil::push('同城配送订单重复多于1个. store_order_id:' . $orderId . ',wx_store_id:' . $wxStoreId);
+                    noticeUtil::push('同城配送订单重复多于1个. store_order_id:' . $storeOrderId . ',wx_store_id:' . $wxStoreId);
                 }
             }
 
@@ -614,13 +592,13 @@ class IntraCityController extends BaseController
         // 从配置中获取安全token
         // $token = Yii::$app->params['wx_intracity_token'] ?? 'your_token_here';
         // $result = IntraCityExpress::handleOrderCallback($callbackData, $token);
-
         // 记录回调日志
         Yii::info('同城配送回调:' . json_encode($callbackData, JSON_UNESCAPED_UNICODE), 'intraCity');
 
         $storeOrderId = $callbackData['store_order_id'] ?? 0;
         $wxStoreId = $callbackData['wx_store_id'] ?? ''; //微信门店编号
         if (empty($storeOrderId) || empty($wxStoreId)) {
+            Yii::error("配送单回调接口的请求参数出错,storeOrderId = $storeOrderId, wxStoreId = $wxStoreId");
             return $this->asJson(['return_code' => 1, 'return_msg' => '请求参数不正确']);
         }
 
@@ -628,7 +606,7 @@ class IntraCityController extends BaseController
             // 使用 storeOrderId 与 wxStoreId 去查询 xhExpressOrder 表
             $eo = ExpressOrderClass::getByCondition(['storeOrderId' => $storeOrderId, 'wxStoreId' => $wxStoreId], true, false);
             if (empty($eo)) {
-                Yii::error('订单不存在.store_order_id: ' . $storeOrderId . ',wx_store_id: ' . $wxStoreId);
+                Yii::error('订单不存在. store_order_id: ' . $storeOrderId . ',wx_store_id: ' . $wxStoreId);
                 return $this->asJson(['return_code' => 1, 'return_msg' => '系统错误']);
             }
             // 从 $storeOrderId 提取 orderId

+ 54 - 53
common/components/IntraCityExpress.php

@@ -11,6 +11,22 @@ use phpseclib\Crypt\RSA;
 
 class IntraCityExpress
 {
+    /**
+     * 订单状态常量
+     */
+    const ORDER_STATUS_CREATED = 10000;        // 订单创建成功
+    const ORDER_STATUS_CANCELED_BY_MERCHANT = 20000;  // 商家取消订单
+    const ORDER_STATUS_CANCELED_BY_DELIVERY = 20001;  // 配送方取消订单
+    const ORDER_STATUS_ACCEPTED = 30000;       // 配送员接单
+    const ORDER_STATUS_ARRIVED = 40000;        // 配送员到店
+    const ORDER_STATUS_DELIVERING = 50000;     // 配送中
+    const ORDER_STATUS_WITHDRAWN = 60000;      // 配送员撤单
+    const ORDER_STATUS_COMPLETED = 70000;      // 配送完成
+    const ORDER_STATUS_EXCEPTION = 90000;      // 配送异常
+
+    // 物品类型
+    const GOODS_TYPE_FLOWER = 14;      // 鲜花
+
     /**
      * 获取 access_token
      * @param $merchant
@@ -46,11 +62,11 @@ class IntraCityExpress
         // 获取私钥
         $env = getenv('YII_ENV') == 'production' ? 'production' : 'dev';
         $privateKeyPath = __DIR__ . '/wxapi/' . $env . '/rsa-private-key.txt';
-        
+
         if (!file_exists($privateKeyPath)) {
             throw new \Exception("私钥文件不存在: {$privateKeyPath}");
         }
-        
+
         $privateKey = file_get_contents($privateKeyPath);
         if (!$privateKey) {
             throw new \Exception('无法获取私钥文件');
@@ -69,9 +85,8 @@ class IntraCityExpress
         // $base64Signature = base64_encode($signature);
         // \Yii::info("生成的签名: " . $base64Signature, 'intracity_signature');
         // return $base64Signature;
-            
 
-            
+
         // 方案二:使用 RSA SHA256签名
         try {
             // 使用RSA SHA256签名
@@ -80,17 +95,17 @@ class IntraCityExpress
             $rsa->setHash("sha256");
             $rsa->setMGFHash("sha256");
             $signature = $rsa->sign($payload);
-            
+
             // $rsa = new RSA();
             // $rsa->loadKey($privateKey);
             // $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1); // 明确使用PKCS#1 v1.5
             // $rsa->setHash("sha256");
             // 不要设置MGF,PKCS#1 v1.5不使用MGF
             // $signature = $rsa->sign($payload);
-            
+
             $base64Signature = base64_encode($signature);
             \Yii::info("phpseclib生成的签名: " . $base64Signature, 'intracity_signature');
-            
+
             return $base64Signature;
         } catch (\Exception $e) {
             \Yii::error("所有签名方法都失败 - OpenSSL: " . $e->getMessage() . " phpseclib: " . $e->getMessage(), 'intracity_signature');
@@ -164,7 +179,6 @@ class IntraCityExpress
     }
 
 
-
     // ==================== API URL常量 ====================
     const API_BASE_URL = 'https://api.weixin.qq.com/cgi-bin/express/intracity';
 
@@ -195,6 +209,7 @@ class IntraCityExpress
 
 
     // ==================== 门店管理接口 ====================
+
     /**
      * 创建门店
      * @param array $storeData 门店信息
@@ -215,7 +230,7 @@ class IntraCityExpress
             'order_pattern' => 1,
             "address_info" => $storeData['address_info']
         ];
-        
+
         return self::sendRequest(self::API_CREATE_STORE, $data, $accessToken);
     }
 
@@ -231,10 +246,10 @@ class IntraCityExpress
         if ($merchant === null) {
             $merchant = self::getMerchant();
         }
-        
+
         $accessToken = self::getAccessToken($merchant, $ptStyle);
         $data = $storeData;
-        
+
         return self::sendRequest(self::API_UPDATE_STORE, $data, $accessToken);
     }
 
@@ -250,12 +265,12 @@ class IntraCityExpress
         if ($merchant === null) {
             $merchant = self::getMerchant();
         }
-        
+
         $accessToken = self::getAccessToken($merchant, $ptStyle);
         $data = [
             'out_store_id' => $outStoreId,
         ];
-        
+
         return self::sendRequest(self::API_QUERY_STORE, $data, $accessToken);
     }
 
@@ -277,6 +292,7 @@ class IntraCityExpress
 
 
     // ==================== 订单管理接口 ====================
+
     /**
      * 创建订单
      * @param array $orderData 订单信息
@@ -289,7 +305,7 @@ class IntraCityExpress
         if ($merchant === null) {
             $merchant = self::getMerchant();
         }
-        
+
         $accessToken = self::getAccessToken($merchant, $ptStyle);
         //开发环境只能使用沙箱 ssh
         if (getenv('YII_ENV') != 'production') {
@@ -301,7 +317,7 @@ class IntraCityExpress
             $orderData['user_lat'] = (double)40.014747;
         }
         $data = $orderData;
-        
+
         return self::sendRequest(self::API_ADD_ORDER, $data, $accessToken);
     }
 
@@ -324,9 +340,9 @@ class IntraCityExpress
         if ($merchant === null) {
             $merchant = self::getMerchant();
         }
-        
+
         $accessToken = self::getAccessToken($merchant, $ptStyle);
-        
+
         // 请求体
         $data = $orderData;
 
@@ -348,7 +364,7 @@ class IntraCityExpress
             $merchant = self::getMerchant();
         }
         $accessToken = self::getAccessToken($merchant, $ptStyle);
-        
+
         $data = [];
         if (!empty($wxOrderId)) {
             $data['wx_order_id'] = $wxOrderId;
@@ -374,7 +390,7 @@ class IntraCityExpress
      * @param int $ptStyle
      * @return array
      */
-    public static function queryOrder($wxStoreId, $storeOrderId='', $wxOrderId='', $merchant = null, $ptStyle = 0)
+    public static function queryOrder($wxStoreId, $storeOrderId = '', $wxOrderId = '', $merchant = null, $ptStyle = 0)
     {
         if ($merchant === null) {
             $merchant = self::getMerchant();
@@ -384,19 +400,20 @@ class IntraCityExpress
         if (empty($wxOrderId) && (empty($storeOrderId) || empty($wxStoreId))) {
             util::fail("参数不足:wx_order_id 或 (store_order_id + wx_store_id) 必须提供一组");
         }
-        
+
         $data = [];
         if ($wxStoreId != '') {
             $data['wx_order_id'] = $wxOrderId;
         }
         $data['store_order_id'] = $storeOrderId;
         $data['wx_store_id'] = $wxStoreId;
-        
+
         return self::sendRequest(self::API_GET_ORDER, $data, $accessToken);
     }
 
 
     // ==================== 资金管理接口 ====================
+
     /**
      * 查询门店余额
      * @param string $wxStoreId
@@ -486,6 +503,7 @@ class IntraCityExpress
     }
 
     // ==================== 测试接口 ====================
+
     /**
      * 模拟回调接口
      * @param string $wxOrderId 微信订单号
@@ -501,13 +519,13 @@ class IntraCityExpress
         if ($merchant === null) {
             $merchant = self::getMerchant();
         }
-        
+
         $accessToken = self::getAccessToken($merchant, $ptStyle);
-        
+
         $data = [
             'order_status' => $orderStatus,
         ];
-        
+
         if (!empty($wxOrderId)) {
             $data['wx_order_id'] = $wxOrderId;
         }
@@ -516,7 +534,7 @@ class IntraCityExpress
             $data['wx_store_id'] = $outStoreId;
             $data['store_order_id'] = $outOrderId;
         }
-        
+
         return self::sendRequest(self::API_MOCK_NOTIFY, $data, $accessToken);
     }
 
@@ -536,22 +554,23 @@ class IntraCityExpress
                 $signParams[$field] = $params[$field];
             }
         }
-        
+
         // 2. 按字典序排序参数
         ksort($signParams);
-        
+
         // 3. 拼接参数字符串
         $signStr = '';
         foreach ($signParams as $key => $value) {
             $signStr .= $key . '=' . $value . '&';
         }
         $signStr .= 'token=' . $token;
-        
+
         // 4. 计算MD5并转为小写
         return strtolower(md5($signStr));
     }
 
     // ==================== 回调验证接口 ====================
+
     /**
      * 验证回调签名
      * @param array $params 回调参数
@@ -563,12 +582,12 @@ class IntraCityExpress
         if (!isset($params['sign'])) {
             return false;
         }
-        
+
         $receivedSign = $params['sign'];
         unset($params['sign']);
-        
+
         $calculatedSign = self::generateCallbackSignature($params, $token);
-        
+
         return $receivedSign === $calculatedSign;
     }
 
@@ -587,16 +606,16 @@ class IntraCityExpress
                 'return_msg' => '签名验证失败'
             ];
         }
-        
+
         // 处理订单状态变化
         $orderStatus = $callbackData['order_status'];
         $wxOrderId = $callbackData['wx_order_id'];
         $outOrderId = $callbackData['store_order_id'] ?? '';
         $outStoreId = $callbackData['wx_store_id'] ?? '';
-        
+
         // 这里可以添加具体的业务逻辑处理
         // 例如:更新数据库中的订单状态、发送通知等
-        
+
         // 伪代码示例:
         /*
         switch ($orderStatus) {
@@ -625,28 +644,10 @@ class IntraCityExpress
                 break;
         }
         */
-        
+
         return [
             'return_code' => 0,
             'return_msg' => 'OK'
         ];
     }
-
-    // ==================== 常量定义 ====================
-
-    /**
-     * 订单状态常量
-     */
-    const ORDER_STATUS_CREATED = 10000;        // 订单创建成功
-    const ORDER_STATUS_CANCELED_BY_MERCHANT = 20000;  // 商家取消订单
-    const ORDER_STATUS_CANCELED_BY_DELIVERY = 20001;  // 配送方取消订单
-    const ORDER_STATUS_ACCEPTED = 30000;       // 配送员接单
-    const ORDER_STATUS_ARRIVED = 40000;        // 配送员到店
-    const ORDER_STATUS_DELIVERING = 50000;     // 配送中
-    const ORDER_STATUS_WITHDRAWN = 60000;      // 配送员撤单
-    const ORDER_STATUS_COMPLETED = 70000;      // 配送完成
-    const ORDER_STATUS_EXCEPTION = 90000;      // 配送异常
-
-    const GOODS_TYPE_FLOWER = 14;      // 鲜花
-
 }