Expressquery.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. <?php
  2. namespace addons\expressquery\library;
  3. use think\Db;
  4. use think\Exception;
  5. use Throwable;
  6. class Expressquery
  7. {
  8. /**
  9. * 实现查询快递信息的钩子方法
  10. *
  11. * @param 类型 array 参数一的说明 [$express,$expresssn,$mobile]
  12. * @return array 返回类型
  13. * @example 示例 hook('get_express_list', [快递公司编码, 快递单号, 手机号])
  14. * @author Created by Xing <464401240@qq.com>
  15. */
  16. public function getExpressList($express, $expresssn, $mobile = '')
  17. {
  18. $list = ['code' => 0, 'msg' => '配置参数错误', 'data' => ''];
  19. if ($express && $expresssn) {
  20. $express_set = \app\admin\model\ExpressqueryConfig::all();
  21. $express_set = $express_set[0];
  22. $express = $express == 'jymwl' ? 'jiayunmeiwuliu' : $express;
  23. $express = $express == 'TTKD' ? 'tiantian' : $express;
  24. $express = $express == 'jjwl' ? 'jiajiwuliu' : $express;
  25. $express = $express == 'zhongtiekuaiyun' ? 'ztky' : $express;
  26. if ($express_set['express_type'] == 'kuaidiniao') {
  27. $list = $this->getExpressBird($express, $expresssn, $express_set, $mobile);
  28. } elseif ($express_set['express_type'] == 'kuaidi100') {
  29. $list = $this->getExpressOneHundred($express, $expresssn, $express_set, $mobile);
  30. } else {
  31. if ($express_set['express_type'] == 'ali') {
  32. $list = $this->getExpressAli($express, $expresssn, $express_set, $mobile);
  33. }
  34. }
  35. }
  36. return $list;
  37. }
  38. /**
  39. * 快递鸟
  40. * @param $express
  41. * @param $expresssn
  42. * @param string $mobile
  43. * @param $express_set
  44. * @return array|bool
  45. */
  46. private function getExpressBird($express, $expresssn, $express_set, $mobile = '')
  47. {
  48. if (empty($express_set['express_bird_userid']) || empty($express_set['express_bird_apikey'])) {
  49. return ['code' => 0, 'msg' => '配置参数错误', 'data' => ''];
  50. }
  51. if (!empty($express_set['express_bird_cache']) && 0 < $express_set['express_bird_cache']) {
  52. $cache_time = $express_set['express_bird_cache'] * 60;
  53. $cache = Db::name('expressquery_cache')->where(['express' => $express, 'expresssn' => $expresssn])->find();
  54. if (time() <= $cache['lasttime'] + $cache_time && !empty($cache['datas'])) {
  55. return ['code' => 1, 'msg' => '获取缓存数据成功', 'data' => json_decode($cache['datas'], true)];
  56. }
  57. }
  58. $url = 'http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx';
  59. $expressInfo = Db::name('expressquery')->where(['coding' => $express])->find();
  60. if (empty($expressInfo)) {
  61. return ['code' => 0, 'msg' => '没有找到快递公司编码', 'data' => ''];
  62. }
  63. $expressEncoding = $expressInfo['coding'];
  64. $requestData = array('ShipperCode' => $expressEncoding, 'LogisticCode' => $expresssn);
  65. if ($expressEncoding == 'SF') {
  66. $cunstomername = substr($mobile, -4);
  67. $requestData['CustomerName'] = $cunstomername;
  68. }
  69. if ($expressEncoding == 'JGSD') {
  70. $requestData['CustomerName'] = $express_set['express_bird_customer_name'];
  71. }
  72. $requestData = json_encode($requestData);
  73. $datas = array(
  74. 'EBusinessID' => $express_set['express_bird_userid'],
  75. 'RequestType' => '1002',
  76. 'RequestData' => urlencode($requestData),
  77. 'DataType' => '2'
  78. );
  79. $datas['DataSign'] = urlencode(base64_encode(md5($requestData . $express_set['express_bird_apikey'])));
  80. $response = $this->httpPost($url, $datas);
  81. $expressData = json_decode($response, true);
  82. if ($expressData['Success'] == false) {
  83. //重试一次
  84. $datas = array(
  85. 'EBusinessID' => $express_set['express_bird_userid'],
  86. 'RequestType' => '8001',
  87. 'RequestData' => urlencode($requestData),
  88. 'DataType' => '2'
  89. );
  90. $datas['DataSign'] = urlencode(base64_encode(md5($requestData . $express_set['express_bird_apikey'])));
  91. $response = $this->httpPost($url, $datas);
  92. $expressData = json_decode($response, true);
  93. }
  94. $list = array();
  95. if (!empty($expressData['Traces']) && is_array($expressData['Traces'])) {
  96. foreach ($expressData['Traces'] as $index => $data) {
  97. $list[] = array('time' => trim($data['AcceptTime']), 'step' => trim($data['AcceptStation']));
  98. }
  99. $list = array_reverse($list);
  100. } else {
  101. return ['code' => 0, 'msg' => $expressData['Reason'], 'data' => $expressData];
  102. }
  103. if (0 < $express_set['express_bird_cache'] && !empty($list)) {
  104. if (empty($cache)) {
  105. Db::name('expressquery_cache')->insert(
  106. [
  107. 'expresssn' => $expresssn,
  108. 'express' => $express,
  109. 'lasttime' => time(),
  110. 'datas' => json_encode($list)
  111. ]
  112. );
  113. } else {
  114. Db::name('expressquery_cache')->where(['id' => $cache['id']])->update(
  115. [
  116. 'lasttime' => time(),
  117. 'datas' => json_encode($list)
  118. ]
  119. );
  120. }
  121. }
  122. return ['code' => 1, 'msg' => 'success', 'data' => $list];
  123. }
  124. /**
  125. * 快递100
  126. * @param $express
  127. * @param $expresssn
  128. * @param string $mobile
  129. * @param $express_set
  130. * @return array
  131. */
  132. private function getExpressOneHundred($express, $expresssn, $express_set, $mobile = '')
  133. {
  134. if (empty($express_set['apikey'])) {
  135. return ['code' => 0, 'msg' => '配置参数错误', 'data' => ''];
  136. }
  137. if (!empty($express_set['express_bird_cache']) && 0 < $express_set['express_bird_cache']) {
  138. $cache_time = $express_set['express_bird_cache'] * 60;
  139. $cache = Db::name('expressquery_cache')->where(['express' => $express, 'expresssn' => $expresssn])->find();
  140. if (time() <= $cache['lasttime'] + $cache_time && !empty($cache['datas'])) {
  141. return ['code' => 1, 'msg' => '获取缓存数据成功', 'data' => json_decode($cache['datas'], true)];
  142. }
  143. }
  144. $expressInfo = Db::name('expressquery')->where(['express' => $express])->find();
  145. if (empty($expressInfo)) {
  146. return ['code' => 0, 'msg' => '没有找到快递公司编码', 'data' => ''];
  147. }
  148. if ($express_set['kuaidi100_type'] == 'free') {
  149. $url = 'http://api.kuaidi100.com/api?id=' . $express_set['apikey'] . '&com=' . $express . '&num=' . $expresssn;
  150. $params = array();
  151. } else {
  152. $url = 'http://poll.kuaidi100.com/poll/query.do';
  153. $params = array(
  154. 'customer' => $express_set['customer'],
  155. 'param' => json_encode(array('com' => $express, 'num' => $expresssn))
  156. );
  157. $params['sign'] = md5($params['param'] . $express_set['apikey'] . $params['customer']);
  158. $params['sign'] = strtoupper($params['sign']);
  159. $params['phone'] = $mobile;
  160. }
  161. $content = $this->httpPost($url, $params);
  162. $info = json_decode($content, true);
  163. $info['request_url'] = $url;
  164. if (!isset($info) || empty($info['data']) || !is_array($info['data'])) {
  165. $useapi = false;
  166. } else {
  167. $useapi = true;
  168. }
  169. $list = array();
  170. if (!empty($info['data']) && is_array($info['data'])) {
  171. foreach ($info['data'] as $index => $data) {
  172. if ($data['context'] == '查无结果') {
  173. continue;
  174. }
  175. $list[] = array('time' => trim($data['time']), 'step' => trim($data['context']));
  176. }
  177. } else {
  178. return ['code' => 0, 'msg' => $info['message'], 'data' => $info];
  179. }
  180. if ($useapi && 0 < $express_set['express_bird_cache'] && !empty($list)) {
  181. if (empty($cache)) {
  182. Db::name('expressquery_cache')->insert(
  183. [
  184. 'expresssn' => $expresssn,
  185. 'express' => $express,
  186. 'lasttime' => time(),
  187. 'datas' => json_encode($list)
  188. ]
  189. );
  190. } else {
  191. Db::name('expressquery_cache')->where(['id' => $cache['id']])->update(
  192. [
  193. 'lasttime' => time(),
  194. 'datas' => json_encode($list)
  195. ]
  196. );
  197. }
  198. }
  199. return ['code' => 1, 'msg' => 'success', 'data' => $list];
  200. }
  201. /**
  202. * 阿里云
  203. * @param $express
  204. * @param $expresssn
  205. * @param string $mobile
  206. * @param $express_set
  207. * @return array
  208. */
  209. private function getExpressAli($express, $expresssn, $express_set, $mobile = '')
  210. {
  211. $appcode = $express_set['aliappcode'];
  212. if (!$appcode) {
  213. return ['code' => 0, 'msg' => '配置参数错误', 'data' => ''];
  214. }
  215. //读取缓存数据
  216. if (!empty($express_set['express_bird_cache']) && 0 < $express_set['express_bird_cache']) {
  217. $cache_time = $express_set['express_bird_cache'] * 60;
  218. $cache = Db::name('expressquery_cache')->where(['express' => $express, 'expresssn' => $expresssn])->find();
  219. if (time() <= $cache['lasttime'] + $cache_time && !empty($cache['datas'])) {
  220. return ['code' => 1, 'msg' => '获取缓存数据成功', 'data' => json_decode($cache['datas'], true)];
  221. }
  222. }
  223. $url = 'https://wdexpress.market.alicloudapi.com/gxali';
  224. $method = 'GET';
  225. $expressInfo = Db::name('expressquery')->where(['express' => $express])->find();
  226. if (empty($expressInfo)) {
  227. return ['code' => 0, 'msg' => '没有找到快递公司编码', 'data' => ''];
  228. }
  229. $expressEncoding = $expressInfo['coding'];
  230. $headers = array();
  231. array_push($headers, 'Authorization:APPCODE ' . $appcode);
  232. if ($expressEncoding == 'SF') {
  233. $cunstomername = substr($mobile, -4);
  234. $querys = 'n=' . $expresssn . ':' . $cunstomername . '&t=' . $expressEncoding;
  235. } else {
  236. $querys = 'n=' . $expresssn . '&t=' . $expressEncoding;
  237. }
  238. $url = $url . '?' . $querys;
  239. $curl = curl_init();
  240. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
  241. curl_setopt($curl, CURLOPT_URL, $url);
  242. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  243. curl_setopt($curl, CURLOPT_FAILONERROR, false);
  244. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  245. curl_setopt($curl, CURLOPT_HEADER, false);
  246. //curl_setopt($curl, CURLOPT_HEADER, true); 如不输出json, 请打开这行代码,打印调试头部状态码。
  247. //状态码: 200 正常;400 URL无效;401 appCode错误; 403 次数用完; 500 API网管错误
  248. if (1 == strpos("$".$url, "https://")) {
  249. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  250. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
  251. }
  252. $out_put = curl_exec($curl);
  253. $expressData = json_decode($out_put, true);
  254. $list = array();
  255. if (!empty($expressData['Traces']) && is_array($expressData['Traces'])) {
  256. foreach ($expressData['Traces'] as $index => $data) {
  257. $list[] = array('time' => trim($data['AcceptTime']), 'step' => trim($data['AcceptStation']));
  258. }
  259. $list = array_reverse($list);
  260. } else {
  261. $expressData['querys'] = $querys;
  262. return ['code' => 0, 'msg' => 'error', 'data' => $expressData];
  263. }
  264. if (0 < $express_set['express_bird_cache'] && !empty($list)) {
  265. if (empty($cache)) {
  266. Db::name('expressquery_cache')->insert(
  267. [
  268. 'expresssn' => $expresssn,
  269. 'express' => $express,
  270. 'lasttime' => time(),
  271. 'datas' => json_encode($list)
  272. ]
  273. );
  274. } else {
  275. Db::name('expressquery_cache')->where(['id' => $cache['id']])->update(
  276. [
  277. 'lasttime' => time(),
  278. 'datas' => json_encode($list)
  279. ]
  280. );
  281. }
  282. }
  283. return ['code' => 1, 'msg' => 'success', 'data' => $list];
  284. }
  285. /**
  286. * Post提交数据
  287. *
  288. * @param string $url 请求的Url
  289. * @param array $datas 提交的数据
  290. * @return string 响应返回的html
  291. * @author Created by Xing <464401240@qq.com>
  292. */
  293. private function httpPost($url, $datas)
  294. {
  295. $temps = array();
  296. foreach ($datas as $key => $value) {
  297. $temps[] = sprintf('%s=%s', $key, $value);
  298. }
  299. $post_data = implode('&', $temps);
  300. $url_info = parse_url($url);
  301. if (empty($url_info['port'])) {
  302. $url_info['port'] = 80;
  303. }
  304. $httpheader = "POST " . $url_info['path'] . " HTTP/1.0\r\n";
  305. $httpheader .= "Host:" . $url_info['host'] . "\r\n";
  306. $httpheader .= "Content-Type:application/x-www-form-urlencoded\r\n";
  307. $httpheader .= "Content-Length:" . strlen($post_data) . "\r\n";
  308. $httpheader .= "Connection:close\r\n\r\n";
  309. $httpheader .= $post_data;
  310. $fd = fsockopen($url_info['host'], $url_info['port']);
  311. fwrite($fd, $httpheader);
  312. $gets = "";
  313. while (!feof($fd)) {
  314. if (($header = @fgets($fd)) && ($header == "\r\n" || $header == "\n")) {
  315. break;
  316. }
  317. }
  318. while (!feof($fd)) {
  319. $gets .= fread($fd, 128);
  320. }
  321. fclose($fd);
  322. return $gets;
  323. }
  324. }