YqLogistics.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <?php
  2. namespace app\common\modules\express\expressCompany;
  3. use app\common\exceptions\AppException;
  4. use app\common\components\ApiController;
  5. use app\common\models\Order;
  6. use Yunshop\WorkWechat\common\service\WorkWechatService;
  7. use Yunshop\YunSignApi\common\models\Apps;
  8. use Yunshop\YunSignApi\common\models\AccessToken;
  9. use Yunshop\YunqianApi\common\service\WechatOcrService;
  10. use Yunshop\YunqianApi\common\service\ExpressService;
  11. use app\common\modules\express\getTraces;
  12. class YqLogistics implements Logistics
  13. {
  14. private $app_id;
  15. private $app_secret;
  16. //正式环境
  17. private $reqURL ='https://www.yunqiankeji.com/addons/yun_shop/api.php?i=1&uuid=0&type=5&route=plugin.yunqian-api.api.Express.getInfo';
  18. // private $reqURL ='https://dev1.yunzmall.com/addons/yun_shop/api.php?i=2&uuid=0&type=5&route=plugin.yunqian-api.api.Express.getInfo'; //测试地址
  19. public function __construct($data)
  20. {
  21. $server_name = $_SERVER['SERVER_NAME'];
  22. if (strexists($server_name, 'dev')) {
  23. //dev环境用本地
  24. $this->reqURL = 'https://dev1.yunzmall.com/addons/yun_shop/api.php?i=2&uuid=0&type=5&route=plugin.yunqian-api.api.Express.getInfo';
  25. }
  26. $this->app_id = trim($data['YQ']['appId']);
  27. $this->app_secret = trim($data['YQ']['appSecret']);
  28. }
  29. public function getTraces($comCode, $expressSn, $orderSn,$phoneLastFour){
  30. $pa = json_encode([
  31. 'number'=> $expressSn,
  32. 'company_code'=> $comCode,
  33. ]);
  34. if ($comCode == 'SF'){
  35. $pa = json_encode([
  36. 'number'=> trim($expressSn).':'.trim($phoneLastFour),
  37. 'company_code'=> $comCode,
  38. ]);
  39. }
  40. $array = $this->http_post_data($pa, $this->generateHeader(),$this->reqURL);
  41. $json_string = $array[1];
  42. $res = json_decode($json_string,true);
  43. $result = $this->format($res['data']);
  44. $result['data'] = array_reverse($result['data']);
  45. return $result;
  46. }
  47. private function generateHeader(){
  48. $millisecond = $this->getMillisecond();//为服务端时间前后5分钟内可以访问
  49. $nonceStr = $this->getNonceStr(16);//10到50位字符串
  50. $header=[
  51. 'appId:'.$this->app_id,
  52. 'signature:'.$this->getSignature($this->app_id,$this->app_secret,$nonceStr,$millisecond),
  53. 'nonceStr:'.$nonceStr,
  54. 'timestamp:'.$millisecond,
  55. 'Content-Type:application/json',
  56. ];
  57. return $header;
  58. }
  59. //计算请求签名值
  60. private function getSignature($appId, $appSecret,$nonceStr,$millisecond)
  61. {
  62. $s = $appId.'_'.$appSecret.'_'.$nonceStr.'_'.$millisecond;
  63. $signature = strtoupper(md5($s));
  64. return $signature;
  65. }
  66. //模拟发送POST请求
  67. /**
  68. * 模拟发送POST 方式请求
  69. * @param $url
  70. * @param $data
  71. * @param $projectId
  72. * @param $signature
  73. * @return array
  74. */
  75. private function http_post_data( $data, $header,$url) {
  76. $ch = curl_init();
  77. curl_setopt($ch, CURLOPT_POST, 1);
  78. curl_setopt($ch, CURLOPT_URL, $url);
  79. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  80. curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
  81. ob_start();
  82. curl_exec($ch);
  83. $return_content = ob_get_contents();
  84. ob_end_clean();
  85. $return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  86. //echo curl_errno($ch);
  87. return array($return_code, $return_content);
  88. }
  89. public function curl_post($postdata = '', $header = '', $url,$options = array())
  90. {
  91. $ch = curl_init($url);
  92. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  93. curl_setopt($ch, CURLOPT_POST, 1);
  94. curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
  95. curl_setopt($ch, CURLOPT_TIMEOUT, 5);
  96. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  97. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  98. curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
  99. if (!empty($options)) {
  100. curl_setopt_array($ch, $options);
  101. }
  102. $data = curl_exec($ch);
  103. curl_close($ch);
  104. return $data;
  105. }
  106. /**
  107. *
  108. * 产生随机字符串,不长于50位
  109. * @param int $length
  110. * @return 产生的随机字符串
  111. */
  112. private function getNonceStr($length = 50)
  113. {
  114. $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  115. $str ="";
  116. for ( $i = 0; $i < $length; $i++ ) {
  117. $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
  118. }
  119. return $str;
  120. }
  121. //获取当前时间戳(毫秒级)
  122. private function getMillisecond()
  123. {
  124. list($s1, $s2) = explode(' ', microtime());
  125. return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
  126. }
  127. private function format($response)
  128. {
  129. $result = [];
  130. foreach ($response['list'] as $trace) {
  131. $result['data'][] = [
  132. 'time' => $trace['time'],
  133. 'ftime' => $trace['time'],
  134. 'context' => $trace['status'],
  135. 'location' => null,
  136. ];
  137. }
  138. $result['state'] = $response['deliverystatus'];
  139. return $result;
  140. }
  141. public function getMobile($order_id)
  142. {
  143. if (empty($order_id)){
  144. throw new ShopException("订单id为空");
  145. }
  146. $address = Order::uniacid()->with(['address'])->where('id',$order_id)->first();
  147. if (empty($address['address']['mobile'])){
  148. throw new ShopException("订单收货人号码为空");
  149. }
  150. $mobile = substr($address['address']['mobile'],-4);
  151. return $mobile;
  152. }
  153. }