LogisticYDService.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. namespace App\Services;
  3. use App\OrderPackage;
  4. use App\Traits\ServiceAppAop;
  5. use Carbon\Carbon;
  6. use Illuminate\Support\Facades\Http;
  7. class LogisticYDService
  8. {
  9. use ServiceAppAop;
  10. private $app_key;
  11. private $app_secret;
  12. private $url;
  13. /**
  14. * 批量订阅接口
  15. * @param $logistic_numbers array
  16. * @return mixed
  17. */
  18. public function registerApi(array $logistic_numbers)
  19. {
  20. $this->app_key = config('api_logistic.YD.prod.app-key', '999999');
  21. $this->app_secret = config('api_logistic.YD.prod.app-secret', '04d4ad40eeec11e9bad2d962f53dda9d');
  22. $this->url = config('api_logistic.YD.prod.register.url');
  23. $sender = [
  24. "address" => "上海市松江区泗泾镇泗砖公路351号",
  25. "city" => "上海市",
  26. "county" => "松江区",
  27. "name" => "施尧",
  28. "phone" => '13761413262',
  29. "province" => "上海市"
  30. ];
  31. $body = [
  32. "orders" => [],
  33. ];
  34. $order_packages = OrderPackage::query()
  35. ->with('order')
  36. ->whereIn('logistic_number', $logistic_numbers)->get();
  37. foreach ($order_packages as $order_package) {
  38. $order = $order_package->order;
  39. $body['orders'][] = [
  40. 'orderid' => $order->client_code,
  41. "mailno" => $order_package->logistic_number,
  42. "receiver" => [
  43. "address" => $order->address,
  44. "city" => $order->city,
  45. "county" => $order->district,
  46. "name" => $order->consignee_name,
  47. "phone" => $order->consignee_phone,
  48. "province" => $order->province ?? $order->city,
  49. ],
  50. "sender" => $sender
  51. ];
  52. }
  53. $json_body = json_encode($body, JSON_UNESCAPED_UNICODE);
  54. $sign = md5($json_body . '_' . $this->app_secret);
  55. $headers = [
  56. 'app-key' => $this->app_key,
  57. 'sign' => $sign,
  58. 'req-time' => now()->timestamp,
  59. "Content-Type" => "application/json"
  60. ];
  61. try {
  62. $response = Http::withHeaders($headers)->withBody($json_body, 'application/json')->post($this->url);
  63. return json_decode($response);
  64. } catch (\GuzzleHttp\Exception\RequestException $e) {
  65. LogService::log(LogisticYDService::class, "韵达-registerApi", $logistic_numbers);
  66. }
  67. }
  68. public function query($logistic_number)
  69. {
  70. $this->app_key = config('api_logistic.YD.prod.app-key', '999999');
  71. $this->app_secret = config('api_logistic.YD.prod.app-secret', '04d4ad40eeec11e9bad2d962f53dda9d');
  72. $this->url = config('api_logistic.YD.prod.search.url');
  73. $body = [
  74. "mailno" => $logistic_number
  75. ];
  76. $sign = md5(json_encode($body, JSON_UNESCAPED_UNICODE) . '_' . $this->app_secret);
  77. $headers = [
  78. 'app-key' => $this->app_key,
  79. 'sign' => $sign,
  80. 'req-time' => now()->timestamp,
  81. "Content-Type" => "application/json"
  82. ];
  83. try {
  84. $response = Http::withHeaders($headers)->withBody(json_encode($body, JSON_UNESCAPED_UNICODE), 'application/json')->post($this->url);
  85. } catch (\GuzzleHttp\Exception\RequestException $e) {
  86. LogService::log(LogisticYDService::class, "韵达-query", $logistic_number);
  87. return null;
  88. }
  89. return json_decode($response->body());
  90. }
  91. public function format($nativeResponse, $logistic_number)
  92. {
  93. if (is_null($nativeResponse) || $nativeResponse->code != '0000' || $nativeResponse->data->result == "false") {
  94. return [
  95. 'logistic_number' => $logistic_number,
  96. 'exception_type' => '揽件异常',
  97. 'exception' => '是',
  98. ];
  99. } else {
  100. $nativeData = $nativeResponse->data;
  101. try {
  102. $result['logistic_number'] = $nativeData->mailno;
  103. } catch (\Exception $e) {
  104. LogService::log(LogisticYDService::class, "YD快递信息异常", $nativeResponse);
  105. return [];
  106. }
  107. $nativeRoutes = $nativeData->steps;
  108. if (!empty($nativeRoutes)) {
  109. $lastNativeRoute = $nativeRoutes[count($nativeRoutes) - 1];
  110. $result['status'] = $this->getStatus($nativeData);
  111. if ($result['status'] == '已收件') {
  112. $result['received_at'] = $lastNativeRoute->time;
  113. }
  114. $result['transfer_status'] = $this->getTransferStatus($nativeRoutes);
  115. $result['routes_length'] = array_key_exists('transfer_status', $result) ? count($result['transfer_status']) : 0;
  116. $orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
  117. $exceptionData = $orderPackageReceivedSyncService->setExceptionType($result, $lastNativeRoute ? $lastNativeRoute->time : null);
  118. $result['exception_type'] = $exceptionData['exception_type'];
  119. $result['exception'] = $exceptionData['exception'];
  120. } else {
  121. $result['status'] = null;
  122. $result['transfer_status'] = [];
  123. }
  124. if (!array_key_exists('status', $result)) {
  125. $result['status'] = null;
  126. $result['transfer_status'] = [];
  127. }
  128. //如果没有发现额外的异常,且查询到物流轨迹,将异常置为无
  129. if (!array_key_exists('exception', $result)
  130. && !array_key_exists('exception_type', $result)
  131. && array_key_exists('transfer_status', $result)
  132. ) {
  133. $result['exception_type'] = '无';
  134. $result['exception'] = '否';
  135. }
  136. return $result;
  137. }
  138. }
  139. /**
  140. * @param $nativeData
  141. * @return string
  142. */
  143. private function getStatus($nativeData): string
  144. {
  145. $status = null;
  146. switch ($nativeData->status) {
  147. case 'GOT':
  148. $status = '已揽收';
  149. break;
  150. case 'TRANSIT':
  151. $status = '在途';
  152. break;
  153. case 'SIGNED':
  154. $status = '已收件';
  155. break;
  156. case 'RETURN':
  157. $status = '返回中';
  158. break;
  159. case 'SIGNFAIL':
  160. $status = '无';
  161. break;
  162. default:
  163. $status = '无';
  164. }
  165. return $status;
  166. }
  167. /**
  168. * @param $nativeRoutes
  169. * @return array
  170. */
  171. private function getTransferStatus($nativeRoutes): array
  172. {
  173. $transferStatus = [];
  174. foreach ($nativeRoutes as $nativeRoute) {
  175. $item = [];
  176. $item['accept_time'] = $nativeRoute->time;
  177. $item['accept_address'] = $nativeRoute->description;
  178. $item['remark'] = "";
  179. $transferStatus[] = $item;
  180. }
  181. return $transferStatus;
  182. }
  183. }