RejectedController.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <?php
  2. namespace App\Http\Controllers\api\thirdPart\jianshang;
  3. use App\Http\Controllers\Controller;
  4. use App\Logistic;
  5. use App\QualityLabel;
  6. use App\RejectedBill;
  7. use App\RejectedBillItem;
  8. use Carbon\Carbon;
  9. use Illuminate\Http\Request;
  10. use Illuminate\Support\Collection;
  11. use Illuminate\Support\Facades\Auth;
  12. use Zttp\Zttp;
  13. use Zttp\ZttpResponse;
  14. class RejectedController extends Controller
  15. {
  16. function sendRejected($rejected){
  17. $amount = $rejected['amount'] ?? '';
  18. $created_at = $rejected['created_at'] ?? '';
  19. $fee_collected = $rejected['fee_collected'] ?? '';
  20. $goods_barcode = $rejected['barcode_goods'] ?? '';
  21. $goods_name = $rejected['name_goods'] ?? '';
  22. $logistic_name_return = Logistic::nameById($rejected['id_logistic_return']);
  23. $logistic_number = $rejected['logistic_number'] ?? '';
  24. $logistic_number_return = $rejected['logistic_number_return'] ?? '';
  25. $order_number = $rejected['order_number'] ?? '';
  26. $quality_label = QualityLabel::where('id',$rejected['id_quality_label'])->first();
  27. $quality_label = $quality_label?$quality_label['name']:'';
  28. $sender_mobile = $rejected['mobile_sender'] ?? '';
  29. $sender_name = $rejected['sender'] ?? '';
  30. $json = $this->packSendToRemote($amount,$created_at,$fee_collected,$goods_barcode,
  31. $goods_name,$logistic_name_return,$logistic_number,$logistic_number_return,$order_number,
  32. $quality_label,$sender_mobile,$sender_name);
  33. if(!$json){
  34. app('LogService')->log(__METHOD__,'error'.'_'.$logistic_number_return,"没有返回");
  35. return false;
  36. }
  37. if(!$json['success']){
  38. app('LogService')->log(__METHOD__,'error'.'_'.$logistic_number_return,"返回错误:".json_encode($json));
  39. return false;
  40. }else{
  41. app('LogService')->log(__METHOD__,'JianshangResponse'.'_'.$logistic_number_return,json_encode($json));
  42. }
  43. return $json;
  44. }
  45. function sendRejectedByApi(Request $request){
  46. $amount = $request->input('amount') ?? '';
  47. $created_at = $request->input('created_at') ?? '';
  48. $fee_collected = $request->input('fee_collected') ?? '';
  49. $goods_barcode = $request->input('goods_barcode') ?? '';
  50. $goods_name = $request->input('goods_name') ?? '';
  51. $logistic_name_return = $request->input('logistic_name_return') ?? '';
  52. $logistic_number = $request->input('logistic_number') ?? '';
  53. $logistic_number_return = $request->input('logistic_number_return') ?? '';
  54. $order_number = $request->input('order_number') ?? '';
  55. $quality_label = $request->input('quality_label') ?? '';
  56. $sender_mobile = $request->input('sender_mobile') ?? '';
  57. $sender_name = $request->input('sender_name') ?? '';
  58. $json = $this->packSendToRemote($amount,$created_at,$fee_collected,$goods_barcode,
  59. $goods_name,$logistic_name_return,$logistic_number,$logistic_number_return,$order_number,
  60. $quality_label,$sender_mobile,$sender_name);
  61. if(!$json)return ['success'=>'false','fail_info'=>'没有JSON回复'];
  62. if(!$json['success']){return $this->apiError(__METHOD__,"返回错误:".json_encode($json));}
  63. return $json;
  64. }
  65. private function packSendToRemote($amount,$created_at,$fee_collected,$goods_barcode,
  66. $goods_name,$logistic_name_return,$logistic_number,$logistic_number_return,$order_number,
  67. $quality_label,$sender_mobile,$sender_name){
  68. if(env('api_faking')){
  69. app('LogService')->log(__METHOD__,'error_'.__FUNCTION__,'API FAKING');
  70. return false;
  71. }
  72. $data="{\"amount\":\"$amount\", \"created_at\":\"$created_at\", \"fee_collected\":\"$fee_collected\",
  73. \"goods_barcode\":\"$goods_barcode\", \"goods_name\":\"$goods_name\", \"logistic_name_return\":\"$logistic_name_return\",
  74. \"logistic_number\":\"$logistic_number\", \"logistic_number_return\":\"$logistic_number_return\",
  75. \"order_number\":\"$order_number\", \"quality_label\":\"$quality_label\", \"sender_mobile\":\"$sender_mobile\", \"sender_name\":\"$sender_name\"}";
  76. $sortParamsAndMd5=function(Array $params,$timestamp,$nonce,$signKey){
  77. $params=new Collection($params);
  78. $params=$params->sortKeys();
  79. $str='';
  80. $params->each(function($param,$key)use(&$str){
  81. $val=trim($param);
  82. if($val){
  83. $str .= $key.$val;
  84. }
  85. });
  86. return strtolower(md5($str.$timestamp.$nonce.$signKey));
  87. };
  88. $timestamp=intval(microtime(true)*1000);
  89. $nonce=md5(microtime(true));
  90. $sign=$sortParamsAndMd5(json_decode($data,true),$timestamp,$nonce,config('api.sign_key_rejected_send_jianshang'));
  91. $url=config('api.url_rejected_send_jianshang');
  92. $response=Zttp::withHeaders([
  93. 'sign'=>$sign,
  94. 'nonce'=>$nonce,
  95. 'timestamp'=>$timestamp,
  96. 'Content-Type'=>'application/json'
  97. ])->post($url,json_decode($data,true));
  98. app('LogService')->log(__METHOD__,__FUNCTION__,$data);
  99. if(!$response){
  100. app('LogService')->log(__METHOD__,'error_'.__FUNCTION__,'回复异常:'.$response->body());
  101. return false;
  102. }
  103. if(!$response->json()){
  104. app('LogService')->log(__METHOD__,'error_'.__FUNCTION__,'json为空:'.$response->body());
  105. return false;
  106. }
  107. return $response->json();
  108. }
  109. function sendRejected2(array $rejected){
  110. if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"发送笕尚接口,进入入口。退单号:{$rejected['logistic_number_return']}",Auth::user()['id']);
  111. $created_at = $rejected['created_at'] ?? '';
  112. $fee_collected = $rejected['fee_collected'] ?? '';
  113. $goodses=[];
  114. foreach ($rejected['goodses'] as $goods){
  115. $temGoods['amount']=$goods['amount'] ?? '';
  116. $temGoods['goods_barcode']=$goods['barcode_goods'] ?? '';
  117. $temGoods['goods_name']=$goods['name_goods'] ?? '';
  118. $temGoods['quality_label']=$goods['quality_label'] ?? '';
  119. $goodses[]=$temGoods;
  120. }
  121. $logistic_name_return = Logistic::nameById($rejected['id_logistic_return']);
  122. $logistic_number = $rejected['logistic_number'] ?? '';
  123. $logistic_number_return = $rejected['logistic_number_return'] ?? '';
  124. $order_number = $rejected['order_number'] ?? '';
  125. $sender_mobile = $rejected['mobile_sender'] ?? '';
  126. $sender_name = $rejected['sender'] ?? '';
  127. $json = $this->packSendToRemote2($created_at,$fee_collected,$goodses,
  128. $logistic_name_return,$logistic_number,$logistic_number_return,$order_number,
  129. $sender_mobile,$sender_name);
  130. if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"发送笕尚接口调度完成。退单号:{$rejected['logistic_number_return']}",Auth::user()['id']);
  131. if(!$json){
  132. if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"发送笕尚接口异常,没有json返回。退单号:{$rejected['logistic_number_return']}",Auth::user()['id']);
  133. return 'fail';
  134. }else if(!isset($json['success'])||!$json['success']){
  135. if(strpos(json_encode($json),'已经接收过')!==false){
  136. return 'received';
  137. }
  138. if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"发送笕尚接口错误。退单号:{$rejected['logistic_number_return']}。".json_encode($json),Auth::user()['id']);
  139. return 'fail';
  140. }
  141. if(!$json['goodses_feedback']){
  142. if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"发送笕尚接口返回不全,没有商品信息返回(goodses)。退单号:{$rejected['logistic_number_return']}。".json_encode($json),Auth::user()['id']);
  143. }
  144. if(!$json['logistic_number_return']){
  145. if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"发送笕尚接口返回不全,没有退回快递单号。退单号:{$rejected['logistic_number_return']}。".json_encode($json),Auth::user()['id']);
  146. }
  147. $storable = (function ()use($json) {
  148. if(count($json['goodses_feedback'])==0)return false;
  149. foreach ($json['goodses_feedback'] as $goods){
  150. if(!$goods['storable']){
  151. return false;
  152. }
  153. }
  154. return true;
  155. })();
  156. if(!$storable){
  157. if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"发送笕尚接口提示,商品不可入库。退单号:{$rejected['logistic_number_return']}".json_encode($json),Auth::user()['id']);
  158. return 'none';
  159. }
  160. if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"发送笕尚接口完成,可入库,待其未来推单。退单号:{$rejected['logistic_number_return']}".json_encode($json),Auth::user()['id']);
  161. // $this->markItemsIsLoaded($json);
  162. return 'storable';
  163. }
  164. private function packSendToRemote2($created_at,$fee_collected,$goodses,
  165. $logistic_name_return,$logistic_number,$logistic_number_return,$order_number,
  166. $sender_mobile,$sender_name){
  167. foreach ($goodses as $goods){
  168. asort($goods);
  169. }
  170. $goodses = json_encode($goodses);
  171. $data="{\"created_at\":\"$created_at\", \"fee_collected\":\"$fee_collected\",
  172. \"goodses\":$goodses,\"logistic_name_return\":\"$logistic_name_return\",
  173. \"logistic_number\":\"$logistic_number\", \"logistic_number_return\":\"$logistic_number_return\",
  174. \"order_number\":\"$order_number\", \"sender_mobile\":\"$sender_mobile\", \"sender_name\":\"$sender_name\"}";
  175. $sortParamsAndMd5=function(Array $params,$timestamp,$nonce,$signKey){
  176. $params=new Collection($params);
  177. $params=$params->sortKeys();
  178. $str='';
  179. $params->each(function($param,$key)use(&$str){
  180. if(is_array($param)){return;
  181. // foreach ($param as &$paramValArr){
  182. // foreach ($paramValArr as &$paramVal){
  183. // $paramVal = trim($paramVal);
  184. // }
  185. // }
  186. // $param=json_encode($param);
  187. }
  188. $val=trim($param);
  189. if($val){
  190. $str .= $key.$val;
  191. }
  192. });
  193. $forSign = $str . $timestamp . $nonce . $signKey;
  194. return strtolower(md5($forSign));
  195. };
  196. $timestamp=intval(microtime(true)*1000);
  197. $nonce=md5(microtime(true));
  198. $sign=$sortParamsAndMd5(json_decode($data,true),$timestamp,$nonce,config('api.sign_key_rejected_send_jianshang'));
  199. app('LogService')->log(__METHOD__,'笕尚接口发送请求:',$data);
  200. $url=config('api.url_rejected_send_jianshang2');
  201. if(env('api_faking'))$url=url(config('api.fakingUrl_rejected_send_jianshang'));
  202. try{
  203. /** @var ZttpResponse $response */
  204. $response=Zttp::withHeaders([
  205. 'sign'=>$sign,
  206. 'nonce'=>$nonce,
  207. 'timestamp'=>$timestamp,
  208. 'Content-Type'=>'application/json'
  209. ])->post($url,json_decode($data,true));
  210. }catch (\Exception $e){
  211. app('LogService')->log(__METHOD__,'笕尚接口返回异常!!:',$e->getMessage().'||'.json_encode($data));
  212. $response=false;
  213. }
  214. if(!$response){
  215. app('LogService')->log(__METHOD__,'笕尚接口返回异常!!:',"沒有返回");
  216. return false;
  217. }
  218. app('LogService')->log(__METHOD__,'笕尚接口返回:',$response->body());
  219. return $response->json();
  220. }
  221. private function markItemsIsLoaded($json){
  222. $barcodes=[];
  223. foreach ($json['goodses_feedback'] as $goods){
  224. $barcodes[]=trim($goods['goods_barcode']);
  225. }
  226. $bill=RejectedBill::where('logistic_number_return',$json['logistic_number_return'])->first();
  227. $items=RejectedBillItem::where('id_rejected_bill',$bill['id'])->whereIn('barcode_goods',$barcodes)->get();
  228. $items->each(function(RejectedBillItem $item)use(&$json){
  229. foreach ($json['goodses_feedback'] as &$goods1){ //标记出有重复条码的商品,并且标记出其中是否同时有不能入库可和可以入库的
  230. $goods1['sameBarcode']=0;
  231. $goods1['hasUnStorable']=false;
  232. $goods1['hasStorable']=false;
  233. foreach ($json['goodses_feedback'] as &$goods2){
  234. if($goods1['goods_barcode']==$goods2['goods_barcode']){
  235. $goods1['sameBarcode']+=1;
  236. if(!$goods2['storable']){
  237. $goods1['hasUnStorable']=true;
  238. }else{
  239. $goods1['hasStorable']=true;
  240. }
  241. }
  242. }
  243. }
  244. foreach ($json['goodses_feedback'] as $goods){
  245. if($item['barcode_goods']==$goods['goods_barcode']){
  246. $item['is_loaded'] = $goods['storable']==='true'|| $goods['storable']===true ? '已入库':'未入库';
  247. if($goods['sameBarcode']>1){//如果该条码有不止一件,并且同时拥有入库和不入库的,就按品质标签来区分入库与否(因为回传不带是否正品消息,也没有ID)
  248. if($goods['hasUnStorable']&&$goods['hasStorable']){
  249. if($item['id_quality_label']==1){
  250. $item['is_loaded'] ='已入库';
  251. }else{
  252. $item['is_loaded'] ='未入库';
  253. }
  254. }
  255. }
  256. $item->update();
  257. }
  258. }
  259. });
  260. return $bill;
  261. }
  262. }