config = ExpressConfig::getInstance(); } public function queryTrack($waybillNo, $phone = '', $expressCode = '', $provider = null, $useCache = true) { $waybillNo = ExpressSanitizer::waybillNo($waybillNo); $phone = ExpressSanitizer::phone($phone); $expressCode = ExpressSanitizer::expressCode($expressCode); if ($waybillNo === '') { throw new \Exception('快递单号不能为空'); } $provider = $provider ?: $this->config->getProvider(); $cacheKey = $this->buildCacheKey($provider, $waybillNo, $phone, $expressCode); if ($useCache) { $cached = Cache::get($cacheKey); if (is_array($cached)) { return $cached; } } $started = microtime(true); $providerResult = null; $errorMessage = ''; try { $providerResult = ExpressProviderRouter::query($waybillNo, $phone, $expressCode, $provider); $normalized = TrackNormalizer::normalize($providerResult); $normalized['trackList'] = TrackNormalizer::fixDeliveringIcons($normalized['trackList']); $normalized['provider'] = $provider; $normalized['raw'] = $providerResult['raw'] ?? null; QueryLogger::log( $provider, $waybillNo, $phone, $expressCode, !empty($normalized['success']), 200, 'ok', (int) round((microtime(true) - $started) * 1000) ); if ($useCache && !empty($normalized['success'])) { Cache::set($cacheKey, $normalized, $this->config->getCacheTtl()); } return $normalized; } catch (\Exception $e) { $errorMessage = $e->getMessage(); QueryLogger::log( $provider, $waybillNo, $phone, $expressCode, false, 500, $errorMessage, (int) round((microtime(true) - $started) * 1000) ); throw $e; } } public function toKdniaoExpressFormat(array $normalized) { return [ 'Success' => !empty($normalized['success']), 'Traces' => $normalized['trackList'] ?? [], 'State' => self::guessStateFromTrackList($normalized['trackList'] ?? []), 'Reason' => $normalized['success'] ? '' : '查询失败', ]; } protected static function guessStateFromTrackList(array $trackList) { if (empty($trackList)) { return '0'; } $action = $trackList[0]['Action'] ?? 2; if (in_array($action, [3, 304], true)) { return '3'; } if ($action == 4) { return '4'; } if ($action == 1) { return '1'; } return '2'; } protected function buildCacheKey($provider, $waybillNo, $phone, $expressCode) { return 'shopro_aliyun_express:' . md5(implode('|', [$provider, $waybillNo, $phone, $expressCode])); } }