ANG YU 4 éve
szülő
commit
0a015a1cca

+ 6 - 1
app/Http/Controllers/TestController.php

@@ -16,7 +16,7 @@ use App\Jobs\BatchTaskJob;
 use App\Jobs\CacheShelfTaskJob;
 use App\Jobs\OrderCreateInstantBill;
 use App\Jobs\OrderCreateWaybill;
-use App\Jobs\SettlementBillReportTask;
+use App\Jobs\SettlementBillReportJob;
 use App\Jobs\StoreCreateInstantBill;
 use App\Jobs\TestJob;
 use App\Jobs\WeightUpdateInstantBill;
@@ -413,4 +413,9 @@ sql;
     public function teset12313(){
         dd(route("discharge.storeApi"));
     }
+
+    public function init_SettlementBillReportTask()
+    {
+        $this->dispatch(new SettlementBillReportJob('2021-08-01',[]));
+    }
 }

+ 0 - 44
app/Jobs/OrderPackageReceivedSync.php

@@ -1,44 +0,0 @@
-<?php
-
-namespace App\Jobs;
-
-use App\Services\OrderPackageReceivedSyncService;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Foundation\Bus\Dispatchable;
-use Illuminate\Queue\InteractsWithQueue;
-use Illuminate\Queue\SerializesModels;
-
-/**
- * 同步快递路由信息任务 调用时需要延迟1h触发
- * Class OrderPackageReceivedSync
- * @package App\Jobs
- */
-class OrderPackageReceivedSync implements ShouldQueue
-{
-    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
-
-    protected $logisticNumbers;
-    protected $service;
-
-    /**
-     * OrderPackageReceivedSync constructor.
-     * @param $logisticNumbers
-     */
-    public function __construct($logisticNumbers)
-    {
-        $this->logisticNumbers = $logisticNumbers;
-        $this->service =  new OrderPackageReceivedSyncService();
-    }
-
-
-    /**
-     * Execute the job.
-     * @return void
-     * @throws \Exception
-     */
-    public function handle()
-    {
-        $this->service->syncLogisticRouteApi($this->logisticNumbers);
-    }
-}

+ 20 - 71
app/Services/OrderPackageReceivedSyncService.php

@@ -23,15 +23,14 @@ class OrderPackageReceivedSyncService
 
     /**
      * 同步快递信息
-     * 1 如果当前时间大于初始化时间 每日执行一次,更新order_packages中创建时间大于初始化时间,没有异常,用户未收货的全部订单的快递路由状态
-     * 2 如果当前时间小于等于初始化时间,执行初始化脚本,将数据库中全部小于等于初始化时间的数据更新
-     * @throws Exception
+     * @param bool $is_to_init 是否为初始化数据状态 初始化同步一个月的 正常执行为15天
+     * @param array $logistic_numbers 指定更新的单号
      */
     public function syncLogisticRoute($is_to_init = false, $logistic_numbers = [])
     {
         ini_set('max_execution_time', 2 * 60 * 60);
         ini_set('memory_limit', '1024M');
-        //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法", '');
+        //没有指定单号
         if (empty($logistic_numbers)) {
             $query = OrderPackage::query()
                 ->select(['logistic_number', 'order_id', 'id'])
@@ -40,14 +39,14 @@ class OrderPackageReceivedSyncService
                 }]);
             if ($is_to_init) {//当前时间小于等于初始化时间
                 $initDate = Carbon::parse(config('api_logistic.init_date'));
-                //初始化查询一个月的数据,exception为否
+                //初始化查询一个月的数据
                 $query = $query->where('created_at', '>=', $initDate)
                     ->whereNull('received_at');
             } else {//查询20天以内的数据
                 $query = $query->where('created_at', '>=', now()->subDays(config('api_logistic.querying_days'))->startOfDay())
                     ->whereNull('received_at');
             }
-        } else {
+        } else {//指定了单号
             $query = OrderPackage::query()
                 ->select(['logistic_number', 'order_id', 'id'])
                 ->with(['order' => function ($query) {
@@ -55,41 +54,34 @@ class OrderPackageReceivedSyncService
                 }])
                 ->whereIn('logistic_number', $logistic_numbers);
         }
