Răsfoiți Sursa

同城配送接口bug修复与完善调整

shizhongqi 1 an în urmă
părinte
comite
c643f43bec

+ 80 - 84
app-hd/controllers/IntraCityController.php

@@ -4,7 +4,6 @@ namespace hd\controllers;
 
 use bizHd\express\classes\ExpressOrderClass;
 use bizHd\express\models\ExpressOrder;
-use bizHd\goods\classes\GoodsClass;
 use bizHd\order\classes\OrderClass;
 use bizHd\order\classes\OrderGoodsClass;
 use bizHd\order\classes\OrderItemClass;
@@ -34,8 +33,6 @@ class IntraCityController extends BaseController
      */
     public function actionCreateStore()
     {
-        Yii::$app->response->format = Response::FORMAT_JSON;
-
         try {
             $shopId = intval($this->shopId);
             if (empty($shopId)) {
@@ -67,9 +64,9 @@ class IntraCityController extends BaseController
             }
 
             // 创建门店前,检查是否已经 开通门店权限 (有wxStoreId,即说明开通了)
-            $shopExt = ShopExtClass::getByCondition(['shopId'=>$shopId], false, false, 'id, wxStoreId');
+            $shopExt = ShopExtClass::getByCondition(['shopId'=>$shopId], true, false, 'id, wxStoreId');
             // 查询是否存在 wx_store_id,不存在则执行apply
-            if ($shopExt['wxStoreId'] == '') {
+            if ($shopExt->wxStoreId == '') {
                 $re = IntraCityExpress::applyStore();
                 if (!is_array($re)) {
                     $re = Json::decode($re, true);
@@ -82,6 +79,10 @@ class IntraCityController extends BaseController
 
             $result = IntraCityExpress::createStore($storeData);
             if ($result['errcode'] === 0) {
+                // 保存微信门店编号(wx_store_id)
+                $shopExt->wxStoreId = $result['wx_store_id'];
+                $shopExt->save();
+
                 util::success("门店创建成功", $result);
             } else {
                 Yii::error("门店创建失败:" . $result['errmsg']);
@@ -102,13 +103,27 @@ class IntraCityController extends BaseController
         if (empty($shopId)) {
             util::fail("门店不存在");
         }
-        $result = IntraCityExpress::getStore($shopId);
-        if ($result['errcode'] === 0) {
-            $store = $result['store_list'][0];
-            util::success($store, "门店查询成功");
+
+        // 首先从门店扩展表查询是否已经创建
+        $shopExt = ShopExtClass::getByCondition(['shopId'=>$shopId], true, false, 'id, wxStoreId');
+        if ($shopExt->wxStoreId == '') { // 不存在,则从微信接口查询
+            $result = IntraCityExpress::getStore($shopId);
+            if ($result['errcode'] === 0) {
+                $store = $result['store_list'][0];
+                // 保存 wx_store_id
+                $shopExt->wxStoreId = $store['wx_store_id'];
+                $shopExt->save();
+
+                util::success($store, "门店查询成功");
+            } else {
+                Yii::error("门店查询失败:" . $result['errmsg']);
+                util::fail('门店查询失败');
+            }
         } else {
-            Yii::error("门店查询失败:" . $result['errmsg']);
-            util::fail('门店查询失败');
+            $field = 'province, city, dist, lat, long, floor, address';
+            $shop = ShopClass::getById($shopId, false, $field);
+            $data = array_merge($shop, $shopExt->toArray());
+            util::success($data, "门店查询成功");
         }
     }
 
@@ -121,24 +136,35 @@ class IntraCityController extends BaseController
         if (empty($shopId)) {
             util::fail("门店不存在");
         }
+        // 首先从门店扩展表查询是否已经创建
+        $shopExt = ShopExtClass::getByCondition(['shopId'=>$shopId], false, false, 'id, wxStoreId');
+        if ($shopExt['wxStoreId'] == '') {
+            util::fail('未创建门店,请先创建');
+        }
+
         $shop = ShopClass::getById($shopId, true, 'id, merchantName, province, city, dist, address, floor, lat, long, telephone');
+
         $storeData = [
-            'out_store_id' => $shopId,
-            'store_name' => $shop->merchantName,
-            'address_info' => [
-                'province' => $shop->province,
-                'city' => $shop->city,
-                'area' => $shop->dist,
-                'street' => $shop->address,
-                'house' => $shop->floor,
-                'lat' => $shop->lat,
-                'lng' => $shop->long,
-                'phone' => $shop->telephone
+            'keys' => ['wx_store_id'=>$shopExt['wxStoreId']],
+            'content' => [
+                'store_name' => $shop->merchantName,
+                'address_info' => [
+                    'province' => $shop->province,
+                    'city' => $shop->city,
+                    'area' => $shop->dist,
+                    'street' => $shop->address,
+                    'house' => $shop->floor,
+                    'lat' => $shop->lat,
+                    'lng' => $shop->long,
+                    'phone' => $shop->telephone
+                ],
+                //"order_pattern" => 2,
+		        //"service_trans_prefer" => "SFTC" //order_pattern = 2时必填
             ]
         ];
-        $result = IntraCityExpress::updateStore($shopId, $storeData);
+        $result = IntraCityExpress::updateStore($storeData);
         if ($result['errcode'] === 0) {
-            util::success("门店更新成功", $result);
+            util::success($result, "门店更新成功");
         } else {
             Yii::error("门店更新失败:" . $result['errmsg']);
             util::fail('门店更新失败');
@@ -157,10 +183,10 @@ class IntraCityController extends BaseController
             util::fail('50元起充');
         }
 
+        $expressId = $post['expressId'];
         $serviceTransIds = ['SFTC', 'DADA'];
-        $expressName = 'SFTC';
-        if (isset($post['expressId']) && in_array($post['expressId'], $serviceTransIds)) {
-            $expressName = $post['expressId'];
+        if (!in_array($expressId, $serviceTransIds)) {
+            util::fail('快递动力ID出错');
         }
 
         $shopId = intval($this->shopId);
@@ -173,7 +199,7 @@ class IntraCityController extends BaseController
             util::fail('微信门店编号为空');
         }
         $wxStoreId = $shopExt['wxStoreId'];
-        $result = IntraCityExpress::storeCharge($wxStoreId, $expressName, $amountTurnFen);
+        $result = IntraCityExpress::storeCharge($wxStoreId, $expressId, $amountTurnFen);
         if ($result['errcode'] === 0) {
             util::success($result, "门店余额充值单已生成");
         } else {
@@ -542,10 +568,7 @@ class IntraCityController extends BaseController
 
             }
         } catch (\Exception $e) {
-            return [
-                'success' => false,
-                'message' => '系统错误:' . $e->getMessage()
-            ];
+
         }
     }
 
@@ -574,10 +597,7 @@ class IntraCityController extends BaseController
                 ];
             }
         } catch (\Exception $e) {
-            return [
-                'success' => false,
-                'message' => '系统错误:' . $e->getMessage()
-            ];
+
         }
     }
 
@@ -589,21 +609,31 @@ class IntraCityController extends BaseController
     {
         try {
             $callbackData = Yii::$app->request->post();
+            if (empty($callbackData)) {
+                $postStr = file_get_contents('php://input');
+                // 处理转义字符,将JSON字符串正确解析为数组
+                $postStr = stripslashes($postStr);
+                $callbackData = json_decode($postStr, true);
+
+                if (empty($callbackData)) {
+                    util::fail('回调请求的数据为空');
+                }
+            }
 
             // 从配置中获取安全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_callback');
+            Yii::info('同城配送回调:' . json_encode($callbackData, JSON_UNESCAPED_UNICODE));
 
-            $orderId = isset($callbackData['store_order_id']) ? intval($callbackData['store_order_id']) : 0;
+            $storeOrderId = isset($callbackData['store_order_id']) ? intval($callbackData['store_order_id']) : 0;
             $wxStoreId = $callbackData['wx_store_id'];
 
-            // 使用 store_order_id 与 wx_store_id 去查询 xhExpressOrder 表
-            $eo = ExpressOrderClass::getByCondition(['store_order_id'=>$orderId, 'wx_order_id'=>$wxStoreId], true, false);
+            // 使用 storeOrderId 与 wxStoreId 去查询 xhExpressOrder 表
+            $eo = ExpressOrderClass::getByCondition(['storeOrderId'=>$storeOrderId, 'wxStoreId'=>$wxStoreId], true, false);
             if (empty($eo)) {
-                Yii::error('订单不存在.store_order_id: '.$orderId.',wx_store_id: '.$wxStoreId);
+                Yii::error('订单不存在.store_order_id: '.$storeOrderId.',wx_store_id: '.$wxStoreId);
                 return [
                     'return_code' => 1,
                     'return_msg' => '系统错误'
@@ -644,8 +674,8 @@ class IntraCityController extends BaseController
             }
             $re = $eo->save();
             if (!$re) {
-                noticeUtil::push('同城配送回调更新订单状态失败. store_order_id:'.$orderId.',wx_store_id:'.$wxStoreId.',status:'.$eo->status);
-                Yii::error('更新订单状态失败. store_order_id:'.$orderId.',wx_store_id:'.$wxStoreId.',status:'.$eo->status);
+                noticeUtil::push('同城配送回调更新订单状态失败. store_order_id:'.$storeOrderId.',wx_store_id:'.$wxStoreId.',status:'.$eo->status);
+                Yii::error('更新订单状态失败. store_order_id:'.$storeOrderId.',wx_store_id:'.$wxStoreId.',status:'.$eo->status);
                 return [
                     'return_code' => 0,
                     'return_msg' => 'OK'
@@ -656,50 +686,16 @@ class IntraCityController extends BaseController
                 'return_code' => 0,
                 'return_msg' => 'OK'
             ];
-            return $result;
+            echo Json::encode($result);
+            exit();
         } catch (\Exception $e) {
-            Yii::error('同城配送回调处理异常:' . $e->getMessage(), 'intracity_callback');
-            return [
+            Yii::error('同城配送回调处理异常:' . $e->getMessage());
+
+            echo Json::encode([
                 'return_code' => 1,
                 'return_msg' => '系统错误'
-            ];
-        }
-    }
-
-    /**
-     * 模拟回调(测试用)
-     * POST /intra-city/mock-notify
-     */
-    public function actionMockNotify()
-    {
-        Yii::$app->response->format = Response::FORMAT_JSON;
-
-        try {
-            $request = Yii::$app->request;
-            $orderStatus = $request->post('order_status');
-            $wxOrderId = $request->post('wx_order_id');
-            $outStoreId = $request->post('out_store_id');
-            $outOrderId = $request->post('store_order_id'); // 修正为 store_order_id
-
-            if (empty($orderStatus)) {
-                util::fail("请提供订单状态");
-            }
-
-            if (empty($wxOrderId) && (empty($outStoreId) || empty($outOrderId))) {
-                util::fail("参数不足:wx_order_id 或 (out_store_id + store_order_id) 必须提供一组");
-            }
-
-            $result = IntraCityExpress::mockNotify($orderStatus, $wxOrderId, $outStoreId, $outOrderId);
-
-            if (isset($result['errcode']) && $result['errcode'] === 0) {
-                util::success("模拟回调成功", $result);
-            } else {
-                Yii::error("模拟回调失败:" . ($result['errmsg'] ?? '未知错误'), 'intracity');
-                util::fail($result['errmsg'] ?? '模拟回调失败', $result['errcode'] ?? -1);
-            }
-        } catch (\Exception $e) {
-            Yii::error("模拟回调异常:" . $e->getMessage(), 'intracity');
-            util::fail("系统出错");
+            ]);
+            exit();
         }
     }
 

+ 11 - 18
common/components/intraCityExpress.php

@@ -4,7 +4,7 @@ namespace common\components;
 
 use hd\models\IntraCity\StoreFeeForm;
 use yii\helpers\Json;
-use linslin\yii2\curl;
+//use linslin\yii2\curl;
 use bizHd\wx\classes\WxOpenClass;
 use phpseclib\Crypt\RSA;
 
@@ -106,14 +106,6 @@ class IntraCityExpress
      */
     public static function sendRequest($url, $data, $accessToken)
     {
-        // 添加access_token到URL
-        $urlWithToken = $url . (strpos($url, '?') !== false ? '&' : '?') . 'access_token=' . $accessToken;
-        $timestamp = time();
-        $body = Json::encode($data);
-        if ($body === '[]') {
-            $body = '{}';
-        }
-
         // ================ 选择哪个 appId  =================
         // 微信开放平台 appId
         $open = \biz\wx\classes\WxOpenClass::getByCondition(['style' => dict::getDict('ptStyle', 'hd')]);
@@ -138,6 +130,14 @@ class IntraCityExpress
         }
 
 
+        // 添加access_token到URL
+        $urlWithToken = $url . (strpos($url, '?') !== false ? '&' : '?') . 'access_token=' . $accessToken;
+        $timestamp = time();
+        $body = Json::encode($data);
+        if ($body === '[]') {
+            $body = '{}';
+        }
+
         // 方式二: 自己处理请求 =========== 失败,不使用(可删除)
         // $signature = self::generateWxApiSignature($url, $appId, $timestamp, $body);
         // 构建请求头,包含微信API签名所需的头部
@@ -231,14 +231,7 @@ class IntraCityExpress
         }
         
         $accessToken = self::getAccessToken($merchant, $ptStyle);
-        $data = [
-            'out_store_id' => $storeData['out_store_id'],
-            'store_name' => $storeData['store_name'] ?? null,
-            'store_address' => $storeData['store_address'] ?? null,
-            'store_longitude' => $storeData['store_longitude'] ?? null,
-            'store_latitude' => $storeData['store_latitude'] ?? null,
-            'store_phone' => $storeData['store_phone'] ?? null,
-        ];
+        $data = $storeData;
         
         return self::sendRequest(self::API_UPDATE_STORE, $data, $accessToken);
     }
@@ -277,7 +270,7 @@ class IntraCityExpress
         }
 
         $accessToken = self::getAccessToken($merchant, $ptStyle);
