|
|
@@ -4,6 +4,8 @@
|
|
|
namespace App\Services;
|
|
|
|
|
|
|
|
|
+use Exception;
|
|
|
+use Illuminate\Http\Client\Response;
|
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
|
|
class LogisticQiaoSFService
|
|
|
@@ -20,10 +22,11 @@ class LogisticQiaoSFService
|
|
|
|
|
|
/**
|
|
|
* 获取顺丰快递揽收数据
|
|
|
- * @param $logisticNums [logisticNums]快递单号数组
|
|
|
+ * @param array $logisticNums [logisticNums]快递单号数组
|
|
|
* @return array 快递揽收信息数组
|
|
|
+ * @throws Exception 未知的丰桥opCode
|
|
|
*/
|
|
|
- public function get($logisticNums): array
|
|
|
+ public function get(array $logisticNums): array
|
|
|
{
|
|
|
// 将$logisticNums以10个位单位进行分割,返回二维数组
|
|
|
$logisticNums_size_10 = array_chunk($logisticNums, config('api_logistic.SF.max_size', 10));
|
|
|
@@ -44,22 +47,16 @@ class LogisticQiaoSFService
|
|
|
* @param string $checkWord 客户秘钥
|
|
|
* @param string $url 顺丰接口地址
|
|
|
* @return array
|
|
|
+ * @throws Exception 未知的丰桥opCode
|
|
|
*/
|
|
|
public function getResultFromSF(string $head, string $numbers, string $checkWord, string $url): array
|
|
|
{
|
|
|
- $xml = $this->buildXmlStr($head, $numbers);
|
|
|
- $checkingJson = $xml . $checkWord;
|
|
|
- $verifyCode = base64_encode(md5($checkingJson, true));
|
|
|
- $response = Http::withHeaders(['Content-Type' => 'text/xml'])->get($url, ['xml' => $xml, 'verifyCode' => $verifyCode]);
|
|
|
-
|
|
|
- $routeResponses = get_object_vars(simplexml_load_string($response)->Body)['RouteResponse'];
|
|
|
+ $responseBody = get_object_vars(simplexml_load_string($this->sendHttpToSF($head, $numbers, $checkWord, $url))->Body)['RouteResponse'];
|
|
|
$result = [];
|
|
|
- if (is_array($routeResponses)) {
|
|
|
- foreach ($routeResponses as $routeResponse) {
|
|
|
- $result[] = $this->buildData(get_object_vars($routeResponse), []);
|
|
|
- }
|
|
|
+ if (is_array($responseBody)) {//SF返回多个单号的查询结果
|
|
|
+ $result = $this->transformSFMoreToArr($responseBody, $result);
|
|
|
} else {
|
|
|
- $result[] = $this->buildData(get_object_vars($routeResponses), []);
|
|
|
+ $result[] = $this->transformSFOneToArr(get_object_vars($responseBody), []);
|
|
|
}
|
|
|
return $result;
|
|
|
}
|
|
|
@@ -70,7 +67,7 @@ class LogisticQiaoSFService
|
|
|
* @param string $number
|
|
|
* @return string
|
|
|
*/
|
|
|
- public function buildXmlStr(string $head, string $number): string
|
|
|
+ private function buildXmlStr(string $head, string $number): string
|
|
|
{
|
|
|
return <<<xml
|
|
|
<?xml version="1.0" encoding="utf-8" ?>
|
|
|
@@ -86,23 +83,117 @@ xml;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 将顺丰的数据转换为数组
|
|
|
+ * 将单个单号的顺丰数据转换为数组
|
|
|
* @param array $routeResponse
|
|
|
* @param array $data
|
|
|
* @return array
|
|
|
+ * @throws Exception
|
|
|
*/
|
|
|
- public function buildData(array $routeResponse, array $data): array
|
|
|
+ public function transformSFOneToArr(array $routeResponse, array $data): array
|
|
|
{
|
|
|
$data['logistic_number'] = $routeResponse['@attributes'][$this->protected_switch['logistic_number']];
|
|
|
- foreach ($routeResponse['Route'] as $route) {
|
|
|
+ $lastRoute = get_object_vars($routeResponse['Route'][count($routeResponse['Route']) - 1])['@attributes'];//获取最新的路由信息
|
|
|
+ $data = $this->switchOpCodeToStatus($lastRoute, $data);
|
|
|
+ $data['transfer_status'] = $this->transformRoutes($routeResponse['Route']);
|
|
|
+ return $data;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换快递路由信息
|
|
|
+ * @param array $routs 快递路由
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public function transformRoutes(array $routs): array
|
|
|
+ {
|
|
|
+ $result = [];
|
|
|
+ foreach ($routs as $route) {
|
|
|
$route = get_object_vars($route)['@attributes'];
|
|
|
- if ($route['opcode'] == config('api_logistic.SF.received_code', 50)) {
|
|
|
+ $data['accept_time'] = $route['accept_time'];
|
|
|
+ $data['accept_address'] = $route['accept_address'];
|
|
|
+ $data['remark'] = $route['remark'];
|
|
|
+ $result[] = $data;
|
|
|
+ }
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将最新路由信息转换为数组
|
|
|
+ * @param array $lastRoute
|
|
|
+ * @param array $data
|
|
|
+ * @return array
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public function switchOpCodeToStatus(array $lastRoute, array $data): array
|
|
|
+ {
|
|
|
+ switch ($lastRoute['opcode']) {
|
|
|
+ case 123:
|
|
|
+ case 130:
|
|
|
+ case 3036:
|
|
|
+ case 31:
|
|
|
+ case 30:
|
|
|
+ $data['status'] = '在途';
|
|
|
+ break;
|
|
|
+ case 70:
|
|
|
+ case 33:
|
|
|
+ $data['status'] = '派送异常';
|
|
|
+ $data['exception'] = '是';
|
|
|
+ break;
|
|
|
+ case 204:
|
|
|
+ case 44:
|
|
|
+ $data['status'] = '派送中';
|
|
|
+ break;
|
|
|
+ case 50:
|
|
|
$data['status'] = '已揽收';
|
|
|
- $data['transfer_status'] = $route[$this->protected_switch['transfer_status']];
|
|
|
- $data['received_at'] = $route[$this->protected_switch['received_at']];
|
|
|
- continue;
|
|
|
- }
|
|
|
+ break;
|
|
|
+ case 607:
|
|
|
+ case 8000:
|
|
|
+ case 80:
|
|
|
+ $data['status'] = '已收件';
|
|
|
+ $data['received_at'] = $lastRoute[$this->protected_switch['received_at']];
|
|
|
+ break;
|
|
|
+ case 648:
|
|
|
+ case 99:
|
|
|
+ $data['status'] = '返回中';
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new Exception("未知的丰桥状态码: " . $lastRoute['opcode'] . '->' . json_encode($lastRoute));
|
|
|
}
|
|
|
return $data;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param string $head
|
|
|
+ * @param string $numbers
|
|
|
+ * @param string $checkWord
|
|
|
+ * @param string $url
|
|
|
+ * @return Response
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public function sendHttpToSF(string $head, string $numbers, string $checkWord, string $url): Response
|
|
|
+ {
|
|
|
+ $xml = $this->buildXmlStr($head, $numbers);
|
|
|
+ $checkingJson = $xml . $checkWord;
|
|
|
+ $verifyCode = base64_encode(md5($checkingJson, true));
|
|
|
+ try {
|
|
|
+ $response = Http::withHeaders(['Content-Type' => 'text/xml'])->get($url, ['xml' => $xml, 'verifyCode' => $verifyCode]);
|
|
|
+ } catch (Exception $e) {
|
|
|
+ throw new Exception("HTTP请求顺丰接口异常" . '->' . $e->getMessage());
|
|
|
+ }
|
|
|
+ return $response;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将多个顺丰的单号转换为数组
|
|
|
+ * @param array $responseBody
|
|
|
+ * @param array $result
|
|
|
+ * @return array
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public function transformSFMoreToArr(array $responseBody, array $result): array
|
|
|
+ {
|
|
|
+ foreach ($responseBody as $routeResponse) {
|
|
|
+ $result[] = $this->transformSFOneToArr(get_object_vars($routeResponse), []);
|
|
|
+ }
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
}
|