-
+        //分块执行
         $query->chunkById(1000, function ($orderPackages) {
-            //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法", json_encode(data_get($orderPackages,'*.logistic_number')));
+            //按照承运商分组
             $logisticNumbers = $this->buildData($orderPackages);
-            //sf
+            //更新顺丰系列
             if (array_key_exists('SF', $logisticNumbers)) {
                 $SFLogisticNumbers = $logisticNumbers['SF'];
-                //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-SF", json_encode($SFLogisticNumbers));
                 foreach ($SFLogisticNumbers as $logisticNumber) {
-                    //  LogService::log(OrderPackageReceivedSyncService::class, "同步SF快递单号", $logisticNumber);
                     LogisticSFSync::dispatch($logisticNumber);
                 }
             }
             //更新中通
             if (array_key_exists('ZTO', $logisticNumbers)) {
                 $ZTOLogisticNumbers = $logisticNumbers['ZTO'];
-                //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-ZTO", json_encode($ZTOLogisticNumbers));
                 foreach ($ZTOLogisticNumbers as $logisticNumber) {
-                    //  LogService::log(OrderPackageReceivedSyncService::class, "同步ZTO快递单号", $logisticNumber);
                     LogisticZopSync::dispatch($logisticNumber);
                 }
             }
             //更新韵达
             if (array_key_exists('YUNDA', $logisticNumbers)) {
                 $YDLogisticNumbers = $logisticNumbers['YUNDA'];
-                //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-YUNDA", json_encode($YDLogisticNumbers));
                 foreach ($YDLogisticNumbers as $logistic_number) {
-                    //  LogService::log(OrderPackageReceivedSyncService::class, "同步YUNDA快递单号", $logisticNumber);
                     LogisticYDSync::dispatch($logistic_number);
                 }
             }
             //更新圆通
             if (array_key_exists('YTO', $logisticNumbers)) {
                 $YTOLogisticNumbers = $logisticNumbers['YTO'];
-                //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-YTO", json_encode($YTOLogisticNumbers));
                 foreach ($YTOLogisticNumbers as $logistic_number) {
                     if ($logistic_number) LogisticYTOSync::dispatch($logistic_number);
                 }
@@ -97,8 +89,13 @@ class OrderPackageReceivedSyncService
         });
     }
 
-    public function syncLogisticRouteByAliJiSu($logistic_numbers = [])
+    /**
+     * 阿里云同步快递信息
+     * @param array $logistic_numbers 指定单号同步
+     */
+    public function syncLogisticRouteByAliJiSu(array $logistic_numbers = [])
     {
+        //没有指定单号
         if (empty($logistic_numbers)) {
             ini_set('max_execution_time', 2 * 60 * 60);
             $query = OrderPackage::query()
@@ -110,20 +107,17 @@ class OrderPackageReceivedSyncService
                 });
             $query = $query->where('created_at', '>=', now()->subDays(config('api_logistic.querying_days')))
                 ->whereNull('received_at');
-        } else {
+        } else {//指定了单号
             $query = OrderPackage::query()
                 ->select(['logistic_number', 'order_id', 'id'])
                 ->whereIn('logistic_number', $logistic_numbers);
         }
 
         $query->chunkById(200, function ($orderPackages) {
-            //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-阿里公用接口", json_encode($orderPackages));
             foreach ($orderPackages as $orderPackage) {
                 if ($orderPackage && $orderPackage->logistic_number) LogisticAliJiSuSync::dispatch($orderPackage->logistic_number);
             }
         });
-        //TODO 暂时不同步京东
-//        $this->syncLogisticRouteJD();
     }
 
     public function syncLogisticRouteJD()
@@ -139,59 +133,12 @@ class OrderPackageReceivedSyncService
         $query = $query->where('created_at', '>=', now()->subDays(config('api_logistic.querying_days')))
             ->whereNull('received_at')->where('logistic_number', 'like', 'JD%');
         $query->chunkById(200, function ($orderPackages) {
-            //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-JD", json_encode($orderPackages));
             foreach ($orderPackages as $orderPackage) {
                 if ($orderPackage && $orderPackage->logistic_number) LogisticAliJiSuSync::dispatch($orderPackage->logistic_number);
             }
         });
     }
 
