LogisticYDService.php 6.2 KB

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