-        return self::sendRequest(self::API_APPLY_STORE, new \stdClass(), $accessToken);
+        return self::sendRequest(self::API_APPLY_STORE, [], $accessToken);
     }
 
 

+ 12 - 10
common/components/wxapi/WxApi.php

@@ -44,30 +44,30 @@ class WxApi
      * Date: 2023/7/14
      * Time: 9:51
      * @param $url
-     * @param $req
+     * @param $reqData
      * @throws ErrorException
      * @throws \Exception
      */
-    public function request($url, $req)
+    public function request($url, $reqData)
     {
 //        $accessToken = '';
         $this->url = $url;
         $urls = $url . "?access_token=" . $this->accessToken;
         //1.数据加密
-        $newRe = $this->getRequestParam($url, $req);
+        $newReData = $this->getRequestParam($url, $reqData);
         //2.获取签名
-        $signature = $this->getSignature($newRe);
+        $signature = $this->getSignature($newReData);
         //本地验签 非必需
-        $checkLocalSig = $this->checkLocalSignature($newRe, $signature);
+        $checkLocalSig = $this->checkLocalSignature($newReData, $signature);
         if (!$checkLocalSig) {
             throw new ErrorException('本地验签错误');
         }
         $appId = $this->appId;
-        $headerArray = ['Wechatmp-Appid:' . $appId, 'Wechatmp-TimeStamp:' . $newRe['ts'], 'Wechatmp-Signature:' . $signature];
+        $headerArray = ['Wechatmp-Appid:' . $appId, 'Wechatmp-TimeStamp:' . $newReData['ts'], 'Wechatmp-Signature:' . $signature];
         
         \Yii::info("请求头: " . json_encode($headerArray), 'wxapi_debug');
         
-        $data = $this->curlPost($urls, $newRe['reqData'], $headerArray);
+        $data = $this->curlPost($urls, $newReData['reqData'], $headerArray);
         $headers = $this->httpParseHeaders($data['header']);
         $body = json_decode($data['body'], true);
         
@@ -78,11 +78,13 @@ class WxApi
             \Yii::error("微信API错误: " . json_encode($body), 'wxapi_debug');
             throw new ErrorException($body['errmsg']);
         }
+
         // 3.响应参数验签 
         // $vertify = $this->vertifyResponse($data);
         // if (!$vertify) {
         //     throw new ErrorException('响应参数验签失败');
         // }
+
         //4.参数解密
         return $this->jM($headers['Wechatmp-TimeStamp'], $body);
     }
@@ -136,11 +138,11 @@ class WxApi
      * Date: 2023/7/14
      * Time: 9:21
      * @param $url
-     * @param $req
+     * @param $reqData
      * @return array
      * @throws \Exception
      */
-    public function getRequestParam($url, $req)
+    public function getRequestParam($url, $reqData)
     {
         $key = base64_decode($this->aes['key']);
         $sn = $this->aes['sn'];
@@ -149,7 +151,7 @@ class WxApi
         //16位随机字符
         $nonce = rtrim(base64_encode(random_bytes(16)), '=');
         $addReq = ["_n" => $nonce, "_appid" => $appId, "_timestamp" => $time];
-        $realReq = array_merge($addReq, $req);
+        $realReq = array_merge($addReq, $reqData);
         $realReq = json_encode($realReq);
         //额外参数
         $aad = $url . "|" . $appId . "|" . $time . "|" . $sn;