-    /**
-     * 根据传递的承运商与快递单号更新快递信息
-     * @param array $logisticNumbers 快递单号
-     * example: ['SF' => ['SF1038651915891', 'SF1038651413847', 'SF1038611050071'],'ZT'=>['75424148714142','548464120822', '75424147834290']....]
-     * @throws Exception 快递接口调用或者返回的信息有误,无法更新指定的快递路由信息
-     */
-    public function syncLogisticRouteApi(array $logisticNumbers)
-    {
-        $this->update($this->getLogisticRoutes($logisticNumbers));
-    }
-
-    /**
-     * 获取快件揽收信息
-     * @param array $request [
-     * 'SF' => ['SF1038651915891', 'SF1038651413847', 'SF1038611050071'],
-     * 'ZT'=>['75424148714142','548464120822', '75424147834290']
-     * ]
-     * @return array
-     * @throws Exception
-     */
-    public function getLogisticRoutes(array $request): array
-    {
-        $this->logisticSFService = new LogisticSFService();
-        $resultSF = [];
-        $resultYD = [];
-        $resultYT = [];
-        $resultOther = [];
-        foreach ($request as $key => $logisticNums) {
-            switch ($key) {
-                case "SF":
-                    $resultSF = $this->logisticSFService->get($logisticNums);
-                    break;
-                case "YD":
-                    $resultYD = [];
-                    break;
-                case "YT":
-                    $resultYT = [];
-                    break;
-                default:
-                    $resultOther = [];
-                    break;
-            }
-        }
-        return array_merge($resultSF, $resultYD, $resultYT, $resultOther);
-    }
-
     /**
      * 根据快递单号更新状态
      * @param array $logisticResponses
@@ -211,11 +158,15 @@ class OrderPackageReceivedSyncService
                     unset($logisticResponse['status']);
                 }
             }
+            //设置异常信息
             $logisticResponse = $this->setExceptionStatus($logisticResponse);
+            //标记为单号异常
             if (Str::contains($orderPackage->logistic_number, ['SO', '#', '-'])) {
                 $logisticResponse['exception_status'] = '单号异常';
             }
-            if (((!isset($logisticResponse['status'])) || ($logisticResponse['status'] === '')) && $orderPackage->status === '') {
+            //没有状态的数据赋予初始状态
+            if (((!isset($logisticResponse['status'])) || ($logisticResponse['status'] === '')) &&
+                $orderPackage->status === '') {
                 $logisticResponse['status'] = '生成订单';
 
                 if (!empty($orderPackage->sent_at)) {
@@ -225,7 +176,6 @@ class OrderPackageReceivedSyncService
                     $logisticResponse['status'] = '已称重';
                 }
             }
-
             if (isset($logisticResponse['exception_status'])) $logisticResponse['exception_status'] = OrderPackage::switchExceptionStatus($logisticResponse['exception_status']);
             if (isset($logisticResponse['status'])) $logisticResponse['status'] = OrderPackage::switchStatus($logisticResponse['status']);
             if (isset($logisticResponse['routes_length'])) unset($logisticResponse['routes_length']);
@@ -248,7 +198,6 @@ class OrderPackageReceivedSyncService
             try {
                 $logisticCode = $orderPackage->order->logistic->code;
             } catch (Exception $e) {
-                //  LogService::log(OrderPackageReceivedSyncService::class, "快递同步按照承运商分组异常", json_encode($orderPackage??[]));
                 continue;
             }
             $key = config('api_logistic.logistic.' . $logisticCode);

+ 38 - 13
app/Services/OrderPackageService.php

@@ -11,6 +11,7 @@ use App\Services\common\DataHandlerService;
 use Carbon\Carbon;
 use App\Traits\ServiceAppAop;
 use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Http\Client\Response;
 use Illuminate\Support\Facades\Http;
 
 
@@ -345,7 +346,9 @@ class OrderPackageService
     }
 
     /**
-     * 一键揽收上传
+     * 中通一键揽收上传
+     * 由于中通接口只支持100条的操作,本接口支持100以上
+     * 如果中途调用中通接口发生异常,本方法不会停止,但在最后会返回错误信息,将执行失败的单号和原因返回
      * @param $logistic_numbers array
      * @return array
      */
@@ -381,14 +384,14 @@ class OrderPackageService
         $appId = config('api_logistic.collectUpload.ZTO.test.appId');
         //中通接口最大支持100条
         $logistic_numbers_chunked = array_chunk($logistic_numbers, 100);
