select(['logistic_number', 'order_id', 'id']) ->with(['order' => function ($query) { return $query->select(['id', 'logistic_id'])->with('logistic:id,name,code'); }]); if ($is_to_init) {//当前时间小于等于初始化时间 $initDate = Carbon::parse(config('api_logistic.init_date')); //初始化查询一个月的数据 $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 {//指定了单号 $query = OrderPackage::query() ->select(['logistic_number', 'order_id', 'id']) ->with(['order' => function ($query) { return $query->select(['id', 'logistic_id'])->with('logistic:id,name,code'); }]) ->whereIn('logistic_number', $logistic_numbers); } //分块执行 $query->chunkById(1000, function ($orderPackages) { //按照承运商分组 $logisticNumbers = $this->buildData($orderPackages); //更新顺丰系列 if (array_key_exists('SF', $logisticNumbers)) { $SFLogisticNumbers = $logisticNumbers['SF']; foreach ($SFLogisticNumbers as $logisticNumber) { LogisticSFSync::dispatch($logisticNumber); } } //更新中通 if (array_key_exists('ZTO', $logisticNumbers)) { $ZTOLogisticNumbers = $logisticNumbers['ZTO']; foreach ($ZTOLogisticNumbers as $logisticNumber) { LogisticZopSync::dispatch($logisticNumber); } } //更新韵达 if (array_key_exists('YUNDA', $logisticNumbers)) { $YDLogisticNumbers = $logisticNumbers['YUNDA']; foreach ($YDLogisticNumbers as $logistic_number) { LogisticYDSync::dispatch($logistic_number); } } //更新圆通 if (array_key_exists('YTO', $logisticNumbers)) { $YTOLogisticNumbers = $logisticNumbers['YTO']; foreach ($YTOLogisticNumbers as $logistic_number) { if ($logistic_number) LogisticYTOSync::dispatch($logistic_number); } } }); } /** * 阿里云同步快递信息 * @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() ->select(['logistic_number', 'order_id', 'id']) ->whereIn('order_id', function ($query) { $query->from('orders')->selectRaw('id')->whereIn('logistic_id', function ($builder) { $builder->from('logistics')->selectRaw('id')->where('type', '=', '快递')->whereNotIn('belong_company', ['顺丰', '中通', '韵达', '圆通', '京东']); }); }); $query = $query->where('created_at', '>=', now()->subDays(config('api_logistic.querying_days'))) ->whereNull('received_at'); } else {//指定了单号 $query = OrderPackage::query() ->select(['logistic_number', 'order_id', 'id']) ->whereIn('logistic_number', $logistic_numbers); } $query->chunkById(200, function ($orderPackages) { foreach ($orderPackages as $orderPackage) { if ($orderPackage && $orderPackage->logistic_number) LogisticAliJiSuSync::dispatch($orderPackage->logistic_number); } }); } public function syncLogisticRouteJD() { ini_set('max_execution_time', 60); $query = OrderPackage::query() ->select(['logistic_number', 'order_id', 'id']) ->whereIn('order_id', function ($query) { $query->from('orders')->selectRaw('id')->whereIn('logistic_id', function ($builder) { $builder->from('logistics')->selectRaw('id')->where('type', '!=', '物流')->where('belong_company', '京东'); }); }); $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) { foreach ($orderPackages as $orderPackage) { if ($orderPackage && $orderPackage->logistic_number) LogisticAliJiSuSync::dispatch($orderPackage->logistic_number); } }); } /** * 根据快递单号更新状态 * @param array $logisticResponses */ public function update(array $logisticResponses) { foreach ($logisticResponses as $logisticResponse) { if (empty($logisticResponse)) continue; $orderPackage = OrderPackage::query()->where('logistic_number', $logisticResponse['logistic_number'])->first(); if(empty($orderPackage)) continue; //如果已经收货,状态改为已签收 if ($logisticResponse['received_at'] ?? false) { $logisticResponse['status'] = '已签收'; } //标记为手动更新的 status不更新 if ($orderPackage->is_manual_update) { if (OrderPackage::switchStatus($orderPackage->status) > OrderPackage::switchStatus($logisticResponse['status'] ?? '生成订单')) { 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 === '') { $logisticResponse['status'] = '生成订单'; if (!empty($orderPackage->sent_at)) { $logisticResponse['status'] = '已复核'; } if (!empty($orderPackage->weighed_at)) { $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']); if(empty($logisticResponse['transfer_status'])) unset($logisticResponse['transfer_status']); OrderPackage::query()->where('logistic_number', $logisticResponse['logistic_number']) ->update($logisticResponse); } } /** * 将orderPackage集合分类并摘取指定数据 * @param Collection $orderPackages * @return array */ private function buildData(Collection $orderPackages): array { $data = []; foreach ($orderPackages as $orderPackage) { try { $logisticCode = $orderPackage->order->logistic->code; } catch (Exception $e) { continue; } $key = config('api_logistic.logistic.' . $logisticCode); if (!isset($data[$key])) { $data[$key] = []; } $data[$key][] = $orderPackage->logistic_number; } return $data; } }