|
|
@@ -4,13 +4,13 @@ namespace App\Services;
|
|
|
|
|
|
use App\OrderPackage;
|
|
|
use App\Traits\ServiceAppAop;
|
|
|
+use Carbon\Carbon;
|
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
|
|
class LogisticYDService
|
|
|
{
|
|
|
use ServiceAppAop;
|
|
|
|
|
|
-// protected $modelClass=LogisticYD::class;
|
|
|
private $app_key;
|
|
|
private $app_secret;
|
|
|
private $url;
|
|
|
@@ -19,12 +19,13 @@ class LogisticYDService
|
|
|
/**
|
|
|
* 批量订阅接口
|
|
|
* @param $logistic_numbers array
|
|
|
+ * @return mixed
|
|
|
*/
|
|
|
public function registerApi(array $logistic_numbers)
|
|
|
{
|
|
|
- $this->app_key = config('api_logistic.YD.test.app-key', '999999');
|
|
|
- $this->app_secret = config('api_logistic.YD.test.app-secret', '04d4ad40eeec11e9bad2d962f53dda9d');
|
|
|
- $this->url = config('api_logistic.YD.test.register.url');
|
|
|
+ $this->app_key = config('api_logistic.YD.prod.app-key', '999999');
|
|
|
+ $this->app_secret = config('api_logistic.YD.prod.app-secret', '04d4ad40eeec11e9bad2d962f53dda9d');
|
|
|
+ $this->url = config('api_logistic.YD.prod.register.url');
|
|
|
$sender = [
|
|
|
"address" => "上海市松江区泗泾镇泗砖公路351号",
|
|
|
"city" => "上海市",
|
|
|
@@ -64,19 +65,14 @@ class LogisticYDService
|
|
|
"Content-Type" => "application/json"
|
|
|
];
|
|
|
$response = Http::withHeaders($headers)->withBody($json_body, 'application/json')->post($this->url);
|
|
|
- dump([
|
|
|
- 'url' => $this->url,
|
|
|
- 'headers' => $headers,
|
|
|
- 'body' => $body,
|
|
|
- 'response' => $response->body(),
|
|
|
- ]);
|
|
|
+ return json_decode($response);
|
|
|
}
|
|
|
|
|
|
public function query($logistic_number)
|
|
|
{
|
|
|
- $this->app_key = config('api_logistic.YD.test.app-key', '999999');
|
|
|
- $this->app_secret = config('api_logistic.YD.test.app-secret', '04d4ad40eeec11e9bad2d962f53dda9d');
|
|
|
- $this->url = config('api_logistic.YD.test.search.url');
|
|
|
+ $this->app_key = config('api_logistic.YD.prod.app-key', '999999');
|
|
|
+ $this->app_secret = config('api_logistic.YD.prod.app-secret', '04d4ad40eeec11e9bad2d962f53dda9d');
|
|
|
+ $this->url = config('api_logistic.YD.prod.search.url');
|
|
|
$body = [
|
|
|
"mailno" => $logistic_number
|
|
|
];
|
|
|
@@ -88,11 +84,251 @@ class LogisticYDService
|
|
|
"Content-Type" => "application/json"
|
|
|
];
|
|
|
$response = Http::withHeaders($headers)->withBody(json_encode($body, JSON_UNESCAPED_UNICODE), 'application/json')->post($this->url);
|
|
|
- dump([
|
|
|
- 'url' => $this->url,
|
|
|
- 'headers' => $headers,
|
|
|
- 'body' => $body,
|
|
|
- 'response' => $response->body(),
|
|
|
- ]);
|
|
|
+ return json_decode($response->body());
|
|
|
+ }
|
|
|
+
|
|
|
+ public function format($nativeResponse)
|
|
|
+ {
|
|
|
+ $result = [];
|
|
|
+ if ($nativeResponse->code != '0000') {
|
|
|
+ return [];
|
|
|
+ } else {
|
|
|
+ $nativeData = $nativeResponse->data;
|
|
|
+ $result['logistic_number'] = $nativeData->mailno;
|
|
|
+ $nativeRoutes = $nativeData->steps;
|
|
|
+ if (!empty($nativeRoutes)) {
|
|
|
+ $lastNativeRoute = $nativeRoutes[count($nativeRoutes) - 1];
|
|
|
+ $result['status'] = $this->getStatus($nativeData);
|
|
|
+ if ($result['status'] == '已收件') {
|
|
|
+ $result['received_at'] = $lastNativeRoute->time;
|
|
|
+ }
|
|
|
+ $result['transfer_status'] = $this->getTransferStatus($nativeRoutes);
|
|
|
+ $exceptionData = $this->setExceptionType($result, $lastNativeRoute ? $lastNativeRoute->time : null);
|
|
|
+ $result['exception_type'] = $exceptionData['exception_type'];
|
|
|
+ $result['exception'] = $exceptionData['exception'];
|
|
|
+
|
|
|
+ } else {
|
|
|
+ $result['status'] = null;
|
|
|
+ $result['transfer_status'] = [];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!array_key_exists('status', $result)) {
|
|
|
+ $result['status'] = null;
|
|
|
+ $result['transfer_status'] = [];
|
|
|
+ }
|
|
|
+ //如果没有发现额外的异常,且查询到物流轨迹,将异常置为无
|
|
|
+ if (!array_key_exists('exception', $result)
|
|
|
+ && !array_key_exists('exception_type', $result)
|
|
|
+ && array_key_exists('transfer_status', $result)
|
|
|
+ ) {
|
|
|
+ $result['exception_type'] = '无';
|
|
|
+ $result['exception'] = '否';
|
|
|
+ }
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param array $data
|
|
|
+ * @param $lastRouteDate
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function setExceptionType(array $data, $lastRouteDate): array
|
|
|
+ {
|
|
|
+ $logistic_number = $data['logistic_number'];
|
|
|
+ /** @var OrderPackage $orderPackage */
|
|
|
+ $orderPackage = OrderPackage::query()->with('order')->where('logistic_number', $logistic_number)->first();
|
|
|
+ $delivered_duration = now()->diffInHours(Carbon::parse($orderPackage['sent_at']));
|
|
|
+ $last_routed_duration = now()->diffInHours(Carbon::parse($lastRouteDate));
|
|
|
+ $VALID_HOURS = 4;
|
|
|
+ $SHORT_RESPONSE_HOURS = (function ($province) {
|
|
|
+ switch ($province) {
|
|
|
+ case '浙江省':
|
|
|
+ case '江苏省':
|
|
|
+ case '上海':
|
|
|
+ case '安徽省':
|
|
|
+ return 24;
|
|
|
+ case '北京':
|
|
|
+ case '天津':
|
|
|
+ case '江西省':
|
|
|
+ case '湖北省':
|
|
|
+ case '湖南省':
|
|
|
+ case '广东省':
|
|
|
+ case '福建省':
|
|
|
+ case '山东省':
|
|
|
+ case '河北省':
|
|
|
+ case '河南省':
|
|
|
+ case '山西省':
|
|
|
+ case '四川省':
|
|
|
+ case '陕西省':
|
|
|
+ case '重庆':
|
|
|
+ case '广西壮族自治区':
|
|
|
+ case '贵州省':
|
|
|
+ case '云南省':
|
|
|
+ case '海南省':
|
|
|
+ case '吉林省':
|
|
|
+ case '黑龙江省':
|
|
|
+ case '辽宁省':
|
|
|
+ return 72;
|
|
|
+ case '青海省':
|
|
|
+ case '宁夏回族自治区':
|
|
|
+ case '甘肃省':
|
|
|
+ case '内蒙古自治区':
|
|
|
+ case '新疆维吾尔自治区':
|
|
|
+ case '西藏自治区':
|
|
|
+ return 120;
|
|
|
+ default:
|
|
|
+ return 24;
|
|
|
+ }
|
|
|
+ })($orderPackage->order->province);
|
|
|
+ $LONG_RESPONSE_HOURS = (function ($province) {
|
|
|
+ switch ($province) {
|
|
|
+ case '浙江省':
|
|
|
+ case '江苏省':
|
|
|
+ case '上海':
|
|
|
+ case '安徽省':
|
|
|
+ return 72;
|
|
|
+ case '北京':
|
|
|
+ case '天津':
|
|
|
+ case '江西省':
|
|
|
+ case '湖北省':
|
|
|
+ case '湖南省':
|
|
|
+ case '广东省':
|
|
|
+ case '福建省':
|
|
|
+ case '山东省':
|
|
|
+ case '河北省':
|
|
|
+ case '河南省':
|
|
|
+ case '山西省':
|
|
|
+ case '四川省':
|
|
|
+ case '陕西省':
|
|
|
+ case '重庆':
|
|
|
+ case '广西壮族自治区':
|
|
|
+ case '贵州省':
|
|
|
+ case '云南省':
|
|
|
+ case '海南省':
|
|
|
+ case '吉林省':
|
|
|
+ case '黑龙江省':
|
|
|
+ case '辽宁省':
|
|
|
+ return 120;
|
|
|
+ case '青海省':
|
|
|
+ case '宁夏回族自治区':
|
|
|
+ case '甘肃省':
|
|
|
+ case '内蒙古自治区':
|
|
|
+ case '新疆维吾尔自治区':
|
|
|
+ case '西藏自治区':
|
|
|
+ return 168;
|
|
|
+ default:
|
|
|
+ return 72;
|
|
|
+ }
|
|
|
+ })($orderPackage->order->province);
|
|
|
+ $SENDING_RESPONSE_HOURS = 48;
|
|
|
+ $IS_ROUTED = 1; //0000 0001 有路由信息
|
|
|
+ $IS_IN_VALID_TIME = 2; //0000 0010 大于4小时
|
|
|
+ $IS_WEIGHED = 4; //0000 0100 称重过
|
|
|
+ $IS_RECEIVED = 8; //0000 1000 已经收货
|
|
|
+ $IS_SENDING = 16; //0001 0000 正在派送
|
|
|
+ $IS_SHORT_NO_RESPONSE = 32; //0010 0000 中转异常
|
|
|
+ $IS_LONG_NO_RESPONSE = 64; //0010 0000 疑似丢件
|
|
|
+ $IS_SENDING_NO_RESPONSE = 128; //0010 0000 派送异常
|
|
|
+ $conclusion = (function () use (
|
|
|
+ $data, $delivered_duration, $last_routed_duration,
|
|
|
+ $VALID_HOURS, $IS_ROUTED, $IS_IN_VALID_TIME, $IS_WEIGHED, $IS_RECEIVED, $IS_SENDING, $IS_SHORT_NO_RESPONSE, $IS_LONG_NO_RESPONSE, $IS_SENDING_NO_RESPONSE,
|
|
|
+ $SHORT_RESPONSE_HOURS, $LONG_RESPONSE_HOURS, $SENDING_RESPONSE_HOURS,
|
|
|
+ $orderPackage
|
|
|
+ ) {
|
|
|
+ $conclusion = 0;
|
|
|
+ $conclusion |= !empty($data['transfer_status']) ? $IS_ROUTED : 0;
|
|
|
+ $conclusion |= ($delivered_duration > $VALID_HOURS) ? $IS_IN_VALID_TIME : 0;
|
|
|
+ $conclusion |= ($orderPackage->weighed_at) ? $IS_WEIGHED : 0;
|
|
|
+ $conclusion |= ($data['status'] == '已收件') ? $IS_RECEIVED : 0;
|
|
|
+ $conclusion |= ($data['status'] == '派送中') ? $IS_SENDING : 0;//
|
|
|
+ $conclusion |= ($last_routed_duration > $SHORT_RESPONSE_HOURS && $last_routed_duration < $LONG_RESPONSE_HOURS) ? $IS_SHORT_NO_RESPONSE : 0;
|
|
|
+ $conclusion |= ($last_routed_duration > $LONG_RESPONSE_HOURS) ? $IS_LONG_NO_RESPONSE : 0;
|
|
|
+ $conclusion |= ($last_routed_duration > $SENDING_RESPONSE_HOURS && $data['status'] == '派送中') ? $IS_SENDING_NO_RESPONSE : 0;
|
|
|
+ return $conclusion;
|
|
|
+ })();
|
|
|
+ switch ($conclusion) {
|
|
|
+ case $IS_IN_VALID_TIME:
|
|
|
+ $data['exception_type'] = '疑似库内丢件';
|
|
|
+ break;
|
|
|
+ case $IS_IN_VALID_TIME | $IS_WEIGHED:
|
|
|
+ $data['exception_type'] = '揽件异常';
|
|
|
+ break;
|
|
|
+ case $IS_ROUTED | $IS_IN_VALID_TIME | $IS_SHORT_NO_RESPONSE:
|
|
|
+ case $IS_ROUTED | $IS_IN_VALID_TIME | $IS_SHORT_NO_RESPONSE | $IS_WEIGHED:
|
|
|
+ $data['exception_type'] = '中转异常';
|
|
|
+ break;
|
|
|
+ case $IS_ROUTED | $IS_IN_VALID_TIME | $IS_LONG_NO_RESPONSE:
|
|
|
+ case $IS_ROUTED | $IS_IN_VALID_TIME | $IS_LONG_NO_RESPONSE | $IS_WEIGHED:
|
|
|
+ $data['exception_type'] = '疑似丢件';
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if ($conclusion
|
|
|
+ == ($conclusion | $IS_ROUTED | $IS_IN_VALID_TIME | $IS_SENDING | $IS_SENDING_NO_RESPONSE)) {
|
|
|
+ $data['exception_type'] = '派件异常';
|
|
|
+ }
|
|
|
+ switch ($conclusion) {
|
|
|
+ case $IS_IN_VALID_TIME:
|
|
|
+ case $IS_IN_VALID_TIME | $IS_WEIGHED:
|
|
|
+ case $IS_ROUTED | $IS_SHORT_NO_RESPONSE:
|
|
|
+ case $IS_LONG_NO_RESPONSE:
|
|
|
+ $data['exception'] = '是';
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return [
|
|
|
+ 'exception_type' => array_key_exists('exception_type', $data) ? $data['exception_type'] : null,
|
|
|
+ 'exception' => array_key_exists('exception', $data) ? $data['exception'] : null,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param $nativeData
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ private function getStatus($nativeData): string
|
|
|
+ {
|
|
|
+ $status = null;
|
|
|
+ switch ($nativeData->status) {
|
|
|
+ case 'GOT':
|
|
|
+ $status = '已揽收';
|
|
|
+ break;
|
|
|
+ case 'TRANSIT':
|
|
|
+ $status = '在途';
|
|
|
+ break;
|
|
|
+ case 'SIGNED':
|
|
|
+ $status = '已收件';
|
|
|
+ break;
|
|
|
+ case 'RETURN':
|
|
|
+ $status = '返回中';
|
|
|
+ break;
|
|
|
+ case 'SIGNFAIL':
|
|
|
+ $status = '无';
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ $status = '无';
|
|
|
+ }
|
|
|
+ return $status;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param $nativeRoutes
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function getTransferStatus($nativeRoutes): array
|
|
|
+ {
|
|
|
+ $transferStatus = [];
|
|
|
+ foreach ($nativeRoutes as $nativeRoute) {
|
|
|
+ $item = [];
|
|
|
+ $item['accept_time'] = $nativeRoute->time;
|
|
|
+ $item['accept_address'] = $nativeRoute->description;
|
|
|
+ $item['remark'] = "";
|
|
|
+ $transferStatus[] = $item;
|
|
|
+ }
|
|
|
+ return $transferStatus;
|
|
|
}
|
|
|
}
|