+        //中通接口返回异常信息数组
         $errorMessage = [];
         foreach ($logistic_numbers_chunked as $logistic_numbers_chunked_items) {
             $orderPackages = OrderPackage::query()
                 ->select('weight', 'logistic_number')
                 ->whereIn('logistic_number', $logistic_numbers_chunked_items)->get();
-
+            //中通接口请求body
             $collectUploadDTOS = [];
-
             foreach ($orderPackages as $orderPackage) {
                 $collectUploadDTOS[] = [
                     'billCode' => $orderPackage->logistic_number,
@@ -397,16 +400,15 @@ class OrderPackageService
                     'importDate' => now()->toDateTimeString(),
                 ];
             }
-            $body = json_encode([
-                'collectUploadDTOS' => $collectUploadDTOS,
-            ], JSON_UNESCAPED_UNICODE);
-            $data_digest = base64_encode(md5($body . $appSecret, TRUE));
-            $headers = [
-                'Content-Type' => 'application/json; charset=UTF-8',
-                'x-companyid' => $xAppKey,
-                'x-datadigest' => $data_digest,
-            ];
-            $response = Http::withHeaders($headers)->withBody($body, 'application/json')->post($url);
+            try {
+                $response = $this->sentReqToZOP($collectUploadDTOS, $appSecret, $xAppKey, $url);
+            } catch (\Exception $e) {
+                $errorMessage[] = [
+                    'status_code' => 'REQUEST_ERROR',
+                    'message' => [$e->getMessage()],
+                    'logistic_number' => $logistic_numbers_chunked_items,
+                ];
+            }
             $responseBody = json_decode($response->body());
             if ($responseBody->statusCode === 'S210' ||//无权限
                 $responseBody->statusCode === 'PARAM_ERROR' ||//揽收上传信息为空
@@ -415,6 +417,7 @@ class OrderPackageService
                 $errorMessage[] = [
                     'status_code' => $responseBody->statusCode,
                     'message' => $responseBody->message,
+                    'logistic_number' => $logistic_numbers_chunked_items,
                 ];
             }
         }
@@ -424,4 +427,26 @@ class OrderPackageService
             return ['success' => false, 'message' => $errorMessage];
         }
     }
+
+    /**
+     * 调用中通接口封装
+     * @param array $requestBody 请求体
+     * @param $appSecret
+     * @param $xAppKey
+     * @param $url
+     * @return Response
+     */
+    private function sentReqToZOP(array $requestBody, $appSecret, $xAppKey, $url): Response
+    {
+        $body = json_encode([
+            'collectUploadDTOS' => $requestBody,
+        ], JSON_UNESCAPED_UNICODE);
+        $data_digest = base64_encode(md5($body . $appSecret, TRUE));
+        $headers = [
+            'Content-Type' => 'application/json; charset=UTF-8',
+            'x-companyid' => $xAppKey,
+            'x-datadigest' => $data_digest,
+        ];
+        return Http::withHeaders($headers)->withBody($body, 'application/json')->post($url);
+    }
 }

+ 65 - 20
app/Traits/LogisticSyncTrait.php

