Skip to content

Commit 2e2a6bd

Browse files
authored
Merge pull request #18 from aliliin/Aliliin
Aliliin
2 parents 300e210 + fe1dc26 commit 2e2a6bd

File tree

5 files changed

+514
-56
lines changed

5 files changed

+514
-56
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* 阿里云 [Aliyun](https://homenew.console.aliyun.com/)
1313
* 聚合数据 [Juhe](https://www.juhe.cn/docs/api/id/43)
1414
* 快递100 [Kuaidi100](https://www.kuaidi100.com/)
15+
* 快递鸟 [kdniao](https://www.kdniao.com/)
1516

1617
## 安装
1718

src/Config/logistics.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,9 @@
2424
'app_code' => env('LOGISTICS_APP_CODE'),
2525
'customer' => env('LOGISTICS_CUSTOMER'),
2626
],
27+
28+
'kdniao' => [
29+
'app_code' => env('LOGISTICS_APP_CODE'), /* AppKey */
30+
'customer' => env('LOGISTICS_CUSTOMER'), /* EBusinessID */
31+
],
2732
];

src/Providers/Kdniao.php

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
<?php
2+
/*
3+
* This file is part of the finehco/logistics.
4+
*
5+
* (c) Aliliin <PhperAli@Gmail.com>
6+
*
7+
* This source file is subject to the MIT license that is bundled
8+
* with this source code in the file LICENSE.
9+
*/
10+
11+
namespace Finecho\Logistics\Providers;
12+
13+
use Finecho\Logistics\Exceptions\HttpException;
14+
use Finecho\Logistics\Exceptions\InquiryErrorException;
15+
use Finecho\Logistics\Order;
16+
use Finecho\Logistics\Traits\HasHttpRequest;
17+
18+
/**
19+
* Class Kdniao.
20+
*
21+
* @author Aliliin <PhperAli@Gmail.com>
22+
*/
23+
class Kdniao extends AbstractProvider
24+
{
25+
use HasHttpRequest;
26+
27+
const PROVIDER_NAME = 'Kdniao';
28+
29+
const KDNIAO_NOT_PAY = 1002;
30+
31+
const KDNIAO_PAY = 8001;
32+
33+
const KDNIAO_DATA_TYPE = 2;
34+
35+
const LOGISTICS_INFO_URL = 'http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx';
36+
37+
const LOGISTICS_COM_CODE_URL = 'http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx';
38+
39+
const SUCCESS_STATUS = 200;
40+
const STATUS_ERROR = -1;
41+
const STATUS_NO_TRACK = 0;
42+
const STATUS_PACKAGE = 1;
43+
const STATUS_ON_THE_WAY = 2;
44+
const STATUS_SIGNING = 3;
45+
const STATUS_QUESTION_PACKAGE = 4;
46+
const STATUS_IN_THE_CITY = 201;
47+
const STATUS_IN_THE_PACKAGE = 202;
48+
const STATUS_DIEPOSIT_ARK = 211;
49+
const STATUS_NORMAL_SIGNING = 301;
50+
const STATUS_ABNORMAL_SIGNING = 302;
51+
const STATUS_ISSUING_SIGNING = 304;
52+
const STATUS_ARK_SIGNING = 311;
53+
const STATUS_NO_DELIVERY_INFO = 401;
54+
const STATUS_TIMEOUT_NOT_SIGNING = 402;
55+
const STATUS_TIMEOUT_NOT_UPDATE = 403;
56+
const STATUS_RETURN_PACKAGE = 404;
57+
const STATUS_PACKAGE_ERROR = 405;
58+
const STATUS_RETURN_SINGNING = 406;
59+
const STATUS_RETURN_NOT_SINGNING = 407;
60+
const STATUS_ARK_NOT_SINGNING = 412;
61+
62+
const STATUS_LABELS = [
63+
self::STATUS_ERROR => '异常',
64+
self::STATUS_NO_TRACK => '无轨迹',
65+
self::STATUS_PACKAGE => '已揽收',
66+
self::STATUS_SIGNING => '已签收',
67+
self::STATUS_ON_THE_WAY => '在途中',
68+
self::STATUS_QUESTION_PACKAGE => '问题件',
69+
self::STATUS_IN_THE_CITY => '到达派件城市',
70+
self::STATUS_IN_THE_PACKAGE => '派件中',
71+
self::STATUS_DIEPOSIT_ARK => '已放入快递柜或驿站',
72+
self::STATUS_NORMAL_SIGNING => '正常签收',
73+
self::STATUS_ABNORMAL_SIGNING => '派件异常后最终签收',
74+
self::STATUS_ISSUING_SIGNING => '代收签收',
75+
self::STATUS_ARK_SIGNING => '快递柜或驿站签收',
76+
self::STATUS_NO_DELIVERY_INFO => '发货无信息',
77+
self::STATUS_TIMEOUT_NOT_SIGNING => '超时未签收',
78+
self::STATUS_TIMEOUT_NOT_UPDATE => '超时未更新',
79+
self::STATUS_RETURN_PACKAGE => '拒收(退件)',
80+
self::STATUS_PACKAGE_ERROR => '派件异常',
81+
self::STATUS_RETURN_SINGNING => '退货签收',
82+
self::STATUS_RETURN_NOT_SINGNING => '退货未签收',
83+
self::STATUS_ARK_NOT_SINGNING => '快递柜或驿站超时未取',
84+
];
85+
86+
/**
87+
* @param $no
88+
* @param null $company
89+
*
90+
* @return \Finecho\Logistics\Order
91+
*
92+
* @throws \Finecho\Logistics\Exceptions\HttpException
93+
* @throws \Finecho\Logistics\Exceptions\InquiryErrorException
94+
* @throws \Finecho\Logistics\Exceptions\InvalidArgumentException
95+
*/
96+
public function order($no, $company = null)
97+
{
98+
99+
if (empty($company)) {
100+
$query['LogisticCode'] = $no;
101+
102+
$params = $this->getRequestParams($query,self::LOGISTICS_COM_CODE_TYPE);
103+
104+
$response = $this->sendRequestGet(self::LOGISTICS_COM_CODE_URL, $params, []);
105+
106+
if (!\is_array($response)) {
107+
$response = \json_decode($response, true);
108+
}
109+
110+
if (empty($response) || empty($response['Shippers'][0]['ShipperCode'])) {
111+
throw new InquiryErrorException('未查询到该订单信息!', 404, $response);
112+
}
113+
114+
$param['ShipperCode'] = $response['Shippers'][0]['ShipperCode'];
115+
} else {
116+
117+
$param['ShipperCode'] = $this->getLogisticsCompanyAliases($company);
118+
$this->company = $company;
119+
}
120+
121+
$param['LogisticCode'] = $no;
122+
123+
$params = $this->getRequestParams($param);
124+
125+
$response = $this->sendRequestPost(self::LOGISTICS_INFO_URL, $params, [], self::SUCCESS_STATUS);
126+
127+
// 处理未付费用户
128+
if ($response && $response['Success'] == false) {
129+
$params['RequestType'] = self::KDNIAO_NOT_PAY;
130+
131+
$response = $this->sendRequestPost(
132+
self::LOGISTICS_INFO_URL,
133+
$params,
134+
[],
135+
self::SUCCESS_STATUS
136+
);
137+
}
138+
139+
return $this->mapLogisticsOrderToObject($response)->merge(['original' => $response]);
140+
}
141+
142+
/**
143+
* @param $requestData
144+
* @param $requestType
145+
*
146+
* @return array
147+
*
148+
*/
149+
private function getRequestParams($requestData, $requestType = self::KDNIAO_PAY)
150+
{
151+
return [
152+
'EBusinessID' => $this->config[\strtolower(self::PROVIDER_NAME)]['customer'],
153+
'DataType' => self::KDNIAO_DATA_TYPE,
154+
'RequestType' => $requestType,
155+
'RequestData' => \urlencode(\json_encode($requestData)),
156+
'DataSign' => $this->generateSign($requestData, $this->config[\strtolower(self::PROVIDER_NAME)]['app_code']),
157+
];
158+
}
159+
160+
/**
161+
* @param $url
162+
* @param $params
163+
* @param $headers
164+
* @param int $SUCCESS_STATUS
165+
*
166+
* @return array
167+
*
168+
* @throws \Finecho\Logistics\Exceptions\HttpException
169+
* @throws \Finecho\Logistics\Exceptions\InquiryErrorException
170+
*/
171+
protected function sendRequestPost($url, $params, $headers, $SUCCESS_STATUS = self::GLOBAL_SUCCESS_CODE)
172+
{
173+
try {
174+
$result = $this->post($url, $params, $headers);
175+
} catch (\Exception $e) {
176+
throw new HttpException($e->getMessage(), $e->getCode(), $e);
177+
}
178+
179+
if (!\is_array($result)) {
180+
$result = \json_decode($result, true);
181+
}
182+
183+
if (isset($result['returnCode']) && $SUCCESS_STATUS != $result['returnCode']) {
184+
throw new InquiryErrorException($result['message'], $result['returnCode'], $result);
185+
}
186+
187+
return $result;
188+
}
189+
190+
/**
191+
* @param $logisticsOrder
192+
*
193+
* @return \Finecho\Logistics\Order
194+
*/
195+
protected function mapLogisticsOrderToObject($logisticsOrder)
196+
{
197+
$status = empty($logisticsOrder['StateEx']) ? \intval($logisticsOrder['State']) : \intval($logisticsOrder['StateEx']);
198+
199+
$list = $this->resetList($logisticsOrder['Traces']);
200+
201+
return new Order([
202+
'code' => self::GLOBAL_SUCCESS_CODE,
203+
'msg' => self::GLOBAL_SUCCESS_MSG,
204+
'company' => $this->company ?: $logisticsOrder['ShipperCode'],
205+
'no' => $logisticsOrder['LogisticCode'],
206+
'status' => \in_array($status, \array_keys(self::STATUS_LABELS)) ? self::STATUS_LABELS[$status] : self::STATUS_LABELS[self::STATUS_ERROR],
207+
'list' => $list,
208+
'original' => $logisticsOrder,
209+
]);
210+
}
211+
212+
/**
213+
* @param array $list
214+
*
215+
* @return array
216+
*/
217+
protected function resetList($list)
218+
{
219+
if (\array_intersect(['AcceptStation', 'AcceptTime'], \array_keys(\current($list))) == ['AcceptStation', 'AcceptTime'] || empty($list)) {
220+
return $list;
221+
}
222+
223+
\array_walk($list, function (&$list, $key, $names) {
224+
unset($list['time']);
225+
$list = array_combine($names, $list);
226+
}, ['AcceptStation', 'AcceptTime']);
227+
228+
return $list;
229+
}
230+
231+
/**
232+
* @param string $url
233+
* @param array $params
234+
* @param array $headers
235+
*
236+
* @return array
237+
*
238+
* @throws \Finecho\Logistics\Exceptions\HttpException
239+
*/
240+
protected function sendRequestGet($url, $params, $headers)
241+
{
242+
try {
243+
$result = $this->get($url, $params, $headers);
244+
} catch (\Exception $e) {
245+
throw new HttpException($e->getMessage(), $e->getCode(), $e);
246+
}
247+
248+
return $result;
249+
}
250+
251+
/**
252+
* @return string
253+
*/
254+
public function getProviderName()
255+
{
256+
return static::PROVIDER_NAME;
257+
}
258+
259+
/**
260+
* @param $param
261+
* @param $key
262+
* @param $customer
263+
*
264+
* @return string
265+
*/
266+
protected function generateSign($param, $key)
267+
{
268+
return urlencode(base64_encode(md5(\json_encode($param) . $key)));
269+
}
270+
}

0 commit comments

Comments
 (0)