@@ -9,17 +9,23 @@ use function DeepCopy\deep_copy;
 
 trait LogisticSyncTrait
 {
+    /**
+     * 设置 status 与 exception_status
+     * @param array $data
+     * @return array
+     */
     public function setExceptionStatus(array $data): array
     {
-
+        //获取快递单号
         $logistic_number = $data['logistic_number'];
         /** @var OrderPackage $orderPackage */
         $orderPackage = OrderPackage::query()
             ->with(['order'])
             ->where('logistic_number', $logistic_number)
             ->first();
+        //这种类型的单,不需要再更新状态
         if ($orderPackage->exception_status === '单号异常' ||
-            $orderPackage->exception_status === '无法获取路由') {//这种类型的单,不需要再更新状态
+            $orderPackage->exception_status === '无法获取路由') {
             return $data;
         }
         /** @var \Carbon\Carbon $sent_at */
@@ -40,7 +46,7 @@ trait LogisticSyncTrait
             if (empty($transfer_status)) {//没有路由信息
                 //延迟发货
                 $created_at_clone = deep_copy($created_at);
-                if ($created_at->gt($created_at_clone->startOfDay()->addHours(16)->addMinutes(30))) {//下午16的单
+                if ($created_at->gt($created_at_clone->startOfDay()->addHours(16)->addMinutes(30))) {//下午16.30的单
                     $created_at_clone = deep_copy($created_at);
                     if ($created_at_clone->addDay()->endOfDay()->lt(now())) {//超过第二天的24时
                         $created_at_clone = deep_copy($created_at);
@@ -53,9 +59,6 @@ trait LogisticSyncTrait
                         $data['is_delay_deliver'] = true;
                     }
                 }
-            } else {
-                //虚拟揽件
-//                $data['exception_status'] = '虚拟揽件'; //没有复核但是有路由信息   21-09-10 取消虚拟揽件状态
             }
         } else {//复核过
             if (empty($transfer_status)) {//没有路由信息
@@ -71,12 +74,13 @@ trait LogisticSyncTrait
             } else {//有路由信息
                 $transfer_status = $this->sortTransferStatusByAcceptTimeDESC($transfer_status);
                 $last_transfer_accept_time = $transfer_status[0]['accept_time'];
-                $last_remark = empty(!$transfer_status[0]['remark']) ? $transfer_status[0]['remark'] : $transfer_status[0]['accept_address'];
+                $last_remark = $this->getLastRemark($transfer_status[0]);
                 if (count($transfer_status) < 3) {//三条以内的不管地区 时间限制为24h
                     if (Carbon::parse($last_transfer_accept_time)->diffInHours(now()) > 24) {
                         $data['exception_status'] = '在途异常';
                     }
                 } else {
+                    //根据地区获取超时时间限制
                     $SHORT_RESPONSE_HOURS = (function ($province) {
                         switch ($province) {
                             case '浙江省':
@@ -121,34 +125,31 @@ trait LogisticSyncTrait
                         $data['exception_status'] = '在途异常';
                     }
                 }
-                if (($data['exception_status'] ?? '' === '在途异常') && ($data['status'] ?? '' === '派送中')) {//在途异常修正为派送异常
+                //在途异常修正为派送异常
+                if (($data['exception_status'] ?? '' === '在途异常') && ($data['status'] ?? '' === '派送中')) {
                     $data['exception_status'] = '派送异常';
                 }
+                //内容中有一下信息的,视为签收
                 if (Str::contains($last_remark, ['代收', '快递柜', '驿站', '自提柜', '丰巢', '快递小屋', '合作点', '快递超市', '签收'])) {
-                    $data['exception_status'] = '';
-                    $data['status'] = '已签收';
+                    $data = $this->setStatus已签收($data, $last_transfer_accept_time);
                 }
             }
         }
         //如果复核时间>前一天的18.00,则不添加异常信息
-        if ((!empty($sent_at)) && ($sent_at->gt(now()->subDay()->startOfDay()->addHours(18))) && isset($data['exception_status'])) {
+        if ((!empty($sent_at)) &&
+            ($sent_at->gt(now()->subDay()->startOfDay()->addHours(18))) &&
+            isset($data['exception_status'])) {
             unset($data['exception_status']);
         }
         //邮政待揽收状态不是在途
         $logistic_id = $orderPackage->order->logistic_id ?? null;
-        if ((!empty($logistic_id)) && ($logistic_id === 6 || $logistic_id === 88)) {
-            if (!empty($transfer_status)) {
-                $this->sortTransferStatusByAcceptTimeDESC($transfer_status);
-                $last_remark = empty(!$transfer_status[0]['remark']) ? $transfer_status[0]['remark'] : $transfer_status[0]['accept_address'];
-                if (Str::contains($last_remark, ['等待揽收', '商品已下单'])) {
-                    $data['status'] = '已复核';
-                }
-            }
-        }
+        //判断承运商是否为邮政
+        $data = $this->邮政实际待揽收由在途改为已复核($logistic_id, $transfer_status, $data);
         return $data;
     }
 
     /**
+     * 按照accept_time倒序排序
      * @param $transfer_status
      * @return mixed
      */
@@ -162,4 +163,48 @@ trait LogisticSyncTrait
         });
         return $transfer_status;
     }
+
+    /**
+     * 获取最新一条路由信息的remark
+     * @param $transfer_status
+     * @return mixed
+     */
+    private function getLastRemark($transfer_status)
+    {
+        //部分接口的remark在accept_address字段中
+        return empty(!$transfer_status['remark']) ? $transfer_status['remark'] : $transfer_status['accept_address'];
+    }
+
+    /**
+     * @param array $data
+     * @param $last_transfer_accept_time
+     * @return array
+     */
+    private function setStatus已签收(array $data, $last_transfer_accept_time): array
+    {
+        $data['exception_status'] = '';
+        $data['status'] = '已签收';
+        $data['received_at'] = $last_transfer_accept_time;
+        return $data;
+    }
+
+    /**
+     * @param $logistic_id
+     * @param $transfer_status
+     * @param array $data
+     * @return array
+     */
+    private function 邮政实际待揽收由在途改为已复核($logistic_id, $transfer_status, array $data): array
+    {
+        if ((!empty($logistic_id)) && ($logistic_id === 6 || $logistic_id === 88)) {
+            if (!empty($transfer_status)) {
+                $this->sortTransferStatusByAcceptTimeDESC($transfer_status);
+                $last_remark = $this->getLastRemark($transfer_status);
+                if (Str::contains($last_remark, ['等待揽收', '商品已下单'])) {
+                    $data['status'] = '已复核';
+                }
+            }
+        }
+        return $data;
+    }
 }